@obsunified/collector 2.0.1 → 2.1.1
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/dist/auth.d.ts +1 -1
- package/dist/auth.js +1 -1
- package/dist/{chunk-UGWDOGGH.js → chunk-KMEZKGSO.js} +22 -10
- package/dist/chunk-KMEZKGSO.js.map +1 -0
- package/dist/index.d.ts +322 -26
- package/dist/index.js +1478 -415
- package/dist/index.js.map +1 -1
- package/dist/{ingest-auth-HFVO1zIp.d.ts → ingest-auth-C5-8Mly5.d.ts} +9 -0
- package/package.json +5 -5
- package/src/analyses/derive.ts +26 -25
- package/src/analyses/investigations.ts +8 -8
- package/src/analyses/tier0.ts +22 -22
- package/src/auth/dashboard-auth.test.ts +791 -0
- package/src/auth/dashboard-auth.ts +187 -38
- package/src/auth/login-rate-limit.test.ts +129 -0
- package/src/auth/login-rate-limit.ts +143 -0
- package/src/framework/body-limit.test.ts +165 -0
- package/src/framework/collector.ts +355 -115
- package/src/framework/env.ts +9 -0
- package/src/framework/limits.ts +31 -0
- package/src/framework/scheduled-handlers.test.ts +342 -0
- package/src/index.ts +16 -1
- package/src/lib/action-retention.test.ts +472 -0
- package/src/lib/action-retention.ts +420 -0
- package/src/lib/actions-store.ts +6 -12
- package/src/lib/ai-store/calls.ts +2 -2
- package/src/lib/ai-store/sessions.ts +3 -3
- package/src/lib/ai-store/spans.ts +1 -1
- package/src/lib/ai-store/types.ts +2 -1
- package/src/lib/alerts-store.test.ts +153 -0
- package/src/lib/alerts-store.ts +122 -21
- package/src/lib/analyses-runner.test.ts +75 -0
- package/src/lib/analyses-runner.ts +60 -3
- package/src/lib/analyses-store-latest.test.ts +61 -0
- package/src/lib/analyses-store.ts +17 -10
- package/src/lib/blob-store.ts +1 -1
- package/src/lib/housekeeping.test.ts +73 -0
- package/src/lib/housekeeping.ts +93 -0
- package/src/lib/identity-index/action-lookups.ts +6 -6
- package/src/lib/identity-index/key-lookups.ts +2 -2
- package/src/lib/identity-index/user-lookup.ts +8 -5
- package/src/lib/identity-index.test.ts +2 -3
- package/src/lib/metrics-store-series.test.ts +99 -0
- package/src/lib/metrics-store.test.ts +23 -0
- package/src/lib/metrics-store.ts +27 -3
- package/src/lib/projects-store.test.ts +25 -0
- package/src/lib/projects-store.ts +4 -3
- package/src/lib/sql-db-dialect.test.ts +12 -3
- package/src/lib/sql-db-postgres.integration.test.ts +1225 -0
- package/src/lib/sql-db-postgres.test.ts +314 -0
- package/src/lib/sql-db-postgres.ts +392 -54
- package/src/lib/sql-db-sqlite-time-windows.test.ts +194 -0
- package/src/lib/sql-db.ts +40 -6
- package/src/lib/test-utils/action-graph-fixtures.ts +307 -0
- package/src/lib/test-utils/node-sqlite-db.ts +188 -0
- package/src/lib/webhook-url.test.ts +122 -0
- package/src/lib/webhook-url.ts +155 -0
- package/src/migrations/041_ingest_key_hash_text.sql +5 -0
- package/src/migrations/042_session_replay_project_composite_pk.sql +52 -0
- package/src/migrations/043_metric_exemplars_text_timestamps.sql +5 -0
- package/src/migrations/044_actions_started_at_index.sql +10 -0
- package/src/migrations/045_user_profiles_project_composite_pk.sql +40 -0
- package/src/migrations/046_action_graph_project_composite_pk.sql +255 -0
- package/src/migrations/047_ai_span_payloads_project_composite_pk.sql +61 -0
- package/src/migrations/048_telemetry_spans_project_composite_pk.sql +92 -0
- package/src/migrations/049_alert_state_notified.sql +17 -0
- package/src/migrations/alert-state-notified.test.ts +111 -0
- package/src/migrations/parity.test.ts +64 -0
- package/src/migrations/project-scoped-keys.test.ts +432 -0
- package/src/migrations-postgres/009_projects_and_keys.sql +4 -4
- package/src/migrations-postgres/026_obs_dashboard_project_seed.sql +1 -1
- package/src/migrations-postgres/035_metric_exemplars.sql +5 -2
- package/src/migrations-postgres/041_ingest_key_hash_text.sql +32 -0
- package/src/migrations-postgres/042_session_replay_project_composite_pk.sql +16 -0
- package/src/migrations-postgres/043_metric_exemplars_text_timestamps.sql +47 -0
- package/src/migrations-postgres/044_actions_started_at_index.sql +8 -0
- package/src/migrations-postgres/045_user_profiles_project_composite_pk.sql +33 -0
- package/src/migrations-postgres/046_action_graph_project_composite_pk.sql +39 -0
- package/src/migrations-postgres/047_ai_span_payloads_project_composite_pk.sql +30 -0
- package/src/migrations-postgres/048_telemetry_spans_project_composite_pk.sql +37 -0
- package/src/migrations-postgres/049_alert_state_notified.sql +10 -0
- package/src/migrations-postgres/README.md +58 -5
- package/src/otlp/decode/body.test.ts +76 -0
- package/src/otlp/decode/body.ts +67 -6
- package/src/plugins/_json.ts +21 -0
- package/src/plugins/action-graph-processor.ts +6 -12
- package/src/plugins/ai-receiver.ts +5 -12
- package/src/plugins/ai-span-payloads-processor.ts +1 -2
- package/src/plugins/alerts-evaluator-retention.test.ts +170 -0
- package/src/plugins/alerts-evaluator.test.ts +464 -3
- package/src/plugins/alerts-evaluator.ts +165 -41
- package/src/plugins/alerts-routes.ts +10 -6
- package/src/plugins/ask-routes.ts +4 -5
- package/src/plugins/connected-routes.test.ts +106 -0
- package/src/plugins/connected-routes.ts +14 -5
- package/src/plugins/dashboard-routes.test.ts +120 -0
- package/src/plugins/dashboard-routes.ts +11 -2
- package/src/plugins/eval-cases-routes.ts +8 -17
- package/src/plugins/identity-receiver.ts +9 -11
- package/src/plugins/json-body.test.ts +91 -0
- package/src/plugins/onboarding-routes.test.ts +105 -0
- package/src/plugins/onboarding-routes.ts +26 -11
- package/src/plugins/projects-routes.ts +2 -1
- package/src/plugins/replay-isolation.test.ts +922 -0
- package/src/plugins/replay-receiver.ts +8 -8
- package/src/plugins/usage-receiver.ts +3 -6
- package/dist/chunk-UGWDOGGH.js.map +0 -1
|
@@ -73,10 +73,19 @@ interface CollectorEnv {
|
|
|
73
73
|
INGEST_KEY?: string;
|
|
74
74
|
/** Password for dashboard login */
|
|
75
75
|
DASHBOARD_PASSWORD?: string;
|
|
76
|
+
/** Programmatic read/admin bearer token for /internal/* endpoints (e.g. MCP server) */
|
|
77
|
+
DASHBOARD_TOKEN?: string;
|
|
76
78
|
/** Comma-separated allowed origins for CORS (e.g. "https://my-app.com,https://staging.my-app.com") */
|
|
77
79
|
ALLOWED_ORIGINS?: string;
|
|
78
80
|
/** Set to "true" to allow unauthenticated ingest (local dev only) */
|
|
79
81
|
ALLOW_UNAUTHENTICATED?: string;
|
|
82
|
+
/** Raw request body cap in bytes for /v1/* and /internal/* (default 10 MiB). */
|
|
83
|
+
MAX_BODY_BYTES?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Set to "true" to let alert webhooks target loopback / private / link-local
|
|
86
|
+
* hosts (self-hosted receivers). Off by default to block SSRF.
|
|
87
|
+
*/
|
|
88
|
+
ALERT_WEBHOOK_ALLOW_PRIVATE?: string;
|
|
80
89
|
TELEMETRY_REDACT_FIELDS?: string;
|
|
81
90
|
/**
|
|
82
91
|
* Local/test escape hatch for payload capture. Production should prefer the
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obsunified/collector",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Plugin-based observability collector runtime with pluggable SQL/blob storage.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/
|
|
8
|
+
"url": "https://github.com/dev-sawan-ruparel/obs-unified.git",
|
|
9
9
|
"directory": "packages/obs-collector"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@bufbuild/protobuf": "^2.11.0",
|
|
41
|
-
"@obsunified/pprof-decoder": "2.0.
|
|
42
|
-
"@obsunified/types": "2.0.
|
|
41
|
+
"@obsunified/pprof-decoder": "2.0.2",
|
|
42
|
+
"@obsunified/types": "2.0.2"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"hono": "^4.7.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@bufbuild/buf": "^1.68.1",
|
|
55
55
|
"@bufbuild/protoc-gen-es": "^2.11.0",
|
|
56
56
|
"@types/pg": "^8.11.10",
|
|
57
|
-
"hono": "^4.
|
|
57
|
+
"hono": "^4.13.13",
|
|
58
58
|
"pg": "^8.13.1",
|
|
59
59
|
"tsup": "^8.3.5",
|
|
60
60
|
"typescript": "^6.0.2"
|
package/src/analyses/derive.ts
CHANGED
|
@@ -59,7 +59,7 @@ const fetchShape = async (
|
|
|
59
59
|
FROM telemetry_spans
|
|
60
60
|
WHERE project_id = ?
|
|
61
61
|
AND service_name IS NOT NULL
|
|
62
|
-
AND received_at >=
|
|
62
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')`,
|
|
63
63
|
)
|
|
64
64
|
.bind(projectId)
|
|
65
65
|
.all<{ service_name: string }>();
|
|
@@ -83,7 +83,7 @@ const fetchShape = async (
|
|
|
83
83
|
AND parent.trace_id = child.trace_id
|
|
84
84
|
AND parent.span_id = child.parent_span_id
|
|
85
85
|
WHERE child.project_id = ?
|
|
86
|
-
AND child.received_at >=
|
|
86
|
+
AND child.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
87
87
|
AND parent.service_name IS NOT NULL
|
|
88
88
|
AND child.service_name IS NOT NULL
|
|
89
89
|
AND parent.service_name <> child.service_name`,
|
|
@@ -101,7 +101,7 @@ const fetchShape = async (
|
|
|
101
101
|
`SELECT DISTINCT json_extract(attributes_json, '$."messaging.destination"') AS topic
|
|
102
102
|
FROM telemetry_spans
|
|
103
103
|
WHERE project_id = ?
|
|
104
|
-
AND received_at >=
|
|
104
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
105
105
|
AND json_extract(attributes_json, '$."messaging.destination"') IS NOT NULL`,
|
|
106
106
|
)
|
|
107
107
|
.bind(projectId)
|
|
@@ -121,7 +121,7 @@ const fetchShape = async (
|
|
|
121
121
|
`SELECT 1
|
|
122
122
|
FROM telemetry_spans
|
|
123
123
|
WHERE project_id = ?
|
|
124
|
-
AND received_at >=
|
|
124
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
125
125
|
AND (
|
|
126
126
|
json_extract(attributes_json, '$."openinference.span.kind"') = 'LLM'
|
|
127
127
|
OR json_extract(attributes_json, '$."gen_ai.system"') IS NOT NULL
|
|
@@ -194,7 +194,7 @@ const makeServiceErrorRate = (
|
|
|
194
194
|
FROM telemetry_spans
|
|
195
195
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
196
196
|
AND service_name = '${sqlEscape(service)}'
|
|
197
|
-
AND received_at >=
|
|
197
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
198
198
|
),
|
|
199
199
|
base_window AS (
|
|
200
200
|
SELECT
|
|
@@ -203,8 +203,8 @@ const makeServiceErrorRate = (
|
|
|
203
203
|
FROM telemetry_spans
|
|
204
204
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
205
205
|
AND service_name = '${sqlEscape(service)}'
|
|
206
|
-
AND received_at >=
|
|
207
|
-
AND received_at <
|
|
206
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
207
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
208
208
|
),
|
|
209
209
|
spark AS (
|
|
210
210
|
SELECT
|
|
@@ -214,7 +214,7 @@ const makeServiceErrorRate = (
|
|
|
214
214
|
FROM telemetry_spans
|
|
215
215
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
216
216
|
AND service_name = '${sqlEscape(service)}'
|
|
217
|
-
AND received_at >=
|
|
217
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
218
218
|
GROUP BY minute
|
|
219
219
|
ORDER BY minute ASC
|
|
220
220
|
)
|
|
@@ -280,7 +280,7 @@ const makeServiceLatencyP95 = (
|
|
|
280
280
|
FROM telemetry_spans
|
|
281
281
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
282
282
|
AND service_name = '${sqlEscape(service)}'
|
|
283
|
-
AND received_at >=
|
|
283
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
284
284
|
),
|
|
285
285
|
base AS (
|
|
286
286
|
SELECT duration_ms,
|
|
@@ -289,8 +289,8 @@ const makeServiceLatencyP95 = (
|
|
|
289
289
|
FROM telemetry_spans
|
|
290
290
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
291
291
|
AND service_name = '${sqlEscape(service)}'
|
|
292
|
-
AND received_at >=
|
|
293
|
-
AND received_at <
|
|
292
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-25 hours')
|
|
293
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-24 hours')
|
|
294
294
|
),
|
|
295
295
|
cur_p95 AS (
|
|
296
296
|
SELECT duration_ms FROM cur
|
|
@@ -360,7 +360,7 @@ const makeDependencyHealth = (
|
|
|
360
360
|
WHERE child.project_id = '${sqlEscape(projectId)}'
|
|
361
361
|
AND parent.service_name = '${sqlEscape(source)}'
|
|
362
362
|
AND child.service_name = '${sqlEscape(target)}'
|
|
363
|
-
AND child.received_at >=
|
|
363
|
+
AND child.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
364
364
|
),
|
|
365
365
|
edge_base AS (
|
|
366
366
|
SELECT child.status_code AS sc
|
|
@@ -372,8 +372,8 @@ const makeDependencyHealth = (
|
|
|
372
372
|
WHERE child.project_id = '${sqlEscape(projectId)}'
|
|
373
373
|
AND parent.service_name = '${sqlEscape(source)}'
|
|
374
374
|
AND child.service_name = '${sqlEscape(target)}'
|
|
375
|
-
AND child.received_at >=
|
|
376
|
-
AND child.received_at <
|
|
375
|
+
AND child.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
376
|
+
AND child.received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
377
377
|
),
|
|
378
378
|
now_agg AS (
|
|
379
379
|
SELECT COUNT(*) AS total,
|
|
@@ -438,7 +438,7 @@ const makeMessagingLag = (
|
|
|
438
438
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
439
439
|
AND span_kind = 4
|
|
440
440
|
AND json_extract(attributes_json, '$."messaging.destination"') = '${sqlEscape(topic)}'
|
|
441
|
-
AND received_at >=
|
|
441
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-15 minutes')
|
|
442
442
|
),
|
|
443
443
|
consumers AS (
|
|
444
444
|
SELECT trace_id,
|
|
@@ -448,7 +448,7 @@ const makeMessagingLag = (
|
|
|
448
448
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
449
449
|
AND span_kind = 5
|
|
450
450
|
AND json_extract(attributes_json, '$."messaging.destination"') = '${sqlEscape(topic)}'
|
|
451
|
-
AND received_at >=
|
|
451
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-15 minutes')
|
|
452
452
|
),
|
|
453
453
|
gaps AS (
|
|
454
454
|
SELECT
|
|
@@ -514,15 +514,15 @@ const makeAiCostBurn = (projectId: string): AnalysisDefinition => ({
|
|
|
514
514
|
COUNT(*) AS n
|
|
515
515
|
FROM ai_calls
|
|
516
516
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
517
|
-
AND received_at >=
|
|
517
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
518
518
|
),
|
|
519
519
|
prev AS (
|
|
520
520
|
SELECT COALESCE(SUM(total_cost_usd), 0) AS cost,
|
|
521
521
|
COUNT(*) AS n
|
|
522
522
|
FROM ai_calls
|
|
523
523
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
524
|
-
AND received_at >=
|
|
525
|
-
AND received_at <
|
|
524
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-2 hours')
|
|
525
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
526
526
|
),
|
|
527
527
|
delta AS (
|
|
528
528
|
SELECT CASE
|
|
@@ -560,25 +560,26 @@ const makeAiErrorRate = (projectId: string): AnalysisDefinition => ({
|
|
|
560
560
|
// AI error rate is per-call; 5 min cadence balances signal vs cost on
|
|
561
561
|
// installs with hundreds of LLM spans.
|
|
562
562
|
refreshSeconds: 300,
|
|
563
|
-
// is_error
|
|
563
|
+
// is_error fraction in the last 5 minutes vs trailing 1h baseline. Tested
|
|
564
|
+
// as a bare boolean so it works for INTEGER 0/1 (D1) and BOOLEAN (Postgres).
|
|
564
565
|
// Same thresholds as overall_error_rate.
|
|
565
566
|
sql: `
|
|
566
567
|
WITH now_window AS (
|
|
567
568
|
SELECT
|
|
568
569
|
COUNT(*) AS total,
|
|
569
|
-
SUM(CASE WHEN is_error
|
|
570
|
+
SUM(CASE WHEN is_error THEN 1 ELSE 0 END) AS errors
|
|
570
571
|
FROM ai_calls
|
|
571
572
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
572
|
-
AND received_at >=
|
|
573
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
573
574
|
),
|
|
574
575
|
base_window AS (
|
|
575
576
|
SELECT
|
|
576
577
|
COUNT(*) AS total,
|
|
577
|
-
SUM(CASE WHEN is_error
|
|
578
|
+
SUM(CASE WHEN is_error THEN 1 ELSE 0 END) AS errors
|
|
578
579
|
FROM ai_calls
|
|
579
580
|
WHERE project_id = '${sqlEscape(projectId)}'
|
|
580
|
-
AND received_at >=
|
|
581
|
-
AND received_at <
|
|
581
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
582
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
582
583
|
)
|
|
583
584
|
SELECT
|
|
584
585
|
CASE
|
|
@@ -48,7 +48,7 @@ const errorTopOffenders: AnalysisDefinition = {
|
|
|
48
48
|
COUNT(*) AS errors
|
|
49
49
|
FROM telemetry_spans
|
|
50
50
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
51
|
-
AND received_at >=
|
|
51
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
52
52
|
AND status_code = 2
|
|
53
53
|
GROUP BY service_name
|
|
54
54
|
ORDER BY errors DESC
|
|
@@ -59,8 +59,8 @@ const errorTopOffenders: AnalysisDefinition = {
|
|
|
59
59
|
COUNT(*) AS errors
|
|
60
60
|
FROM telemetry_spans
|
|
61
61
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
62
|
-
AND received_at >=
|
|
63
|
-
AND received_at <
|
|
62
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
63
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
64
64
|
AND status_code = 2
|
|
65
65
|
GROUP BY service_name
|
|
66
66
|
ORDER BY errors DESC
|
|
@@ -128,7 +128,7 @@ const latencyOutlierAttribution: AnalysisDefinition = {
|
|
|
128
128
|
COUNT(*) OVER () AS n
|
|
129
129
|
FROM telemetry_spans
|
|
130
130
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
131
|
-
AND received_at >=
|
|
131
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-15 minutes')
|
|
132
132
|
),
|
|
133
133
|
p95_cut AS (
|
|
134
134
|
-- Conservatively call "tail" the slowest 5% of the window.
|
|
@@ -203,12 +203,12 @@ const logAnomalySummary: AnalysisDefinition = {
|
|
|
203
203
|
(SELECT l2.message FROM logs l2
|
|
204
204
|
WHERE l2.project_id = '{{PROJECT_ID}}'
|
|
205
205
|
AND COALESCE(l2.logger_name, '<unknown>') = COALESCE(l1.logger_name, '<unknown>')
|
|
206
|
-
AND l2.received_at >=
|
|
206
|
+
AND l2.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
207
207
|
AND l2.severity_number >= 17
|
|
208
208
|
ORDER BY l2.received_at DESC LIMIT 1) AS sample_message
|
|
209
209
|
FROM logs l1
|
|
210
210
|
WHERE l1.project_id = '{{PROJECT_ID}}'
|
|
211
|
-
AND l1.received_at >=
|
|
211
|
+
AND l1.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
212
212
|
AND l1.severity_number >= 17
|
|
213
213
|
GROUP BY l1.logger_name
|
|
214
214
|
),
|
|
@@ -216,8 +216,8 @@ const logAnomalySummary: AnalysisDefinition = {
|
|
|
216
216
|
SELECT DISTINCT COALESCE(logger_name, '<unknown>') AS logger
|
|
217
217
|
FROM logs
|
|
218
218
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
219
|
-
AND received_at >=
|
|
220
|
-
AND received_at <
|
|
219
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
220
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
221
221
|
AND severity_number >= 17
|
|
222
222
|
),
|
|
223
223
|
newcomers AS (
|
package/src/analyses/tier0.ts
CHANGED
|
@@ -40,7 +40,7 @@ const overallErrorRate: AnalysisDefinition = {
|
|
|
40
40
|
SUM(CASE WHEN status_code = 2 THEN 1 ELSE 0 END) AS errors
|
|
41
41
|
FROM telemetry_spans
|
|
42
42
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
43
|
-
AND received_at >=
|
|
43
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
44
44
|
),
|
|
45
45
|
base_window AS (
|
|
46
46
|
SELECT
|
|
@@ -48,8 +48,8 @@ const overallErrorRate: AnalysisDefinition = {
|
|
|
48
48
|
SUM(CASE WHEN status_code = 2 THEN 1 ELSE 0 END) AS errors
|
|
49
49
|
FROM telemetry_spans
|
|
50
50
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
51
|
-
AND received_at >=
|
|
52
|
-
AND received_at <
|
|
51
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
52
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
53
53
|
),
|
|
54
54
|
spark AS (
|
|
55
55
|
-- per-minute error rate over the last 30 minutes for sparkline rendering
|
|
@@ -59,7 +59,7 @@ const overallErrorRate: AnalysisDefinition = {
|
|
|
59
59
|
SUM(CASE WHEN status_code = 2 THEN 1 ELSE 0 END) AS errors
|
|
60
60
|
FROM telemetry_spans
|
|
61
61
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
62
|
-
AND received_at >=
|
|
62
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
63
63
|
GROUP BY minute
|
|
64
64
|
ORDER BY minute ASC
|
|
65
65
|
)
|
|
@@ -123,7 +123,7 @@ const topErrorServices: AnalysisDefinition = {
|
|
|
123
123
|
SUM(CASE WHEN status_code = 2 THEN 1 ELSE 0 END) AS errors
|
|
124
124
|
FROM telemetry_spans
|
|
125
125
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
126
|
-
AND received_at >=
|
|
126
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
127
127
|
GROUP BY service
|
|
128
128
|
),
|
|
129
129
|
top5 AS (
|
|
@@ -183,7 +183,7 @@ const latencyP95Overall: AnalysisDefinition = {
|
|
|
183
183
|
COUNT(*) OVER () AS n
|
|
184
184
|
FROM telemetry_spans
|
|
185
185
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
186
|
-
AND received_at >=
|
|
186
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
187
187
|
),
|
|
188
188
|
base AS (
|
|
189
189
|
SELECT duration_ms,
|
|
@@ -191,8 +191,8 @@ const latencyP95Overall: AnalysisDefinition = {
|
|
|
191
191
|
COUNT(*) OVER () AS n
|
|
192
192
|
FROM telemetry_spans
|
|
193
193
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
194
|
-
AND received_at >=
|
|
195
|
-
AND received_at <
|
|
194
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-25 hours')
|
|
195
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-24 hours')
|
|
196
196
|
),
|
|
197
197
|
cur_p95 AS (
|
|
198
198
|
SELECT duration_ms FROM cur
|
|
@@ -214,7 +214,7 @@ const latencyP95Overall: AnalysisDefinition = {
|
|
|
214
214
|
COUNT(*) AS n
|
|
215
215
|
FROM telemetry_spans
|
|
216
216
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
217
|
-
AND received_at >=
|
|
217
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
218
218
|
GROUP BY bucket
|
|
219
219
|
ORDER BY bucket ASC
|
|
220
220
|
),
|
|
@@ -271,7 +271,7 @@ const throughputSlope: AnalysisDefinition = {
|
|
|
271
271
|
COUNT(*) OVER () AS n
|
|
272
272
|
FROM telemetry_spans
|
|
273
273
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
274
|
-
AND received_at >=
|
|
274
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
275
275
|
),
|
|
276
276
|
prev AS (
|
|
277
277
|
SELECT duration_ms,
|
|
@@ -279,8 +279,8 @@ const throughputSlope: AnalysisDefinition = {
|
|
|
279
279
|
COUNT(*) OVER () AS n
|
|
280
280
|
FROM telemetry_spans
|
|
281
281
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
282
|
-
AND received_at >=
|
|
283
|
-
AND received_at <
|
|
282
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-60 minutes')
|
|
283
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
284
284
|
),
|
|
285
285
|
cur_n AS (SELECT COALESCE((SELECT n FROM cur LIMIT 1), 0) AS n),
|
|
286
286
|
prev_n AS (SELECT COALESCE((SELECT n FROM prev LIMIT 1), 0) AS n),
|
|
@@ -347,7 +347,7 @@ const activeSessions: AnalysisDefinition = {
|
|
|
347
347
|
SELECT COUNT(DISTINCT session_id) AS n
|
|
348
348
|
FROM usage_events
|
|
349
349
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
350
|
-
AND received_at >=
|
|
350
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-15 minutes')
|
|
351
351
|
),
|
|
352
352
|
hourly AS (
|
|
353
353
|
SELECT
|
|
@@ -355,7 +355,7 @@ const activeSessions: AnalysisDefinition = {
|
|
|
355
355
|
COUNT(DISTINCT session_id) AS sessions
|
|
356
356
|
FROM usage_events
|
|
357
357
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
358
|
-
AND received_at >=
|
|
358
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-24 hours')
|
|
359
359
|
GROUP BY hour
|
|
360
360
|
ORDER BY hour ASC
|
|
361
361
|
)
|
|
@@ -400,7 +400,7 @@ const logErrorRate: AnalysisDefinition = {
|
|
|
400
400
|
SUM(CASE WHEN severity_number >= 17 THEN 1 ELSE 0 END) AS errors
|
|
401
401
|
FROM logs
|
|
402
402
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
403
|
-
AND received_at >=
|
|
403
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
404
404
|
),
|
|
405
405
|
base_window AS (
|
|
406
406
|
SELECT
|
|
@@ -408,8 +408,8 @@ const logErrorRate: AnalysisDefinition = {
|
|
|
408
408
|
SUM(CASE WHEN severity_number >= 17 THEN 1 ELSE 0 END) AS errors
|
|
409
409
|
FROM logs
|
|
410
410
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
411
|
-
AND received_at >=
|
|
412
|
-
AND received_at <
|
|
411
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-1 hour')
|
|
412
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
413
413
|
),
|
|
414
414
|
spark AS (
|
|
415
415
|
SELECT
|
|
@@ -418,7 +418,7 @@ const logErrorRate: AnalysisDefinition = {
|
|
|
418
418
|
SUM(CASE WHEN severity_number >= 17 THEN 1 ELSE 0 END) AS errors
|
|
419
419
|
FROM logs
|
|
420
420
|
WHERE project_id = '{{PROJECT_ID}}'
|
|
421
|
-
AND received_at >=
|
|
421
|
+
AND received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
422
422
|
GROUP BY minute
|
|
423
423
|
ORDER BY minute ASC
|
|
424
424
|
)
|
|
@@ -490,19 +490,19 @@ const serviceCpuUtilization: AnalysisDefinition = {
|
|
|
490
490
|
WHERE s.project_id = '{{PROJECT_ID}}'
|
|
491
491
|
AND s.name = 'process.cpu.utilization'
|
|
492
492
|
AND s.service_name IS NOT NULL
|
|
493
|
-
AND p.received_at >=
|
|
493
|
+
AND p.received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
494
494
|
),
|
|
495
495
|
now_window AS (
|
|
496
496
|
SELECT service_name, AVG(value) AS avg_util
|
|
497
497
|
FROM cpu_points
|
|
498
|
-
WHERE received_at >=
|
|
498
|
+
WHERE received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
499
499
|
GROUP BY service_name
|
|
500
500
|
),
|
|
501
501
|
base_window AS (
|
|
502
502
|
SELECT service_name, AVG(value) AS avg_util
|
|
503
503
|
FROM cpu_points
|
|
504
|
-
WHERE received_at >=
|
|
505
|
-
AND received_at <
|
|
504
|
+
WHERE received_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 minutes')
|
|
505
|
+
AND received_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-5 minutes')
|
|
506
506
|
GROUP BY service_name
|
|
507
507
|
),
|
|
508
508
|
top_now AS (
|