@senad-d/observme 0.1.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.
Files changed (111) hide show
  1. package/.env.example +57 -0
  2. package/CHANGELOG.md +52 -0
  3. package/LICENSE +21 -0
  4. package/ObservMe-Production-Docs/00-README.md +79 -0
  5. package/ObservMe-Production-Docs/01-requirements-and-scope.md +207 -0
  6. package/ObservMe-Production-Docs/02-reference-architecture.md +306 -0
  7. package/ObservMe-Production-Docs/03-pi-event-and-session-model.md +266 -0
  8. package/ObservMe-Production-Docs/04-telemetry-semantic-conventions.md +722 -0
  9. package/ObservMe-Production-Docs/05-otel-pipeline-and-collector.md +355 -0
  10. package/ObservMe-Production-Docs/06-security-privacy-redaction.md +294 -0
  11. package/ObservMe-Production-Docs/07-extension-implementation-blueprint.md +447 -0
  12. package/ObservMe-Production-Docs/08-query-grafana-integration.md +276 -0
  13. package/ObservMe-Production-Docs/09-dashboards-alerts-slos.md +640 -0
  14. package/ObservMe-Production-Docs/10-testing-release-operations.md +319 -0
  15. package/ObservMe-Production-Docs/11-deployment-runbooks.md +203 -0
  16. package/ObservMe-Production-Docs/12-configuration-reference.md +337 -0
  17. package/ObservMe-Production-Docs/13-source-notes.md +33 -0
  18. package/ObservMe-Production-Docs/pi-session-format.md +427 -0
  19. package/README.md +356 -0
  20. package/SECURITY.md +45 -0
  21. package/dashboards/observme-agent-node-graphs.json +250 -0
  22. package/dashboards/observme-agents.json +1880 -0
  23. package/dashboards/observme-alerts.yaml +113 -0
  24. package/dashboards/observme-branches-compactions.json +1042 -0
  25. package/dashboards/observme-cost.json +1254 -0
  26. package/dashboards/observme-errors.json +1659 -0
  27. package/dashboards/observme-export-health.json +1802 -0
  28. package/dashboards/observme-latency.json +1494 -0
  29. package/dashboards/observme-llm-conversations.json +730 -0
  30. package/dashboards/observme-logs-llm.json +644 -0
  31. package/dashboards/observme-models.json +933 -0
  32. package/dashboards/observme-overview.json +2129 -0
  33. package/dashboards/observme-slo-health.json +737 -0
  34. package/dashboards/observme-slos.yaml +56 -0
  35. package/dashboards/observme-tools.json +902 -0
  36. package/dashboards/observme-trace-journey.json +1793 -0
  37. package/docs/STRUCTURE.md +49 -0
  38. package/docs/agent-subagent-observability-requirements.md +997 -0
  39. package/docs/compatibility-matrix.md +39 -0
  40. package/docs/configuration-tui-design-standard.md +767 -0
  41. package/docs/configuration.md +38 -0
  42. package/docs/review-validation.md +115 -0
  43. package/docs/validation-flow.md +117 -0
  44. package/examples/collector.yaml +123 -0
  45. package/examples/observme.yaml +131 -0
  46. package/img/demo.gif +0 -0
  47. package/img/icon.svg +47 -0
  48. package/package.json +103 -0
  49. package/src/commands/obs-agents-runtime.ts +150 -0
  50. package/src/commands/obs-agents.ts +491 -0
  51. package/src/commands/obs-args.ts +63 -0
  52. package/src/commands/obs-backfill.ts +1334 -0
  53. package/src/commands/obs-command-support.ts +43 -0
  54. package/src/commands/obs-cost.ts +228 -0
  55. package/src/commands/obs-diagnostics.ts +22 -0
  56. package/src/commands/obs-errors.ts +156 -0
  57. package/src/commands/obs-health.ts +301 -0
  58. package/src/commands/obs-link.ts +90 -0
  59. package/src/commands/obs-logs.ts +194 -0
  60. package/src/commands/obs-loki-summary.ts +184 -0
  61. package/src/commands/obs-session.ts +259 -0
  62. package/src/commands/obs-status.ts +359 -0
  63. package/src/commands/obs-tools.ts +274 -0
  64. package/src/commands/obs-trace.ts +411 -0
  65. package/src/commands/obs.ts +211 -0
  66. package/src/config/bootstrap-project-config.ts +300 -0
  67. package/src/config/defaults.ts +143 -0
  68. package/src/config/load-config.ts +631 -0
  69. package/src/config/project-paths.ts +61 -0
  70. package/src/config/schema.ts +405 -0
  71. package/src/config/validate.ts +456 -0
  72. package/src/constants.ts +4 -0
  73. package/src/diagnostics/sanitize.ts +6 -0
  74. package/src/extension.ts +38 -0
  75. package/src/otel/logs.ts +160 -0
  76. package/src/otel/metrics.ts +165 -0
  77. package/src/otel/otlp-endpoint.ts +10 -0
  78. package/src/otel/sdk.ts +114 -0
  79. package/src/otel/shutdown.ts +102 -0
  80. package/src/otel/traces.ts +166 -0
  81. package/src/pi/agent-lineage.ts +378 -0
  82. package/src/pi/agent-tree-tracker.ts +258 -0
  83. package/src/pi/event-handlers/agent-turn.ts +155 -0
  84. package/src/pi/event-handlers/lifecycle.ts +642 -0
  85. package/src/pi/event-handlers/llm.ts +115 -0
  86. package/src/pi/event-handlers/session-events.ts +159 -0
  87. package/src/pi/event-handlers/tool-bash.ts +275 -0
  88. package/src/pi/handler-internals.ts +2154 -0
  89. package/src/pi/handler-runtime.ts +633 -0
  90. package/src/pi/handler-types.ts +261 -0
  91. package/src/pi/handlers.ts +75 -0
  92. package/src/pi/subagent-spawn.ts +975 -0
  93. package/src/pi/subagent-types.ts +29 -0
  94. package/src/privacy/content-capture.ts +104 -0
  95. package/src/privacy/hash.ts +93 -0
  96. package/src/privacy/redact.ts +619 -0
  97. package/src/privacy/secret-patterns.ts +185 -0
  98. package/src/privacy/truncate.ts +69 -0
  99. package/src/query/grafana-readiness.ts +164 -0
  100. package/src/query/grafana-transport.ts +481 -0
  101. package/src/query/grafana.ts +371 -0
  102. package/src/query/loki.ts +332 -0
  103. package/src/query/prometheus.ts +388 -0
  104. package/src/query/tempo.ts +332 -0
  105. package/src/safety/sensitive-input.ts +208 -0
  106. package/src/semconv/attributes.ts +279 -0
  107. package/src/semconv/metrics.ts +146 -0
  108. package/src/semconv/spans.ts +19 -0
  109. package/src/semconv/values.ts +13 -0
  110. package/src/util/bounded-map.ts +97 -0
  111. package/tsconfig.json +15 -0
@@ -0,0 +1,902 @@
1
+ {
2
+ "__requires": [
3
+ {
4
+ "id": "grafana",
5
+ "name": "Grafana",
6
+ "type": "grafana",
7
+ "version": "10.0.0"
8
+ },
9
+ {
10
+ "id": "prometheus",
11
+ "name": "Prometheus",
12
+ "type": "datasource",
13
+ "version": "1.0.0"
14
+ },
15
+ {
16
+ "id": "loki",
17
+ "name": "Loki",
18
+ "type": "datasource",
19
+ "version": "1.0.0"
20
+ },
21
+ {
22
+ "id": "row",
23
+ "name": "Row",
24
+ "type": "panel",
25
+ "version": ""
26
+ },
27
+ {
28
+ "id": "timeseries",
29
+ "name": "Time series",
30
+ "type": "panel",
31
+ "version": ""
32
+ },
33
+ {
34
+ "id": "bargauge",
35
+ "name": "Bar gauge",
36
+ "type": "panel",
37
+ "version": ""
38
+ },
39
+ {
40
+ "id": "table",
41
+ "name": "Table",
42
+ "type": "panel",
43
+ "version": ""
44
+ },
45
+ {
46
+ "id": "logs",
47
+ "name": "Logs",
48
+ "type": "panel",
49
+ "version": ""
50
+ }
51
+ ],
52
+ "annotations": {
53
+ "list": []
54
+ },
55
+ "editable": true,
56
+ "fiscalYearStartMonth": 0,
57
+ "graphTooltip": 1,
58
+ "id": null,
59
+ "links": [
60
+ {
61
+ "icon": "external link",
62
+ "includeVars": true,
63
+ "keepTime": true,
64
+ "targetBlank": false,
65
+ "title": "Latency",
66
+ "tooltip": "Open cross-stage latency tables with tool volume context.",
67
+ "type": "link",
68
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
69
+ },
70
+ {
71
+ "icon": "external link",
72
+ "includeVars": true,
73
+ "keepTime": true,
74
+ "targetBlank": false,
75
+ "title": "Errors",
76
+ "tooltip": "Open aggregate failure pressure and parsed failure details.",
77
+ "type": "link",
78
+ "url": "/d/observme-errors/observme-errors?${__url_time_range}"
79
+ },
80
+ {
81
+ "icon": "external link",
82
+ "includeVars": true,
83
+ "keepTime": true,
84
+ "targetBlank": false,
85
+ "title": "Tool failure logs",
86
+ "tooltip": "Open the parsed tool.call.failed log table.",
87
+ "type": "link",
88
+ "url": "/d/observme-errors/observme-errors?${__url_time_range}&viewPanel=7"
89
+ },
90
+ {
91
+ "icon": "external link",
92
+ "includeVars": true,
93
+ "keepTime": true,
94
+ "targetBlank": false,
95
+ "title": "Trace Journey",
96
+ "tooltip": "Open execution logs and Tempo traces for representative tool calls.",
97
+ "type": "link",
98
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
99
+ }
100
+ ],
101
+ "liveNow": false,
102
+ "panels": [
103
+ {
104
+ "collapsed": false,
105
+ "gridPos": {
106
+ "h": 1,
107
+ "w": 24,
108
+ "x": 0,
109
+ "y": 0
110
+ },
111
+ "id": 100,
112
+ "panels": [],
113
+ "title": "Traffic and reliability",
114
+ "type": "row"
115
+ },
116
+ {
117
+ "datasource": {
118
+ "type": "prometheus",
119
+ "uid": "prometheus"
120
+ },
121
+ "description": "Top 10 tool-call rates grouped by the bounded tool_name label. A single unlabeled zero means no call series is active; that can be an idle range or missing telemetry, so check Export Health when calls were expected.",
122
+ "fieldConfig": {
123
+ "defaults": {
124
+ "color": {
125
+ "mode": "palette-classic"
126
+ },
127
+ "mappings": [],
128
+ "min": 0,
129
+ "thresholds": {
130
+ "mode": "absolute",
131
+ "steps": [
132
+ {
133
+ "color": "blue",
134
+ "value": null
135
+ }
136
+ ]
137
+ },
138
+ "unit": "ops"
139
+ },
140
+ "overrides": []
141
+ },
142
+ "gridPos": {
143
+ "h": 8,
144
+ "w": 12,
145
+ "x": 0,
146
+ "y": 1
147
+ },
148
+ "id": 1,
149
+ "links": [
150
+ {
151
+ "targetBlank": false,
152
+ "title": "Open Trace Journey",
153
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
154
+ }
155
+ ],
156
+ "options": {
157
+ "legend": {
158
+ "calcs": [
159
+ "lastNotNull",
160
+ "max"
161
+ ],
162
+ "displayMode": "table",
163
+ "placement": "bottom",
164
+ "showLegend": true
165
+ },
166
+ "tooltip": {
167
+ "mode": "multi",
168
+ "sort": "desc"
169
+ }
170
+ },
171
+ "pluginVersion": "11.1.0",
172
+ "targets": [
173
+ {
174
+ "datasource": {
175
+ "type": "prometheus",
176
+ "uid": "prometheus"
177
+ },
178
+ "editorMode": "code",
179
+ "expr": "topk(10, sum by (tool_name) (rate(observme_tool_calls_total[$__rate_interval]))) or on() vector(0)",
180
+ "legendFormat": "{{tool_name}}",
181
+ "range": true,
182
+ "refId": "A"
183
+ }
184
+ ],
185
+ "title": "Tool calls by name",
186
+ "type": "timeseries"
187
+ },
188
+ {
189
+ "datasource": {
190
+ "type": "prometheus",
191
+ "uid": "prometheus"
192
+ },
193
+ "description": "Top 10 tool failure ratios. Matching call series zero-fill missing failure numerators by tool_name, so active tools with no failures remain visible at zero. Yellow is a tunable 5% review level; red matches the default 10% over 10m ObservMeHighToolFailureRate alert. A lone unlabeled zero means no active call denominator, not proven health.",
194
+ "fieldConfig": {
195
+ "defaults": {
196
+ "color": {
197
+ "mode": "palette-classic"
198
+ },
199
+ "mappings": [],
200
+ "max": 1,
201
+ "min": 0,
202
+ "thresholds": {
203
+ "mode": "absolute",
204
+ "steps": [
205
+ {
206
+ "color": "green",
207
+ "value": null
208
+ },
209
+ {
210
+ "color": "yellow",
211
+ "value": 0.05
212
+ },
213
+ {
214
+ "color": "red",
215
+ "value": 0.1
216
+ }
217
+ ]
218
+ },
219
+ "unit": "percentunit"
220
+ },
221
+ "overrides": []
222
+ },
223
+ "gridPos": {
224
+ "h": 8,
225
+ "w": 12,
226
+ "x": 12,
227
+ "y": 1
228
+ },
229
+ "id": 2,
230
+ "links": [
231
+ {
232
+ "targetBlank": false,
233
+ "title": "Open parsed tool failure logs",
234
+ "url": "/d/observme-errors/observme-errors?${__url_time_range}&viewPanel=7"
235
+ },
236
+ {
237
+ "targetBlank": false,
238
+ "title": "Open Trace Journey",
239
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
240
+ }
241
+ ],
242
+ "options": {
243
+ "legend": {
244
+ "calcs": [
245
+ "lastNotNull",
246
+ "max"
247
+ ],
248
+ "displayMode": "table",
249
+ "placement": "bottom",
250
+ "showLegend": true
251
+ },
252
+ "tooltip": {
253
+ "mode": "multi",
254
+ "sort": "desc"
255
+ }
256
+ },
257
+ "pluginVersion": "11.1.0",
258
+ "targets": [
259
+ {
260
+ "datasource": {
261
+ "type": "prometheus",
262
+ "uid": "prometheus"
263
+ },
264
+ "editorMode": "code",
265
+ "expr": "topk(10, clamp_max(((sum by (tool_name) (rate(observme_tool_failures_total[$__rate_interval])) or on (tool_name) (0 * sum by (tool_name) (rate(observme_tool_calls_total[$__rate_interval])))) / on (tool_name) clamp_min(sum by (tool_name) (rate(observme_tool_calls_total[$__rate_interval])), 1e-9)), 1)) or on() vector(0)",
266
+ "legendFormat": "{{tool_name}}",
267
+ "range": true,
268
+ "refId": "A"
269
+ }
270
+ ],
271
+ "title": "Tool failure rate",
272
+ "type": "timeseries"
273
+ },
274
+ {
275
+ "collapsed": false,
276
+ "gridPos": {
277
+ "h": 1,
278
+ "w": 24,
279
+ "x": 0,
280
+ "y": 9
281
+ },
282
+ "id": 101,
283
+ "panels": [],
284
+ "title": "Latency and size",
285
+ "type": "row"
286
+ },
287
+ {
288
+ "datasource": {
289
+ "type": "prometheus",
290
+ "uid": "prometheus"
291
+ },
292
+ "description": "Top 10 p95 tool-call duration trends grouped by bounded tool_name. The histogram aggregation preserves le. Sparse calls can make p95 jump or disappear; compare selected-range volume in Top offenders before treating a tool as slow.",
293
+ "fieldConfig": {
294
+ "defaults": {
295
+ "color": {
296
+ "mode": "palette-classic"
297
+ },
298
+ "mappings": [],
299
+ "min": 0,
300
+ "thresholds": {
301
+ "mode": "absolute",
302
+ "steps": [
303
+ {
304
+ "color": "blue",
305
+ "value": null
306
+ }
307
+ ]
308
+ },
309
+ "unit": "ms"
310
+ },
311
+ "overrides": []
312
+ },
313
+ "gridPos": {
314
+ "h": 8,
315
+ "w": 12,
316
+ "x": 0,
317
+ "y": 10
318
+ },
319
+ "id": 3,
320
+ "links": [
321
+ {
322
+ "targetBlank": false,
323
+ "title": "Open Latency",
324
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
325
+ },
326
+ {
327
+ "targetBlank": false,
328
+ "title": "Open Trace Journey",
329
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
330
+ }
331
+ ],
332
+ "options": {
333
+ "legend": {
334
+ "calcs": [
335
+ "lastNotNull",
336
+ "max"
337
+ ],
338
+ "displayMode": "table",
339
+ "placement": "bottom",
340
+ "showLegend": true
341
+ },
342
+ "tooltip": {
343
+ "mode": "multi",
344
+ "sort": "desc"
345
+ }
346
+ },
347
+ "pluginVersion": "11.1.0",
348
+ "targets": [
349
+ {
350
+ "datasource": {
351
+ "type": "prometheus",
352
+ "uid": "prometheus"
353
+ },
354
+ "editorMode": "code",
355
+ "expr": "topk(10, histogram_quantile(0.95, sum by (tool_name, le) (rate(observme_tool_duration_ms_bucket[$__rate_interval]))))",
356
+ "legendFormat": "{{tool_name}}",
357
+ "range": true,
358
+ "refId": "A"
359
+ }
360
+ ],
361
+ "title": "Tool p95 latency",
362
+ "type": "timeseries"
363
+ },
364
+ {
365
+ "datasource": {
366
+ "type": "prometheus",
367
+ "uid": "prometheus"
368
+ },
369
+ "description": "Top 10 p95 tool-result sizes in characters, grouped by bounded tool_name. observme_tool_result_size_chars is a character count, never bytes. Sparse or unsupported result-size instrumentation can produce no data; compare tool-call volume before interpreting a percentile.",
370
+ "fieldConfig": {
371
+ "defaults": {
372
+ "color": {
373
+ "mode": "palette-classic"
374
+ },
375
+ "mappings": [],
376
+ "min": 0,
377
+ "thresholds": {
378
+ "mode": "absolute",
379
+ "steps": [
380
+ {
381
+ "color": "blue",
382
+ "value": null
383
+ }
384
+ ]
385
+ },
386
+ "unit": "short"
387
+ },
388
+ "overrides": []
389
+ },
390
+ "gridPos": {
391
+ "h": 8,
392
+ "w": 12,
393
+ "x": 12,
394
+ "y": 10
395
+ },
396
+ "id": 5,
397
+ "links": [
398
+ {
399
+ "targetBlank": false,
400
+ "title": "Open Latency",
401
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
402
+ },
403
+ {
404
+ "targetBlank": false,
405
+ "title": "Open Trace Journey",
406
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
407
+ }
408
+ ],
409
+ "options": {
410
+ "legend": {
411
+ "calcs": [
412
+ "lastNotNull",
413
+ "max"
414
+ ],
415
+ "displayMode": "table",
416
+ "placement": "bottom",
417
+ "showLegend": true
418
+ },
419
+ "tooltip": {
420
+ "mode": "multi",
421
+ "sort": "desc"
422
+ }
423
+ },
424
+ "pluginVersion": "11.1.0",
425
+ "targets": [
426
+ {
427
+ "datasource": {
428
+ "type": "prometheus",
429
+ "uid": "prometheus"
430
+ },
431
+ "editorMode": "code",
432
+ "expr": "topk(10, histogram_quantile(0.95, sum by (tool_name, le) (rate(observme_tool_result_size_chars_bucket[$__rate_interval]))))",
433
+ "legendFormat": "{{tool_name}}",
434
+ "range": true,
435
+ "refId": "A"
436
+ }
437
+ ],
438
+ "title": "Tool result size distribution",
439
+ "type": "timeseries"
440
+ },
441
+ {
442
+ "collapsed": false,
443
+ "gridPos": {
444
+ "h": 1,
445
+ "w": 24,
446
+ "x": 0,
447
+ "y": 18
448
+ },
449
+ "id": 102,
450
+ "panels": [],
451
+ "title": "Bash outcomes",
452
+ "type": "row"
453
+ },
454
+ {
455
+ "datasource": {
456
+ "type": "loki",
457
+ "uid": "loki"
458
+ },
459
+ "description": "Selected-range interactive user-bash completion counts from Pi ! and !! commands, grouped by exact process exit code. Assistant bash tool calls appear in the tool panels instead. Each bar label is the exit code and its value is the number of completions. Exit 0 generally means success; non-zero meanings are command-specific.",
460
+ "fieldConfig": {
461
+ "defaults": {
462
+ "color": {
463
+ "mode": "palette-classic"
464
+ },
465
+ "mappings": [],
466
+ "min": 0,
467
+ "thresholds": {
468
+ "mode": "absolute",
469
+ "steps": [
470
+ {
471
+ "color": "blue",
472
+ "value": null
473
+ }
474
+ ]
475
+ },
476
+ "unit": "short"
477
+ },
478
+ "overrides": []
479
+ },
480
+ "gridPos": {
481
+ "h": 7,
482
+ "w": 24,
483
+ "x": 0,
484
+ "y": 19
485
+ },
486
+ "id": 4,
487
+ "links": [
488
+ {
489
+ "targetBlank": false,
490
+ "title": "Open Trace Journey",
491
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
492
+ }
493
+ ],
494
+ "options": {
495
+ "displayMode": "gradient",
496
+ "maxVizHeight": 300,
497
+ "minVizHeight": 16,
498
+ "minVizWidth": 8,
499
+ "namePlacement": "auto",
500
+ "orientation": "horizontal",
501
+ "reduceOptions": {
502
+ "calcs": [
503
+ "lastNotNull"
504
+ ],
505
+ "fields": "",
506
+ "values": false
507
+ },
508
+ "showUnfilled": true,
509
+ "sizing": "auto",
510
+ "valueMode": "color"
511
+ },
512
+ "pluginVersion": "11.1.0",
513
+ "targets": [
514
+ {
515
+ "datasource": {
516
+ "type": "loki",
517
+ "uid": "loki"
518
+ },
519
+ "editorMode": "code",
520
+ "expr": "topk(10, sum by (pi_bash_exit_code) (count_over_time({service_name=\"observme-pi-extension\", event_name=\"bash.completed\", pi_bash_exit_code!=\"\"}[$__range])))",
521
+ "instant": true,
522
+ "legendFormat": "exit code {{pi_bash_exit_code}}",
523
+ "queryType": "instant",
524
+ "range": false,
525
+ "refId": "A"
526
+ }
527
+ ],
528
+ "title": "Bash completions by exact exit code",
529
+ "type": "bargauge"
530
+ },
531
+ {
532
+ "collapsed": false,
533
+ "gridPos": {
534
+ "h": 1,
535
+ "w": 24,
536
+ "x": 0,
537
+ "y": 26
538
+ },
539
+ "id": 104,
540
+ "panels": [],
541
+ "title": "Tool error output (opt-in)",
542
+ "type": "row"
543
+ },
544
+ {
545
+ "datasource": {
546
+ "type": "loki",
547
+ "uid": "loki"
548
+ },
549
+ "description": "Captured output from failed tool calls, including GuardMe denials, when capture.toolResults is explicitly enabled. Redaction remains enabled by default, so safe text is preserved while detected secrets are replaced. This panel is empty when capture is disabled, redaction fails closed, or no captured tool failure occurred. Expand a row for tool, error, session, and trace labels.",
550
+ "fieldConfig": {
551
+ "defaults": {},
552
+ "overrides": []
553
+ },
554
+ "gridPos": {
555
+ "h": 10,
556
+ "w": 24,
557
+ "x": 0,
558
+ "y": 27
559
+ },
560
+ "id": 8,
561
+ "links": [
562
+ {
563
+ "targetBlank": false,
564
+ "title": "Open Trace Journey",
565
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
566
+ }
567
+ ],
568
+ "options": {
569
+ "dedupStrategy": "none",
570
+ "enableLogDetails": true,
571
+ "prettifyLogMessage": false,
572
+ "showCommonLabels": false,
573
+ "showLabels": true,
574
+ "showTime": true,
575
+ "sortOrder": "Descending",
576
+ "wrapLogMessage": true
577
+ },
578
+ "pluginVersion": "11.1.0",
579
+ "targets": [
580
+ {
581
+ "datasource": {
582
+ "type": "loki",
583
+ "uid": "loki"
584
+ },
585
+ "editorMode": "code",
586
+ "expr": "{service_name=\"observme-pi-extension\", event_name=\"tool.error.captured\", event_category=\"tool_content\"} | json | line_format \"{{.body}}\"",
587
+ "legendFormat": "{{pi_tool_name}} / {{error_type}}",
588
+ "maxLines": 200,
589
+ "queryType": "range",
590
+ "range": true,
591
+ "refId": "A"
592
+ }
593
+ ],
594
+ "title": "Captured tool error output (opt-in, redacted)",
595
+ "type": "logs"
596
+ },
597
+ {
598
+ "collapsed": false,
599
+ "gridPos": {
600
+ "h": 1,
601
+ "w": 24,
602
+ "x": 0,
603
+ "y": 37
604
+ },
605
+ "id": 103,
606
+ "panels": [],
607
+ "title": "Top offenders",
608
+ "type": "row"
609
+ },
610
+ {
611
+ "datasource": {
612
+ "type": "prometheus",
613
+ "uid": "prometheus"
614
+ },
615
+ "description": "Top 10 selected-range tool failure counts, failure ratios, and call volumes. Active call series zero-fill absent failure series by tool_name. The 5% review level is tunable and 10% matches the default alert. Tool metrics do not emit error_class; open the parsed tool.call.failed table for bounded error context and Tempo links.",
616
+ "fieldConfig": {
617
+ "defaults": {
618
+ "color": {
619
+ "mode": "thresholds"
620
+ },
621
+ "mappings": [],
622
+ "min": 0,
623
+ "thresholds": {
624
+ "mode": "absolute",
625
+ "steps": [
626
+ {
627
+ "color": "green",
628
+ "value": null
629
+ },
630
+ {
631
+ "color": "red",
632
+ "value": 1e-9
633
+ }
634
+ ]
635
+ },
636
+ "unit": "short"
637
+ },
638
+ "overrides": [
639
+ {
640
+ "matcher": {
641
+ "id": "byFrameRefID",
642
+ "options": "B"
643
+ },
644
+ "properties": [
645
+ {
646
+ "id": "unit",
647
+ "value": "percentunit"
648
+ },
649
+ {
650
+ "id": "max",
651
+ "value": 1
652
+ },
653
+ {
654
+ "id": "thresholds",
655
+ "value": {
656
+ "mode": "absolute",
657
+ "steps": [
658
+ {
659
+ "color": "green",
660
+ "value": null
661
+ },
662
+ {
663
+ "color": "yellow",
664
+ "value": 0.05
665
+ },
666
+ {
667
+ "color": "red",
668
+ "value": 0.1
669
+ }
670
+ ]
671
+ }
672
+ }
673
+ ]
674
+ }
675
+ ]
676
+ },
677
+ "gridPos": {
678
+ "h": 9,
679
+ "w": 12,
680
+ "x": 0,
681
+ "y": 38
682
+ },
683
+ "id": 6,
684
+ "links": [
685
+ {
686
+ "targetBlank": false,
687
+ "title": "Open parsed tool failure logs",
688
+ "url": "/d/observme-errors/observme-errors?${__url_time_range}&viewPanel=7"
689
+ },
690
+ {
691
+ "targetBlank": false,
692
+ "title": "Open Trace Journey",
693
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
694
+ }
695
+ ],
696
+ "options": {
697
+ "cellHeight": "sm",
698
+ "footer": {
699
+ "countRows": false,
700
+ "fields": "",
701
+ "reducer": [
702
+ "sum"
703
+ ],
704
+ "show": false
705
+ },
706
+ "showHeader": true
707
+ },
708
+ "pluginVersion": "11.1.0",
709
+ "targets": [
710
+ {
711
+ "datasource": {
712
+ "type": "prometheus",
713
+ "uid": "prometheus"
714
+ },
715
+ "editorMode": "code",
716
+ "expr": "topk(10, (sum by (tool_name) (increase(observme_tool_failures_total[$__range])) or on (tool_name) (0 * sum by (tool_name) (increase(observme_tool_calls_total[$__range])))))",
717
+ "format": "table",
718
+ "instant": true,
719
+ "legendFormat": "failures {{tool_name}}",
720
+ "range": false,
721
+ "refId": "A"
722
+ },
723
+ {
724
+ "datasource": {
725
+ "type": "prometheus",
726
+ "uid": "prometheus"
727
+ },
728
+ "editorMode": "code",
729
+ "expr": "topk(10, clamp_max(((sum by (tool_name) (increase(observme_tool_failures_total[$__range])) or on (tool_name) (0 * sum by (tool_name) (increase(observme_tool_calls_total[$__range])))) / on (tool_name) clamp_min(sum by (tool_name) (increase(observme_tool_calls_total[$__range])), 1)), 1))",
730
+ "format": "table",
731
+ "instant": true,
732
+ "legendFormat": "failure ratio {{tool_name}}",
733
+ "range": false,
734
+ "refId": "B"
735
+ },
736
+ {
737
+ "datasource": {
738
+ "type": "prometheus",
739
+ "uid": "prometheus"
740
+ },
741
+ "editorMode": "code",
742
+ "expr": "topk(10, sum by (tool_name) (increase(observme_tool_calls_total[$__range])))",
743
+ "format": "table",
744
+ "instant": true,
745
+ "legendFormat": "calls {{tool_name}}",
746
+ "range": false,
747
+ "refId": "C"
748
+ }
749
+ ],
750
+ "title": "Tool failures by severity",
751
+ "type": "table"
752
+ },
753
+ {
754
+ "datasource": {
755
+ "type": "prometheus",
756
+ "uid": "prometheus"
757
+ },
758
+ "description": "Top 10 selected-range p50/p95/p99 tool latency estimates with call volume. Each histogram query preserves le and tool_name and uses bucket increases over $__range. Low call volume makes percentile ranks sparse; treat the adjacent call totals as required context.",
759
+ "fieldConfig": {
760
+ "defaults": {
761
+ "color": {
762
+ "mode": "palette-classic"
763
+ },
764
+ "mappings": [],
765
+ "min": 0,
766
+ "thresholds": {
767
+ "mode": "absolute",
768
+ "steps": [
769
+ {
770
+ "color": "blue",
771
+ "value": null
772
+ }
773
+ ]
774
+ },
775
+ "unit": "ms"
776
+ },
777
+ "overrides": [
778
+ {
779
+ "matcher": {
780
+ "id": "byFrameRefID",
781
+ "options": "D"
782
+ },
783
+ "properties": [
784
+ {
785
+ "id": "unit",
786
+ "value": "short"
787
+ }
788
+ ]
789
+ }
790
+ ]
791
+ },
792
+ "gridPos": {
793
+ "h": 9,
794
+ "w": 12,
795
+ "x": 12,
796
+ "y": 38
797
+ },
798
+ "id": 7,
799
+ "links": [
800
+ {
801
+ "targetBlank": false,
802
+ "title": "Open Latency",
803
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
804
+ },
805
+ {
806
+ "targetBlank": false,
807
+ "title": "Open Trace Journey",
808
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
809
+ }
810
+ ],
811
+ "options": {
812
+ "cellHeight": "sm",
813
+ "footer": {
814
+ "countRows": false,
815
+ "fields": "",
816
+ "reducer": [
817
+ "sum"
818
+ ],
819
+ "show": false
820
+ },
821
+ "showHeader": true
822
+ },
823
+ "pluginVersion": "11.1.0",
824
+ "targets": [
825
+ {
826
+ "datasource": {
827
+ "type": "prometheus",
828
+ "uid": "prometheus"
829
+ },
830
+ "editorMode": "code",
831
+ "expr": "topk(10, histogram_quantile(0.50, sum by (tool_name, le) (increase(observme_tool_duration_ms_bucket[$__range]))))",
832
+ "format": "table",
833
+ "instant": true,
834
+ "legendFormat": "p50 {{tool_name}}",
835
+ "range": false,
836
+ "refId": "A"
837
+ },
838
+ {
839
+ "datasource": {
840
+ "type": "prometheus",
841
+ "uid": "prometheus"
842
+ },
843
+ "editorMode": "code",
844
+ "expr": "topk(10, histogram_quantile(0.95, sum by (tool_name, le) (increase(observme_tool_duration_ms_bucket[$__range]))))",
845
+ "format": "table",
846
+ "instant": true,
847
+ "legendFormat": "p95 {{tool_name}}",
848
+ "range": false,
849
+ "refId": "B"
850
+ },
851
+ {
852
+ "datasource": {
853
+ "type": "prometheus",
854
+ "uid": "prometheus"
855
+ },
856
+ "editorMode": "code",
857
+ "expr": "topk(10, histogram_quantile(0.99, sum by (tool_name, le) (increase(observme_tool_duration_ms_bucket[$__range]))))",
858
+ "format": "table",
859
+ "instant": true,
860
+ "legendFormat": "p99 {{tool_name}}",
861
+ "range": false,
862
+ "refId": "C"
863
+ },
864
+ {
865
+ "datasource": {
866
+ "type": "prometheus",
867
+ "uid": "prometheus"
868
+ },
869
+ "editorMode": "code",
870
+ "expr": "topk(10, sum by (tool_name) (increase(observme_tool_calls_total[$__range])))",
871
+ "format": "table",
872
+ "instant": true,
873
+ "legendFormat": "calls {{tool_name}}",
874
+ "range": false,
875
+ "refId": "D"
876
+ }
877
+ ],
878
+ "title": "Tool latency percentiles with volume",
879
+ "type": "table"
880
+ }
881
+ ],
882
+ "refresh": "30s",
883
+ "schemaVersion": 39,
884
+ "style": "dark",
885
+ "tags": [
886
+ "observme",
887
+ "tools"
888
+ ],
889
+ "templating": {
890
+ "list": []
891
+ },
892
+ "time": {
893
+ "from": "now-6h",
894
+ "to": "now"
895
+ },
896
+ "timepicker": {},
897
+ "timezone": "browser",
898
+ "title": "ObservMe Tools",
899
+ "uid": "observme-tools",
900
+ "version": 4,
901
+ "weekStart": ""
902
+ }