visionary-sdk 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +19 -0
- data/LICENSE +202 -0
- data/README.md +198 -0
- data/lib/visionary/agent.rb +174 -0
- data/lib/visionary/body.rb +162 -0
- data/lib/visionary/config.rb +151 -0
- data/lib/visionary/context.rb +97 -0
- data/lib/visionary/fork.rb +16 -0
- data/lib/visionary/middleware.rb +169 -0
- data/lib/visionary/queue.rb +57 -0
- data/lib/visionary/railtie.rb +48 -0
- data/lib/visionary/redactor.rb +94 -0
- data/lib/visionary/retention.rb +90 -0
- data/lib/visionary/schema/mysql/requests.sql +37 -0
- data/lib/visionary/schema/mysql/system.sql +76 -0
- data/lib/visionary/schema/mysql/telemetry.sql +52 -0
- data/lib/visionary/schema/postgres/requests.sql +37 -0
- data/lib/visionary/schema/postgres/system.sql +76 -0
- data/lib/visionary/schema/postgres/telemetry.sql +52 -0
- data/lib/visionary/schema/sqlite/requests.sql +37 -0
- data/lib/visionary/schema/sqlite/system.sql +76 -0
- data/lib/visionary/schema/sqlite/telemetry.sql +52 -0
- data/lib/visionary/schema.rb +163 -0
- data/lib/visionary/schemas.rb +64 -0
- data/lib/visionary/store/active_record.rb +103 -0
- data/lib/visionary/store/d1.rb +129 -0
- data/lib/visionary/store/sql.rb +272 -0
- data/lib/visionary/store.rb +53 -0
- data/lib/visionary/system/recorder.rb +353 -0
- data/lib/visionary/system/sources.rb +191 -0
- data/lib/visionary/telemetry/errors.rb +118 -0
- data/lib/visionary/telemetry/hooks.rb +115 -0
- data/lib/visionary/telemetry/sql_text.rb +44 -0
- data/lib/visionary/telemetry.rb +116 -0
- data/lib/visionary/version.rb +5 -0
- data/lib/visionary/writer.rb +185 -0
- data/lib/visionary.rb +157 -0
- metadata +90 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Visionary
|
|
6
|
+
# Scrubs credentials from headers and bodies before anything is stored.
|
|
7
|
+
# The body patterns are regexes on purpose, so bodies cut off by the
|
|
8
|
+
# capture cap (invalid JSON) are still scrubbed.
|
|
9
|
+
class Redactor
|
|
10
|
+
REDACTED = "[REDACTED]"
|
|
11
|
+
DEFAULT_HEADERS = %w[Authorization Proxy-Authorization Cookie Set-Cookie X-Api-Key X-Auth-Token].freeze
|
|
12
|
+
DEFAULT_FIELDS = %w[
|
|
13
|
+
password passwd secret client_secret token access_token refresh_token id_token
|
|
14
|
+
api_key apikey otp pin card_number cvv private_key
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
def initialize(extra_headers = [], extra_fields = [], request_only = [])
|
|
18
|
+
@headers = (DEFAULT_HEADERS + extra_headers).map { |h| h.strip.downcase }.reject(&:empty?).to_h { |h| [h, true] }
|
|
19
|
+
both = key_pattern(DEFAULT_FIELDS + extra_fields)
|
|
20
|
+
req_only = key_pattern(request_only)
|
|
21
|
+
req_keys = req_only.empty? ? both : "#{both}|#{req_only}"
|
|
22
|
+
@resp_json = json_secrets(both)
|
|
23
|
+
@req_json = json_secrets(req_keys)
|
|
24
|
+
@form = /(^|&)(#{req_keys})=[^&]*/i
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Headers is [[name, value], ...]; the result is a JSON object.
|
|
28
|
+
def headers(pairs)
|
|
29
|
+
return "" if pairs.empty?
|
|
30
|
+
out = {}
|
|
31
|
+
pairs.each { |name, value| out[Visionary.utf8(name)] = @headers[name.downcase] ? REDACTED : Visionary.utf8(value) }
|
|
32
|
+
JSON.generate(out.sort.to_h)
|
|
33
|
+
rescue JSON::GeneratorError, EncodingError
|
|
34
|
+
""
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def request_body(body, content_type)
|
|
38
|
+
return "" if body.empty?
|
|
39
|
+
if content_type.to_s.include?("application/x-www-form-urlencoded")
|
|
40
|
+
body.gsub(@form) { "#{Regexp.last_match(1)}#{Regexp.last_match(2)}=#{REDACTED}" }
|
|
41
|
+
else
|
|
42
|
+
body.gsub(@req_json) { "#{Regexp.last_match(1)}\"#{REDACTED}\"" }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def response_body(body)
|
|
47
|
+
return "" if body.empty?
|
|
48
|
+
body.gsub(@resp_json) { "#{Regexp.last_match(1)}\"#{REDACTED}\"" }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# The error code and key from a JSON error response at dotted paths.
|
|
52
|
+
# Bodies that aren't valid JSON (e.g. truncated) fall back to a pattern
|
|
53
|
+
# match on the path's last segment.
|
|
54
|
+
def self.error_fields(body, code_path, key_path)
|
|
55
|
+
v = begin
|
|
56
|
+
JSON.parse(body)
|
|
57
|
+
rescue JSON::ParserError, EncodingError
|
|
58
|
+
return [match_field(body, code_path), match_field(body, key_path)]
|
|
59
|
+
end
|
|
60
|
+
[lookup(v, code_path), lookup(v, key_path)]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.lookup(v, path)
|
|
64
|
+
return "" if path.to_s.empty?
|
|
65
|
+
path.split(".").each do |seg|
|
|
66
|
+
return "" unless v.is_a?(Hash)
|
|
67
|
+
v = v[seg]
|
|
68
|
+
end
|
|
69
|
+
case v
|
|
70
|
+
when String then v
|
|
71
|
+
when Integer then v.to_s
|
|
72
|
+
when Float then v.finite? && v == v.floor && v.abs < 1e15 ? v.to_i.to_s : v.to_s
|
|
73
|
+
else ""
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.match_field(body, path)
|
|
78
|
+
return "" if path.to_s.empty?
|
|
79
|
+
last = path.split(".").last
|
|
80
|
+
m = body.match(/"#{Regexp.escape(last)}"\s*:\s*"([^"]*)"/)
|
|
81
|
+
m ? m[1] : ""
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def key_pattern(names)
|
|
87
|
+
names.map(&:strip).reject(&:empty?).map { |n| Regexp.escape(n) }.join("|")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def json_secrets(keys)
|
|
91
|
+
/("(?:#{keys})"\s*:\s*)("(?:[^"\\]|\\.)*"?|[^,}\]\s]+)/i
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Visionary
|
|
4
|
+
# Deletes expired rows 60 s after start, then every 24 h, in chunks so no
|
|
5
|
+
# statement runs long or hits D1's limits.
|
|
6
|
+
class Retention
|
|
7
|
+
FIRST_RUN = 60
|
|
8
|
+
EVERY = 24 * 3600
|
|
9
|
+
MAX_ROUNDS = 200
|
|
10
|
+
|
|
11
|
+
# tables: { "api_logs" => days, ... }; 0 days keeps forever.
|
|
12
|
+
def initialize(store, logger, tables)
|
|
13
|
+
@store = store
|
|
14
|
+
@logger = logger
|
|
15
|
+
@tables = tables.select { |_, days| days.to_i.positive? }
|
|
16
|
+
reset
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def needed? = !@tables.empty?
|
|
20
|
+
|
|
21
|
+
def start
|
|
22
|
+
return self unless needed?
|
|
23
|
+
@thread = Thread.new { run }
|
|
24
|
+
@thread.name = "visionary-retention" if @thread.respond_to?(:name=)
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def after_fork
|
|
29
|
+
reset
|
|
30
|
+
start
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def close
|
|
34
|
+
@mutex.synchronize do
|
|
35
|
+
@stopped = true
|
|
36
|
+
@cond.broadcast
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def purge(table, days)
|
|
41
|
+
cutoff = Visionary.timestamp(Time.now - (days * 86_400))
|
|
42
|
+
sql = Schema.purge_sql(@store.dialect, table)
|
|
43
|
+
total = 0
|
|
44
|
+
MAX_ROUNDS.times do
|
|
45
|
+
break if stopped?
|
|
46
|
+
n = begin
|
|
47
|
+
@store.changes(sql, [cutoff])
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
@logger.error("visionary: retention purge of #{table} failed after #{total} rows: #{e.message}")
|
|
50
|
+
return total
|
|
51
|
+
end
|
|
52
|
+
total += n
|
|
53
|
+
break if n < Schema::PURGE_CHUNK
|
|
54
|
+
end
|
|
55
|
+
@logger.info("visionary: retention purge of #{table} deleted #{total} rows older than #{cutoff}") if total.positive?
|
|
56
|
+
total
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def reset
|
|
62
|
+
@mutex = Mutex.new
|
|
63
|
+
@cond = ConditionVariable.new
|
|
64
|
+
@stopped = false
|
|
65
|
+
@thread = nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def stopped? = @mutex.synchronize { @stopped }
|
|
69
|
+
|
|
70
|
+
def run
|
|
71
|
+
Telemetry.internal!
|
|
72
|
+
wait = FIRST_RUN
|
|
73
|
+
loop do
|
|
74
|
+
@mutex.synchronize do
|
|
75
|
+
deadline = mono + wait
|
|
76
|
+
until @stopped || (left = deadline - mono) <= 0
|
|
77
|
+
@cond.wait(@mutex, left)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
break if stopped?
|
|
81
|
+
@tables.each { |table, days| purge(table, days) }
|
|
82
|
+
wait = EVERY
|
|
83
|
+
end
|
|
84
|
+
rescue StandardError => e
|
|
85
|
+
@logger.error("visionary: retention stopped: #{e.message}")
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def mono = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS api_logs (
|
|
2
|
+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
3
|
+
request_id VARCHAR(128) NOT NULL,
|
|
4
|
+
created_at VARCHAR(32) NOT NULL,
|
|
5
|
+
method VARCHAR(16) NOT NULL,
|
|
6
|
+
path TEXT NOT NULL,
|
|
7
|
+
route VARCHAR(255),
|
|
8
|
+
query TEXT,
|
|
9
|
+
status INT NOT NULL,
|
|
10
|
+
duration_ms DOUBLE NOT NULL,
|
|
11
|
+
ip VARCHAR(64),
|
|
12
|
+
user_agent TEXT,
|
|
13
|
+
user_id VARCHAR(128),
|
|
14
|
+
user_handle VARCHAR(255),
|
|
15
|
+
user_role VARCHAR(64),
|
|
16
|
+
request_headers TEXT,
|
|
17
|
+
request_content_type VARCHAR(255),
|
|
18
|
+
request_body MEDIUMTEXT,
|
|
19
|
+
request_body_truncated TINYINT NOT NULL DEFAULT 0,
|
|
20
|
+
request_size BIGINT NOT NULL DEFAULT 0,
|
|
21
|
+
response_content_type VARCHAR(255),
|
|
22
|
+
response_body MEDIUMTEXT,
|
|
23
|
+
response_body_truncated TINYINT NOT NULL DEFAULT 0,
|
|
24
|
+
response_size BIGINT NOT NULL DEFAULT 0,
|
|
25
|
+
error_code VARCHAR(128),
|
|
26
|
+
error_key VARCHAR(255)
|
|
27
|
+
service VARCHAR(255),
|
|
28
|
+
version VARCHAR(255),
|
|
29
|
+
db_count BIGINT,
|
|
30
|
+
db_ms DOUBLE,
|
|
31
|
+
http_count BIGINT,
|
|
32
|
+
http_ms DOUBLE
|
|
33
|
+
) CHARACTER SET utf8mb4;
|
|
34
|
+
CREATE INDEX idx_api_logs_created_at ON api_logs (created_at);
|
|
35
|
+
CREATE INDEX idx_api_logs_user_created ON api_logs (user_id, created_at);
|
|
36
|
+
CREATE INDEX idx_api_logs_route_status ON api_logs (route, status);
|
|
37
|
+
CREATE INDEX idx_api_logs_request_id ON api_logs (request_id);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS system_metrics (
|
|
2
|
+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
3
|
+
created_at VARCHAR(32) NOT NULL,
|
|
4
|
+
instance VARCHAR(128) NOT NULL,
|
|
5
|
+
interval_s DOUBLE NOT NULL,
|
|
6
|
+
host_cpu_percent DOUBLE,
|
|
7
|
+
load_1 DOUBLE,
|
|
8
|
+
load_5 DOUBLE,
|
|
9
|
+
load_15 DOUBLE,
|
|
10
|
+
host_mem_used_mb DOUBLE,
|
|
11
|
+
host_mem_total_mb DOUBLE,
|
|
12
|
+
host_mem_percent DOUBLE,
|
|
13
|
+
disk_used_percent DOUBLE,
|
|
14
|
+
disk_free_gb DOUBLE,
|
|
15
|
+
net_rx_kbps DOUBLE,
|
|
16
|
+
net_tx_kbps DOUBLE,
|
|
17
|
+
proc_cpu_percent DOUBLE,
|
|
18
|
+
proc_rss_mb DOUBLE,
|
|
19
|
+
proc_threads INT,
|
|
20
|
+
proc_open_fds INT,
|
|
21
|
+
goroutines INT,
|
|
22
|
+
heap_alloc_mb DOUBLE,
|
|
23
|
+
heap_inuse_mb DOUBLE,
|
|
24
|
+
heap_objects BIGINT,
|
|
25
|
+
gc_count INT,
|
|
26
|
+
gc_pause_ms DOUBLE,
|
|
27
|
+
gc_cpu_percent DOUBLE,
|
|
28
|
+
db_total_conns INT,
|
|
29
|
+
db_idle_conns INT,
|
|
30
|
+
db_acquired_conns INT,
|
|
31
|
+
db_max_conns INT,
|
|
32
|
+
db_acquires BIGINT,
|
|
33
|
+
db_empty_acquires BIGINT,
|
|
34
|
+
db_acquire_wait_ms DOUBLE,
|
|
35
|
+
http_requests BIGINT,
|
|
36
|
+
http_errors BIGINT,
|
|
37
|
+
http_rps DOUBLE,
|
|
38
|
+
http_in_flight INT,
|
|
39
|
+
uptime_s BIGINT,
|
|
40
|
+
cpu_count BIGINT,
|
|
41
|
+
cpu_user_percent DOUBLE,
|
|
42
|
+
cpu_system_percent DOUBLE,
|
|
43
|
+
cpu_iowait_percent DOUBLE,
|
|
44
|
+
cpu_steal_percent DOUBLE,
|
|
45
|
+
host_mem_available_mb DOUBLE,
|
|
46
|
+
host_mem_cached_mb DOUBLE,
|
|
47
|
+
swap_used_mb DOUBLE,
|
|
48
|
+
swap_total_mb DOUBLE,
|
|
49
|
+
disk_total_gb DOUBLE,
|
|
50
|
+
disk_inodes_percent DOUBLE,
|
|
51
|
+
disk_read_kbps DOUBLE,
|
|
52
|
+
disk_write_kbps DOUBLE,
|
|
53
|
+
disk_read_iops DOUBLE,
|
|
54
|
+
disk_write_iops DOUBLE,
|
|
55
|
+
disk_busy_percent DOUBLE,
|
|
56
|
+
disk_await_ms DOUBLE,
|
|
57
|
+
net_rx_pps DOUBLE,
|
|
58
|
+
net_tx_pps DOUBLE,
|
|
59
|
+
net_errors BIGINT,
|
|
60
|
+
net_drops BIGINT,
|
|
61
|
+
tcp_established BIGINT,
|
|
62
|
+
tcp_retrans BIGINT,
|
|
63
|
+
host_procs BIGINT,
|
|
64
|
+
procs_running BIGINT,
|
|
65
|
+
procs_blocked BIGINT,
|
|
66
|
+
ctx_switches_ps DOUBLE,
|
|
67
|
+
proc_read_kbps DOUBLE,
|
|
68
|
+
proc_write_kbps DOUBLE,
|
|
69
|
+
proc_max_fds BIGINT
|
|
70
|
+
service VARCHAR(255),
|
|
71
|
+
version VARCHAR(255),
|
|
72
|
+
sdk VARCHAR(255),
|
|
73
|
+
runtime VARCHAR(255)
|
|
74
|
+
) CHARACTER SET utf8mb4;
|
|
75
|
+
CREATE INDEX idx_system_metrics_created_at ON system_metrics (created_at);
|
|
76
|
+
CREATE INDEX idx_system_metrics_instance_created ON system_metrics (instance, created_at);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS spans (
|
|
2
|
+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
3
|
+
created_at VARCHAR(32) NOT NULL,
|
|
4
|
+
request_id VARCHAR(255),
|
|
5
|
+
service VARCHAR(255),
|
|
6
|
+
instance VARCHAR(255) NOT NULL,
|
|
7
|
+
kind VARCHAR(255) NOT NULL,
|
|
8
|
+
name VARCHAR(255) NOT NULL,
|
|
9
|
+
target VARCHAR(255),
|
|
10
|
+
detail TEXT,
|
|
11
|
+
offset_ms DOUBLE,
|
|
12
|
+
duration_ms DOUBLE NOT NULL,
|
|
13
|
+
status VARCHAR(255) NOT NULL,
|
|
14
|
+
error TEXT,
|
|
15
|
+
row_count INT
|
|
16
|
+
) CHARACTER SET utf8mb4;
|
|
17
|
+
CREATE INDEX idx_spans_created_at ON spans (created_at);
|
|
18
|
+
CREATE INDEX idx_spans_request_id ON spans (request_id);
|
|
19
|
+
CREATE INDEX idx_spans_kind_name_created_at ON spans (kind, name, created_at);
|
|
20
|
+
CREATE TABLE IF NOT EXISTS errors (
|
|
21
|
+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
22
|
+
created_at VARCHAR(32) NOT NULL,
|
|
23
|
+
service VARCHAR(255),
|
|
24
|
+
instance VARCHAR(255) NOT NULL,
|
|
25
|
+
version VARCHAR(255),
|
|
26
|
+
request_id VARCHAR(255),
|
|
27
|
+
method VARCHAR(255),
|
|
28
|
+
route VARCHAR(255),
|
|
29
|
+
path TEXT,
|
|
30
|
+
user_id VARCHAR(255),
|
|
31
|
+
type VARCHAR(255) NOT NULL,
|
|
32
|
+
message TEXT,
|
|
33
|
+
stack MEDIUMTEXT,
|
|
34
|
+
fingerprint VARCHAR(255) NOT NULL,
|
|
35
|
+
handled INT NOT NULL DEFAULT 0,
|
|
36
|
+
runtime VARCHAR(255)
|
|
37
|
+
) CHARACTER SET utf8mb4;
|
|
38
|
+
CREATE INDEX idx_errors_created_at ON errors (created_at);
|
|
39
|
+
CREATE INDEX idx_errors_fingerprint_created_at ON errors (fingerprint, created_at);
|
|
40
|
+
CREATE INDEX idx_errors_request_id ON errors (request_id);
|
|
41
|
+
CREATE TABLE IF NOT EXISTS releases (
|
|
42
|
+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
43
|
+
created_at VARCHAR(32) NOT NULL,
|
|
44
|
+
service VARCHAR(255),
|
|
45
|
+
instance VARCHAR(255) NOT NULL,
|
|
46
|
+
version VARCHAR(255) NOT NULL,
|
|
47
|
+
sdk VARCHAR(255),
|
|
48
|
+
sdk_version VARCHAR(255),
|
|
49
|
+
runtime VARCHAR(255)
|
|
50
|
+
) CHARACTER SET utf8mb4;
|
|
51
|
+
CREATE INDEX idx_releases_created_at ON releases (created_at);
|
|
52
|
+
CREATE INDEX idx_releases_version_created_at ON releases (version, created_at);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS api_logs (
|
|
2
|
+
id BIGSERIAL PRIMARY KEY,
|
|
3
|
+
request_id TEXT NOT NULL,
|
|
4
|
+
created_at TEXT NOT NULL,
|
|
5
|
+
method TEXT NOT NULL,
|
|
6
|
+
path TEXT NOT NULL,
|
|
7
|
+
route TEXT,
|
|
8
|
+
query TEXT,
|
|
9
|
+
status INTEGER NOT NULL,
|
|
10
|
+
duration_ms DOUBLE PRECISION NOT NULL,
|
|
11
|
+
ip TEXT,
|
|
12
|
+
user_agent TEXT,
|
|
13
|
+
user_id TEXT,
|
|
14
|
+
user_handle TEXT,
|
|
15
|
+
user_role TEXT,
|
|
16
|
+
request_headers TEXT,
|
|
17
|
+
request_content_type TEXT,
|
|
18
|
+
request_body TEXT,
|
|
19
|
+
request_body_truncated INTEGER NOT NULL DEFAULT 0,
|
|
20
|
+
request_size BIGINT NOT NULL DEFAULT 0,
|
|
21
|
+
response_content_type TEXT,
|
|
22
|
+
response_body TEXT,
|
|
23
|
+
response_body_truncated INTEGER NOT NULL DEFAULT 0,
|
|
24
|
+
response_size BIGINT NOT NULL DEFAULT 0,
|
|
25
|
+
error_code TEXT,
|
|
26
|
+
error_key TEXT
|
|
27
|
+
service TEXT,
|
|
28
|
+
version TEXT,
|
|
29
|
+
db_count BIGINT,
|
|
30
|
+
db_ms DOUBLE PRECISION,
|
|
31
|
+
http_count BIGINT,
|
|
32
|
+
http_ms DOUBLE PRECISION
|
|
33
|
+
);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_created_at ON api_logs (created_at);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_user_created ON api_logs (user_id, created_at);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_route_status ON api_logs (route, status);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_request_id ON api_logs (request_id);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS system_metrics (
|
|
2
|
+
id BIGSERIAL PRIMARY KEY,
|
|
3
|
+
created_at TEXT NOT NULL,
|
|
4
|
+
instance TEXT NOT NULL,
|
|
5
|
+
interval_s DOUBLE PRECISION NOT NULL,
|
|
6
|
+
host_cpu_percent DOUBLE PRECISION,
|
|
7
|
+
load_1 DOUBLE PRECISION,
|
|
8
|
+
load_5 DOUBLE PRECISION,
|
|
9
|
+
load_15 DOUBLE PRECISION,
|
|
10
|
+
host_mem_used_mb DOUBLE PRECISION,
|
|
11
|
+
host_mem_total_mb DOUBLE PRECISION,
|
|
12
|
+
host_mem_percent DOUBLE PRECISION,
|
|
13
|
+
disk_used_percent DOUBLE PRECISION,
|
|
14
|
+
disk_free_gb DOUBLE PRECISION,
|
|
15
|
+
net_rx_kbps DOUBLE PRECISION,
|
|
16
|
+
net_tx_kbps DOUBLE PRECISION,
|
|
17
|
+
proc_cpu_percent DOUBLE PRECISION,
|
|
18
|
+
proc_rss_mb DOUBLE PRECISION,
|
|
19
|
+
proc_threads INTEGER,
|
|
20
|
+
proc_open_fds INTEGER,
|
|
21
|
+
goroutines INTEGER,
|
|
22
|
+
heap_alloc_mb DOUBLE PRECISION,
|
|
23
|
+
heap_inuse_mb DOUBLE PRECISION,
|
|
24
|
+
heap_objects BIGINT,
|
|
25
|
+
gc_count INTEGER,
|
|
26
|
+
gc_pause_ms DOUBLE PRECISION,
|
|
27
|
+
gc_cpu_percent DOUBLE PRECISION,
|
|
28
|
+
db_total_conns INTEGER,
|
|
29
|
+
db_idle_conns INTEGER,
|
|
30
|
+
db_acquired_conns INTEGER,
|
|
31
|
+
db_max_conns INTEGER,
|
|
32
|
+
db_acquires BIGINT,
|
|
33
|
+
db_empty_acquires BIGINT,
|
|
34
|
+
db_acquire_wait_ms DOUBLE PRECISION,
|
|
35
|
+
http_requests BIGINT,
|
|
36
|
+
http_errors BIGINT,
|
|
37
|
+
http_rps DOUBLE PRECISION,
|
|
38
|
+
http_in_flight INTEGER,
|
|
39
|
+
uptime_s BIGINT,
|
|
40
|
+
cpu_count BIGINT,
|
|
41
|
+
cpu_user_percent DOUBLE PRECISION,
|
|
42
|
+
cpu_system_percent DOUBLE PRECISION,
|
|
43
|
+
cpu_iowait_percent DOUBLE PRECISION,
|
|
44
|
+
cpu_steal_percent DOUBLE PRECISION,
|
|
45
|
+
host_mem_available_mb DOUBLE PRECISION,
|
|
46
|
+
host_mem_cached_mb DOUBLE PRECISION,
|
|
47
|
+
swap_used_mb DOUBLE PRECISION,
|
|
48
|
+
swap_total_mb DOUBLE PRECISION,
|
|
49
|
+
disk_total_gb DOUBLE PRECISION,
|
|
50
|
+
disk_inodes_percent DOUBLE PRECISION,
|
|
51
|
+
disk_read_kbps DOUBLE PRECISION,
|
|
52
|
+
disk_write_kbps DOUBLE PRECISION,
|
|
53
|
+
disk_read_iops DOUBLE PRECISION,
|
|
54
|
+
disk_write_iops DOUBLE PRECISION,
|
|
55
|
+
disk_busy_percent DOUBLE PRECISION,
|
|
56
|
+
disk_await_ms DOUBLE PRECISION,
|
|
57
|
+
net_rx_pps DOUBLE PRECISION,
|
|
58
|
+
net_tx_pps DOUBLE PRECISION,
|
|
59
|
+
net_errors BIGINT,
|
|
60
|
+
net_drops BIGINT,
|
|
61
|
+
tcp_established BIGINT,
|
|
62
|
+
tcp_retrans BIGINT,
|
|
63
|
+
host_procs BIGINT,
|
|
64
|
+
procs_running BIGINT,
|
|
65
|
+
procs_blocked BIGINT,
|
|
66
|
+
ctx_switches_ps DOUBLE PRECISION,
|
|
67
|
+
proc_read_kbps DOUBLE PRECISION,
|
|
68
|
+
proc_write_kbps DOUBLE PRECISION,
|
|
69
|
+
proc_max_fds BIGINT
|
|
70
|
+
service TEXT,
|
|
71
|
+
version TEXT,
|
|
72
|
+
sdk TEXT,
|
|
73
|
+
runtime TEXT
|
|
74
|
+
);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_system_metrics_created_at ON system_metrics (created_at);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_system_metrics_instance_created ON system_metrics (instance, created_at);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS spans (
|
|
2
|
+
id BIGSERIAL PRIMARY KEY,
|
|
3
|
+
created_at TEXT NOT NULL,
|
|
4
|
+
request_id TEXT,
|
|
5
|
+
service TEXT,
|
|
6
|
+
instance TEXT NOT NULL,
|
|
7
|
+
kind TEXT NOT NULL,
|
|
8
|
+
name TEXT NOT NULL,
|
|
9
|
+
target TEXT,
|
|
10
|
+
detail TEXT,
|
|
11
|
+
offset_ms DOUBLE PRECISION,
|
|
12
|
+
duration_ms DOUBLE PRECISION NOT NULL,
|
|
13
|
+
status TEXT NOT NULL,
|
|
14
|
+
error TEXT,
|
|
15
|
+
row_count INTEGER
|
|
16
|
+
);
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_spans_created_at ON spans (created_at);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_spans_request_id ON spans (request_id);
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_spans_kind_name_created_at ON spans (kind, name, created_at);
|
|
20
|
+
CREATE TABLE IF NOT EXISTS errors (
|
|
21
|
+
id BIGSERIAL PRIMARY KEY,
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
service TEXT,
|
|
24
|
+
instance TEXT NOT NULL,
|
|
25
|
+
version TEXT,
|
|
26
|
+
request_id TEXT,
|
|
27
|
+
method TEXT,
|
|
28
|
+
route TEXT,
|
|
29
|
+
path TEXT,
|
|
30
|
+
user_id TEXT,
|
|
31
|
+
type TEXT NOT NULL,
|
|
32
|
+
message TEXT,
|
|
33
|
+
stack TEXT,
|
|
34
|
+
fingerprint TEXT NOT NULL,
|
|
35
|
+
handled INTEGER NOT NULL DEFAULT 0,
|
|
36
|
+
runtime TEXT
|
|
37
|
+
);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_errors_created_at ON errors (created_at);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_errors_fingerprint_created_at ON errors (fingerprint, created_at);
|
|
40
|
+
CREATE INDEX IF NOT EXISTS idx_errors_request_id ON errors (request_id);
|
|
41
|
+
CREATE TABLE IF NOT EXISTS releases (
|
|
42
|
+
id BIGSERIAL PRIMARY KEY,
|
|
43
|
+
created_at TEXT NOT NULL,
|
|
44
|
+
service TEXT,
|
|
45
|
+
instance TEXT NOT NULL,
|
|
46
|
+
version TEXT NOT NULL,
|
|
47
|
+
sdk TEXT,
|
|
48
|
+
sdk_version TEXT,
|
|
49
|
+
runtime TEXT
|
|
50
|
+
);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_releases_created_at ON releases (created_at);
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_releases_version_created_at ON releases (version, created_at);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS api_logs (
|
|
2
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
request_id TEXT NOT NULL,
|
|
4
|
+
created_at TEXT NOT NULL,
|
|
5
|
+
method TEXT NOT NULL,
|
|
6
|
+
path TEXT NOT NULL,
|
|
7
|
+
route TEXT,
|
|
8
|
+
query TEXT,
|
|
9
|
+
status INTEGER NOT NULL,
|
|
10
|
+
duration_ms REAL NOT NULL,
|
|
11
|
+
ip TEXT,
|
|
12
|
+
user_agent TEXT,
|
|
13
|
+
user_id INTEGER,
|
|
14
|
+
user_handle TEXT,
|
|
15
|
+
user_role TEXT,
|
|
16
|
+
request_headers TEXT,
|
|
17
|
+
request_content_type TEXT,
|
|
18
|
+
request_body TEXT,
|
|
19
|
+
request_body_truncated INTEGER NOT NULL DEFAULT 0,
|
|
20
|
+
request_size INTEGER NOT NULL DEFAULT 0,
|
|
21
|
+
response_content_type TEXT,
|
|
22
|
+
response_body TEXT,
|
|
23
|
+
response_body_truncated INTEGER NOT NULL DEFAULT 0,
|
|
24
|
+
response_size INTEGER NOT NULL DEFAULT 0,
|
|
25
|
+
error_code TEXT,
|
|
26
|
+
error_key TEXT
|
|
27
|
+
service TEXT,
|
|
28
|
+
version TEXT,
|
|
29
|
+
db_count INTEGER,
|
|
30
|
+
db_ms REAL,
|
|
31
|
+
http_count INTEGER,
|
|
32
|
+
http_ms REAL
|
|
33
|
+
);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_created_at ON api_logs (created_at);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_user_created ON api_logs (user_id, created_at);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_route_status ON api_logs (route, status);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_api_logs_request_id ON api_logs (request_id);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS system_metrics (
|
|
2
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
created_at TEXT NOT NULL,
|
|
4
|
+
instance TEXT NOT NULL,
|
|
5
|
+
interval_s REAL NOT NULL,
|
|
6
|
+
host_cpu_percent REAL,
|
|
7
|
+
load_1 REAL,
|
|
8
|
+
load_5 REAL,
|
|
9
|
+
load_15 REAL,
|
|
10
|
+
host_mem_used_mb REAL,
|
|
11
|
+
host_mem_total_mb REAL,
|
|
12
|
+
host_mem_percent REAL,
|
|
13
|
+
disk_used_percent REAL,
|
|
14
|
+
disk_free_gb REAL,
|
|
15
|
+
net_rx_kbps REAL,
|
|
16
|
+
net_tx_kbps REAL,
|
|
17
|
+
proc_cpu_percent REAL,
|
|
18
|
+
proc_rss_mb REAL,
|
|
19
|
+
proc_threads INTEGER,
|
|
20
|
+
proc_open_fds INTEGER,
|
|
21
|
+
goroutines INTEGER,
|
|
22
|
+
heap_alloc_mb REAL,
|
|
23
|
+
heap_inuse_mb REAL,
|
|
24
|
+
heap_objects INTEGER,
|
|
25
|
+
gc_count INTEGER,
|
|
26
|
+
gc_pause_ms REAL,
|
|
27
|
+
gc_cpu_percent REAL,
|
|
28
|
+
db_total_conns INTEGER,
|
|
29
|
+
db_idle_conns INTEGER,
|
|
30
|
+
db_acquired_conns INTEGER,
|
|
31
|
+
db_max_conns INTEGER,
|
|
32
|
+
db_acquires INTEGER,
|
|
33
|
+
db_empty_acquires INTEGER,
|
|
34
|
+
db_acquire_wait_ms REAL,
|
|
35
|
+
http_requests INTEGER,
|
|
36
|
+
http_errors INTEGER,
|
|
37
|
+
http_rps REAL,
|
|
38
|
+
http_in_flight INTEGER,
|
|
39
|
+
uptime_s INTEGER,
|
|
40
|
+
cpu_count INTEGER,
|
|
41
|
+
cpu_user_percent REAL,
|
|
42
|
+
cpu_system_percent REAL,
|
|
43
|
+
cpu_iowait_percent REAL,
|
|
44
|
+
cpu_steal_percent REAL,
|
|
45
|
+
host_mem_available_mb REAL,
|
|
46
|
+
host_mem_cached_mb REAL,
|
|
47
|
+
swap_used_mb REAL,
|
|
48
|
+
swap_total_mb REAL,
|
|
49
|
+
disk_total_gb REAL,
|
|
50
|
+
disk_inodes_percent REAL,
|
|
51
|
+
disk_read_kbps REAL,
|
|
52
|
+
disk_write_kbps REAL,
|
|
53
|
+
disk_read_iops REAL,
|
|
54
|
+
disk_write_iops REAL,
|
|
55
|
+
disk_busy_percent REAL,
|
|
56
|
+
disk_await_ms REAL,
|
|
57
|
+
net_rx_pps REAL,
|
|
58
|
+
net_tx_pps REAL,
|
|
59
|
+
net_errors INTEGER,
|
|
60
|
+
net_drops INTEGER,
|
|
61
|
+
tcp_established INTEGER,
|
|
62
|
+
tcp_retrans INTEGER,
|
|
63
|
+
host_procs INTEGER,
|
|
64
|
+
procs_running INTEGER,
|
|
65
|
+
procs_blocked INTEGER,
|
|
66
|
+
ctx_switches_ps REAL,
|
|
67
|
+
proc_read_kbps REAL,
|
|
68
|
+
proc_write_kbps REAL,
|
|
69
|
+
proc_max_fds INTEGER
|
|
70
|
+
service TEXT,
|
|
71
|
+
version TEXT,
|
|
72
|
+
sdk TEXT,
|
|
73
|
+
runtime TEXT
|
|
74
|
+
);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_system_metrics_created_at ON system_metrics (created_at);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_system_metrics_instance_created ON system_metrics (instance, created_at);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS spans (
|
|
2
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
created_at TEXT NOT NULL,
|
|
4
|
+
request_id TEXT,
|
|
5
|
+
service TEXT,
|
|
6
|
+
instance TEXT NOT NULL,
|
|
7
|
+
kind TEXT NOT NULL,
|
|
8
|
+
name TEXT NOT NULL,
|
|
9
|
+
target TEXT,
|
|
10
|
+
detail TEXT,
|
|
11
|
+
offset_ms REAL,
|
|
12
|
+
duration_ms REAL NOT NULL,
|
|
13
|
+
status TEXT NOT NULL,
|
|
14
|
+
error TEXT,
|
|
15
|
+
row_count INTEGER
|
|
16
|
+
);
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_spans_created_at ON spans (created_at);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_spans_request_id ON spans (request_id);
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_spans_kind_name_created_at ON spans (kind, name, created_at);
|
|
20
|
+
CREATE TABLE IF NOT EXISTS errors (
|
|
21
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
service TEXT,
|
|
24
|
+
instance TEXT NOT NULL,
|
|
25
|
+
version TEXT,
|
|
26
|
+
request_id TEXT,
|
|
27
|
+
method TEXT,
|
|
28
|
+
route TEXT,
|
|
29
|
+
path TEXT,
|
|
30
|
+
user_id TEXT,
|
|
31
|
+
type TEXT NOT NULL,
|
|
32
|
+
message TEXT,
|
|
33
|
+
stack TEXT,
|
|
34
|
+
fingerprint TEXT NOT NULL,
|
|
35
|
+
handled INTEGER NOT NULL DEFAULT 0,
|
|
36
|
+
runtime TEXT
|
|
37
|
+
);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_errors_created_at ON errors (created_at);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_errors_fingerprint_created_at ON errors (fingerprint, created_at);
|
|
40
|
+
CREATE INDEX IF NOT EXISTS idx_errors_request_id ON errors (request_id);
|
|
41
|
+
CREATE TABLE IF NOT EXISTS releases (
|
|
42
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
43
|
+
created_at TEXT NOT NULL,
|
|
44
|
+
service TEXT,
|
|
45
|
+
instance TEXT NOT NULL,
|
|
46
|
+
version TEXT NOT NULL,
|
|
47
|
+
sdk TEXT,
|
|
48
|
+
sdk_version TEXT,
|
|
49
|
+
runtime TEXT
|
|
50
|
+
);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_releases_created_at ON releases (created_at);
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_releases_version_created_at ON releases (version, created_at);
|