openclaw-observability 2026.4.1 → 2026.4.21
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.
- package/README.md +4 -4
- package/dist/cloud/api-key-auth.d.ts.map +1 -1
- package/dist/cloud/api-key-auth.js +4 -9
- package/dist/cloud/api-key-auth.js.map +1 -1
- package/dist/cloud/types.d.ts +2 -3
- package/dist/cloud/types.d.ts.map +1 -1
- package/dist/config.d.ts +34 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -2
- package/dist/config.js.map +1 -1
- package/dist/gateway/register-observability-gateway.d.ts +6 -4
- package/dist/gateway/register-observability-gateway.d.ts.map +1 -1
- package/dist/gateway/register-observability-gateway.js +105 -2
- package/dist/gateway/register-observability-gateway.js.map +1 -1
- package/dist/hooks/messages.d.ts +4 -3
- package/dist/hooks/messages.d.ts.map +1 -1
- package/dist/hooks/messages.js +23 -1
- package/dist/hooks/messages.js.map +1 -1
- package/dist/hooks/session.d.ts +4 -3
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +9 -4
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/subagent.d.ts +4 -3
- package/dist/hooks/subagent.d.ts.map +1 -1
- package/dist/hooks/subagent.js +4 -1
- package/dist/hooks/subagent.js.map +1 -1
- package/dist/hooks/tools.d.ts +3 -3
- package/dist/hooks/tools.d.ts.map +1 -1
- package/dist/hooks/tools.js +122 -4
- package/dist/hooks/tools.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +472 -118
- package/dist/index.js.map +1 -1
- package/dist/llm/replay-runtime.d.ts +16 -0
- package/dist/llm/replay-runtime.d.ts.map +1 -0
- package/dist/llm/replay-runtime.js +596 -0
- package/dist/llm/replay-runtime.js.map +1 -0
- package/dist/llm/replay.d.ts +3 -0
- package/dist/llm/replay.d.ts.map +1 -1
- package/dist/llm/replay.js.map +1 -1
- package/dist/redaction.d.ts +1 -1
- package/dist/redaction.js +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +3 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/session-context.d.ts +4 -3
- package/dist/runtime/session-context.d.ts.map +1 -1
- package/dist/runtime/session-context.js +37 -17
- package/dist/runtime/session-context.js.map +1 -1
- package/dist/security/chain-detector.d.ts +4 -4
- package/dist/security/chain-detector.d.ts.map +1 -1
- package/dist/security/chain-detector.js.map +1 -1
- package/dist/security/rules.d.ts +2 -2
- package/dist/security/rules.d.ts.map +1 -1
- package/dist/security/rules.js +9 -2
- package/dist/security/rules.js.map +1 -1
- package/dist/security/scanner.d.ts +8 -3
- package/dist/security/scanner.d.ts.map +1 -1
- package/dist/security/scanner.js +85 -7
- package/dist/security/scanner.js.map +1 -1
- package/dist/security/types.d.ts +3 -0
- package/dist/security/types.d.ts.map +1 -1
- package/dist/storage/buffer.d.ts +7 -7
- package/dist/storage/buffer.d.ts.map +1 -1
- package/dist/storage/buffer.js +2 -2
- package/dist/storage/buffer.js.map +1 -1
- package/dist/storage/cloud-export-writer.d.ts +23 -0
- package/dist/storage/cloud-export-writer.d.ts.map +1 -0
- package/dist/storage/cloud-export-writer.js +202 -0
- package/dist/storage/cloud-export-writer.js.map +1 -0
- package/dist/storage/duckdb-local-writer.d.ts +19 -3
- package/dist/storage/duckdb-local-writer.d.ts.map +1 -1
- package/dist/storage/duckdb-local-writer.js +261 -81
- package/dist/storage/duckdb-local-writer.js.map +1 -1
- package/dist/storage/duckdb-observability-forwarder.d.ts +16 -0
- package/dist/storage/duckdb-observability-forwarder.d.ts.map +1 -0
- package/dist/storage/duckdb-observability-forwarder.js +289 -0
- package/dist/storage/duckdb-observability-forwarder.js.map +1 -0
- package/dist/storage/mysql-writer.d.ts +35 -6
- package/dist/storage/mysql-writer.d.ts.map +1 -1
- package/dist/storage/mysql-writer.js +251 -32
- package/dist/storage/mysql-writer.js.map +1 -1
- package/dist/storage/schema.d.ts +2 -2
- package/dist/storage/schema.d.ts.map +1 -1
- package/dist/storage/schema.js +181 -53
- package/dist/storage/schema.js.map +1 -1
- package/dist/storage/structured-model.d.ts +11 -2
- package/dist/storage/structured-model.d.ts.map +1 -1
- package/dist/storage/structured-model.js +183 -5
- package/dist/storage/structured-model.js.map +1 -1
- package/dist/storage/writer.d.ts +14 -2
- package/dist/storage/writer.d.ts.map +1 -1
- package/dist/types.d.ts +28 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/dist/web/api.d.ts +80 -2
- package/dist/web/api.d.ts.map +1 -1
- package/dist/web/api.js +917 -113
- package/dist/web/api.js.map +1 -1
- package/dist/web/routes.d.ts +22 -2
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +264 -21
- package/dist/web/routes.js.map +1 -1
- package/dist/web/ui.d.ts +3 -1
- package/dist/web/ui.d.ts.map +1 -1
- package/dist/web/ui.js +2678 -633
- package/dist/web/ui.js.map +1 -1
- package/openclaw.plugin.json +145 -4
- package/package.json +1 -1
package/dist/storage/schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* MySQL database schema definition and migrations
|
|
4
|
-
* Creates
|
|
4
|
+
* Creates observation tables in MySQL-compatible databases
|
|
5
5
|
*
|
|
6
6
|
* WARNING: DuckDB schema is defined in duckdb-local-writer.ts (DUCKDB_SCHEMA_STATEMENTS).
|
|
7
7
|
* When modifying table structure, update both places.
|
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.ensureSchema = ensureSchema;
|
|
11
11
|
/**
|
|
12
|
-
* Create
|
|
12
|
+
* Create observation tables in MySQL (if not exists)
|
|
13
13
|
*/
|
|
14
14
|
async function ensureSchema(pool) {
|
|
15
|
-
// Create
|
|
15
|
+
// Create observation_actions core table (DDL does not support prepared statements)
|
|
16
16
|
await pool.query(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS
|
|
17
|
+
CREATE TABLE IF NOT EXISTS observation_actions (
|
|
18
18
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
19
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
20
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
21
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
19
22
|
session_id VARCHAR(64) NOT NULL,
|
|
20
23
|
action_type VARCHAR(32) NOT NULL,
|
|
21
24
|
action_name VARCHAR(255) NOT NULL,
|
|
@@ -26,67 +29,61 @@ async function ensureSchema(pool) {
|
|
|
26
29
|
completion_tokens INT DEFAULT NULL,
|
|
27
30
|
duration_ms INT DEFAULT NULL,
|
|
28
31
|
user_id VARCHAR(128) DEFAULT '',
|
|
32
|
+
parent_session_id VARCHAR(128) DEFAULT '',
|
|
33
|
+
run_id VARCHAR(128) DEFAULT '',
|
|
34
|
+
parent_run_id VARCHAR(128) DEFAULT '',
|
|
29
35
|
channel_id VARCHAR(128) DEFAULT '',
|
|
30
36
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
31
37
|
INDEX idx_session_id (session_id),
|
|
32
38
|
INDEX idx_action_type (action_type),
|
|
33
39
|
INDEX idx_created_at (created_at),
|
|
34
40
|
INDEX idx_user_id (user_id),
|
|
35
|
-
INDEX
|
|
41
|
+
INDEX idx_parent_session_id (parent_session_id),
|
|
42
|
+
INDEX idx_run_id (run_id),
|
|
43
|
+
INDEX idx_parent_run_id (parent_run_id),
|
|
44
|
+
INDEX idx_channel_id (channel_id),
|
|
45
|
+
INDEX idx_project_created (scope_id, created_at),
|
|
46
|
+
INDEX idx_org_project (organization_id, scope_id)
|
|
36
47
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
37
48
|
`);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Create audit_sessions summary table
|
|
49
|
+
await ensureMysqlColumn(pool, 'observation_actions', 'run_id', "VARCHAR(128) DEFAULT ''");
|
|
50
|
+
await ensureMysqlColumn(pool, 'observation_actions', 'parent_run_id', "VARCHAR(128) DEFAULT ''");
|
|
51
|
+
await ensureMysqlColumnLongText(pool, 'observation_actions', 'input_params');
|
|
52
|
+
await ensureMysqlColumnLongText(pool, 'observation_actions', 'output_result');
|
|
53
|
+
await ensureMysqlIndex(pool, 'observation_actions', 'idx_run_id', 'run_id');
|
|
54
|
+
await ensureMysqlIndex(pool, 'observation_actions', 'idx_parent_run_id', 'parent_run_id');
|
|
55
|
+
// Create observation_sessions summary table
|
|
46
56
|
await pool.query(`
|
|
47
|
-
CREATE TABLE IF NOT EXISTS
|
|
48
|
-
|
|
57
|
+
CREATE TABLE IF NOT EXISTS observation_sessions (
|
|
58
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
59
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
60
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
61
|
+
session_id VARCHAR(64) NOT NULL,
|
|
49
62
|
user_id VARCHAR(128) DEFAULT '',
|
|
63
|
+
parent_session_id VARCHAR(128) DEFAULT '',
|
|
50
64
|
model_name VARCHAR(128) DEFAULT '',
|
|
51
65
|
channel_id VARCHAR(128) DEFAULT '',
|
|
52
66
|
start_time TIMESTAMP NOT NULL,
|
|
53
67
|
end_time TIMESTAMP NULL DEFAULT NULL,
|
|
54
68
|
total_actions INT DEFAULT 0,
|
|
55
69
|
total_tokens INT DEFAULT 0,
|
|
70
|
+
PRIMARY KEY (scope_id, session_id),
|
|
56
71
|
INDEX idx_user_id (user_id),
|
|
72
|
+
INDEX idx_parent_session_id (parent_session_id),
|
|
57
73
|
INDEX idx_start_time (start_time),
|
|
58
|
-
INDEX idx_channel_id (channel_id)
|
|
74
|
+
INDEX idx_channel_id (channel_id),
|
|
75
|
+
INDEX idx_project_end (scope_id, end_time),
|
|
76
|
+
INDEX idx_org_project (organization_id, scope_id)
|
|
59
77
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
60
78
|
`);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
await pool.query(`ALTER TABLE audit_sessions DROP COLUMN session_key`);
|
|
64
|
-
console.log('[openclaw-observability] Dropped session_key column from audit_sessions');
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
// Column does not exist, ignore
|
|
68
|
-
}
|
|
69
|
-
// Migration: add channel_id column if it doesn't exist (for existing databases)
|
|
70
|
-
try {
|
|
71
|
-
await pool.query(`ALTER TABLE audit_actions ADD COLUMN channel_id VARCHAR(128) DEFAULT ''`);
|
|
72
|
-
await pool.query(`ALTER TABLE audit_actions ADD INDEX idx_channel_id (channel_id)`);
|
|
73
|
-
console.log('[openclaw-observability] Added channel_id column to audit_actions');
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// Column may already exist, ignore
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
await pool.query(`ALTER TABLE audit_sessions ADD COLUMN channel_id VARCHAR(128) DEFAULT ''`);
|
|
80
|
-
await pool.query(`ALTER TABLE audit_sessions ADD INDEX idx_channel_id (channel_id)`);
|
|
81
|
-
console.log('[openclaw-observability] Added channel_id column to audit_sessions');
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// Column may already exist, ignore
|
|
85
|
-
}
|
|
86
|
-
// Create audit_alerts security alerts table
|
|
79
|
+
await ensureMysqlSessionPrimaryKey(pool);
|
|
80
|
+
// Create observation_alerts security alerts table
|
|
87
81
|
await pool.query(`
|
|
88
|
-
CREATE TABLE IF NOT EXISTS
|
|
82
|
+
CREATE TABLE IF NOT EXISTS observation_alerts (
|
|
89
83
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
84
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
85
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
86
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
90
87
|
alert_id VARCHAR(64) NOT NULL,
|
|
91
88
|
session_id VARCHAR(64) NOT NULL,
|
|
92
89
|
action_type VARCHAR(32) NOT NULL,
|
|
@@ -108,13 +105,18 @@ async function ensureSchema(pool) {
|
|
|
108
105
|
INDEX idx_alert_status (status),
|
|
109
106
|
INDEX idx_alert_session (session_id),
|
|
110
107
|
INDEX idx_alert_created (created_at),
|
|
111
|
-
INDEX idx_alert_rule (rule_id)
|
|
108
|
+
INDEX idx_alert_rule (rule_id),
|
|
109
|
+
INDEX idx_alert_project_created (scope_id, created_at),
|
|
110
|
+
INDEX idx_alert_org_project (organization_id, scope_id)
|
|
112
111
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
113
112
|
`);
|
|
114
113
|
// Legacy metrics snapshots table (compatibility with existing APIs)
|
|
115
114
|
await pool.query(`
|
|
116
115
|
CREATE TABLE IF NOT EXISTS observability_metrics_samples (
|
|
117
116
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
117
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
118
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
119
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
118
120
|
metric_name VARCHAR(256) NOT NULL,
|
|
119
121
|
metric_type VARCHAR(32) DEFAULT 'untyped',
|
|
120
122
|
metric_help TEXT,
|
|
@@ -125,12 +127,16 @@ async function ensureSchema(pool) {
|
|
|
125
127
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
126
128
|
INDEX idx_metrics_name_ts (metric_name, sample_timestamp_ms),
|
|
127
129
|
INDEX idx_metrics_ts (sample_timestamp_ms),
|
|
128
|
-
INDEX idx_metrics_fp_ts (label_fingerprint(255), sample_timestamp_ms)
|
|
130
|
+
INDEX idx_metrics_fp_ts (label_fingerprint(255), sample_timestamp_ms),
|
|
131
|
+
INDEX idx_metrics_project_ts (scope_id, sample_timestamp_ms)
|
|
129
132
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
130
133
|
`);
|
|
131
134
|
await pool.query(`
|
|
132
135
|
CREATE TABLE IF NOT EXISTS oc_traces (
|
|
133
136
|
trace_id VARCHAR(128) PRIMARY KEY,
|
|
137
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
138
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
139
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
134
140
|
session_id VARCHAR(128) NOT NULL,
|
|
135
141
|
user_id VARCHAR(128) DEFAULT '',
|
|
136
142
|
channel_id VARCHAR(128) DEFAULT '',
|
|
@@ -144,12 +150,16 @@ async function ensureSchema(pool) {
|
|
|
144
150
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
145
151
|
INDEX idx_oc_trace_time (start_time),
|
|
146
152
|
INDEX idx_oc_trace_user (user_id),
|
|
147
|
-
INDEX idx_oc_trace_channel (channel_id)
|
|
153
|
+
INDEX idx_oc_trace_channel (channel_id),
|
|
154
|
+
INDEX idx_oc_trace_project_time (scope_id, start_time)
|
|
148
155
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
149
156
|
`);
|
|
150
157
|
await pool.query(`
|
|
151
158
|
CREATE TABLE IF NOT EXISTS oc_observations_core (
|
|
152
159
|
observation_id VARCHAR(160) PRIMARY KEY,
|
|
160
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
161
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
162
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
153
163
|
trace_id VARCHAR(128) NOT NULL,
|
|
154
164
|
parent_observation_id VARCHAR(160) DEFAULT NULL,
|
|
155
165
|
root_observation_id VARCHAR(160) NOT NULL,
|
|
@@ -177,7 +187,8 @@ async function ensureSchema(pool) {
|
|
|
177
187
|
INDEX idx_oc_obs_parent_time (parent_observation_id, start_time),
|
|
178
188
|
INDEX idx_oc_obs_run (run_id),
|
|
179
189
|
INDEX idx_oc_obs_tool_call (tool_call_id),
|
|
180
|
-
INDEX idx_oc_obs_type_time (observation_type, start_time)
|
|
190
|
+
INDEX idx_oc_obs_type_time (observation_type, start_time),
|
|
191
|
+
INDEX idx_oc_obs_project_time (scope_id, start_time)
|
|
181
192
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
182
193
|
`);
|
|
183
194
|
await pool.query(`
|
|
@@ -195,6 +206,9 @@ async function ensureSchema(pool) {
|
|
|
195
206
|
await pool.query(`
|
|
196
207
|
CREATE TABLE IF NOT EXISTS oc_events_raw (
|
|
197
208
|
event_id VARCHAR(180) PRIMARY KEY,
|
|
209
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
210
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
211
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
198
212
|
trace_id VARCHAR(128) NOT NULL,
|
|
199
213
|
observation_id VARCHAR(160) NOT NULL,
|
|
200
214
|
event_type VARCHAR(64) NOT NULL,
|
|
@@ -205,12 +219,16 @@ async function ensureSchema(pool) {
|
|
|
205
219
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
206
220
|
INDEX idx_oc_evt_trace_time (trace_id, event_time),
|
|
207
221
|
INDEX idx_oc_evt_obs_time (observation_id, event_time),
|
|
208
|
-
INDEX idx_oc_evt_type_time (event_type, event_time)
|
|
222
|
+
INDEX idx_oc_evt_type_time (event_type, event_time),
|
|
223
|
+
INDEX idx_oc_evt_project_time (scope_id, event_time)
|
|
209
224
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
210
225
|
`);
|
|
211
226
|
await pool.query(`
|
|
212
227
|
CREATE TABLE IF NOT EXISTS oc_metric_series (
|
|
213
|
-
series_id VARCHAR(
|
|
228
|
+
series_id VARCHAR(512) PRIMARY KEY,
|
|
229
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
230
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
231
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
214
232
|
metric_name VARCHAR(256) NOT NULL,
|
|
215
233
|
metric_type VARCHAR(32) DEFAULT 'untyped',
|
|
216
234
|
metric_unit VARCHAR(64) DEFAULT '',
|
|
@@ -223,25 +241,33 @@ async function ensureSchema(pool) {
|
|
|
223
241
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
224
242
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
225
243
|
INDEX idx_oc_metric_series_name (metric_name),
|
|
244
|
+
INDEX idx_oc_metric_series_project_name (scope_id, metric_name),
|
|
226
245
|
INDEX idx_oc_metric_series_seen (last_seen_ms)
|
|
227
246
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
228
247
|
`);
|
|
229
248
|
await pool.query(`
|
|
230
249
|
CREATE TABLE IF NOT EXISTS oc_metric_points_number (
|
|
231
250
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
232
|
-
|
|
251
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
252
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
253
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
254
|
+
series_id VARCHAR(512) NOT NULL,
|
|
233
255
|
ts_ms BIGINT NOT NULL,
|
|
234
256
|
start_ts_ms BIGINT DEFAULT NULL,
|
|
235
257
|
value DOUBLE NOT NULL,
|
|
236
258
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
237
259
|
INDEX idx_oc_metric_num_series_ts (series_id(255), ts_ms),
|
|
238
|
-
INDEX idx_oc_metric_num_ts (ts_ms)
|
|
260
|
+
INDEX idx_oc_metric_num_ts (ts_ms),
|
|
261
|
+
INDEX idx_oc_metric_num_project_ts (scope_id, ts_ms)
|
|
239
262
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
240
263
|
`);
|
|
241
264
|
await pool.query(`
|
|
242
265
|
CREATE TABLE IF NOT EXISTS oc_metric_points_histogram (
|
|
243
266
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
244
|
-
|
|
267
|
+
organization_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
268
|
+
scope_id VARCHAR(64) NOT NULL DEFAULT 'local',
|
|
269
|
+
environment VARCHAR(32) NOT NULL DEFAULT 'prod',
|
|
270
|
+
series_id VARCHAR(512) NOT NULL,
|
|
245
271
|
ts_ms BIGINT NOT NULL,
|
|
246
272
|
start_ts_ms BIGINT DEFAULT NULL,
|
|
247
273
|
count BIGINT NOT NULL,
|
|
@@ -252,8 +278,110 @@ async function ensureSchema(pool) {
|
|
|
252
278
|
bucket_counts_json LONGTEXT,
|
|
253
279
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
254
280
|
INDEX idx_oc_metric_hist_series_ts (series_id(255), ts_ms),
|
|
255
|
-
INDEX idx_oc_metric_hist_ts (ts_ms)
|
|
281
|
+
INDEX idx_oc_metric_hist_ts (ts_ms),
|
|
282
|
+
INDEX idx_oc_metric_hist_project_ts (scope_id, ts_ms)
|
|
283
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
284
|
+
`);
|
|
285
|
+
// -------- Cloud scope management tables --------
|
|
286
|
+
await pool.query(`
|
|
287
|
+
CREATE TABLE IF NOT EXISTS scopes (
|
|
288
|
+
id VARCHAR(64) PRIMARY KEY,
|
|
289
|
+
name VARCHAR(255) NOT NULL,
|
|
290
|
+
token_hash VARCHAR(128) DEFAULT NULL,
|
|
291
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
292
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
293
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
294
|
+
`);
|
|
295
|
+
await ensureMysqlColumn(pool, 'scopes', 'token_hash', 'VARCHAR(128) DEFAULT NULL');
|
|
296
|
+
await pool.query(`
|
|
297
|
+
CREATE TABLE IF NOT EXISTS scope_memberships (
|
|
298
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
299
|
+
scope_id VARCHAR(64) NOT NULL,
|
|
300
|
+
user_id VARCHAR(128) NOT NULL,
|
|
301
|
+
role VARCHAR(16) NOT NULL,
|
|
302
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
303
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
304
|
+
UNIQUE KEY uk_scope_user (scope_id, user_id)
|
|
305
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
306
|
+
`);
|
|
307
|
+
await pool.query(`
|
|
308
|
+
CREATE TABLE IF NOT EXISTS scope_api_keys (
|
|
309
|
+
id VARCHAR(64) PRIMARY KEY,
|
|
310
|
+
scope_id VARCHAR(64) NOT NULL,
|
|
311
|
+
public_key VARCHAR(128) NOT NULL,
|
|
312
|
+
hashed_secret_key VARCHAR(255) NOT NULL,
|
|
313
|
+
display_secret_key VARCHAR(64) NOT NULL,
|
|
314
|
+
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
315
|
+
expires_at TIMESTAMP NULL DEFAULT NULL,
|
|
316
|
+
last_used_at TIMESTAMP NULL DEFAULT NULL,
|
|
317
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
318
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
319
|
+
UNIQUE KEY uk_public_key (public_key),
|
|
320
|
+
INDEX idx_scope_api_keys_scope (scope_id)
|
|
321
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
322
|
+
`);
|
|
323
|
+
await pool.query(`
|
|
324
|
+
CREATE TABLE IF NOT EXISTS scope_security_configs (
|
|
325
|
+
scope_id VARCHAR(64) PRIMARY KEY,
|
|
326
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
327
|
+
config_json LONGTEXT NOT NULL,
|
|
328
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
329
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
256
330
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
|
257
331
|
`);
|
|
258
332
|
}
|
|
333
|
+
async function ensureMysqlColumn(pool, table, column, definition) {
|
|
334
|
+
const [rows] = await pool.query(`SELECT 1
|
|
335
|
+
FROM information_schema.columns
|
|
336
|
+
WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?
|
|
337
|
+
LIMIT 1`, [table, column]);
|
|
338
|
+
if (Array.isArray(rows) && rows.length > 0)
|
|
339
|
+
return;
|
|
340
|
+
await pool.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${column}\` ${definition}`);
|
|
341
|
+
}
|
|
342
|
+
async function ensureMysqlColumnLongText(pool, table, column) {
|
|
343
|
+
const [rows] = await pool.query(`SELECT data_type
|
|
344
|
+
FROM information_schema.columns
|
|
345
|
+
WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?
|
|
346
|
+
LIMIT 1`, [table, column]);
|
|
347
|
+
const row = Array.isArray(rows) && rows.length > 0 ? rows[0] : null;
|
|
348
|
+
if (!row)
|
|
349
|
+
return;
|
|
350
|
+
const dataType = String(row.data_type || '').toLowerCase();
|
|
351
|
+
if (dataType === 'longtext')
|
|
352
|
+
return;
|
|
353
|
+
await pool.query(`ALTER TABLE \`${table}\` MODIFY COLUMN \`${column}\` LONGTEXT NULL`);
|
|
354
|
+
}
|
|
355
|
+
async function ensureMysqlIndex(pool, table, index, column) {
|
|
356
|
+
const [rows] = await pool.query(`SELECT 1
|
|
357
|
+
FROM information_schema.statistics
|
|
358
|
+
WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?
|
|
359
|
+
LIMIT 1`, [table, index]);
|
|
360
|
+
if (Array.isArray(rows) && rows.length > 0)
|
|
361
|
+
return;
|
|
362
|
+
await pool.query(`CREATE INDEX \`${index}\` ON \`${table}\` (\`${column}\`)`);
|
|
363
|
+
}
|
|
364
|
+
async function ensureMysqlSessionPrimaryKey(pool) {
|
|
365
|
+
const [rows] = await pool.query(`SELECT kcu.column_name AS column_name, kcu.ordinal_position AS ordinal_position
|
|
366
|
+
FROM information_schema.table_constraints tc
|
|
367
|
+
JOIN information_schema.key_column_usage kcu
|
|
368
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
369
|
+
AND tc.table_schema = kcu.table_schema
|
|
370
|
+
AND tc.table_name = kcu.table_name
|
|
371
|
+
WHERE tc.table_schema = DATABASE()
|
|
372
|
+
AND tc.table_name = 'observation_sessions'
|
|
373
|
+
AND tc.constraint_type = 'PRIMARY KEY'
|
|
374
|
+
ORDER BY kcu.ordinal_position`);
|
|
375
|
+
const columns = Array.isArray(rows)
|
|
376
|
+
? rows.map((r) => String(r.column_name || '').toLowerCase()).filter(Boolean)
|
|
377
|
+
: [];
|
|
378
|
+
if (columns.length === 2 && columns[0] === 'scope_id' && columns[1] === 'session_id') {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (columns.length > 0) {
|
|
382
|
+
await pool.query('ALTER TABLE `observation_sessions` DROP PRIMARY KEY, ADD PRIMARY KEY (`scope_id`, `session_id`)');
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
await pool.query('ALTER TABLE `observation_sessions` ADD PRIMARY KEY (`scope_id`, `session_id`)');
|
|
386
|
+
}
|
|
259
387
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAOH,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObservabilityAction } from '../types';
|
|
2
2
|
export interface TraceUpsertRecord {
|
|
3
3
|
traceId: string;
|
|
4
|
+
organizationId: string;
|
|
5
|
+
scopeId: string;
|
|
6
|
+
environment: string;
|
|
4
7
|
sessionId: string;
|
|
5
8
|
userId: string;
|
|
6
9
|
channelId: string;
|
|
@@ -13,6 +16,9 @@ export interface TraceUpsertRecord {
|
|
|
13
16
|
}
|
|
14
17
|
export interface ObservationCoreRecord {
|
|
15
18
|
observationId: string;
|
|
19
|
+
organizationId: string;
|
|
20
|
+
scopeId: string;
|
|
21
|
+
environment: string;
|
|
16
22
|
traceId: string;
|
|
17
23
|
parentObservationId: string | null;
|
|
18
24
|
rootObservationId: string;
|
|
@@ -49,6 +55,9 @@ export interface ObservationPayloadRecord {
|
|
|
49
55
|
}
|
|
50
56
|
export interface EventRawRecord {
|
|
51
57
|
eventId: string;
|
|
58
|
+
organizationId: string;
|
|
59
|
+
scopeId: string;
|
|
60
|
+
environment: string;
|
|
52
61
|
traceId: string;
|
|
53
62
|
observationId: string;
|
|
54
63
|
eventType: string;
|
|
@@ -64,5 +73,5 @@ export interface StructuredWriteBatch {
|
|
|
64
73
|
payloads: ObservationPayloadRecord[];
|
|
65
74
|
events: EventRawRecord[];
|
|
66
75
|
}
|
|
67
|
-
export declare function buildStructuredWriteBatch(actions:
|
|
76
|
+
export declare function buildStructuredWriteBatch(actions: ObservabilityAction[]): StructuredWriteBatch;
|
|
68
77
|
//# sourceMappingURL=structured-model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-model.d.ts","sourceRoot":"","sources":["../../src/storage/structured-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"structured-model.d.ts","sourceRoot":"","sources":["../../src/storage/structured-model.ts"],"names":[],"mappings":"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"}
|