diff --git a/.docker/docker-compose-infra.yml b/.docker/docker-compose-infra.yml index a5fc77293..3c5a82a7a 100644 --- a/.docker/docker-compose-infra.yml +++ b/.docker/docker-compose-infra.yml @@ -185,15 +185,25 @@ services: # - '6379:6379' # Optional for tracing -# otel: -# extends: -# service: otel-collector -# file: ./.docker/docker-compose-monitoring.yml -# -# jaeger: -# extends: -# service: jaeger -# file: ./.docker/docker-compose-monitoring.yml + otel: + extends: + service: otel-collector + file: ./.docker/docker-compose-monitoring.yml + + jaeger: + extends: + service: jaeger + file: ./.docker/docker-compose-monitoring.yml + + grafana: + extends: + service: grafana + file: ./.docker/docker-compose-monitoring.yml + + prometheus: + extends: + service: prometheus + file: ./.docker/docker-compose-monitoring.yml configs: init.sql: diff --git a/.docker/docker-compose-monitoring.yml b/.docker/docker-compose-monitoring.yml index 2fcd4cfb5..5489e1fcb 100644 --- a/.docker/docker-compose-monitoring.yml +++ b/.docker/docker-compose-monitoring.yml @@ -25,6 +25,7 @@ services: container_name: prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' + - '--web.enable-remote-write-receiver' ports: - 9090:9090 restart: unless-stopped @@ -61,6 +62,7 @@ services: - "4317:4317" # OTLP gRPC receiver - "4318:4318" # OTLP Http receiver - "55680:55680" # OTLP HTTP receiver + - "9200:9200" # Prometheus metrics receiver command: [ "--config=/etc/otel/otel-collector-config.yml" ] depends_on: - jaeger diff --git a/.env.sample b/.env.sample index 4af5f40b9..b27346d89 100644 --- a/.env.sample +++ b/.env.sample @@ -147,8 +147,13 @@ WEBHOOK_API_KEY= ####################################### # Monitoring ####################################### -DEFAULT_METRICS_ENABLED=true LOG_LEVEL=info +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317 +OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4317 +OTEL_METRICS_EXPORT_INTERVAL_MS=5000 +OTEL_METRICS_ENABLED=true +PROMETHEUS_METRICS_ENABLED=true + LOGFLARE_ENABLED=false LOGFLARE_API_KEY=api_key diff --git a/.gitignore b/.gitignore index 5b4e62bb7..dccbc2b1b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ data/ bin/ coverage/ .idea/ -src/scripts/*.py \ No newline at end of file +src/scripts/*.py +.claude/ \ No newline at end of file diff --git a/monitoring/grafana/dashboards/storage-otel.json b/monitoring/grafana/dashboards/storage-otel.json new file mode 100644 index 000000000..02dbb1b9d --- /dev/null +++ b/monitoring/grafana/dashboards/storage-otel.json @@ -0,0 +1,5736 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Storage API OTel Metrics Dashboard with tenant and region support", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": 2, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [], + "title": "Overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Application Performance Index score based on request latency. Score >= 90% is good (green), 70-90% needs attention (orange), < 70% is poor (red). Target and tolerated thresholds are configurable.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#C4162A", + "value": 0 + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 70 + }, + { + "color": "#299c46", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 5, + "x": 0, + "y": 1 + }, + "id": 200, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "((sum(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"0.3\",status_code=~\"2..\"}) + (sum(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"1.2\",status_code=~\"2..\"}) - sum(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"0.3\",status_code=~\"2..\"})) / 2) / sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"2..\"})) * 100", + "legendFormat": "score", + "refId": "A" + } + ], + "title": "Apdex Score", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Current queries per second (QPS). Shows the real-time request rate across all endpoints.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": 0 + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 100 + }, + { + "color": "#C4162A", + "value": 200 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 5, + "y": 1 + }, + "id": 201, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "max" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "", + "refId": "A" + } + ], + "title": "QPS", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Total number of HTTP requests processed during the selected time range.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "rgb(31, 120, 193)", + "mode": "fixed" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 8, + "y": 1 + }, + "id": 202, + "options": { + "colorMode": "none", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(increase(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Process restart count during the selected time range. High restart counts may indicate crashes or OOM issues.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": 0 + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "#C4162A", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 11, + "y": 1 + }, + "id": 203, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(changes(storage_api_otel_process_start_time_seconds{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Restarts", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Server error rate (5xx) as a percentage of total requests. Values above 1% require investigation.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": 0 + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 5 + }, + { + "color": "#C4162A", + "value": 10 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 14, + "y": 1 + }, + "id": 204, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "(sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"5..\"} OR on() vector(0)) / sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}))*100", + "legendFormat": "error %", + "refId": "A" + } + ], + "title": "5xx Errors", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Client error rate (4xx) as a percentage of total requests. High rates may indicate API misuse or client bugs.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": 0 + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 10 + }, + { + "color": "#C4162A", + "value": 20 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 17, + "y": 1 + }, + "id": 205, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "(sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"4..\"} OR on() vector(0)) / sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}))*100", + "legendFormat": "error %", + "refId": "A" + } + ], + "title": "4xx Errors", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "File upload statistics: started, completed, multipart, and standard uploads during the selected time range.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 20, + "y": 1 + }, + "id": 206, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(increase(storage_api_otel_upload_started_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "Started", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(increase(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "Completed", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(increase(storage_api_otel_upload_started_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "File Uploads", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Current CPU usage as a percentage. Values above 75% indicate high CPU load, above 90% is critical.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 75 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 3 + }, + "id": 207, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "avg(rate(storage_api_otel_process_cpu_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Avg", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "max(rate(storage_api_otel_process_cpu_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "hide": false, + "instant": false, + "legendFormat": "Max", + "range": true, + "refId": "B" + } + ], + "title": "CPU", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Current RAM usage as a percentage of 2GB limit. Monitor for memory pressure and potential OOM issues.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 0.8 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 3 + }, + "id": 209, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "avg((storage_api_otel_process_memory_usage{region=~\"$region\", instance=~\"$instance\"}) / (2*1024*1024*1024))", + "legendFormat": "Avg", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "max(storage_api_otel_process_resident_memory_bytes{region=~\"$region\", instance=~\"$instance\"}) / (2*1024*1024*1024)", + "hide": false, + "instant": false, + "legendFormat": "Max", + "range": true, + "refId": "B" + } + ], + "title": "RAM", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Event loop utilization ratio (0-1). Values close to 1 indicate the event loop is saturated.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 0.7 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 3 + }, + "id": 212, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_nodejs_eventloop_utilization_ratio{region=~\"$region\", instance=~\"$instance\"}", + "range": true, + "refId": "A" + } + ], + "title": "Event Loop", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Response counts grouped by HTTP status code category (2xx success, 4xx client errors, 5xx server errors).", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": 0 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 15, + "y": 3 + }, + "id": 211, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "center", + "orientation": "vertical", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"2..\"}) or vector(0)", + "legendFormat": "2xx", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"4..\"}) or vector(0)", + "legendFormat": "4xx", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"5..\"}) or vector(0)", + "legendFormat": "5xx", + "refId": "C" + } + ], + "title": "Responses By Code", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Active database connection pools. High counts may indicate connection pool pressure.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 50 + }, + { + "color": "red", + "value": 100 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 20, + "y": 3 + }, + "id": 213, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_db_pool{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "", + "refId": "A" + } + ], + "title": "DB Pools", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Pending queue jobs across all job types. Growing queues indicate processing bottlenecks.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 100 + }, + { + "color": "red", + "value": 500 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 7 + }, + "id": 214, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Queue Jobs", + "type": "stat" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 215, + "panels": [], + "title": "Requests Overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "HTTP requests per second broken down by status code category. Shows total requests along with 2xx (success), 4xx (client errors), and 5xx (server errors) rates. Use this to monitor overall API traffic and identify error spikes.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 12 + }, + "id": 2, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Total", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"2xx\"}[$__rate_interval]))", + "legendFormat": "2xx", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx\"}[$__rate_interval]))", + "legendFormat": "4xx", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval]))", + "legendFormat": "5xx", + "refId": "D" + } + ], + "title": "Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "HTTP request duration percentiles (p50, p90, p99). P50 shows median latency, p90 shows latency for 90% of requests, and p99 captures tail latency. High p99 values may indicate slow database queries, external service delays, or resource contention.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 12 + }, + "id": 3, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.50, sum(rate(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p50", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.90, sum(rate(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p90", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.99, sum(rate(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p99", + "refId": "C" + } + ], + "title": "Request Latency (Percentiles)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Server error rate as a percentage of total requests. Values above 1% may indicate service issues requiring investigation. Common causes include database connection failures, S3 errors, or application exceptions.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 12 + }, + "id": 4, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval])) / sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Error Rate", + "refId": "A" + } + ], + "title": "Error Rate (5xx)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Network transfer rates based on HTTP Content-Length headers. Transfer In shows data received from clients (uploads, POST bodies). Transfer Out shows data sent to clients (downloads, responses). Useful for monitoring bandwidth usage and identifying large file transfers.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Transfer In" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Transfer Out" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 216, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "sum" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_http_request_size_bytes_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Transfer In", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_http_response_size_bytes_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Transfer Out", + "range": true, + "refId": "B" + } + ], + "title": "Transfer In/Out", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Top API endpoints by request count. Shows which routes receive the most traffic. Use this to identify hot paths, optimize frequently accessed endpoints, and understand API usage patterns.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "route" + }, + "properties": [ + { + "id": "custom.width", + "value": 300 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "displayName", + "value": "Requests/sec" + }, + { + "id": "unit", + "value": "reqps" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 217, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "topk(10, sum by (route) (rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])))", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Requests by Path", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": {}, + "renameByName": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Error count over time broken down by status code. Shows 4xx client errors and 5xx server errors separately to help distinguish between client-side issues and server-side problems.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "4xx Errors" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx Errors" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 218, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "sum" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx\"}[$__rate_interval]))", + "legendFormat": "4xx Errors", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval]))", + "legendFormat": "5xx Errors", + "refId": "B" + } + ], + "title": "Errors Over Time", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Top API endpoints by error count. Shows which routes are generating the most errors. Use this to identify problematic endpoints that need attention or debugging.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 1 + }, + { + "color": "red", + "value": 10 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "route" + }, + "properties": [ + { + "id": "custom.width", + "value": 300 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "displayName", + "value": "Errors/sec" + }, + { + "id": "unit", + "value": "short" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 219, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "topk(10, sum by (route) (rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx|5xx\"}[$__rate_interval])))", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Errors by Path", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": {}, + "renameByName": {} + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 10, + "panels": [], + "title": "HTTP Requests by Tenant", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "HTTP requests per second grouped by tenant ID. Use this to identify high-traffic tenants, detect unusual activity patterns, or investigate tenant-specific issues. Filter by tenant using the dropdown above.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 37 + }, + "id": 11, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}[$__rate_interval])) by (tenantId)", + "legendFormat": "{{ tenantId }}", + "refId": "A" + } + ], + "title": "Request Rate by Tenant", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "95th percentile request latency per tenant. Helps identify tenants experiencing performance issues due to large files, complex queries, or resource-intensive operations. Compare against baseline to detect anomalies.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 37 + }, + "id": 12, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}[$__rate_interval])) by (le, tenantId))", + "legendFormat": "{{ tenantId }}", + "refId": "A" + } + ], + "title": "P95 Latency by Tenant", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 45 + }, + "id": 20, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "The 10 most frequently called API endpoints by requests per second. Use this to understand API usage patterns, identify heavily-used endpoints for optimization, and detect unexpected traffic patterns.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 46 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "topk(10, sum(rate(storage_api_otel_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (route))", + "legendFormat": "{{ route }}", + "refId": "A" + } + ], + "title": "Top 10 Routes by Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "The 10 slowest API endpoints by 95th percentile latency. These endpoints are prime candidates for performance optimization. High latency may indicate complex database operations, large file transfers, or inefficient code paths.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 46 + }, + "id": 22, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "topk(10, histogram_quantile(0.95, sum(rate(storage_api_otel_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, route)))", + "legendFormat": "{{ route }}", + "range": true, + "refId": "A" + } + ], + "title": "Top 10 Slowest Routes (P95)", + "type": "timeseries" + } + ], + "title": "HTTP Requests by Route", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 30, + "panels": [], + "title": "Uploads", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Comparison of started uploads versus successfully completed uploads. A growing gap between these values may indicate upload failures, timeouts, or client disconnections. Use this to monitor upload reliability.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 47 + }, + "id": 31, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_started_total{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Started", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Success", + "range": true, + "refId": "B" + } + ], + "title": "Uploads (Started vs Success)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Successful uploads categorized by upload method: standard (single request), resumable (TUS protocol), S3 (direct S3 upload), and multipart. Helps understand which upload mechanisms are most used and their success rates.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 47 + }, + "id": 32, + "options": { + "displayMode": "gradient", + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "valueMode": "color" + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_standard=\"1\"})", + "legendFormat": "Standard", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_resumable=\"1\"})", + "legendFormat": "Resumable (TUS)", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_s3=\"1\"})", + "legendFormat": "S3", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_multipart=\"1\"})", + "legendFormat": "Multipart", + "range": true, + "refId": "D" + } + ], + "title": "Uploads by Type", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Successful uploads grouped by tenant ID. Use this to identify high-volume uploaders, track tenant activity, and investigate tenant-specific upload issues.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 47 + }, + "id": 33, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_upload_success_total{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}) by (tenantId)", + "legendFormat": "{{ tenantId }}", + "range": true, + "refId": "A" + } + ], + "title": "Uploads by Tenant", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 55 + }, + "id": 40, + "panels": [], + "title": "Database", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Database query latency percentiles (p50, p95) grouped by operation type. Identifies slow queries that may need optimization through indexing, query rewriting, or connection pool tuning. Monitor for performance regressions.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 41, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.50, sum(rate(storage_api_otel_database_query_performance_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p50 {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_otel_database_query_performance_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p95 {{ name }}", + "refId": "B" + } + ], + "title": "Database Query Performance by Operation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Active database connection pool count. High values may indicate connection leaks or pool exhaustion. Monitor this alongside query performance to ensure adequate connection availability.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 56 + }, + "id": 42, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_db_pool{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Active Pools", + "refId": "A" + } + ], + "title": "Database Pools", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Database connections categorized by type (internal vs external). External connections are from external services. Monitor for connection growth patterns and potential connection exhaustion.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 56 + }, + "id": 43, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_db_connections{region=~\"$region\", instance=~\"$instance\"}) by (is_external)", + "legendFormat": "External: {{ is_external }}", + "refId": "A" + } + ], + "title": "Database Connections", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Rate of database queries per second grouped by operation type. Use this to monitor database load, identify query spikes, and correlate with application activity. High query rates may indicate opportunities for caching or query optimization.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 64 + }, + "id": 220, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_database_query_performance_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "{{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_otel_database_query_performance_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Total", + "refId": "B" + } + ], + "title": "Database Query Rate", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 50, + "panels": [], + "title": "Queue", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Number of jobs currently pending in the queue by job type. Growing queues indicate processing bottlenecks. Monitor this to ensure background jobs are being processed in a timely manner.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 73 + }, + "id": 51, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "{{ name }}", + "range": true, + "refId": "A" + } + ], + "title": "Queue Jobs Pending", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Number of successfully completed queue jobs by type. Use this to track job throughput and compare against scheduled jobs to understand completion rates.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 73 + }, + "id": 52, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_queue_job_completed{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "{{ name }}", + "range": true, + "refId": "A" + } + ], + "title": "Queue Jobs Completed", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Queue job errors and retry failures by job type. Errors indicate jobs that failed and may be retried. Retry failures are jobs that exhausted all retry attempts. Investigate persistent failures for root cause.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "red", + "value": 5 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 73 + }, + "id": 53, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_queue_job_error{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Errors {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_queue_job_retry_failed{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Retries {{ name }}", + "refId": "B" + } + ], + "title": "Queue Errors & Retries", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Time taken to schedule jobs in the queue (p50, p95, p99). High scheduling times may indicate database contention, lock contention, or queue saturation. Use this to identify bottlenecks in job submission.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 81 + }, + "id": 224, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_otel_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p50 {{ name }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(storage_api_otel_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p95 {{ name }}", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.99, sum(rate(storage_api_otel_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p99 {{ name }}", + "range": true, + "refId": "C" + } + ], + "title": "Queue Job Scheduling Time", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Rate of jobs being scheduled vs completed per second. A growing gap between scheduled and completed indicates queue backlog. Use this to monitor queue throughput and identify processing bottlenecks.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "ops" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Scheduled.*/" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Completed.*/" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 81 + }, + "id": 225, + "options": { + "legend": { + "calcs": [ + "mean", + "sum" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "Scheduled {{ name }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_queue_job_completed{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "Completed {{ name }}", + "range": true, + "refId": "B" + } + ], + "title": "Scheduled vs Completed Rate", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 89 + }, + "id": 60, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "S3 multipart upload chunk latency percentiles (p50, p95, p99). High latency may indicate S3 throttling, network issues, or large chunk sizes. Compare across regions to identify geographic performance variations.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 145 + }, + "id": 61, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_otel_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p50", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_otel_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p95", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.99, sum(rate(storage_api_otel_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p99", + "refId": "C" + } + ], + "title": "S3 Upload Part Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "HTTP agent connection pool status showing busy and free sockets by protocol (http/https). Busy sockets indicate active connections. High busy-to-free ratios may indicate connection pool pressure or slow upstream services.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 145 + }, + "id": 62, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_pool_busy_sockets{region=~\"$region\", instance=~\"$instance\"}) by (name, protocol)", + "legendFormat": "Busy {{ name }} ({{ protocol }})", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_pool_free_sockets{region=~\"$region\", instance=~\"$instance\"}) by (name, protocol)", + "legendFormat": "Free {{ name }} ({{ protocol }})", + "refId": "B" + } + ], + "title": "HTTP Pool Sockets", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "HTTP agent pending requests and errors by pool. Pending requests queue when all connections are busy. Errors indicate connection failures to upstream services like S3 or external APIs.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "yellow", + "value": 10 + }, + { + "color": "red", + "value": 50 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 145 + }, + "id": 63, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_pool_requests{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Pending {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_otel_http_pool_errors{region=~\"$region\", instance=~\"$instance\"}) by (name, type)", + "legendFormat": "Errors {{ name }} ({{ type }})", + "refId": "B" + } + ], + "title": "HTTP Pool Requests & Errors", + "type": "timeseries" + } + ], + "title": "S3 & HTTP Pool", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 90 + }, + "id": 80, + "panels": [], + "title": "Node.js Runtime (Event Loop)", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Node.js event loop utilization ratio (0-1). Values close to 1 indicate the event loop is fully utilized and may cause response delays. Sustained high utilization suggests CPU-bound work or blocking operations.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 91 + }, + "id": 81, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_nodejs_eventloop_utilization_ratio", + "legendFormat": "Event Loop Utilization", + "range": true, + "refId": "A" + } + ], + "title": "Event Loop Utilization", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Event loop delay percentiles measuring time between scheduled and actual callback execution. High p99 values indicate occasional blocking operations. Delays >100ms may cause noticeable request latency.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 91 + }, + "id": 82, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_nodejs_eventloop_delay_p50_seconds", + "legendFormat": "p50", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_nodejs_eventloop_delay_p90_seconds", + "legendFormat": "p90", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_nodejs_eventloop_delay_p99_seconds", + "legendFormat": "p99", + "refId": "C" + } + ], + "title": "Event Loop Delay (Percentiles)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Network I/O throughput and errors from host metrics. High throughput correlates with upload/download activity. Network errors may indicate connectivity issues, DNS failures, or upstream service problems.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 91 + }, + "id": 73, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "rate(storage_api_otel_system_network_io_total[$__rate_interval])", + "legendFormat": "Network I/O", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "rate(storage_api_otel_system_network_errors_total[$__rate_interval])", + "legendFormat": "Network Errors", + "refId": "B" + } + ], + "title": "Network I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "CPU utilization from host metrics: process CPU (this Node.js instance) vs system CPU (entire host). Compare to identify if the Storage API is the primary CPU consumer or if other processes are competing.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 99 + }, + "id": 71, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_process_cpu_utilization", + "legendFormat": "Process CPU Utilization", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_system_cpu_utilization", + "legendFormat": "System CPU Utilization", + "refId": "B" + } + ], + "title": "CPU Utilization", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Memory usage from host metrics: process memory (this Node.js instance) vs system memory (entire host). Monitor for memory pressure and ensure adequate headroom for garbage collection spikes.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 99 + }, + "id": 72, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_process_memory_usage", + "legendFormat": "Process Memory", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_system_memory_usage", + "legendFormat": "System Memory", + "refId": "B" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 107 + }, + "id": 84, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "V8 JavaScript engine heap memory usage vs limit. Used heap approaching the limit may trigger more frequent garbage collection or out-of-memory errors. Monitor for memory leaks (steadily increasing used heap).", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 147 + }, + "id": 85, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_v8js_memory_heap_used_bytes)", + "legendFormat": "Heap Used", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_otel_v8js_memory_heap_limit_bytes)", + "legendFormat": "Heap Limit", + "range": true, + "refId": "B" + } + ], + "title": "V8 Heap Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Garbage collection duration percentiles by GC type (minor/major/incremental). Long GC pauses can cause request latency spikes. Major GC taking >100ms may require heap size tuning or memory optimization.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 147 + }, + "id": 86, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_otel_v8js_gc_duration_seconds_bucket[$__rate_interval])) by (le, v8js_gc_type))", + "legendFormat": "p50 {{ v8js_gc_type }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.99, sum(rate(storage_api_otel_v8js_gc_duration_seconds_bucket[$__rate_interval])) by (le, v8js_gc_type))", + "legendFormat": "p99 {{ v8js_gc_type }}", + "range": true, + "refId": "B" + } + ], + "title": "GC Duration by Type", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Process memory breakdown: RSS (total resident memory), External (C++ objects bound to JS), ArrayBuffers (binary data buffers). High external/arraybuffer memory may indicate large file operations or buffer leaks.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 147 + }, + "id": 87, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_nodejs_memory_rss_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "RSS", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_nodejs_memory_external_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "External", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_nodejs_memory_array_buffers_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Array Buffers", + "range": true, + "refId": "C" + } + ], + "title": "Process Memory (RSS/External)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Rate of garbage collection operations per second by GC type. Minor GC is fast and frequent (young generation), Major GC is slower (full heap). High major GC rates may indicate memory pressure.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 155 + }, + "id": 221, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_v8js_gc_duration_seconds_count[$__rate_interval])) by (v8js_gc_type)", + "legendFormat": "{{ v8js_gc_type }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_otel_v8js_gc_duration_seconds_count[$__rate_interval]))", + "legendFormat": "Total", + "range": true, + "refId": "B" + } + ], + "title": "GC Rate by Type", + "type": "timeseries" + } + ], + "title": "Node.js Runtime (V8 Memory & GC)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 108 + }, + "id": 88, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Rate of CPU time consumption split between user (application code) and system (kernel operations) time. High system CPU may indicate excessive I/O operations or syscall overhead.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 148 + }, + "id": 89, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "rate(storage_api_otel_process_cpu_user_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "User CPU", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "rate(storage_api_otel_process_cpu_system_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "System CPU", + "range": true, + "refId": "B" + } + ], + "title": "Process CPU Time (Rate)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Active libuv handles (timers, sockets, file descriptors) and pending async requests. High handle counts may indicate resource leaks. Sudden spikes correlate with increased load or connection storms.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 148 + }, + "id": 90, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_nodejs_active_handles_total{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Active Handles", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_otel_nodejs_active_requests_total{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Active Requests", + "refId": "B" + } + ], + "title": "Active Handles & Requests", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Time spent in different event loop phases (idle, active, poll). High poll time indicates waiting for I/O. High active time indicates CPU-bound work. Useful for understanding event loop behavior.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 148 + }, + "id": 91, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "rate(storage_api_otel_nodejs_eventloop_time_seconds_total[$__rate_interval])", + "legendFormat": "{{ nodejs_eventloop_state }}", + "range": true, + "refId": "A" + } + ], + "title": "Event Loop Time by State", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Percentage of file descriptors in use (open/max). High values (>80%) may indicate FD exhaustion risk. Monitor for leaks - a steadily increasing value without corresponding traffic increase suggests FD leaks. Only available on Linux.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line+area" + } + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "orange", + "value": 0.7 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 164 + }, + "id": 222, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_process_open_fds{region=~\"$region\", instance=~\"$instance\"} / storage_api_otel_process_max_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "FD Usage", + "range": true, + "refId": "A" + } + ], + "title": "Used File Descriptors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Number of open file descriptors over time. Useful for tracking FD usage patterns and identifying potential leaks. Compare with max FD limit to assess headroom. Only available on Linux.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 164 + }, + "id": 223, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_process_open_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Open FDs", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_otel_process_max_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Max FDs", + "range": true, + "refId": "B" + } + ], + "title": "Open File Descriptors", + "type": "timeseries" + } + ], + "title": "Node.js Runtime (Process)", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 109 + }, + "id": 70, + "panels": [], + "title": "Node.js Runtime (Host Metrics)", + "type": "row" + } + ], + "preload": false, + "refresh": "5s", + "schemaVersion": 42, + "tags": [ + "storage", + "otel", + "api" + ], + "templating": { + "list": [ + { + "current": { + "text": [ + "local" + ], + "value": [ + "local" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "definition": "label_values(storage_api_otel_process_start_time_seconds,region)", + "includeAll": true, + "multi": true, + "name": "region", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(storage_api_otel_process_start_time_seconds,region)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "allValue": ".*", + "current": { + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "definition": "label_values(storage_api_otel_process_start_time_seconds,instance)", + "includeAll": true, + "multi": true, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(storage_api_otel_process_start_time_seconds,instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "current": { + "text": [ + "storage-single-tenant" + ], + "value": [ + "storage-single-tenant" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "definition": "label_values(storage_api_otel_http_request_duration_seconds_count,tenantId)", + "includeAll": true, + "multi": true, + "name": "tenant", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(storage_api_otel_http_request_duration_seconds_count,tenantId)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Storage API - OTel Metrics", + "uid": "storage-otel-metrics", + "version": 1 +} \ No newline at end of file diff --git a/monitoring/grafana/dashboards/storage.json b/monitoring/grafana/dashboards/storage.json index 33845199d..c6eba473e 100644 --- a/monitoring/grafana/dashboards/storage.json +++ b/monitoring/grafana/dashboards/storage.json @@ -4,54 +4,35 @@ { "builtIn": 1, "datasource": { - "type": "datasource", - "uid": "grafana" + "type": "grafana", + "uid": "-- Grafana --" }, "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, "type": "dashboard" } ] }, - "description": "Monitor metrics for node.js and express router status.", + "description": "Storage API OTel Metrics Dashboard with tenant and region support", "editable": true, "fiscalYearStartMonth": 0, - "gnetId": 12230, - "graphTooltip": 0, + "graphTooltip": 1, "id": 2, "links": [], - "liveNow": false, "panels": [ { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, + "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, - "id": 121, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "refId": "A" - } - ], - "title": "Overview & Targets", + "id": 1, + "panels": [], + "title": "Overview", "type": "row" }, { @@ -59,6 +40,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Application Performance Index score based on request latency. Score >= 90% is good (green), 70-90% needs attention (orange), < 70% is poor (red). Target and tolerated thresholds are configurable.", "fieldConfig": { "defaults": { "color": { @@ -75,12 +57,14 @@ "type": "special" } ], + "max": 100, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { "color": "#C4162A", - "value": null + "value": 0 }, { "color": "rgba(237, 129, 40, 0.89)", @@ -92,25 +76,23 @@ } ] }, - "unit": "percent", - "unitScale": true + "unit": "percent" }, "overrides": [] }, "gridPos": { "h": 2, - "w": 6, + "w": 5, "x": 0, "y": 1 }, - "id": 51, - "links": [], - "maxDataPoints": 100, + "id": 200, "options": { "colorMode": "background", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -122,21 +104,19 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "(\n ( \n sum(storage_api_http_request_duration_seconds_bucket{instance=~\"$instance\",le=\"$target\",status_code=~\"^2..$\"})\n + (\n sum(storage_api_http_request_duration_seconds_bucket{instance=~\"$instance\",le=\"$tolerated\",status_code=~\"^2..$\"})\n - sum(storage_api_http_request_duration_seconds_bucket{instance=~\"$instance\",le=\"$target\",status_code=~\"^2..$\"})\n ) / 2\n ) / sum(storage_api_http_request_duration_seconds_count{instance=~\"$instance\",status_code=~\"^2..$\"})\n) * 100", - "interval": "", + "expr": "((sum(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"0.3\",status_code=~\"2..\"}) + (sum(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"1.2\",status_code=~\"2..\"}) - sum(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", le=\"0.3\",status_code=~\"2..\"})) / 2) / sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"2..\"})) * 100", "legendFormat": "score", "refId": "A" } ], - "title": "Apdex Score: target $target s, tolerated $tolerated s", + "title": "Apdex Score", "type": "stat" }, { @@ -144,6 +124,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Current queries per second (QPS). Shows the real-time request rate across all endpoints.", "fieldConfig": { "defaults": { "color": { @@ -165,7 +146,7 @@ "steps": [ { "color": "#299c46", - "value": null + "value": 0 }, { "color": "rgba(237, 129, 40, 0.89)", @@ -177,25 +158,23 @@ } ] }, - "unit": "short", - "unitScale": true + "unit": "short" }, "overrides": [] }, "gridPos": { "h": 2, - "w": 2, - "x": 6, + "w": 3, + "x": 5, "y": 1 }, - "id": 57, - "links": [], - "maxDataPoints": 100, + "id": 201, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "max" @@ -207,16 +186,14 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(rate(storage_api_http_request_duration_seconds_count{instance=~\"$instance\",tenant_id=~\"$tenant_id\"}[$__interval]))", - "interval": "", + "expr": "sum(rate(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", "legendFormat": "", "refId": "A" } @@ -229,6 +206,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Total number of HTTP requests processed during the selected time range.", "fieldConfig": { "defaults": { "color": { @@ -252,33 +230,27 @@ "steps": [ { "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 + "value": 0 } ] }, - "unit": "none", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { "h": 2, - "w": 4, + "w": 3, "x": 8, "y": 1 }, - "id": 53, - "links": [], - "maxDataPoints": 100, + "id": 202, "options": { "colorMode": "none", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -290,20 +262,15 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": false, - "expr": "sum(\n\t\tincrease(storage_api_http_request_duration_seconds_sum{instance=~\"$instance\",tenant_id=~\"$tenant_id\"}[$__range]) OR on() vector(0)\n\t)", - "instant": false, - "interval": "", + "expr": "sum(increase(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}[$__range]))", "legendFormat": "", - "range": true, "refId": "A" } ], @@ -315,6 +282,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Process restart count during the selected time range. High restart counts may indicate crashes or OOM issues.", "fieldConfig": { "defaults": { "color": { @@ -335,34 +303,36 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "#299c46", + "value": 0 }, { - "color": "red", - "value": 80 + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "#C4162A", + "value": 2 } ] }, - "unit": "bytes", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { "h": 2, - "w": 4, - "x": 12, + "w": 3, + "x": 11, "y": 1 }, - "id": 59, - "links": [], - "maxDataPoints": 100, + "id": 203, "options": { - "colorMode": "none", + "colorMode": "background", "graphMode": "none", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -374,21 +344,19 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(storage_api_http_response_size_bytes_sum{instance=~\"$instance\"}) + sum(storage_api_http_request_size_bytes_sum{instance=~\"$instance\"})", - "interval": "", + "expr": "sum(changes(storage_api_process_start_time_seconds{region=~\"$region\", instance=~\"$instance\"}[$__range]))", "legendFormat": "", "refId": "A" } ], - "title": "Transferred", + "title": "Restarts", "type": "stat" }, { @@ -396,11 +364,11 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Server error rate (5xx) as a percentage of total requests. Values above 1% require investigation.", "fieldConfig": { "defaults": { "color": { - "fixedColor": "rgb(31, 120, 193)", - "mode": "fixed" + "mode": "thresholds" }, "mappings": [ { @@ -413,38 +381,42 @@ "type": "special" } ], + "max": 100, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "#299c46", + "value": 0 }, { - "color": "red", - "value": 80 + "color": "rgba(237, 129, 40, 0.89)", + "value": 5 + }, + { + "color": "#C4162A", + "value": 10 } ] }, - "unit": "bytes", - "unitScale": true + "unit": "percent" }, "overrides": [] }, "gridPos": { "h": 2, "w": 3, - "x": 16, + "x": 14, "y": 1 }, - "id": 70, - "links": [], - "maxDataPoints": 100, + "id": 204, "options": { - "colorMode": "none", + "colorMode": "background", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -456,21 +428,19 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_http", - "interval": "", - "legendFormat": "", + "expr": "(sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"5..\"} OR on() vector(0)) / sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}))*100", + "legendFormat": "error %", "refId": "A" } ], - "title": "Transfer Rate", + "title": "5xx Errors", "type": "stat" }, { @@ -478,6 +448,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Client error rate (4xx) as a percentage of total requests. High rates may indicate API misuse or client bugs.", "fieldConfig": { "defaults": { "color": { @@ -494,42 +465,42 @@ "type": "special" } ], + "max": 100, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { "color": "#299c46", - "value": null + "value": 0 }, { "color": "rgba(237, 129, 40, 0.89)", - "value": 1 + "value": 10 }, { "color": "#C4162A", - "value": 2 + "value": 20 } ] }, - "unit": "none", - "unitScale": true + "unit": "percent" }, "overrides": [] }, "gridPos": { "h": 2, "w": 3, - "x": 19, + "x": 17, "y": 1 }, - "id": 61, - "links": [], - "maxDataPoints": 100, + "id": 205, "options": { "colorMode": "background", - "graphMode": "none", + "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -541,21 +512,19 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(changes(storage_api_process_start_time_seconds{instance=~\"$instance\"}[$__range]))", - "interval": "", - "legendFormat": "", + "expr": "(sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"4..\"} OR on() vector(0)) / sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\"}))*100", + "legendFormat": "error %", "refId": "A" } ], - "title": "Restarts", + "title": "4xx Errors", "type": "stat" }, { @@ -563,47 +532,41 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "File upload statistics: started, completed, multipart, and standard uploads during the selected time range.", "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, + "decimals": 0, "mappings": [], - "max": 1, - "min": 0, + "noValue": "0", "thresholds": { - "mode": "percentage", + "mode": "absolute", "steps": [ { "color": "green", - "value": null - }, - { - "color": "orange", - "value": 75 - }, - { - "color": "red", - "value": 90 + "value": 0 } ] }, - "unit": "percentunit", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { - "h": 4, - "w": 2, - "x": 0, - "y": 3 + "h": 2, + "w": 4, + "x": 20, + "y": 1 }, - "id": 126, + "id": 206, "options": { - "minVizHeight": 75, - "minVizWidth": 75, + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -611,12 +574,11 @@ "fields": "", "values": false }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto", - "text": {} + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -624,21 +586,45 @@ "uid": "local_prometheus" }, "editorMode": "code", - "expr": "avg(rate(storage_api_process_cpu_seconds_total{instance=~\"$instance\"}[$__interval]))", + "expr": "sum(increase(storage_api_upload_started_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "Started", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(increase(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", + "legendFormat": "Completed", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(increase(storage_api_upload_started_total{region=~\"$region\", instance=~\"$instance\"}[$__range]))", "hide": false, "instant": false, + "legendFormat": "__auto", "range": true, - "refId": "B" + "refId": "C" } ], - "title": "CPU Usage", - "type": "gauge" + "title": "File Uploads", + "type": "stat" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Current CPU usage as a percentage. Values above 75% indicate high CPU load, above 90% is critical.", "fieldConfig": { "defaults": { "color": { @@ -652,7 +638,7 @@ "steps": [ { "color": "green", - "value": null + "value": 0 }, { "color": "orange", @@ -664,35 +650,33 @@ } ] }, - "unit": "percentunit", - "unitScale": true + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 4, - "w": 2, - "x": 2, + "w": 6, + "x": 0, "y": 3 }, - "id": 152, + "id": 207, "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": [ - "max" + "lastNotNull" ], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true, - "sizing": "auto", - "text": {} + "sizing": "auto" }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -700,17 +684,26 @@ "uid": "local_prometheus" }, "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(storage_api_process_cpu_seconds_total{instance=~\"$instance\"}[$__range]))", + "expr": "avg(rate(storage_api_process_cpu_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Avg", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "max(rate(storage_api_process_cpu_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", "hide": false, "instant": false, - "interval": "", - "legendFormat": "Current", - "refId": "A" + "legendFormat": "Max", + "range": true, + "refId": "B" } ], - "title": "MAX CPU Usage", - "transformations": [], + "title": "CPU", "type": "gauge" }, { @@ -718,6 +711,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Current RAM usage as a percentage of 2GB limit. Monitor for memory pressure and potential OOM issues.", "fieldConfig": { "defaults": { "color": { @@ -731,26 +725,25 @@ "steps": [ { "color": "green", - "value": null + "value": 0 }, { "color": "red", - "value": 80 + "value": 0.8 } ] }, - "unit": "percentunit", - "unitScale": true + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 4, - "w": 2, - "x": 4, + "w": 6, + "x": 6, "y": 3 }, - "id": 128, + "id": 209, "options": { "minVizHeight": 75, "minVizWidth": 75, @@ -764,10 +757,9 @@ }, "showThresholdLabels": false, "showThresholdMarkers": true, - "sizing": "auto", - "text": {} + "sizing": "auto" }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -775,15 +767,26 @@ "uid": "local_prometheus" }, "editorMode": "code", - "exemplar": true, - "expr": "avg((storage_api_process_resident_memory_bytes) / (2*1024*1024*1024))", - "interval": "", - "legendFormat": "", + "expr": "avg((storage_api_process_memory_usage{region=~\"$region\", instance=~\"$instance\"}) / (2*1024*1024*1024))", + "legendFormat": "Avg", "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "max(storage_api_process_resident_memory_bytes{region=~\"$region\", instance=~\"$instance\"}) / (2*1024*1024*1024)", + "hide": false, + "instant": false, + "legendFormat": "Max", + "range": true, + "refId": "B" } ], - "title": "RAM Usage", + "title": "RAM", "type": "gauge" }, { @@ -791,6 +794,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Event loop utilization ratio (0-1). Values close to 1 indicate the event loop is saturated.", "fieldConfig": { "defaults": { "color": { @@ -800,55 +804,49 @@ "max": 1, "min": 0, "thresholds": { - "mode": "percentage", + "mode": "absolute", "steps": [ { "color": "green", - "value": null - }, - { - "color": "#EAB839", - "value": 60 + "value": 0 }, { "color": "orange", - "value": 70 + "value": 0.7 }, { "color": "red", - "value": 80 + "value": 0.9 } ] }, - "unit": "percentunit", - "unitScale": true + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 4, - "w": 2, - "x": 6, + "w": 3, + "x": 12, "y": 3 }, - "id": 153, + "id": 212, "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": [ - "max" + "lastNotNull" ], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true, - "sizing": "auto", - "text": {} + "sizing": "auto" }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -856,15 +854,12 @@ "uid": "local_prometheus" }, "editorMode": "code", - "exemplar": true, - "expr": "max(storage_api_process_resident_memory_bytes{instance=~\"$instance\"}) / (2*1024*1024*1024)", - "interval": "", - "legendFormat": "", + "expr": "storage_api_nodejs_eventloop_utilization_ratio{region=~\"$region\", instance=~\"$instance\"}", "range": true, "refId": "A" } ], - "title": "Max RAM Usage", + "title": "Event Loop", "type": "gauge" }, { @@ -872,6 +867,7 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Response counts grouped by HTTP status code category (2xx success, 4xx client errors, 5xx server errors).", "fieldConfig": { "defaults": { "color": { @@ -884,29 +880,27 @@ "steps": [ { "color": "dark-blue", - "value": null + "value": 0 } ] }, - "unit": "none", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { "h": 4, - "w": 4, - "x": 8, + "w": 5, + "x": 15, "y": 3 }, - "id": 146, - "links": [], - "maxDataPoints": 100, + "id": 211, "options": { "colorMode": "background", "graphMode": "area", "justifyMode": "center", "orientation": "vertical", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -918,21 +912,15 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": false, - "expr": "sum(storage_api_http_request_duration_seconds_sum{status_code=~\"^[4]..$\"}) or vector(0)", - "hide": false, - "instant": false, - "interval": "", - "legendFormat": "400", - "range": true, + "expr": "sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"2..\"}) or vector(0)", + "legendFormat": "2xx", "refId": "A" }, { @@ -940,14 +928,8 @@ "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": false, - "expr": "sum(storage_api_http_request_duration_seconds_sum{status_code=~\"^[5]..$\"}) or vector(0)", - "hide": false, - "instant": false, - "interval": "", - "legendFormat": "500", - "range": true, + "expr": "sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"4..\"}) or vector(0)", + "legendFormat": "4xx", "refId": "B" }, { @@ -955,19 +937,12 @@ "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": false, - "expr": "sum(storage_api_http_request_duration_seconds_sum{status_code=~\"^[2]..$\"}) or vector(0)", - "hide": false, - "instant": true, - "interval": "", - "legendFormat": "200", - "range": false, + "expr": "sum(storage_api_http_request_duration_seconds_count{region=~\"$region\", instance=~\"$instance\", status_code=~\"5..\"}) or vector(0)", + "legendFormat": "5xx", "refId": "C" } ], "title": "Responses By Code", - "transformations": [], "type": "stat" }, { @@ -975,58 +950,47 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Active database connection pools. High counts may indicate connection pool pressure.", "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], + "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "#299c46", - "value": null + "color": "green", + "value": 0 }, { - "color": "rgba(237, 129, 40, 0.89)", - "value": 5 + "color": "orange", + "value": 50 }, { - "color": "#C4162A", - "value": 10 + "color": "red", + "value": 100 } ] }, - "unit": "percent", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { - "h": 2, - "w": 2, - "x": 12, + "h": 4, + "w": 3, + "x": 20, "y": 3 }, - "id": 63, - "links": [], - "maxDataPoints": 100, + "id": 213, "options": { - "colorMode": "background", + "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -1038,21 +1002,19 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "(\n\tsum(\n\t\tstorage_api_http_request_duration_seconds_count{instance=~\"$instance\",status_code=~\"^[5]..$\",tenant_id=~\"$tenant_id\"} OR on() vector(0)\n\t) / \n\tsum(\n\t\tstorage_api_http_request_duration_seconds_count{instance=~\"$instance\",tenant_id=~\"$tenant_id\"}\n\t)\n)*100", - "interval": "", - "legendFormat": "error %", + "expr": "sum(storage_api_db_pool{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "", "refId": "A" } ], - "title": "500 Errors", + "title": "DB Pools", "type": "stat" }, { @@ -1060,40 +1022,47 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Pending queue jobs across all job types. Growing queues indicate processing bottlenecks.", "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, - "decimals": 0, "mappings": [], - "noValue": "0", "thresholds": { "mode": "absolute", "steps": [ { "color": "green", - "value": null + "value": 0 + }, + { + "color": "orange", + "value": 100 + }, + { + "color": "red", + "value": 500 } ] }, - "unit": "none", - "unitScale": true + "unit": "none" }, "overrides": [] }, "gridPos": { "h": 4, "w": 4, - "x": 14, - "y": 3 + "x": 0, + "y": 7 }, - "id": 117, + "id": 214, "options": { "colorMode": "value", - "graphMode": "none", - "justifyMode": "center", - "orientation": "auto", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -1102,199 +1071,205 @@ "values": false }, "showPercentChange": false, - "textMode": "value_and_name", + "textMode": "auto", "wideLayout": true }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(increase(storage_api_upload_started{tenant_id=~\"$tenant_id\"}[$__range]))", - "interval": "", - "legendFormat": "Started", - "range": true, + "expr": "sum(storage_api_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "", "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(increase(storage_api_upload_success{tenant_id=~\"$tenant_id\"}[$__range]))", - "hide": false, - "interval": "", - "legendFormat": "Completed", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(increase(storage_api_upload_success{tenant_id=~\"$tenant_id\", is_multipart=\"true\"}[$__range])) or vector(0)", - "hide": false, - "interval": "", - "legendFormat": "Multi Part", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(increase(storage_api_upload_success{tenant_id=~\"$tenant_id\", is_multipart=\"false\"}[$__range]))", - "hide": false, - "instant": false, - "interval": "", - "legendFormat": "Standard", - "refId": "D" } ], - "title": "File Uploads", + "title": "Queue Jobs", "type": "stat" }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 215, + "panels": [], + "title": "Requests Overview", + "type": "row" + }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "HTTP requests per second broken down by status code category. Shows total requests along with 2xx (success), 4xx (client errors), and 5xx (server errors) rates. Use this to monitor overall API traffic and identify error spikes.", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" }, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } - ], + }, + "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "#299c46", - "value": null - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 5 - }, - { - "color": "#C4162A", - "value": 10 + "color": "green", + "value": 0 } ] }, - "unit": "percent", - "unitScale": true + "unit": "reqps" }, "overrides": [] }, "gridPos": { - "h": 2, - "w": 2, - "x": 12, - "y": 5 + "h": 8, + "w": 8, + "x": 0, + "y": 12 }, - "id": 156, - "links": [], - "maxDataPoints": 100, + "id": 2, "options": { - "colorMode": "background", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "horizontal", - "reduceOptions": { + "legend": { "calcs": [ - "lastNotNull" + "mean", + "max" ], - "fields": "", - "values": false + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": true, - "expr": "(\n\tsum(\n\t\tstorage_api_http_request_duration_seconds_count{instance=~\"$instance\",status_code=~\"^[4]..$\",tenant_id=~\"$tenant_id\"} OR on() vector(0)\n\t) / \n\tsum(\n\t\tstorage_api_http_request_duration_seconds_count{instance=~\"$instance\",tenant_id=~\"$tenant_id\"}\n\t)\n)*100", - "interval": "", - "legendFormat": "error %", - "range": true, + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Total", "refId": "A" - } - ], - "title": "400 Errors", - "type": "stat" - }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 7 - }, - "id": 115, - "panels": [], - "targets": [ + }, { "datasource": { "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "uid": "local_prometheus" }, - "refId": "A" + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"2xx\"}[$__rate_interval]))", + "legendFormat": "2xx", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx\"}[$__rate_interval]))", + "legendFormat": "4xx", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval]))", + "legendFormat": "5xx", + "refId": "D" } ], - "title": "Requests", - "type": "row" + "title": "Request Rate", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "HTTP request duration percentiles (p50, p90, p99). P50 shows median latency, p90 shows latency for 90% of requests, and p99 captures tail latency. High p99 values may indicate slow database queries, external service delays, or resource contention.", "fieldConfig": { "defaults": { "color": { - "mode": "continuous-BlPu" + "mode": "palette-classic" }, "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "inspect": false + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { @@ -1302,336 +1277,76 @@ "steps": [ { "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 + "value": 0 } ] }, - "unit": "none", - "unitScale": true + "unit": "s" }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "route 2" - }, - "properties": [ - { - "id": "custom.width", - "value": 246 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "route 1" - }, - "properties": [ - { - "id": "custom.width", - "value": 305 - } - ] - } - ] + "overrides": [] }, "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 8 + "h": 8, + "w": 8, + "x": 8, + "y": 12 }, - "id": 149, + "id": 3, "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" + "legend": { + "calcs": [ + "mean", + "max" ], - "show": false + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Value (range)" - } - ] + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(increase(storage_api_http_request_duration_seconds_count{tenant_id=~\"$tenant_id\"}[$__range])) by (tenant_id, route, method, status_code)", - "interval": "", - "legendFormat": "tenant_id={{tenant_id}};route={{route}};method={{method}};status_code={{status_code}}", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p50", "refId": "A" - } - ], - "title": "Requests by Path", - "transformations": [ - { - "id": "seriesToRows", - "options": {} - }, - { - "id": "extractFields", - "options": { - "replace": false, - "source": "Metric" - } }, { - "id": "groupBy", - "options": { - "fields": { - "Value": { - "aggregations": [ - "range" - ], - "operation": "aggregate" - }, - "method": { - "aggregations": [], - "operation": "groupby" - }, - "route": { - "aggregations": [], - "operation": "groupby" - }, - "status_code": { - "aggregations": [], - "operation": "groupby" - }, - "tenant_id": { - "aggregations": [], - "operation": "groupby" - } - } - } - }, - { - "id": "filterByValue", - "options": { - "filters": [ - { - "config": { - "id": "equal", - "options": { - "value": "" - } - }, - "fieldName": "Value (range)" - } - ], - "match": "any", - "type": "exclude" - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unitScale": true - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 8 - }, - "id": 150, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Total (lastNotNull)" - } - ] - }, - "pluginVersion": "10.3.1", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(storage_api_http_request_summary_seconds_count{status_code=~\"$error_codes\"}) by (status_code, route, method, tenant_id)", - "interval": "", - "legendFormat": "tenant_id={{tenant_id}};status_code={{status_code}};route={{route}}", - "range": true, - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.90, sum(rate(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p90", + "refId": "B" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(storage_api_http_request_duration_seconds_count{tenant_id=~\"$tenant_id\", status_code=~\"$error_codes\"}) by (status_code, route, method, tenant_id)", - "hide": false, - "interval": "", - "legendFormat": "tenant_id={{tenant_id}};status_code={{status_code}};route={{route}}", - "range": true, - "refId": "B" - } - ], - "title": "Errors by Path", - "transformations": [ - { - "id": "reduce", - "options": { - "includeTimeField": false, - "labelsToFields": true, - "mode": "seriesToRows", - "reducers": [ - "lastNotNull" - ] - } - }, - { - "id": "seriesToColumns", - "options": { - "byField": "tenant_id" - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - "Field": true, - "Last *": false, - "Time": true - }, - "includeByName": {}, - "indexByName": { - "Field": 0, - "Total": 5, - "method": 2, - "route": 3, - "status_code": 4, - "tenant_id": 1 - }, - "renameByName": { - "Last *": "" - } - } - }, - { - "id": "groupBy", - "options": { - "fields": { - "Last *": { - "aggregations": [], - "operation": "groupby" - }, - "Total": { - "aggregations": [ - "lastNotNull" - ], - "operation": "aggregate" - }, - "method": { - "aggregations": [], - "operation": "groupby" - }, - "route": { - "aggregations": [], - "operation": "groupby" - }, - "status_code": { - "aggregations": [], - "operation": "groupby" - }, - "tenant_id": { - "aggregations": [], - "operation": "groupby" - } - } - } - }, - { - "id": "filterByValue", - "options": { - "filters": [ - { - "config": { - "id": "equal", - "options": { - "value": 0 - } - }, - "fieldName": "Total (lastNotNull)" - } - ], - "match": "any", - "type": "exclude" - } + "expr": "histogram_quantile(0.99, sum(rate(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p99", + "refId": "C" } ], - "type": "table" + "title": "Request Latency (Percentiles)", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Server error rate as a percentage of total requests. Values above 1% may indicate service issues requiring investigation. Common causes include database connection failures, S3 errors, or application exceptions.", "fieldConfig": { "defaults": { "color": { @@ -1644,8 +1359,9 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1653,13 +1369,14 @@ "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -1670,61 +1387,55 @@ } }, "mappings": [], - "noValue": "0", "thresholds": { "mode": "absolute", "steps": [ { "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 + "value": 0 } ] }, - "unitScale": true + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 12, - "x": 0, - "y": 17 + "w": 8, + "x": 16, + "y": 12 }, - "id": 142, + "id": 4, "options": { "legend": { - "calcs": [], - "displayMode": "list", + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": false, - "expr": "storage_api_http_request_duration_seconds_count{status_code=~\"$error_codes\"}", - "hide": false, - "instant": false, - "legendFormat": "{{status_code}}", - "range": true, - "refId": "B" + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval])) / sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Error Rate", + "refId": "A" } ], - "title": "Errors Over Time", + "title": "Error Rate (5xx)", "type": "timeseries" }, { @@ -1732,10 +1443,11 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Network transfer rates based on HTTP Content-Length headers. Transfer In shows data received from clients (uploads, POST bodies). Transfer Out shows data sent to clients (downloads, responses). Useful for monitoring bandwidth usage and identifying large file transfers.", "fieldConfig": { "defaults": { "color": { - "mode": "continuous-BlPu" + "mode": "palette-classic" }, "custom": { "axisBorderShow": false, @@ -1744,22 +1456,24 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "hue", + "fillOpacity": 10, + "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -1775,52 +1489,95 @@ "steps": [ { "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 + "value": 0 } ] }, - "unit": "none", - "unitScale": true + "unit": "Bps" }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Transfer In" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Transfer Out" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] }, "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 17 + "x": 0, + "y": 20 }, - "id": 147, + "id": 216, "options": { "legend": { - "calcs": [], - "displayMode": "list", - "placement": "right", - "showLegend": false + "calcs": [ + "mean", + "max", + "sum" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(increase(storage_api_http_request_duration_seconds_count{tenant_id=~\"$tenant_id\"}[$__interval]))", - "interval": "", - "legendFormat": "{{ tenant_id }} - {{route}} - {{method}} ", + "editorMode": "code", + "expr": "sum(rate(storage_api_http_request_size_bytes_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Transfer In", + "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_http_response_size_bytes_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Transfer Out", + "range": true, + "refId": "B" } ], - "title": "Total Number of Requests Over Time", + "title": "Transfer In/Out", "type": "timeseries" }, { @@ -1828,42 +1585,21 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Top API endpoints by request count. Shows which routes receive the most traffic. Use this to identify hot paths, optimize frequently accessed endpoints, and understand API usage patterns.", "fieldConfig": { "defaults": { "color": { - "mode": "continuous-BlPu" + "mode": "thresholds" }, "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "hue", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" + "align": "auto", + "cellOptions": { + "type": "auto" }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" + "footer": { + "reducers": [] }, - "thresholdsStyle": { - "mode": "off" - } + "inspect": false }, "mappings": [], "thresholds": { @@ -1871,75 +1607,102 @@ "steps": [ { "color": "green", - "value": null - }, + "value": 0 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "route" + }, + "properties": [ { - "color": "red", - "value": 80 + "id": "custom.width", + "value": 300 } ] }, - "unit": "s", - "unitScale": true - }, - "overrides": [] + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "displayName", + "value": "Requests/sec" + }, + { + "id": "unit", + "value": "reqps" + } + ] + } + ] }, "gridPos": { "h": 8, "w": 12, - "x": 0, - "y": 25 + "x": 12, + "y": 20 }, - "id": 134, + "id": 217, "options": { - "legend": { - "calcs": [ - "min", - "max" + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" ], - "displayMode": "list", - "placement": "right", - "showLegend": true + "show": false }, - "tooltip": { - "mode": "single", - "sort": "none" - } + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "histogram_quantile(0.5, sum(increase(storage_api_http_request_duration_seconds_bucket{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, route, method, tenant_id))", - "hide": true, - "interval": "", - "legendFormat": "{{ tenant_id }} - {{route}} - {{method}} ", + "expr": "topk(10, sum by (route) (rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])))", + "format": "table", + "instant": true, + "legendFormat": "__auto", "refId": "A" - }, + } + ], + "title": "Requests by Path", + "transformations": [ { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "sum(rate(storage_api_http_request_duration_seconds_sum{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, route, method, tenant_id) / sum(rate(storage_api_http_request_duration_seconds_count{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, route, method, tenant_id)", - "hide": false, - "interval": "", - "legendFormat": "{{ tenant_id }} - {{route}} - {{method}} ", - "refId": "B" + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": {}, + "renameByName": {} + } } ], - "title": "AVG Response Time", - "type": "timeseries" + "type": "table" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Error count over time broken down by status code. Shows 4xx client errors and 5xx server errors separately to help distinguish between client-side issues and server-side problems.", "fieldConfig": { "defaults": { "color": { @@ -1952,8 +1715,9 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1961,13 +1725,14 @@ "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -1983,337 +1748,1938 @@ "steps": [ { "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 + "value": 0 } ] }, - "unit": "s", - "unitScale": true + "unit": "short" }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "4xx Errors" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx Errors" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] }, "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 25 + "x": 0, + "y": 28 }, - "id": 103, - "interval": "5s", + "id": 218, "options": { "legend": { "calcs": [ - "min", + "mean", "max", - "mean" + "sum" ], - "displayMode": "list", - "placement": "right", + "displayMode": "table", + "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(increase(storage_api_http_request_duration_seconds_bucket{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, route, method, status_code, tenant_id))", - "format": "time_series", - "instant": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ tenant_id}} {{method}} {{route}}", + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx\"}[$__rate_interval]))", + "legendFormat": "4xx Errors", "refId": "A" - } - ], - "title": "Http Request Duration (p95)", - "type": "timeseries" - }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 33 - }, - "id": 98, - "panels": [], - "targets": [ + }, { "datasource": { "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "uid": "local_prometheus" }, - "refId": "A" + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"5xx\"}[$__rate_interval]))", + "legendFormat": "5xx Errors", + "refId": "B" } ], - "title": "Queue", - "type": "row" + "title": "Errors Over Time", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Top API endpoints by error count. Shows which routes are generating the most errors. Use this to identify problematic endpoints that need attention or debugging.", "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + }, "mappings": [], - "noValue": "0", "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": 0 + }, + { + "color": "orange", + "value": 1 + }, + { + "color": "red", + "value": 10 } ] - }, - "unitScale": true + } }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "route" + }, + "properties": [ + { + "id": "custom.width", + "value": 300 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "displayName", + "value": "Errors/sec" + }, + { + "id": "unit", + "value": "short" + } + ] + } + ] }, "gridPos": { - "h": 4, - "w": 8, - "x": 0, - "y": 34 + "h": 8, + "w": 12, + "x": 12, + "y": 28 }, - "id": 105, + "id": 219, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "range" - ], + "cellHeight": "sm", + "footer": { + "countRows": false, "fields": "", - "values": false + "reducer": [ + "sum" + ], + "show": false }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(storage_api_queue_job_scheduled{tenant_id=~\"$tenant_id\"}) by (name)", - "interval": "", - "legendFormat": "{{ name }}", - "range": true, + "expr": "topk(10, sum by (route) (rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", status_code=~\"4xx|5xx\"}[$__rate_interval])))", + "format": "table", + "instant": true, + "legendFormat": "__auto", "refId": "A" } ], - "title": "Queue Pending Messages", - "type": "stat" + "title": "Errors by Path", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": {}, + "renameByName": {} + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 10, + "panels": [], + "title": "HTTP Requests by Tenant", + "type": "row" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "HTTP requests per second grouped by tenant ID. Use this to identify high-traffic tenants, detect unusual activity patterns, or investigate tenant-specific issues. Filter by tenant using the dropdown above.", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], - "noValue": "0", "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 1 + "color": "green", + "value": 0 } ] }, - "unitScale": true + "unit": "reqps" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 2, - "x": 8, - "y": 34 + "w": 12, + "x": 0, + "y": 37 }, - "id": 129, + "id": 11, "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { + "legend": { "calcs": [ + "mean", "max" ], - "fields": "", - "values": false + "displayMode": "table", + "placement": "right", + "showLegend": true }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(storage_api_queue_job_retry_failed{tenant_id=~\"$tenant_id\"}) by (name)", - "interval": "", - "legendFormat": "{{ name }}", + "expr": "sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}[$__rate_interval])) by (tenantId)", + "legendFormat": "{{ tenantId }}", "refId": "A" } ], - "title": "Queue Failed and Retried", - "type": "gauge" + "title": "Request Rate by Tenant", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "95th percentile request latency per tenant. Helps identify tenants experiencing performance issues due to large files, complex queries, or resource-intensive operations. Compare against baseline to detect anomalies.", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" }, - "mappings": [], - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 1 + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 37 + }, + "id": 12, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}[$__rate_interval])) by (le, tenantId))", + "legendFormat": "{{ tenantId }}", + "refId": "A" + } + ], + "title": "P95 Latency by Tenant", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 45 + }, + "id": 20, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "The 10 most frequently called API endpoints by requests per second. Use this to understand API usage patterns, identify heavily-used endpoints for optimization, and detect unexpected traffic patterns.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 46 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "topk(10, sum(rate(storage_api_http_requests_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (route))", + "legendFormat": "{{ route }}", + "refId": "A" + } + ], + "title": "Top 10 Routes by Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "The 10 slowest API endpoints by 95th percentile latency. These endpoints are prime candidates for performance optimization. High latency may indicate complex database operations, large file transfers, or inefficient code paths.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 46 + }, + "id": 22, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "topk(10, histogram_quantile(0.95, sum(rate(storage_api_http_request_duration_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, route)))", + "legendFormat": "{{ route }}", + "range": true, + "refId": "A" + } + ], + "title": "Top 10 Slowest Routes (P95)", + "type": "timeseries" + } + ], + "title": "HTTP Requests by Route", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 30, + "panels": [], + "title": "Uploads", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Comparison of started uploads versus successfully completed uploads. A growing gap between these values may indicate upload failures, timeouts, or client disconnections. Use this to monitor upload reliability.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 47 + }, + "id": 31, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_started_total{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Started", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Success", + "range": true, + "refId": "B" + } + ], + "title": "Uploads (Started vs Success)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Successful uploads categorized by upload method: standard (single request), resumable (TUS protocol), S3 (direct S3 upload), and multipart. Helps understand which upload mechanisms are most used and their success rates.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 47 + }, + "id": 32, + "options": { + "displayMode": "gradient", + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "valueMode": "color" + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_standard=\"1\"})", + "legendFormat": "Standard", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_resumable=\"1\"})", + "legendFormat": "Resumable (TUS)", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_s3=\"1\"})", + "legendFormat": "S3", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\", is_multipart=\"1\"})", + "legendFormat": "Multipart", + "range": true, + "refId": "D" + } + ], + "title": "Uploads by Type", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Successful uploads grouped by tenant ID. Use this to identify high-volume uploaders, track tenant activity, and investigate tenant-specific upload issues.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 47 + }, + "id": 33, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_upload_success_total{region=~\"$region\", instance=~\"$instance\", tenantId=~\"$tenant\"}) by (tenantId)", + "legendFormat": "{{ tenantId }}", + "range": true, + "refId": "A" + } + ], + "title": "Uploads by Tenant", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 55 + }, + "id": 40, + "panels": [], + "title": "Database", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Database query latency percentiles (p50, p95) grouped by operation type. Identifies slow queries that may need optimization through indexing, query rewriting, or connection pool tuning. Monitor for performance regressions.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 41, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.50, sum(rate(storage_api_database_query_performance_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p50 {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_database_query_performance_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p95 {{ name }}", + "refId": "B" + } + ], + "title": "Database Query Performance by Operation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Active database connection pool count. High values may indicate connection leaks or pool exhaustion. Monitor this alongside query performance to ensure adequate connection availability.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 56 + }, + "id": 42, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_db_pool{region=~\"$region\", instance=~\"$instance\"})", + "legendFormat": "Active Pools", + "refId": "A" + } + ], + "title": "Database Pools", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Database connections categorized by type (internal vs external). External connections are from external services. Monitor for connection growth patterns and potential connection exhaustion.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 56 + }, + "id": 43, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_db_connections{region=~\"$region\", instance=~\"$instance\"}) by (is_external)", + "legendFormat": "External: {{ is_external }}", + "refId": "A" + } + ], + "title": "Database Connections", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Rate of database queries per second grouped by operation type. Use this to monitor database load, identify query spikes, and correlate with application activity. High query rates may indicate opportunities for caching or query optimization.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 64 + }, + "id": 220, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_database_query_performance_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "{{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(rate(storage_api_database_query_performance_count{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "Total", + "refId": "B" + } + ], + "title": "Database Query Rate", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 50, + "panels": [], + "title": "Queue", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Number of jobs currently pending in the queue by job type. Growing queues indicate processing bottlenecks. Monitor this to ensure background jobs are being processed in a timely manner.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 73 + }, + "id": 51, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "{{ name }}", + "range": true, + "refId": "A" + } + ], + "title": "Queue Jobs Pending", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Number of successfully completed queue jobs by type. Use this to track job throughput and compare against scheduled jobs to understand completion rates.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 73 + }, + "id": 52, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(storage_api_queue_job_completed{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "{{ name }}", + "range": true, + "refId": "A" + } + ], + "title": "Queue Jobs Completed", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Queue job errors and retry failures by job type. Errors indicate jobs that failed and may be retried. Retry failures are jobs that exhausted all retry attempts. Investigate persistent failures for root cause.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "red", + "value": 5 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 73 + }, + "id": 53, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_queue_job_error{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Errors {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_queue_job_retry_failed{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Retries {{ name }}", + "refId": "B" + } + ], + "title": "Queue Errors & Retries", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "Time taken to schedule jobs in the queue (p50, p95, p99). High scheduling times may indicate database contention, lock contention, or queue saturation. Use this to identify bottlenecks in job submission.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 } ] }, - "unitScale": true + "unit": "s" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 3, - "x": 10, - "y": 34 + "w": 12, + "x": 0, + "y": 81 }, - "id": 107, + "id": 224, "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { + "legend": { "calcs": [ + "mean", "max" ], - "fields": "", - "values": false + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(storage_api_queue_job_error{tenant_id=~\"$tenant_id\"}) by (name)", - "interval": "", - "legendFormat": "{{ name }}", + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p50 {{ name }}", + "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(storage_api_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p95 {{ name }}", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.99, sum(rate(storage_api_queue_job_scheduled_time_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le, name))", + "legendFormat": "p99 {{ name }}", + "range": true, + "refId": "C" } ], - "title": "Queue Job Failed", - "type": "gauge" + "title": "Queue Job Scheduling Time", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Rate of jobs being scheduled vs completed per second. A growing gap between scheduled and completed indicates queue backlog. Use this to monitor queue throughput and identify processing bottlenecks.", "fieldConfig": { "defaults": { "color": { - "mode": "continuous-BlPu" + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": 0 } ] }, - "unitScale": true + "unit": "ops" }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Scheduled.*/" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/Completed.*/" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] }, "gridPos": { "h": 8, - "w": 11, - "x": 13, - "y": 34 + "w": 12, + "x": 12, + "y": 81 }, - "id": 155, + "id": 225, "options": { - "displayMode": "gradient", - "maxVizHeight": 300, - "minVizHeight": 10, - "minVizWidth": 0, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { + "legend": { "calcs": [ - "lastNotNull" + "mean", + "sum" ], - "fields": "", - "values": false + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, - "showUnfilled": true, - "sizing": "auto", - "valueMode": "color" + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } }, - "pluginVersion": "10.3.1", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -2321,207 +3687,424 @@ "uid": "local_prometheus" }, "editorMode": "code", - "exemplar": false, - "expr": "sum(storage_api_queue_job_completed{tenant_id=~\"$tenant_id\", name=~\"^[a-z].*\"}) by (name)", - "instant": true, - "interval": "", - "legendFormat": "{{ name }}", - "range": false, + "expr": "sum(rate(storage_api_queue_job_scheduled{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "Scheduled {{ name }}", + "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_queue_job_completed{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (name)", + "legendFormat": "Completed {{ name }}", + "range": true, + "refId": "B" } ], - "title": "Queue Completed", - "type": "bargauge" + "title": "Scheduled vs Completed Rate", + "type": "timeseries" }, { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unitScale": true - }, - "overrides": [] - }, + "collapsed": true, "gridPos": { - "h": 4, - "w": 8, + "h": 1, + "w": 24, "x": 0, - "y": 38 + "y": 89 }, - "id": 106, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "range" + "id": 60, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "S3 multipart upload chunk latency percentiles (p50, p95, p99). High latency may indicate S3 throttling, network issues, or large chunk sizes. Compare across regions to identify geographic performance variations.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 145 + }, + "id": 61, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p50", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.95, sum(rate(storage_api_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p95", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "histogram_quantile(0.99, sum(rate(storage_api_s3_upload_part_seconds_bucket{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])) by (le))", + "legendFormat": "p99", + "refId": "C" + } ], - "fields": "", - "values": false + "title": "S3 Upload Part Latency", + "type": "timeseries" }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "10.3.1", - "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "editorMode": "code", - "exemplar": true, - "expr": "sum(storage_api_queue_job_completed{tenant_id=~\"$tenant_id\"}) by (name)", - "interval": "", - "legendFormat": "{{ name }}", - "range": true, - "refId": "A" - } - ], - "title": "Queue Completed Messages", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" + "description": "HTTP agent connection pool status showing busy and free sockets by protocol (http/https). Busy sockets indicate active connections. High busy-to-free ratios may indicate connection pool pressure or slow upstream services.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "short" }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 145 + }, + "id": 62, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true }, - "thresholdsStyle": { - "mode": "off" + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 42 - }, - "id": 137, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true + "expr": "sum(storage_api_http_pool_busy_sockets{region=~\"$region\", instance=~\"$instance\"}) by (name, protocol)", + "legendFormat": "Busy {{ name }} ({{ protocol }})", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_http_pool_free_sockets{region=~\"$region\", instance=~\"$instance\"}) by (name, protocol)", + "legendFormat": "Free {{ name }} ({{ protocol }})", + "refId": "B" + } + ], + "title": "HTTP Pool Sockets", + "type": "timeseries" }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "avg(rate(storage_api_queue_job_scheduled_time_sum{tenant_id=~\"$tenant_id\"}[$__interval]) / rate(storage_api_queue_job_scheduled_time_count{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, name)", - "interval": "", - "legendFormat": "{{ name }}", - "refId": "A" + "description": "HTTP agent pending requests and errors by pool. Pending requests queue when all connections are busy. Errors indicate connection failures to upstream services like S3 or external APIs.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "yellow", + "value": 10 + }, + { + "color": "red", + "value": 50 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 145 + }, + "id": 63, + "options": { + "legend": { + "calcs": [ + "last" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_http_pool_requests{region=~\"$region\", instance=~\"$instance\"}) by (name)", + "legendFormat": "Pending {{ name }}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "sum(storage_api_http_pool_errors{region=~\"$region\", instance=~\"$instance\"}) by (name, type)", + "legendFormat": "Errors {{ name }} ({{ type }})", + "refId": "B" + } + ], + "title": "HTTP Pool Requests & Errors", + "type": "timeseries" } ], - "title": "Queue Scheduling Time AVG", - "type": "timeseries" + "title": "S3 & HTTP Pool", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 90 + }, + "id": 80, + "panels": [], + "title": "Node.js Runtime (Event Loop)", + "type": "row" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Node.js event loop utilization ratio (0-1). Values close to 1 indicate the event loop is fully utilized and may cause response delays. Sustained high utilization suggests CPU-bound work or blocking operations.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -2536,113 +4119,91 @@ "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "none" + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 12, - "x": 12, - "y": 42 + "w": 8, + "x": 0, + "y": 91 }, - "id": 138, + "id": 81, "options": { "legend": { - "calcs": [], - "displayMode": "list", + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(increase(storage_api_queue_job_scheduled_time_count[$__range])) by (name)", - "interval": "", - "legendFormat": "{{ name }}", + "editorMode": "code", + "expr": "storage_api_nodejs_eventloop_utilization_ratio", + "legendFormat": "Event Loop Utilization", + "range": true, "refId": "A" } ], - "title": "Queue Messages Scheduled Over Time", + "title": "Event Loop Utilization", "type": "timeseries" }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 50 - }, - "id": 111, - "panels": [], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "refId": "A" - } - ], - "title": "Database", - "type": "row" - }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Event loop delay percentiles measuring time between scheduled and actual callback execution. High p99 values indicate occasional blocking operations. Delays >100ms may cause noticeable request latency.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 21, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -2657,11 +4218,8 @@ "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, @@ -2671,40 +4229,36 @@ }, "gridPos": { "h": 8, - "w": 12, - "x": 0, - "y": 51 + "w": 8, + "x": 8, + "y": 91 }, - "id": 101, - "interval": "5s", + "id": 82, "options": { "legend": { "calcs": [ - "min", + "mean", "max" ], - "displayMode": "list", - "placement": "right", + "displayMode": "table", + "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(increase(storage_api_database_query_performance_bucket{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, tenant_id, name))", - "format": "time_series", - "hide": false, - "instant": false, - "interval": "", - "legendFormat": "P95 - {{ tenant_id}} - {{name}}", + "expr": "storage_api_nodejs_eventloop_delay_p50_seconds", + "legendFormat": "p50", "refId": "A" }, { @@ -2712,15 +4266,21 @@ "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(increase(storage_api_database_query_performance_bucket{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, tenant_id, name))", - "hide": false, - "interval": "", - "legendFormat": "P99 - {{ tenant_id}} - {{name}}", + "expr": "storage_api_nodejs_eventloop_delay_p90_seconds", + "legendFormat": "p90", "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_nodejs_eventloop_delay_p99_seconds", + "legendFormat": "p99", + "refId": "C" } ], - "title": "DB Query Performance (p95)", + "title": "Event Loop Delay (Percentiles)", "type": "timeseries" }, { @@ -2728,32 +4288,37 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Network I/O throughput and errors from host metrics. High throughput correlates with upload/download activity. Network errors may indicate connectivity issues, DNS failures, or upstream service problems.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -2768,51 +4333,60 @@ "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "s" + "unit": "Bps" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 12, - "x": 12, - "y": 51 + "w": 8, + "x": 16, + "y": 91 }, - "id": 123, + "id": 73, "options": { "legend": { - "calcs": [], - "displayMode": "list", + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "avg(rate(storage_api_database_query_performance_sum{tenant_id=~\"$tenant_id\"}[$__interval]) / rate(storage_api_database_query_performance_count{tenant_id=~\"$tenant_id\"}[$__interval])) by (le, name)", - "interval": "", - "legendFormat": "{{ name }}", + "expr": "rate(storage_api_system_network_io_total[$__rate_interval])", + "legendFormat": "Network I/O", "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "rate(storage_api_system_network_errors_total[$__rate_interval])", + "legendFormat": "Network Errors", + "refId": "B" } ], - "title": "Database Performance AVG", + "title": "Network I/O", "type": "timeseries" }, { @@ -2820,32 +4394,37 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "CPU utilization from host metrics: process CPU (this Node.js instance) vs system CPU (entire host). Compare to identify if the Storage API is the primary CPU consumer or if other processes are competing.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -2860,98 +4439,98 @@ "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] - } + }, + "unit": "percentunit" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 12, + "w": 8, "x": 0, - "y": 59 + "y": 99 }, - "id": 102, - "interval": "5s", + "id": 71, "options": { "legend": { - "calcs": [], - "displayMode": "list", + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "sum(rate(storage_api_database_query_performance_count{tenant_id=~\"$tenant_id\"}[$__interval])) by (name)", - "instant": false, - "interval": "", - "legendFormat": "{{name}} ", + "expr": "storage_api_process_cpu_utilization", + "legendFormat": "Process CPU Utilization", "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_system_cpu_utilization", + "legendFormat": "System CPU Utilization", + "refId": "B" } ], - "title": "DB Query Rate", + "title": "CPU Utilization", "type": "timeseries" }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 67 - }, - "id": 157, - "panels": [], - "title": "PgBouncer - Pooler", - "type": "row" - }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Memory usage from host metrics: process memory (this Node.js instance) vs system memory (entire host). Monitor for memory pressure and ensure adequate headroom for garbage collection spikes.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -2966,220 +4545,91 @@ "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] - } + }, + "unit": "bytes" }, "overrides": [] }, "gridPos": { "h": 8, - "w": 12, - "x": 0, - "y": 68 + "w": 8, + "x": 8, + "y": 99 }, - "id": 131, + "id": 72, "options": { "legend": { - "calcs": [], - "displayMode": "list", + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, + "pluginVersion": "12.3.1", "targets": [ { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "pgbouncer_databases_database_current_connections{database=\"postgres\"}", - "interval": "", - "legendFormat": "Native Connections", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "editorMode": "code", - "exemplar": true, - "expr": "pgbouncer_pools_client_active_connections{database=\"postgres\"}", - "hide": false, - "interval": "", - "legendFormat": "Active Client Connections", - "range": true, - "refId": "B" - } - ], - "title": "Pg Connections", - "type": "timeseries" - }, - { - "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 76 - }, - "id": 87, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 2, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 76 - }, - "id": 21, - "options": { - "legend": { - "calcs": [ - "lastNotNull" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.3.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_nodejs_eventloop_lag_seconds{instance=~\"$instance\"}", - "hide": false, - "instant": false, - "interval": "", - "legendFormat": "last", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_nodejs_eventloop_lag_p99_seconds{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "p99", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_nodejs_eventloop_lag_p50_seconds{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "p50", - "refId": "C" - } - ], - "title": "Eventloop Latency", - "type": "timeseries" + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_process_memory_usage", + "legendFormat": "Process Memory", + "refId": "A" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "expr": "storage_api_system_memory_usage", + "legendFormat": "System Memory", + "refId": "B" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 107 + }, + "id": 84, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "description": "V8 JavaScript engine heap memory usage vs limit. Used heap approaching the limit may trigger more frequent garbage collection or out-of-memory errors. Monitor for memory leaks (steadily increasing used heap).", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", @@ -3188,14 +4638,16 @@ "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -3204,158 +4656,69 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "percentunit" + "unit": "bytes" }, "overrides": [] }, "gridPos": { - "h": 5, + "h": 8, "w": 8, - "x": 8, - "y": 76 + "x": 0, + "y": 147 }, - "id": 42, + "id": 85, "options": { "legend": { "calcs": [ "mean", "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "rate(storage_api_process_cpu_seconds_total{instance=~\"$instance\"}[$interval])", - "interval": "", - "legendFormat": "cpu", + "editorMode": "code", + "expr": "sum(storage_api_v8js_memory_heap_used_bytes)", + "legendFormat": "Heap Used", + "range": true, "refId": "A" - } - ], - "title": "Rate of CPU Time Spent", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 2, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 16, - "y": 76 - }, - "id": 82, - "options": { - "legend": { - "calcs": [ - "lastNotNull", - "max" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.3.3", - "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_process_resident_memory_bytes{instance=~\"$instance\"} / (2*1024*1024*1024)", - "interval": "", - "legendFormat": "resident memory {{instance}}", - "refId": "A" + "editorMode": "code", + "expr": "sum(storage_api_v8js_memory_heap_limit_bytes)", + "legendFormat": "Heap Limit", + "range": true, + "refId": "B" } ], - "title": "Process Memory %", + "title": "V8 Heap Memory", "type": "timeseries" }, { @@ -3363,33 +4726,38 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Garbage collection duration percentiles by GC type (minor/major/incremental). Long GC pauses can cause request latency spikes. Major GC taking >100ms may require heap size tuning or memory optimization.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 1, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -3398,57 +4766,54 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "bytes" + "unit": "s" }, "overrides": [] }, "gridPos": { - "h": 5, + "h": 8, "w": 8, - "x": 0, - "y": 81 + "x": 8, + "y": 147 }, - "id": 124, + "id": 86, "options": { "legend": { "calcs": [ - "lastNotNull", + "mean", "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_process_virtual_memory_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "virtual memory {{instance}}", + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(storage_api_v8js_gc_duration_seconds_bucket[$__rate_interval])) by (le, v8js_gc_type))", + "legendFormat": "p50 {{ v8js_gc_type }}", + "range": true, "refId": "A" }, { @@ -3456,14 +4821,14 @@ "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_process_heap_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "heap memory {{instance}}", + "editorMode": "code", + "expr": "histogram_quantile(0.99, sum(rate(storage_api_v8js_gc_duration_seconds_bucket[$__rate_interval])) by (le, v8js_gc_type))", + "legendFormat": "p99 {{ v8js_gc_type }}", + "range": true, "refId": "B" } ], - "title": "Virtual Memory", + "title": "GC Duration by Type", "type": "timeseries" }, { @@ -3471,33 +4836,38 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Process memory breakdown: RSS (total resident memory), External (C++ objects bound to JS), ArrayBuffers (binary data buffers). High external/arraybuffer memory may indicate large file operations or buffer leaks.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 2, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -3506,17 +4876,13 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, @@ -3525,38 +4891,39 @@ "overrides": [] }, "gridPos": { - "h": 5, + "h": 8, "w": 8, - "x": 8, - "y": 81 + "x": 16, + "y": 147 }, - "id": 127, + "id": 87, "options": { "legend": { "calcs": [ - "lastNotNull", + "mean", "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_process_resident_memory_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "resident memory {{instance}}", + "editorMode": "code", + "expr": "storage_api_nodejs_memory_rss_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "RSS", + "range": true, "refId": "A" }, { @@ -3564,233 +4931,64 @@ "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_process_heap_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "heap memory {{instance}}", + "editorMode": "code", + "expr": "storage_api_nodejs_memory_external_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "External", + "range": true, "refId": "B" - } - ], - "title": "Process Memory", - "type": "timeseries" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 86 - }, - "hiddenSeries": false, - "id": 77, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.0.1", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_process_open_fds{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "{{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Number of Open FDs", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "links": [] }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 86 - }, - "hiddenSeries": false, - "id": 79, - "legend": { - "avg": false, - "current": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.0.1", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "( storage_api_process_open_fds{instance=~\"$instance\"} / storage_api_process_max_fds{instance=~\"$instance\"})", - "interval": "", - "legendFormat": "{{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Used File Descriptors", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false + "editorMode": "code", + "expr": "storage_api_nodejs_memory_array_buffers_bytes{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Array Buffers", + "range": true, + "refId": "C" } ], - "yaxis": { - "align": false - } + "title": "Process Memory (RSS/External)", + "type": "timeseries" }, { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Rate of garbage collection operations per second by GC type. Minor GC is fast and frequent (young generation), Major GC is slower (full heap). High major GC rates may indicate memory pressure.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 4, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -3799,226 +4997,122 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 91 - }, - "id": 66, - "options": { - "legend": { - "calcs": [ - "lastNotNull", - "max" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.3.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_nodejs_active_handles_total{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "Active Handler", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "exemplar": true, - "expr": "storage_api_nodejs_active_requests_total{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "Active Request", - "refId": "B" - } - ], - "title": "Active Handlers/Requests", - "type": "timeseries" - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "refId": "A" - } - ], - "title": "Node.js Process", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 77 - }, - "id": 40, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "fieldConfig": { - "defaults": { - "links": [] + "unit": "ops" }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { - "h": 5, - "w": 12, - "x": 0, - "y": 77 - }, - "hiddenSeries": false, - "id": 43, - "legend": { - "avg": true, - "current": false, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", + "h": 8, + "w": 8, + "x": 8, + "y": 155 + }, + "id": 221, "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.0.1", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "rate(storage_api_nodejs_gc_duration_seconds_sum{instance=~\"$instance\"}[$interval])", - "interval": "", - "legendFormat": "{{kind}}", + "editorMode": "code", + "expr": "sum(rate(storage_api_v8js_gc_duration_seconds_count[$__rate_interval])) by (v8js_gc_type)", + "legendFormat": "{{ v8js_gc_type }}", + "range": true, "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Rate of Garbage Collection Duration", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "label": "", - "logBase": 1, - "show": true }, { - "format": "short", - "logBase": 1, - "show": false + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(storage_api_v8js_gc_duration_seconds_count[$__rate_interval]))", + "legendFormat": "Total", + "range": true, + "refId": "B" } ], - "yaxis": { - "align": false - } - }, + "title": "GC Rate by Type", + "type": "timeseries" + } + ], + "title": "Node.js Runtime (V8 Memory & GC)", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 108 + }, + "id": 88, + "panels": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, + "description": "Rate of CPU time consumption split between user (application code) and system (kernel operations) time. High system CPU may indicate excessive I/O operations or syscall overhead.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 2, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -4027,61 +5121,69 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "short" + "unit": "s" }, "overrides": [] }, "gridPos": { - "h": 5, - "w": 12, - "x": 12, - "y": 77 + "h": 8, + "w": 8, + "x": 0, + "y": 148 }, - "id": 38, + "id": 89, "options": { "legend": { "calcs": [ "mean", "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "rate(storage_api_nodejs_gc_duration_seconds_count{instance=~\"$instance\"}[$interval])", - "interval": "", - "legendFormat": "{{kind}}", + "editorMode": "code", + "expr": "rate(storage_api_process_cpu_user_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "User CPU", + "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "rate(storage_api_process_cpu_system_seconds_total{region=~\"$region\", instance=~\"$instance\"}[$__rate_interval])", + "legendFormat": "System CPU", + "range": true, + "refId": "B" } ], - "title": "Rate of Garbage Collection", + "title": "Process CPU Time (Rate)", "type": "timeseries" }, { @@ -4089,34 +5191,38 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Active libuv handles (timers, sockets, file descriptors) and pending async requests. High handle counts may indicate resource leaks. Sudden spikes correlate with increased load or connection storms.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 1, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { - "log": 2, - "type": "log" + "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -4125,60 +5231,65 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "s" + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 5, - "w": 12, - "x": 0, - "y": 82 + "h": 8, + "w": 8, + "x": 8, + "y": 148 }, - "id": 46, + "id": 90, "options": { "legend": { "calcs": [ - "lastNotNull" + "mean", + "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_nodejs_gc_duration_seconds_sum{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "{{kind}}", + "expr": "storage_api_nodejs_active_handles_total{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Active Handles", "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "expr": "storage_api_nodejs_active_requests_total{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Active Requests", + "refId": "B" } ], - "title": "Garbage Collection Duration", + "title": "Active Handles & Requests", "type": "timeseries" }, { @@ -4186,34 +5297,38 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Time spent in different event loop phases (idle, active, poll). High poll time indicates waiting for I/O. High active time indicates CPU-bound work. Useful for understanding event loop behavior.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 1, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { - "log": 2, - "type": "log" + "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -4222,60 +5337,58 @@ "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "short" + "unit": "s" }, "overrides": [] }, "gridPos": { - "h": 5, - "w": 12, - "x": 12, - "y": 82 + "h": 8, + "w": 8, + "x": 16, + "y": 148 }, - "id": 45, + "id": 91, "options": { "legend": { "calcs": [ - "lastNotNull" + "mean", + "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_nodejs_gc_duration_seconds_count{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "{{kind}}", + "editorMode": "code", + "expr": "rate(storage_api_nodejs_eventloop_time_seconds_total[$__rate_interval])", + "legendFormat": "{{ nodejs_eventloop_state }}", + "range": true, "refId": "A" } ], - "title": "Garbage Collection Count", + "title": "Event Loop Time by State", "type": "timeseries" }, { @@ -4283,122 +5396,107 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Percentage of file descriptors in use (open/max). High values (>80%) may indicate FD exhaustion risk. Monitor for leaks - a steadily increasing value without corresponding traffic increase suggests FD leaks. Only available on Linux.", "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" + "mode": "thresholds" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 5, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { - "mode": "off" + "mode": "line+area" } }, - "links": [], "mappings": [], + "max": 1, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { "color": "green" }, + { + "color": "orange", + "value": 0.7 + }, { "color": "red", - "value": 80 + "value": 0.9 } ] }, - "unit": "bytes" + "unit": "percentunit" }, "overrides": [] }, "gridPos": { - "h": 5, - "w": 12, + "h": 8, + "w": 8, "x": 0, - "y": 87 + "y": 164 }, - "id": 34, + "id": 222, "options": { "legend": { "calcs": [ - "lastNotNull" + "mean", + "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_nodejs_heap_size_total_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "total", + "editorMode": "code", + "expr": "storage_api_process_open_fds{region=~\"$region\", instance=~\"$instance\"} / storage_api_process_max_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "FD Usage", + "range": true, "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "expr": "nodejs_heap_size_used_bytes{instance=~\"$instance\"}", - "legendFormat": "used", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "expr": "process_resident_memory_bytes{instance=~\"$instance\"}", - "legendFormat": "resident", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "expr": "nodejs_external_memory_bytes{instance=~\"$instance\"}", - "legendFormat": "external", - "refId": "D" } ], - "title": "Heap Memory Usage", + "title": "Used File Descriptors", "type": "timeseries" }, { @@ -4406,380 +5504,223 @@ "type": "prometheus", "uid": "local_prometheus" }, + "description": "Number of open file descriptors over time. Useful for tracking FD usage patterns and identifying potential leaks. Compare with max FD limit to assess headroom. Only available on Linux.", "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 2, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", - "spanNulls": true, + "showValues": false, + "spanNulls": false, "stacking": { "group": "A", - "mode": "normal" + "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, - "links": [], "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "red", - "value": 80 + "color": "green", + "value": 0 } ] }, - "unit": "bytes" + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 5, - "w": 12, - "x": 12, - "y": 87 + "h": 8, + "w": 8, + "x": 8, + "y": 164 }, - "id": 36, + "id": 223, "options": { "legend": { "calcs": [ - "lastNotNull" + "mean", + "max" ], - "displayMode": "list", + "displayMode": "table", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", - "sort": "none" + "hideZeros": false, + "mode": "multi", + "sort": "desc" } }, - "pluginVersion": "8.3.3", + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "exemplar": true, - "expr": "storage_api_nodejs_heap_space_size_used_bytes{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "{{space}}", + "editorMode": "code", + "expr": "storage_api_process_open_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Open FDs", + "range": true, "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "local_prometheus" + }, + "editorMode": "code", + "expr": "storage_api_process_max_fds{region=~\"$region\", instance=~\"$instance\"}", + "legendFormat": "Max FDs", + "range": true, + "refId": "B" } ], - "title": "Heap Space Used", + "title": "Open File Descriptors", "type": "timeseries" } ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "refId": "A" - } - ], - "title": "Node.js Garbage Collection", + "title": "Node.js Runtime (Process)", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 109 + }, + "id": 70, + "panels": [], + "title": "Node.js Runtime (Host Metrics)", "type": "row" } ], + "preload": false, "refresh": "5s", - "schemaVersion": 39, + "schemaVersion": 42, "tags": [ - "node.js", - "express", - "prometheus" + "storage", + "otel", + "api" ], "templating": { "list": [ { "current": { - "selected": true, "text": [ - "All" + "local" ], "value": [ - "$__all" + "local" ] }, "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "definition": "label_values(storage_api_nodejs_version_info, instance)", - "hide": 0, + "definition": "label_values(storage_api_process_start_time_seconds,region)", "includeAll": true, - "label": "instance", "multi": true, - "name": "instance", + "name": "region", "options": [], "query": { - "query": "label_values(storage_api_nodejs_version_info, instance)", - "refId": "StandardVariableQuery" + "qryType": 1, + "query": "label_values(storage_api_process_start_time_seconds,region)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, "regex": "", - "skipUrlSync": false, "sort": 1, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "selected": false, - "text": "1m", - "value": "1m" - }, - "hide": 2, - "name": "interval", - "options": [ - { - "selected": true, - "text": "1m", - "value": "1m" - }, - { - "selected": false, - "text": "10m", - "value": "10m" - }, - { - "selected": false, - "text": "30m", - "value": "30m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - }, - { - "selected": false, - "text": "6h", - "value": "6h" - }, - { - "selected": false, - "text": "12h", - "value": "12h" - }, - { - "selected": false, - "text": "1d", - "value": "1d" - }, - { - "selected": false, - "text": "7d", - "value": "7d" - }, - { - "selected": false, - "text": "14d", - "value": "14d" - }, - { - "selected": false, - "text": "30d", - "value": "30d" - } - ], - "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", - "refresh": 2, - "skipUrlSync": false, - "type": "interval" - }, - { - "current": { - "isNone": true, - "selected": false, - "text": "None", - "value": "" - }, - "datasource": { - "type": "prometheus", - "uid": "local_prometheus" - }, - "definition": "label_values(storage_api_http_request_duration_seconds_bucket, le)", - "hide": 2, - "includeAll": false, - "multi": false, - "name": "target", - "options": [], - "query": { - "query": "label_values(storage_api_http_request_duration_seconds_bucket, le)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 3, "type": "query" }, { + "allValue": ".*", "current": { - "isNone": true, - "selected": false, - "text": "None", - "value": "" + "text": [ + "All" + ], + "value": [ + "$__all" + ] }, "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "definition": "label_values(storage_api_http_request_duration_seconds_bucket, le)", - "hide": 2, - "includeAll": false, - "multi": false, - "name": "tolerated", + "definition": "label_values(storage_api_process_start_time_seconds,instance)", + "includeAll": true, + "multi": true, + "name": "instance", "options": [], "query": { - "query": "label_values(storage_api_http_request_duration_seconds_bucket, le)", - "refId": "StandardVariableQuery" + "qryType": 1, + "query": "label_values(storage_api_process_start_time_seconds,instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" }, - "refresh": 1, + "refresh": 2, "regex": "", - "skipUrlSync": false, - "sort": 3, + "sort": 1, "type": "query" }, - { - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "selected": false, - "text": "1d", - "value": "1d" - }, - "hide": 2, - "name": "restarts_interval", - "options": [ - { - "selected": true, - "text": "1d", - "value": "1d" - }, - { - "selected": false, - "text": "7d", - "value": "7d" - }, - { - "selected": false, - "text": "14d", - "value": "14d" - }, - { - "selected": false, - "text": "30d", - "value": "30d" - } - ], - "query": "1d,7d,14d,30d", - "queryValue": "", - "refresh": 2, - "skipUrlSync": false, - "type": "interval" - }, { "current": { - "selected": true, "text": [ - "All" + "storage-single-tenant" ], "value": [ - "$__all" + "storage-single-tenant" ] }, "datasource": { "type": "prometheus", "uid": "local_prometheus" }, - "definition": "label_values(storage_api_http_request_duration_seconds_count, tenant_id)", - "hide": 0, + "definition": "label_values(storage_api_http_request_duration_seconds_count,tenantId)", "includeAll": true, "multi": true, - "name": "tenant_id", + "name": "tenant", "options": [], "query": { - "query": "label_values(storage_api_http_request_duration_seconds_count, tenant_id)", - "refId": "StandardVariableQuery" + "qryType": 1, + "query": "label_values(storage_api_http_request_duration_seconds_count,tenantId)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, "regex": "", - "skipUrlSync": false, - "sort": 0, + "sort": 1, "type": "query" - }, - { - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "hide": 0, - "includeAll": true, - "multi": true, - "name": "error_codes", - "options": [ - { - "selected": true, - "text": "All", - "value": "$__all" - }, - { - "selected": false, - "text": "5xx", - "value": "5xx" - }, - { - "selected": false, - "text": "4xx", - "value": "4xx" - } - ], - "query": "5xx,4xx", - "queryValue": "", - "skipUrlSync": false, - "type": "custom" } ] }, @@ -4787,23 +5728,9 @@ "from": "now-5m", "to": "now" }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Supabase Storage Dashboard", - "uid": "3J_78b6Zz", - "version": 1, - "weekStart": "" + "timepicker": {}, + "timezone": "browser", + "title": "Storage API - OTel Metrics", + "uid": "storage-otel-metrics", + "version": 1 } \ No newline at end of file diff --git a/monitoring/otel/config/otel-collector-config.yml b/monitoring/otel/config/otel-collector-config.yml index 0dd1e19e3..a2038f7f9 100644 --- a/monitoring/otel/config/otel-collector-config.yml +++ b/monitoring/otel/config/otel-collector-config.yml @@ -9,9 +9,41 @@ processors: check_interval: 1s limit_percentage: 70 spike_limit_percentage: 20 - batch: + batch/traces: send_batch_size: 10000 timeout: 10s + batch/metrics: + send_batch_size: 10000 + timeout: 10s + # Copy region and instance from Resource attributes to metric data point attributes + # This ensures all metrics have the region and instance labels + transform/add_resource_attributes: + metric_statements: + - context: datapoint + statements: + - set(attributes["region"], resource.attributes["region"]) where resource.attributes["region"] != nil + - set(attributes["instance"], resource.attributes["instance"]) where resource.attributes["instance"] != nil + # Add storage_api_otel_ prefix to all metrics + # Note: storage_api_ transform must be FIRST to avoid double prefix + metricstransform/host: + transforms: + - include: ^storage_api_(.*)$$ + match_type: regexp + action: update + new_name: $${1} + # Catch-all: prefix any metric not already prefixed with storage_api_otel_ + - include: ^(.*)$$ + match_type: regexp + action: update + new_name: storage_api_otel_$${1} + + metricstransform/prom_prefix: + transforms: + - include: ^(.*)$$ + match_type: regexp + action: update + new_name: storage_api_$${1} + tail_sampling/storage: decision_wait: 10s expected_new_traces_per_sec: 10000 @@ -155,7 +187,7 @@ processors: { name: success-status-codes, type: numeric_attribute, - numeric_attribute: { key: http.status_code, min_value: 200, max_value: 399 } + numeric_attribute: { key: http.status_code, min_value: 200, max_value: 400 } }, { name: full-sampling, @@ -174,10 +206,22 @@ exporters: endpoint: "jaeger:4317" tls: insecure: true + prometheus: + endpoint: "0.0.0.0:9200" + prometheusremotewrite: + endpoint: "http://prometheus:9090/api/v1/write" service: pipelines: traces: receivers: [otlp] - processors: [memory_limiter, tail_sampling/storage, batch] - exporters: [otlp/jaeger] \ No newline at end of file + processors: [memory_limiter, tail_sampling/storage, batch/traces] + exporters: [otlp/jaeger] + metrics/otel: + receivers: [otlp] + processors: [memory_limiter, transform/add_resource_attributes, metricstransform/host, batch/metrics] + exporters: [prometheusremotewrite] + metrics/prometheus: + receivers: [otlp] + processors: [memory_limiter, transform/add_resource_attributes, metricstransform/prom_prefix, batch/metrics] + exporters: [prometheus] \ No newline at end of file diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index a03a205b4..ef7eb80a0 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -8,7 +8,7 @@ alerting: - targets: [] scheme: http timeout: 15s - api_version: v1 + api_version: v2 scrape_configs: - job_name: storage_api honor_timestamps: true @@ -20,7 +20,7 @@ scrape_configs: - targets: # - storage:5000 # - storage:5001 - - host.docker.internal:5001 + - otel:9200 - job_name: 'postgres' static_configs: diff --git a/package-lock.json b/package-lock.json index 778efae7b..e1ae198dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,12 +22,18 @@ "@isaacs/ttlcache": "^1.4.1", "@kubernetes/client-node": "^1.3.0", "@opentelemetry/api": "^1.8.0", - "@opentelemetry/auto-instrumentations-node": "^0.50.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", + "@opentelemetry/auto-instrumentations-node": "^0.67.3", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.208.0", + "@opentelemetry/exporter-prometheus": "^0.208.0", + "@opentelemetry/host-metrics": "^0.38.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.56.0", + "@opentelemetry/instrumentation-fastify": "^0.50.0", + "@opentelemetry/instrumentation-http": "^0.208.0", + "@opentelemetry/instrumentation-knex": "^0.53.0", + "@opentelemetry/instrumentation-pg": "^0.55.0", + "@opentelemetry/instrumentation-runtime-node": "^0.22.0", + "@opentelemetry/sdk-metrics": "^2.2.0", + "@opentelemetry/sdk-node": "^0.208.0", "@shopify/semaphore": "^3.0.2", "@smithy/node-http-handler": "^2.3.1", "@tus/file-store": "2.0.0", @@ -44,7 +50,6 @@ "crypto-js": "^4.2.0", "dotenv": "^16.0.0", "fastify": "^4.28.1", - "fastify-metrics": "^10.2.0", "fastify-plugin": "^4.5.1", "fastify-xml-body-parser": "^2.2.0", "fs-extra": "^10.0.1", @@ -65,7 +70,6 @@ "pino": "^9.7.0", "pino-logflare": "^0.5.2", "postgres-migrations": "^5.3.0", - "prom-client": "^14.0.1", "xml2js": "^0.6.2" }, "bin": { @@ -8288,1195 +8292,1579 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "engines": { "node": ">=8.0.0" } }, "node_modules/@opentelemetry/api-logs": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz", - "integrity": "sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz", + "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==", "dependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": ">=14" + "node": ">=8.0.0" } }, "node_modules/@opentelemetry/auto-instrumentations-node": { - "version": "0.50.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.50.0.tgz", - "integrity": "sha512-LqoSiWrOM4Cnr395frDHL4R/o5c2fuqqrqW8sZwhxvkasImmVlyL66YMPHllM2O5xVj2nP2ANUKHZSd293meZA==", - "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/instrumentation-amqplib": "^0.42.0", - "@opentelemetry/instrumentation-aws-lambda": "^0.44.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-bunyan": "^0.41.0", - "@opentelemetry/instrumentation-cassandra-driver": "^0.41.0", - "@opentelemetry/instrumentation-connect": "^0.39.0", - "@opentelemetry/instrumentation-cucumber": "^0.9.0", - "@opentelemetry/instrumentation-dataloader": "^0.12.0", - "@opentelemetry/instrumentation-dns": "^0.39.0", - "@opentelemetry/instrumentation-express": "^0.42.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-fs": "^0.15.0", - "@opentelemetry/instrumentation-generic-pool": "^0.39.0", - "@opentelemetry/instrumentation-graphql": "^0.43.0", - "@opentelemetry/instrumentation-grpc": "^0.53.0", - "@opentelemetry/instrumentation-hapi": "^0.41.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-ioredis": "^0.43.0", - "@opentelemetry/instrumentation-kafkajs": "^0.3.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-koa": "^0.43.0", - "@opentelemetry/instrumentation-lru-memoizer": "^0.40.0", - "@opentelemetry/instrumentation-memcached": "^0.39.0", - "@opentelemetry/instrumentation-mongodb": "^0.47.0", - "@opentelemetry/instrumentation-mongoose": "^0.42.0", - "@opentelemetry/instrumentation-mysql": "^0.41.0", - "@opentelemetry/instrumentation-mysql2": "^0.41.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.40.0", - "@opentelemetry/instrumentation-net": "^0.39.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", - "@opentelemetry/instrumentation-pino": "^0.42.0", - "@opentelemetry/instrumentation-redis": "^0.42.0", - "@opentelemetry/instrumentation-redis-4": "^0.42.0", - "@opentelemetry/instrumentation-restify": "^0.41.0", - "@opentelemetry/instrumentation-router": "^0.40.0", - "@opentelemetry/instrumentation-socket.io": "^0.42.0", - "@opentelemetry/instrumentation-tedious": "^0.14.0", - "@opentelemetry/instrumentation-undici": "^0.6.0", - "@opentelemetry/instrumentation-winston": "^0.40.0", - "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.1", - "@opentelemetry/resource-detector-aws": "^1.6.1", - "@opentelemetry/resource-detector-azure": "^0.2.11", - "@opentelemetry/resource-detector-container": "^0.4.1", - "@opentelemetry/resource-detector-gcp": "^0.29.11", - "@opentelemetry/resources": "^1.24.0", - "@opentelemetry/sdk-node": "^0.53.0" + "version": "0.67.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.67.3.tgz", + "integrity": "sha512-sRzw/T1JU7CCATGxnnKhHbWMlwMH1qO62+4/znfsJTg24ATP5qNKFkt8B/JD7HAQ/0ceMeyQin9KOBnjkLkCvA==", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/instrumentation-amqplib": "^0.56.0", + "@opentelemetry/instrumentation-aws-lambda": "^0.61.1", + "@opentelemetry/instrumentation-aws-sdk": "^0.64.1", + "@opentelemetry/instrumentation-bunyan": "^0.54.0", + "@opentelemetry/instrumentation-cassandra-driver": "^0.54.1", + "@opentelemetry/instrumentation-connect": "^0.52.0", + "@opentelemetry/instrumentation-cucumber": "^0.24.0", + "@opentelemetry/instrumentation-dataloader": "^0.26.1", + "@opentelemetry/instrumentation-dns": "^0.52.0", + "@opentelemetry/instrumentation-express": "^0.57.1", + "@opentelemetry/instrumentation-fastify": "^0.53.1", + "@opentelemetry/instrumentation-fs": "^0.28.0", + "@opentelemetry/instrumentation-generic-pool": "^0.52.0", + "@opentelemetry/instrumentation-graphql": "^0.56.0", + "@opentelemetry/instrumentation-grpc": "^0.208.0", + "@opentelemetry/instrumentation-hapi": "^0.55.1", + "@opentelemetry/instrumentation-http": "^0.208.0", + "@opentelemetry/instrumentation-ioredis": "^0.57.0", + "@opentelemetry/instrumentation-kafkajs": "^0.18.1", + "@opentelemetry/instrumentation-knex": "^0.53.1", + "@opentelemetry/instrumentation-koa": "^0.57.1", + "@opentelemetry/instrumentation-lru-memoizer": "^0.53.1", + "@opentelemetry/instrumentation-memcached": "^0.52.1", + "@opentelemetry/instrumentation-mongodb": "^0.62.0", + "@opentelemetry/instrumentation-mongoose": "^0.55.1", + "@opentelemetry/instrumentation-mysql": "^0.55.0", + "@opentelemetry/instrumentation-mysql2": "^0.55.1", + "@opentelemetry/instrumentation-nestjs-core": "^0.55.0", + "@opentelemetry/instrumentation-net": "^0.53.0", + "@opentelemetry/instrumentation-openai": "^0.7.1", + "@opentelemetry/instrumentation-oracledb": "^0.34.1", + "@opentelemetry/instrumentation-pg": "^0.61.2", + "@opentelemetry/instrumentation-pino": "^0.55.1", + "@opentelemetry/instrumentation-redis": "^0.57.2", + "@opentelemetry/instrumentation-restify": "^0.54.0", + "@opentelemetry/instrumentation-router": "^0.53.0", + "@opentelemetry/instrumentation-runtime-node": "^0.22.0", + "@opentelemetry/instrumentation-socket.io": "^0.55.1", + "@opentelemetry/instrumentation-tedious": "^0.28.0", + "@opentelemetry/instrumentation-undici": "^0.19.0", + "@opentelemetry/instrumentation-winston": "^0.53.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.32.0", + "@opentelemetry/resource-detector-aws": "^2.9.0", + "@opentelemetry/resource-detector-azure": "^0.17.0", + "@opentelemetry/resource-detector-container": "^0.8.0", + "@opentelemetry/resource-detector-gcp": "^0.44.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-node": "^0.208.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^2.0.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/instrumentation-aws-sdk": { + "version": "0.64.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.64.1.tgz", + "integrity": "sha512-A8joPAuHwvwrkG5UpH7OYhzkeYznNBiG3o1TKoZ7yvyXU/q4CNxnZ7vzZBEpt9OocptCe6X/YyBENFSa0axqiw==", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/instrumentation-fastify": { + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.53.1.tgz", + "integrity": "sha512-tTa84J9rcrl4iTHdJDwirrNbM4prgJH+MF0iMlVLu++6gZg8TTfmYYqDiKPWBgdXB4M+bnlCkvgag36uV34uwA==", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.4.1" + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.53.1.tgz", + "integrity": "sha512-tIW3gqVC8d9CCE+oxPO63WNvC+5PKC/LrPrYWFobii5afUpHJV+0pfyt08okAFBHztzT0voMOEPGkLKoacZRXQ==", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.61.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.61.2.tgz", + "integrity": "sha512-l1tN4dX8Ig1bKzMu81Q1EBXWFRy9wqchXbeHDRniJsXYND5dC8u1Uhah7wz1zZta3fbBWflP2mJZcDPWNsAMRg==", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/context-async-hooks": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.26.0.tgz", - "integrity": "sha512-HedpXXYzzbaoutw6DFLWLDket2FwLkLpil4hGCZ1xYEIMTcivdfwEOISgdbLEWyG3HW52gTq2V9mOVJrONgiwg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz", + "integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==", "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/core": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.26.0.tgz", - "integrity": "sha512-1iKxXXE8415Cdv0yjG3G6hQnB5eVEsJce3QaawX8SjDn0mAS0ZM8fAbZZJD4ajvhC15cePvosSCut404KrIIvQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/exporter-logs-otlp-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.53.0.tgz", - "integrity": "sha512-x5ygAQgWAQOI+UOhyV3z9eW7QU2dCfnfOuIBiyYmC2AWr74f6x/3JBnP27IAcEx6aihpqBYWKnpoUTztkVPAZw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-AmZDKFzbq/idME/yq68M155CJW1y056MNBekH9OZewiZKaqgwYN4VYfn3mXVPftYsfrCM2r4V6tS8H2LmfiDCg==", "dependencies": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/sdk-logs": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/sdk-logs": "0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-logs-otlp-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.53.0.tgz", - "integrity": "sha512-cSRKgD/n8rb+Yd+Cif6EnHEL/VZg1o8lEcEwFji1lwene6BdH51Zh3feAD9p2TyVoBKrl6Q9Zm2WltSp2k9gWQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.208.0.tgz", + "integrity": "sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==", "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/sdk-logs": "0.53.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/sdk-logs": "0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-logs-otlp-proto": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.53.0.tgz", - "integrity": "sha512-jhEcVL1deeWNmTUP05UZMriZPSWUBcfg94ng7JuBb1q2NExgnADQFl1VQQ+xo62/JepK+MxQe4xAwlsDQFbISA==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.208.0.tgz", + "integrity": "sha512-Wy8dZm16AOfM7yddEzSFzutHZDZ6HspKUODSUJVjyhnZFMBojWDjSNgduyCMlw6qaxJYz0dlb0OEcb4Eme+BfQ==", "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-trace-base": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-YbEnk7jjYmvhIwp2xJGkEvdgnayrA2QSr28R1LR1klDPvCxsoQPxE6TokDbQpoCEhD3+KmJVEXfb4EeEQxjymg==", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.208.0.tgz", + "integrity": "sha512-QZ3TrI90Y0i1ezWQdvreryjY0a5TK4J9gyDLIyhLBwV+EQUvyp5wR7TFPKCAexD4TDSWM0t3ulQDbYYjVtzTyA==", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.208.0.tgz", + "integrity": "sha512-CvvVD5kRDmRB/uSMalvEF6kiamY02pB46YAqclHtfjJccNZFxbkkXkMMmcJ7NgBFa5THmQBNVQ2AHyX29nRxOw==", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.208.0.tgz", + "integrity": "sha512-Rgws8GfIfq2iNWCD3G1dTD9xwYsCof1+tc5S5X0Ahdb5CrAPE+k5P70XCWHqrFFurVCcKaHLJ/6DjIBHWVfLiw==", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.53.0.tgz", - "integrity": "sha512-m6KSh6OBDwfDjpzPVbuJbMgMbkoZfpxYH2r262KckgX9cMYvooWXEKzlJYsNDC6ADr28A1rtRoUVRwNfIN4tUg==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-E/eNdcqVUTAT7BC+e8VOw/krqb+5rjzYkztMZ/o+eyJl+iEY6PfczPXpwWuICwvsm0SIhBoh9hmYED5Vh5RwIw==", "dependencies": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-trace-otlp-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.53.0.tgz", - "integrity": "sha512-m7F5ZTq+V9mKGWYpX8EnZ7NjoqAU7VemQ1E2HAG+W/u0wpY1x0OmbxAXfGKFHCspdJk8UKlwPGrpcB8nay3P8A==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.208.0.tgz", + "integrity": "sha512-jbzDw1q+BkwKFq9yxhjAJ9rjKldbt5AgIy1gmEIJjEV/WRxQ3B6HcLVkwbjJ3RcMif86BDNKR846KJ0tY0aOJA==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-trace-otlp-proto": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.53.0.tgz", - "integrity": "sha512-T/bdXslwRKj23S96qbvGtaYOdfyew3TjPEKOk5mHjkCmkVl1O9C/YMdejwSsdLdOq2YW30KjR9kVi0YMxZushQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.208.0.tgz", + "integrity": "sha512-q844Jc3ApkZVdWYd5OAl+an3n1XXf3RWHa3Zgmnhw3HpsM3VluEKHckUUEqHPzbwDUx2lhPRVkqK7LsJ/CbDzA==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/exporter-zipkin": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.26.0.tgz", - "integrity": "sha512-PW5R34n3SJHO4t0UetyHKiXL6LixIqWN6lWncg3eRXhKuT30x+b7m5sDJS0kEWRfHeS+kG7uCw2vBzmB2lk3Dw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.2.0.tgz", + "integrity": "sha512-VV4QzhGCT7cWrGasBWxelBjqbNBbyHicWWS/66KoZoe9BzYwFB72SH2/kkc4uAviQlO8iwv2okIJy+/jqqEHTg==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, + "node_modules/@opentelemetry/host-metrics": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/host-metrics/-/host-metrics-0.38.0.tgz", + "integrity": "sha512-5iiVhDLa3siMiq95P9/VUtwwNR4mv5/2q79iwMXDbw2if+kRsTGQhSQTClN+POpXeZIEFDlHl/R2TTZ1XWCdkA==", + "dependencies": { + "systeminformation": "5.23.8" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.53.0.tgz", - "integrity": "sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", + "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@types/shimmer": "^1.2.0", - "import-in-the-middle": "^1.8.1", - "require-in-the-middle": "^7.1.1", - "semver": "^7.5.2", - "shimmer": "^1.2.1" + "@opentelemetry/api-logs": "0.208.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-amqplib": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.42.0.tgz", - "integrity": "sha512-fiuU6OKsqHJiydHWgTRQ7MnIrJ2lEqsdgFtNIH4LbAUJl/5XmrIeoDzDnox+hfkgWK65jsleFuQDtYb5hW1koQ==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.56.0.tgz", + "integrity": "sha512-/orV2zO2K7iGa1TR6lbs170LNNDbeTC6E3JF1EeB+okJ3rB5tl1gHFSjoqEDkQYFprNs5CPitqU8Y4l4S2Pkmg==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-aws-lambda": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.44.0.tgz", - "integrity": "sha512-6vmr7FJIuopZzsQjEQTp4xWtF6kBp7DhD7pPIN8FN0dKUKyuVraABIpgWjMfelaUPy4rTYUGkYqPluhG0wx8Dw==", + "version": "0.61.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.61.1.tgz", + "integrity": "sha512-leISmqN7/KSCYAKEVOAnQ0NUCa3rigB7ShCVLnYrHr6+7CXPef7C+nvowElMcYTid8egiHKgApR/FaNdlBda3A==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/propagator-aws-xray": "^1.3.1", - "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/aws-lambda": "8.10.143" + "@types/aws-lambda": "^8.10.155" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-aws-sdk": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.44.0.tgz", - "integrity": "sha512-HIWFg4TDQsayceiikOnruMmyQ0SZYW6WiR+wknWwWVLHC3lHTCpAnqzp5V42ckArOdlwHZu2Jvq2GMSM4Myx3w==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.56.0.tgz", + "integrity": "sha512-Jl2B/FYEb6tBCk9G31CMomKPikGU2g+CEhrGddDI0o1YeNpg3kAO9dExF+w489/IJUGZX6/wudyNvV7z4k9NjQ==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/propagation-utils": "^0.30.11", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/propagation-utils": "^0.31.3", + "@opentelemetry/semantic-conventions": "^1.34.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation-bunyan": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.41.0.tgz", - "integrity": "sha512-NoQS+gcwQ7pzb2PZFyra6bAxDAVXBMmpKxBblEuXJWirGrAksQllg9XTdmqhrwT/KxUYrbVca/lMams7e51ysg==", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.54.0.tgz", + "integrity": "sha512-DnPoHSLcKwQmueW+7OOaXFD/cj1M6hqwTm6P88QdMbln/dqEatLxzt/ACPk4Yb5x4aU3ZLyeLyKxtzfhp76+aw==", "dependencies": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@types/bunyan": "1.8.9" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@types/bunyan": "1.8.11" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-cassandra-driver": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.41.0.tgz", - "integrity": "sha512-hvTNcC8qjCQEHZTLAlTmDptjsEGqCKpN+90hHH8Nn/GwilGr5TMSwGrlfstdJuZWyw8HAnRUed6bcjvmHHk2Xw==", + "version": "0.54.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.54.1.tgz", + "integrity": "sha512-wVGI4YrWmaNNtNjg84KTl8sHebG7jm3PHvmZxPl2V/aSskAyQMSxgJZpnv1dmBmJuISc+a8H8daporljbscCcQ==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-connect": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.39.0.tgz", - "integrity": "sha512-pGBiKevLq7NNglMgqzmeKczF4XQMTOUOTkK8afRHMZMnrK3fcETyTH7lVaSozwiOM3Ws+SuEmXZT7DYrrhxGlg==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.52.0.tgz", + "integrity": "sha512-GXPxfNB5szMbV3I9b7kNWSmQBoBzw7MT0ui6iU/p+NIzVx3a06Ri2cdQO7tG9EKb4aKSLmfX9Cw5cKxXqX6Ohg==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/connect": "3.4.36" + "@types/connect": "3.4.38" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-cucumber": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.9.0.tgz", - "integrity": "sha512-4PQNFnIqnA2WM3ZHpr0xhZpHSqJ5xJ6ppTIzZC7wPqe+ZBpj41vG8B6ieqiPfq+im4QdqbYnzLb3rj48GDEN9g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.24.0.tgz", + "integrity": "sha512-ICHrmax9PwU/Z+fehD0uIjM8W0cEvdToglV1+o76Mgw51HZBVp2Y3mkga1qMPIN5tPMoWUYoYtI4U85rea5HYg==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/instrumentation-dataloader": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.12.0.tgz", - "integrity": "sha512-pnPxatoFE0OXIZDQhL2okF//dmbiWFzcSc8pUg9TqofCLYZySSxDCgQc69CJBo5JnI3Gz1KP+mOjS4WAeRIH4g==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.26.1.tgz", + "integrity": "sha512-S2JAM6lV16tMravuPLd3tJCC6ySb5a//5KgJeXutbTVb/UbSTXcnHSdEtMaAvE2KbazVWyWzcoytLRy6AUOwsw==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-dns": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.39.0.tgz", - "integrity": "sha512-+iPzvXqVdJa67QBuz2tuP0UI3LS1/cMMo6dS7360DDtOQX+sQzkiN+mo3Omn4T6ZRhkTDw6c7uwsHBcmL31+1g==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.52.0.tgz", + "integrity": "sha512-XJvS8PkZec+X6HhOi1xldJydTpmIUAW14+1vyqwAK97LWKXlxmiWst8/fjZ709+CHgshz8i5V37yCHlr6o3pxw==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "semver": "^7.5.4" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-express": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.42.0.tgz", - "integrity": "sha512-YNcy7ZfGnLsVEqGXQPT+S0G1AE46N21ORY7i7yUQyfhGAL4RBjnZUqefMI0NwqIl6nGbr1IpF0rZGoN8Q7x12Q==", + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.57.1.tgz", + "integrity": "sha512-r+ulPbvgG8rGgFFWbJWJpTh7nMzsEYH7rBFNWdFs7ZfVAtgpFijMkRtU7DecIo6ItF8Op+RxogSuk/083W8HKw==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-fastify": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.39.0.tgz", - "integrity": "sha512-SS9uSlKcsWZabhBp2szErkeuuBDgxOUlllwkS92dVaWRnMmwysPhcEgHKB8rUe3BHg/GnZC1eo1hbTZv4YhfoA==", + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.50.0.tgz", + "integrity": "sha512-j30yphIxdt6Wm8dgUoRORSORxlcFX2IxCLV6QZ9G5HtvvMIEP0hA0UnhJ3CDrDHKJRSHCiW8E8piOSbtU+0MLA==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.205.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/api-logs": { + "version": "0.205.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.205.0.tgz", + "integrity": "sha512-wBlPk1nFB37Hsm+3Qy73yQSobVn28F4isnWIBvKpd5IUH/eat8bwcL02H9yzmHyyPmukeccSl2mbN5sDQZYnPg==", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/instrumentation": { + "version": "0.205.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.205.0.tgz", + "integrity": "sha512-cgvm7tvQdu9Qo7VurJP84wJ7ZV9F6WqDDGZpUc6rUEXwjV7/bXWs0kaYp9v+1Vh1+3TZCD3i6j/lUBcPhu8NhA==", + "dependencies": { + "@opentelemetry/api-logs": "0.205.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@opentelemetry/instrumentation-fastify/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation-fs": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.15.0.tgz", - "integrity": "sha512-JWVKdNLpu1skqZQA//jKOcKdJC66TWKqa2FUFq70rKohvaSq47pmXlnabNO+B/BvLfmidfiaN35XakT5RyMl2Q==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.28.0.tgz", + "integrity": "sha512-FFvg8fq53RRXVBRHZViP+EMxMR03tqzEGpuq55lHNbVPyFklSVfQBN50syPhK5UYYwaStx0eyCtHtbRreusc5g==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-generic-pool": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.39.0.tgz", - "integrity": "sha512-y4v8Y+tSfRB3NNBvHjbjrn7rX/7sdARG7FuK6zR8PGb28CTa0kHpEGCJqvL9L8xkTNvTXo+lM36ajFGUaK1aNw==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.52.0.tgz", + "integrity": "sha512-ISkNcv5CM2IwvsMVL31Tl61/p2Zm2I2NAsYq5SSBgOsOndT0TjnptjufYVScCnD5ZLD1tpl4T3GEYULLYOdIdQ==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-graphql": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.43.0.tgz", - "integrity": "sha512-aI3YMmC2McGd8KW5du1a2gBA0iOMOGLqg4s9YjzwbjFwjlmMNFSK1P3AIg374GWg823RPUGfVTIgZ/juk9CVOA==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.56.0.tgz", + "integrity": "sha512-IPvNk8AFoVzTAM0Z399t34VDmGDgwT6rIqCUug8P9oAGerl2/PEIYMPOl/rerPGu+q8gSWdmbFSjgg7PDVRd3Q==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.53.0.tgz", - "integrity": "sha512-Ss338T92yE1UCgr9zXSY3cPuaAy27uQw+wAC5IwsQKCXL5wwkiOgkd+2Ngksa9EGsgUEMwGeHi76bDdHFJ5Rrw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.208.0.tgz", + "integrity": "sha512-8hFEQRAiOyIWO6LYj7tUfdAgNCuQUdYjLYMItRYlOLGJhshGdGYD7aeNzt2H+HPMDEWnKWqldIHfLTqM7ep7gg==", "dependencies": { - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-hapi": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.41.0.tgz", - "integrity": "sha512-jKDrxPNXDByPlYcMdZjNPYCvw0SQJjN+B1A+QH+sx+sAHsKSAf9hwFiJSrI6C4XdOls43V/f/fkp9ITkHhKFbQ==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.55.1.tgz", + "integrity": "sha512-Pm1HCHnnijUOGXd+nyJp96CfU8Lb6XdT6H6YvvmXO/NHMb6tV+EjzDRBr9sZ/XQjka9zLCz7jR0js7ut0IJAyg==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.53.0.tgz", - "integrity": "sha512-H74ErMeDuZfj7KgYCTOFGWF5W9AfaPnqLQQxeFq85+D29wwV2yqHbz2IKLYpkOh7EI6QwDEl7rZCIxjJLyc/CQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.208.0.tgz", + "integrity": "sha512-rhmK46DRWEbQQB77RxmVXGyjs6783crXCnFjYQj+4tDH/Kpv9Rbg3h2kaNyp5Vz2emF1f9HOQQvZoHzwMWOFZQ==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/semantic-conventions": "1.27.0", - "semver": "^7.5.2" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-ioredis": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.43.0.tgz", - "integrity": "sha512-i3Dke/LdhZbiUAEImmRG3i7Dimm/BD7t8pDDzwepSvIQ6s2X6FPia7561gw+64w+nx0+G9X14D7rEfaMEmmjig==", + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.57.0.tgz", + "integrity": "sha512-o/PYGPbfFbS0Sq8EEQC8YUgDMiTGvwoMejPjV2d466yJoii+BUpffGejVQN0hC5V5/GT29m1B1jL+3yruNxwDw==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-kafkajs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.3.0.tgz", - "integrity": "sha512-UnkZueYK1ise8FXQeKlpBd7YYUtC7mM8J0wzUSccEfc/G8UqHQqAzIyYCUOUPUKp8GsjLnWOOK/3hJc4owb7Jg==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.18.1.tgz", + "integrity": "sha512-qM9hk7BIsVWqWJsrCa1fAEcEfutVvwhHO9kk4vpwaTGYR+lPWRk2r5+nEPcM+sIiYBmQNJCef5tEjQpKxTpP0A==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.30.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-knex": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.40.0.tgz", - "integrity": "sha512-6jka2jfX8+fqjEbCn6hKWHVWe++mHrIkLQtaJqUkBt3ZBs2xn1+y0khxiDS0v/mNb0bIKDJWwtpKFfsQDM1Geg==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.53.0.tgz", + "integrity": "sha512-xngn5cH2mVXFmiT1XfQ1aHqq1m4xb5wvU6j9lSgLlihJ1bXzsO543cpDwjrZm2nMrlpddBf55w8+bfS4qDh60g==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.1" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-koa": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.43.0.tgz", - "integrity": "sha512-lDAhSnmoTIN6ELKmLJBplXzT/Jqs5jGZehuG22EdSMaTwgjMpxMDI1YtlKEhiWPWkrz5LUsd0aOO0ZRc9vn3AQ==", + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.57.1.tgz", + "integrity": "sha512-XPjdzgXvMG3YSZvsSgOj0Je0fsmlaBYIFFGJqUn1HRpbrVjdpP45eXI+6yUp48J8N5Qss32WDD5f+2tmV7Xvsg==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.36.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "@opentelemetry/api": "^1.9.0" } }, "node_modules/@opentelemetry/instrumentation-lru-memoizer": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.40.0.tgz", - "integrity": "sha512-21xRwZsEdMPnROu/QsaOIODmzw59IYpGFmuC4aFWvMj6stA8+Ei1tX67nkarJttlNjoM94um0N4X26AD7ff54A==", + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.53.1.tgz", + "integrity": "sha512-L93bPJKFzrObD4FvKpsavYEFTzXFKMmAeRHz7J4lUFc7TPZLouxX3PYW1+YGr/bT1y24H9NLNX66l7BW1s75QA==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-memcached": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.39.0.tgz", - "integrity": "sha512-WfwvKAZ9I1qILRP5EUd88HQjwAAL+trXpCpozjBi4U6a0A07gB3fZ5PFAxbXemSjF5tHk9KVoROnqHvQ+zzFSQ==", + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.52.1.tgz", + "integrity": "sha512-qg92SyWAypSZmX3Lhm2wz4BsovKarkWg9OHm4DPW6fGzmk40eB5voQIuctrBAfsml6gr+vbg4VEBcC1AKRvzzQ==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", "@types/memcached": "^2.2.6" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-mongodb": { - "version": "0.47.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.47.0.tgz", - "integrity": "sha512-yqyXRx2SulEURjgOQyJzhCECSh5i1uM49NUaq9TqLd6fA7g26OahyJfsr9NE38HFqGRHpi4loyrnfYGdrsoVjQ==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.62.0.tgz", + "integrity": "sha512-hcEEW26ToGVpQGblXk9m3p2cXkBu9j2bcyeevS/ahujr1WodfrItmMldWCEJkmN4+4uMo9pb6jAMhm6bZIMnig==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/sdk-metrics": "^1.9.1", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-mongoose": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.42.0.tgz", - "integrity": "sha512-AnWv+RaR86uG3qNEMwt3plKX1ueRM7AspfszJYVkvkehiicC3bHQA6vWdb6Zvy5HAE14RyFbu9+2hUUjR2NSyg==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.55.1.tgz", + "integrity": "sha512-M2MusLn/31YOt176Y6qXJQcpDuZPmq/fqQ9vIaKb4x/qIJ3oYO2lT45SUMFmZpODEhrpYXgGaEKwG6TGXhlosA==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-mysql": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.41.0.tgz", - "integrity": "sha512-jnvrV6BsQWyHS2qb2fkfbfSb1R/lmYwqEZITwufuRl37apTopswu9izc0b1CYRp/34tUG/4k/V39PND6eyiNvw==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.55.0.tgz", + "integrity": "sha512-tEGaVMzqAlwhoDomaUWOP2H4KkK16m18qq+TZoyvcSe9O21UxnYFWQa87a4kmc7N4Q6Q70L/YhwDt+fC+NDRBA==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/mysql": "2.15.26" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-mysql2": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.41.0.tgz", - "integrity": "sha512-REQB0x+IzVTpoNgVmy5b+UnH1/mDByrneimP6sbDHkp1j8QOl1HyWOrBH/6YWR0nrbU3l825Em5PlybjT3232g==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.55.1.tgz", + "integrity": "sha512-/cw7TzEmeaCQ5xi+FwrCWQUlY8v9RXjN5tqtb0D1sgBedfiV6DvW+dlMl1jo6Nkx9eSHmGcDy9IjyR0frHpKLg==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@opentelemetry/sql-common": "^0.40.1" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-nestjs-core": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.40.0.tgz", - "integrity": "sha512-WF1hCUed07vKmf5BzEkL0wSPinqJgH7kGzOjjMAiTGacofNXjb/y4KQ8loj2sNsh5C/NN7s1zxQuCgbWbVTGKg==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.55.0.tgz", + "integrity": "sha512-JFLNhbbEGnnQrMKOYoXx0nNk5N9cPeghu4xP/oup40a7VaSeYruyOiFbg9nkbS4ZQiI8aMuRqUT3Mo4lQjKEKg==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.30.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-net": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.39.0.tgz", - "integrity": "sha512-rixHoODfI/Cx1B0mH1BpxCT0bRSxktuBDrt9IvpT2KSEutK5hR0RsRdgdz/GKk+BQ4u+IG6godgMSGwNQCueEA==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.53.0.tgz", + "integrity": "sha512-d8tU5z0fx28z622RwVwU4zfNt40EKxzEcQcaPzch/CqpkKNAlvBOW/1K9OkjNdydpsKqxpMkbjvo3tY6PD1EMA==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-openai": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-openai/-/instrumentation-openai-0.7.1.tgz", + "integrity": "sha512-QDnnAYxByJoJ3jMly/EwRbXhnfZpGigfBcHyPcgWEMR4bfawJZhdOdFi1GVcC4ImdS7fGaYQOTX1WW24mftISg==", + "dependencies": { + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-oracledb": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-oracledb/-/instrumentation-oracledb-0.34.1.tgz", + "integrity": "sha512-RI5EV3ZIkHA748dPm4hwLkUnqYU/rrBcq+qA5cNks0dZaAgsu46XMA/MEPcubrBSsgaG1NAIG78P9NLZs2gN/A==", + "dependencies": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@types/oracledb": "6.5.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-pg": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.44.0.tgz", - "integrity": "sha512-oTWVyzKqXud1BYEGX1loo2o4k4vaU1elr3vPO8NZolrBtFvQ34nx4HgUaexUDuEog00qQt+MLR5gws/p+JXMLQ==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.55.0.tgz", + "integrity": "sha512-yfJ5bYE7CnkW/uNsnrwouG/FR7nmg09zdk2MSs7k0ZOMkDDAE3WBGpVFFApGgNu2U+gtzLgEzOQG4I/X+60hXw==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@opentelemetry/sql-common": "^0.40.1", - "@types/pg": "8.6.1", + "@opentelemetry/sql-common": "^0.41.0", + "@types/pg": "8.15.4", "@types/pg-pool": "2.0.6" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-pg/node_modules/@types/pg": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", - "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "version": "8.15.4", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz", + "integrity": "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==", "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation-pino": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.42.0.tgz", - "integrity": "sha512-SoX6FzucBfTuFNMZjdurJhcYWq2ve8/LkhmyVLUW31HpIB45RF1JNum0u4MkGisosDmXlK4njomcgUovShI+WA==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.55.1.tgz", + "integrity": "sha512-rt35H5vvP9KA1xrMrJGsnqwcVxyt8dher04pR64gvX4rxLwsmijUF1cEMbPZ2O8jXpeV8nAIzGHBnWEYp5ILNA==", "dependencies": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/core": "^1.25.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-redis": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.42.0.tgz", - "integrity": "sha512-jZBoqve0rEC51q0HuhjtZVq1DtUvJHzEJ3YKGvzGar2MU1J4Yt5+pQAQYh1W4jSoDyKeaI4hyeUdWM5N0c2lqA==", + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.57.2.tgz", + "integrity": "sha512-vD1nzOUDOPjnvDCny7fmRSX/hMTFzPUCZKADF5tQ5DvBqlOEV/de/tOkwvIwo9YX956EBMT+8qSjhd7qPXFkRw==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@opentelemetry/instrumentation-redis-4": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.42.0.tgz", - "integrity": "sha512-NaD+t2JNcOzX/Qa7kMy68JbmoVIV37fT/fJYzLKu2Wwd+0NCxt+K2OOsOakA8GVg8lSpFdbx4V/suzZZ2Pvdjg==", + "node_modules/@opentelemetry/instrumentation-restify": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.54.0.tgz", + "integrity": "sha512-V6kCoAtU8jLuUi9hr3IEWVTHr8d8s4wObV1DlI/A+VzYToK1W4Zv1SI8x3hiF0yR1poRjOY6rl91Q427HHTMww==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@opentelemetry/instrumentation-restify": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.41.0.tgz", - "integrity": "sha512-gKEo+X/wVKUBuD2WDDlF7SlDNBHMWjSQoLxFCsGqeKgHR0MGtwMel8uaDGg9LJ83nKqYy+7Vl/cDFxjba6H+/w==", + "node_modules/@opentelemetry/instrumentation-router": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.53.0.tgz", + "integrity": "sha512-3gF9jJ7C3lwlCOer1KzKKdpLr6/c7yOZBP44KI+Xi/TqiZjhsfUlHjetzC6BLDjkSk1DnIGyf+YzJR4aF5dJBQ==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@opentelemetry/instrumentation-router": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.40.0.tgz", - "integrity": "sha512-bRo4RaclGFiKtmv/N1D0MuzO7DuxbeqMkMCbPPng6mDwzpHAMpHz/K/IxJmF+H1Hi/NYXVjCKvHGClageLe9eA==", + "node_modules/@opentelemetry/instrumentation-runtime-node": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.22.0.tgz", + "integrity": "sha512-27aodhzdWqPuPVWM2UsLYz2gl6yLRqLP7Z6Kn6ukUx/I+9oruaztJkLtYg4SqCrm/7Nsv9FIly7gO3/ZyDIMPg==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-socket.io": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.42.0.tgz", - "integrity": "sha512-xB5tdsBzuZyicQTO3hDzJIpHQ7V1BYJ6vWPWgl19gWZDBdjEGc3HOupjkd3BUJyDoDhbMEHGk2nNlkUU99EfkA==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.55.1.tgz", + "integrity": "sha512-KQaOvZlw7NpA/VDRJdm45FIdzt4hXrDhvtmLU5a2AttcTI9e/VpVg4Y/LPOXM+o29VkKxETZzJfRlOJEIHl+uQ==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-tedious": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.14.0.tgz", - "integrity": "sha512-ofq7pPhSqvRDvD2FVx3RIWPj76wj4QubfrbqJtEx0A+fWoaYxJOCIQ92tYJh28elAmjMmgF/XaYuJuBhBv5J3A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.28.0.tgz", + "integrity": "sha512-nQ9k1Bdk2yG4SPRuHZ+QVcc3YMm2sfsBV1MQIc/Y/OcN83Q+jA7gXgYgYIblQ1wI+/RtKlJpdl6hobAXuj+pSA==", "dependencies": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", "@types/tedious": "^4.0.14" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/instrumentation-undici": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.6.0.tgz", - "integrity": "sha512-ABJBhm5OdhGmbh0S/fOTE4N69IZ00CsHC5ijMYfzbw3E5NwLgpQk5xsljaECrJ8wz1SfXbO03FiSuu5AyRAkvQ==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.19.0.tgz", + "integrity": "sha512-Pst/RhR61A2OoZQZkn6OLpdVpXp6qn3Y92wXa6umfJe9rV640r4bc6SWvw4pPN6DiQqPu2c8gnSSZPDtC6JlpQ==", "dependencies": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.24.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.7.0" } }, "node_modules/@opentelemetry/instrumentation-winston": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.40.0.tgz", - "integrity": "sha512-eMk2tKl86YJ8/yHvtDbyhrE35/R0InhO9zuHTflPx8T0+IvKVUhPV71MsJr32sImftqeOww92QHt4Jd+a5db4g==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.53.0.tgz", + "integrity": "sha512-yF9v0DphyG715er1HG1pbweNUSygvc22xw2s2Y8E8oaEMJo2/nH3Ww/8c4K6gdI/6xvi2unla1KQBCYN4uCo8w==", "dependencies": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/otlp-exporter-base": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.53.0.tgz", - "integrity": "sha512-UCWPreGQEhD6FjBaeDuXhiMf6kkBODF0ZQzrk/tuQcaVDJ+dDQ/xhJp192H9yWnKxVpEjFrSSLnpqmX4VwX+eA==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.208.0.tgz", + "integrity": "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-transformer": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-transformer": "0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/otlp-grpc-exporter-base": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.53.0.tgz", - "integrity": "sha512-F7RCN8VN+lzSa4fGjewit8Z5fEUpY/lmMVy5EWn2ZpbAabg3EE3sCLuTNfOiooNGnmvzimUPruoeqeko/5/TzQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.208.0.tgz", + "integrity": "sha512-fGvAg3zb8fC0oJAzfz7PQppADI2HYB7TSt/XoCaBJFi1mSquNUjtHXEoviMgObLAa1NRIgOC1lsV1OUKi+9+lQ==", "dependencies": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/otlp-transformer": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.53.0.tgz", - "integrity": "sha512-rM0sDA9HD8dluwuBxLetUmoqGJKSAbWenwD65KY9iZhUxdBHRLrIdrABfNDP7aiTjcgK8XFyTn5fhDz7N+W6DA==", - "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-metrics": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.208.0.tgz", + "integrity": "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==", + "dependencies": { + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/propagation-utils": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.30.11.tgz", - "integrity": "sha512-rY4L/2LWNk5p/22zdunpqVmgz6uN419DsRTw5KFMa6u21tWhXS8devlMy4h8m8nnS20wM7r6yYweCNNKjgLYJw==", + "version": "0.31.12", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.31.12.tgz", + "integrity": "sha512-VLdEdHYYbIWGSo6RO5qvnHE3b/OrmuO3+6yiWo/ghrQ+PTkBqFL85/kw4lpCayFGAFCfVsAWsU51OFgQHdPKmQ==", "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@opentelemetry/propagator-aws-xray": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-aws-xray/-/propagator-aws-xray-1.26.0.tgz", - "integrity": "sha512-Sex+JyEZ/xX328TArBqQjh1NZSfNyw5NdASUIi9hnPsnMBMSBaDe7B9JRnXv0swz7niNyAnXa6MY7yOCV76EvA==", - "dependencies": { - "@opentelemetry/core": "1.26.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, "node_modules/@opentelemetry/propagator-b3": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.26.0.tgz", - "integrity": "sha512-vvVkQLQ/lGGyEy9GT8uFnI047pajSOVnZI2poJqVGD3nJ+B9sFGdlHNnQKophE3lHfnIH0pw2ubrCTjZCgIj+Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.2.0.tgz", + "integrity": "sha512-9CrbTLFi5Ee4uepxg2qlpQIozoJuoAZU5sKMx0Mn7Oh+p7UrgCiEV6C02FOxxdYVRRFQVCinYR8Kf6eMSQsIsw==", "dependencies": { - "@opentelemetry/core": "1.26.0" + "@opentelemetry/core": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/propagator-jaeger": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.26.0.tgz", - "integrity": "sha512-DelFGkCdaxA1C/QA0Xilszfr0t4YbGd3DjxiCDPh34lfnFr+VkkrjV9S8ZTJvAzfdKERXhfOxIKBoGPJwoSz7Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.2.0.tgz", + "integrity": "sha512-FfeOHOrdhiNzecoB1jZKp2fybqmqMPJUXe2ZOydP7QzmTPYcfPeuaclTLYVhK3HyJf71kt8sTl92nV4YIaLaKA==", "dependencies": { - "@opentelemetry/core": "1.26.0" + "@opentelemetry/core": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/redis-common": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", - "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" } }, "node_modules/@opentelemetry/resource-detector-alibaba-cloud": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.29.1.tgz", - "integrity": "sha512-Qshebw6azBuKUqGkVgambZlLS6Xh+LCoLXep1oqW1RSzSOHQxGYDsPs99v8NzO65eJHHOu8wc2yKsWZQAgYsSw==", + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.32.0.tgz", + "integrity": "sha512-W+n4ZIbNndOaW6xlGeW7afKQeCMNlOHsSflGRLkzjnSfAl2tWJU5Mhr6hf/t6m8uhic71psHx/CoFQMsRQKnvQ==", "dependencies": { - "@opentelemetry/resources": "^1.0.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/resource-detector-aws": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-1.6.1.tgz", - "integrity": "sha512-A/3lqx9xoew7sFi+AVUUVr6VgB7UJ5qqddkKR3gQk9hWLm1R7HUXVJG09cLcZ7DMNpX13DohPRGmHE/vp1vafw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-2.9.0.tgz", + "integrity": "sha512-2dk1TuuImatD8n0OyBgghucluGcj2XtnortmJdLH0OffM7cVtat4h7Dcg8IZvP7WrMjbP4ZQQ2cpD1Fhvx6BsA==", "dependencies": { - "@opentelemetry/core": "^1.0.0", - "@opentelemetry/resources": "^1.10.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/resource-detector-azure": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.2.11.tgz", - "integrity": "sha512-XepvQfTXWyHAoAziCfXGwYbSZL0LHtFk5iuKKN2VE2vzcoiw5Tepi0Qafuwb7CCtpQRReao4H7E29MFbCmh47g==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.17.0.tgz", + "integrity": "sha512-JGNPW+Om8MNiVOK1Jl5jg3znGJQP7YeGsgRQiegftqEZj0th8e1Uf6U5s6H672KBT442WDGOG0a4du5xJgJB5w==", "dependencies": { - "@opentelemetry/core": "^1.25.1", - "@opentelemetry/resources": "^1.10.1", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.37.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/resource-detector-container": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.4.1.tgz", - "integrity": "sha512-v0bvO6RxYtbxvY/HwqrPQnZ4UtP4nBq4AOyS30iqV2vEtiLTY1gNTbNvTF1lwN/gg/g5CY1tRSrHcYODDOv0vw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.8.0.tgz", + "integrity": "sha512-nq0DlvJuKtnQWTqK3kwvYiaWnHgErpdS60e/JA50btD0CDqMq0vkl1xd6YFC7PvcPsOdiwXINRP5J/GncF70UQ==", "dependencies": { - "@opentelemetry/resources": "^1.10.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/resource-detector-gcp": { - "version": "0.29.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.29.11.tgz", - "integrity": "sha512-07wJx4nyxD/c2z3n70OQOg8fmoO/baTsq8uU+f7tZaehRNQx76MPkRbV2L902N40Z21SPIG8biUZ30OXE9tOIg==", + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.44.0.tgz", + "integrity": "sha512-sj9WSSjMyZJDP7DSmfQpsfivM2sQECwhjAmK6V97uVAeJiXSMiPhfo3fZi0Hpu+GQQ1Wb09qQIkwkMjwr0MH/g==", "dependencies": { - "@opentelemetry/core": "^1.0.0", - "@opentelemetry/resources": "^1.0.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", "gcp-metadata": "^6.0.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/resources": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.26.0.tgz", - "integrity": "sha512-CPNYchBE7MBecCSVy0HKpUISEeJOniWqcHaAHpmasZ3j9o6V3AyBzhRc90jdmemq0HOxDr6ylhUbDhBqqPpeNw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", + "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-logs": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.53.0.tgz", - "integrity": "sha512-dhSisnEgIj/vJZXZV6f6KcTnyLDx/VuQ6l3ejuZpMpPlh9S1qMHiZU9NMmOkVkwwHkMy3G6mEBwdP23vUZVr4g==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.208.0.tgz", + "integrity": "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==", "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.26.0.tgz", - "integrity": "sha512-0SvDXmou/JjzSDOjUmetAAvcKQW6ZrvosU0rkbDGpXvvZN+pQF6JbK/Kd4hNdK4q/22yeruqvukXEJyySTzyTQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.2.0.tgz", + "integrity": "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-node": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.53.0.tgz", - "integrity": "sha512-0hsxfq3BKy05xGktwG8YdGdxV978++x40EAKyKr1CaHZRh8uqVlXnclnl7OMi9xLMJEcXUw7lGhiRlArFcovyg==", - "dependencies": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/exporter-logs-otlp-grpc": "0.53.0", - "@opentelemetry/exporter-logs-otlp-http": "0.53.0", - "@opentelemetry/exporter-logs-otlp-proto": "0.53.0", - "@opentelemetry/exporter-trace-otlp-grpc": "0.53.0", - "@opentelemetry/exporter-trace-otlp-http": "0.53.0", - "@opentelemetry/exporter-trace-otlp-proto": "0.53.0", - "@opentelemetry/exporter-zipkin": "1.26.0", - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-metrics": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "@opentelemetry/sdk-trace-node": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" - }, - "engines": { - "node": ">=14" + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.208.0.tgz", + "integrity": "sha512-pbAqpZ7zTMFuTf3YecYsecsto/mheuvnK2a/jgstsE5ynWotBjgF5bnz5500W9Xl2LeUfg04WMt63TWtAgzRMw==", + "dependencies": { + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-logs-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-logs-otlp-http": "0.208.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.208.0", + "@opentelemetry/exporter-prometheus": "0.208.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-trace-otlp-http": "0.208.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.208.0", + "@opentelemetry/exporter-zipkin": "2.2.0", + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/propagator-b3": "2.2.0", + "@opentelemetry/propagator-jaeger": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", + "@opentelemetry/sdk-trace-node": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.26.0.tgz", - "integrity": "sha512-olWQldtvbK4v22ymrKLbIcBi9L2SpMO84sCPY54IVsJhP9fRsxJT194C/AVaAuJzLE30EdhhM1VmvVYR7az+cw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz", + "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==", "dependencies": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-trace-node": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.26.0.tgz", - "integrity": "sha512-Fj5IVKrj0yeUwlewCRwzOVcr5avTuNnMHWf7GPc1t6WaT78J6CJyF3saZ/0RkZfdeNO8IcBl/bNcWMVZBMRW8Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.2.0.tgz", + "integrity": "sha512-+OaRja3f0IqGG2kptVeYsrZQK9nKRSpfFrKtRBq4uh6nIB8bTBgaGvYQrQoRrQWQMA5dK5yLhDMDc0dvYvCOIQ==", "dependencies": { - "@opentelemetry/context-async-hooks": "1.26.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/propagator-b3": "1.26.0", - "@opentelemetry/propagator-jaeger": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "semver": "^7.5.2" + "@opentelemetry/context-async-hooks": "2.2.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz", - "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", "engines": { "node": ">=14" } }, "node_modules/@opentelemetry/sql-common": { - "version": "0.40.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", - "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", "dependencies": { - "@opentelemetry/core": "^1.1.0" + "@opentelemetry/core": "^2.0.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0" @@ -11368,9 +11756,9 @@ } }, "node_modules/@types/aws-lambda": { - "version": "8.10.143", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.143.tgz", - "integrity": "sha512-u5vzlcR14ge/4pMTTMDQr3MF0wEe38B2F9o84uC4F43vN5DGTy63npRrB6jQhyt+C0lGv4ZfiRcRkqJoZuPnmg==" + "version": "8.10.159", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", + "integrity": "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg==" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -11417,9 +11805,9 @@ } }, "node_modules/@types/bunyan": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.9.tgz", - "integrity": "sha512-ZqS9JGpBxVOvsawzmVt30sP++gSQMTejCkIAQ3VdadOcRE8izTyW66hufvwLeH+YEGP6Js2AW7Gz+RMyvrEbmw==", + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz", + "integrity": "sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==", "dependencies": { "@types/node": "*" } @@ -11443,9 +11831,9 @@ } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dependencies": { "@types/node": "*" } @@ -11565,9 +11953,9 @@ "dev": true }, "node_modules/@types/mysql": { - "version": "2.15.26", - "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", - "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", "dependencies": { "@types/node": "*" } @@ -11590,10 +11978,18 @@ "form-data": "^4.0.4" } }, + "node_modules/@types/oracledb": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@types/oracledb/-/oracledb-6.5.2.tgz", + "integrity": "sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/pg": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.4.tgz", - "integrity": "sha512-uYA7UMVzDFpJobCrqwW/iWkFmvizy6knIUgr0Quaw7K1Le3ZnF7hI3bKqFoxPZ+fju1Sc7zdTvOl9YfFZPcmeA==", + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -11614,11 +12010,6 @@ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", "dev": true }, - "node_modules/@types/shimmer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", - "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==" - }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -11919,9 +12310,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "bin": { "acorn": "bin/acorn" }, @@ -12500,11 +12891,6 @@ "node": ">=8" } }, - "node_modules/bintrees": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", - "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" - }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -13863,18 +14249,6 @@ "toad-cache": "^3.3.0" } }, - "node_modules/fastify-metrics": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/fastify-metrics/-/fastify-metrics-10.2.0.tgz", - "integrity": "sha512-mP977Soe47Cxp0HW7fEAvrU90K3+xkfSAkcxlXhkv4AXvfe1bf8ng82bbLjw1mj+1nFRQG3XBs0jSa7+W7J6Ag==", - "dependencies": { - "fastify-plugin": "^4.3.0", - "prom-client": "^14.1.0" - }, - "peerDependencies": { - "fastify": "^4.9.2" - } - }, "node_modules/fastify-plugin": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", @@ -14088,6 +14462,11 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==" + }, "node_modules/fs-extra": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", @@ -14157,11 +14536,12 @@ } }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" }, "engines": { @@ -14334,6 +14714,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -14436,11 +14824,11 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -14510,11 +14898,11 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", - "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.1.tgz", + "integrity": "sha512-bruMpJ7xz+9jwGzrwEhWgvRrlKRYCRDBrfU+ur3FcasYXLJDxTruJ//8g2Noj+QFyRBeqbpj8Bhn4Fbw6HjvhA==", "dependencies": { - "acorn": "^8.8.2", + "acorn": "^8.14.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^1.2.2", "module-details-from-path": "^1.0.3" @@ -16072,9 +16460,9 @@ } }, "node_modules/module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==" }, "node_modules/ms": { "version": "2.1.2", @@ -16916,17 +17304,6 @@ ], "license": "MIT" }, - "node_modules/prom-client": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz", - "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==", - "dependencies": { - "tdigest": "^0.1.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -17259,22 +17636,21 @@ } }, "node_modules/require-in-the-middle": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.4.0.tgz", - "integrity": "sha512-X34iHADNbNDfr6OTStIAHWSAvvKQRYgLO6duASaVf7J2VA3lvmNYboAHOuLC2huav1IwgZJtyEcJCKVzFxOSMQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", "dependencies": { "debug": "^4.3.5", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.8" + "module-details-from-path": "^1.0.3" }, "engines": { - "node": ">=8.6.0" + "node": ">=9.3.0 || >=8.10.0 <9.0.0" } }, "node_modules/require-in-the-middle/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dependencies": { "ms": "^2.1.3" }, @@ -17586,11 +17962,6 @@ "node": ">=8" } }, - "node_modules/shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -17910,6 +18281,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/systeminformation": { + "version": "5.23.8", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.23.8.tgz", + "integrity": "sha512-Osd24mNKe6jr/YoXLLK3k8TMdzaxDffhpCxgkfgBHcapykIkd50HXThM3TCEuHO2pPuCsSx2ms/SunqhU5MmsQ==", + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } + }, "node_modules/tar-fs": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", @@ -17943,14 +18339,6 @@ "node": ">=8.0.0" } }, - "node_modules/tdigest": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", - "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", - "dependencies": { - "bintrees": "1.0.2" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -24660,776 +25048,1045 @@ } }, "@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" }, "@opentelemetry/api-logs": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz", - "integrity": "sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz", + "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==", "requires": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.3.0" } }, "@opentelemetry/auto-instrumentations-node": { - "version": "0.50.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.50.0.tgz", - "integrity": "sha512-LqoSiWrOM4Cnr395frDHL4R/o5c2fuqqrqW8sZwhxvkasImmVlyL66YMPHllM2O5xVj2nP2ANUKHZSd293meZA==", - "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/instrumentation-amqplib": "^0.42.0", - "@opentelemetry/instrumentation-aws-lambda": "^0.44.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-bunyan": "^0.41.0", - "@opentelemetry/instrumentation-cassandra-driver": "^0.41.0", - "@opentelemetry/instrumentation-connect": "^0.39.0", - "@opentelemetry/instrumentation-cucumber": "^0.9.0", - "@opentelemetry/instrumentation-dataloader": "^0.12.0", - "@opentelemetry/instrumentation-dns": "^0.39.0", - "@opentelemetry/instrumentation-express": "^0.42.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-fs": "^0.15.0", - "@opentelemetry/instrumentation-generic-pool": "^0.39.0", - "@opentelemetry/instrumentation-graphql": "^0.43.0", - "@opentelemetry/instrumentation-grpc": "^0.53.0", - "@opentelemetry/instrumentation-hapi": "^0.41.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-ioredis": "^0.43.0", - "@opentelemetry/instrumentation-kafkajs": "^0.3.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-koa": "^0.43.0", - "@opentelemetry/instrumentation-lru-memoizer": "^0.40.0", - "@opentelemetry/instrumentation-memcached": "^0.39.0", - "@opentelemetry/instrumentation-mongodb": "^0.47.0", - "@opentelemetry/instrumentation-mongoose": "^0.42.0", - "@opentelemetry/instrumentation-mysql": "^0.41.0", - "@opentelemetry/instrumentation-mysql2": "^0.41.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.40.0", - "@opentelemetry/instrumentation-net": "^0.39.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", - "@opentelemetry/instrumentation-pino": "^0.42.0", - "@opentelemetry/instrumentation-redis": "^0.42.0", - "@opentelemetry/instrumentation-redis-4": "^0.42.0", - "@opentelemetry/instrumentation-restify": "^0.41.0", - "@opentelemetry/instrumentation-router": "^0.40.0", - "@opentelemetry/instrumentation-socket.io": "^0.42.0", - "@opentelemetry/instrumentation-tedious": "^0.14.0", - "@opentelemetry/instrumentation-undici": "^0.6.0", - "@opentelemetry/instrumentation-winston": "^0.40.0", - "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.1", - "@opentelemetry/resource-detector-aws": "^1.6.1", - "@opentelemetry/resource-detector-azure": "^0.2.11", - "@opentelemetry/resource-detector-container": "^0.4.1", - "@opentelemetry/resource-detector-gcp": "^0.29.11", - "@opentelemetry/resources": "^1.24.0", - "@opentelemetry/sdk-node": "^0.53.0" + "version": "0.67.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.67.3.tgz", + "integrity": "sha512-sRzw/T1JU7CCATGxnnKhHbWMlwMH1qO62+4/znfsJTg24ATP5qNKFkt8B/JD7HAQ/0ceMeyQin9KOBnjkLkCvA==", + "requires": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/instrumentation-amqplib": "^0.56.0", + "@opentelemetry/instrumentation-aws-lambda": "^0.61.1", + "@opentelemetry/instrumentation-aws-sdk": "^0.64.1", + "@opentelemetry/instrumentation-bunyan": "^0.54.0", + "@opentelemetry/instrumentation-cassandra-driver": "^0.54.1", + "@opentelemetry/instrumentation-connect": "^0.52.0", + "@opentelemetry/instrumentation-cucumber": "^0.24.0", + "@opentelemetry/instrumentation-dataloader": "^0.26.1", + "@opentelemetry/instrumentation-dns": "^0.52.0", + "@opentelemetry/instrumentation-express": "^0.57.1", + "@opentelemetry/instrumentation-fastify": "^0.53.1", + "@opentelemetry/instrumentation-fs": "^0.28.0", + "@opentelemetry/instrumentation-generic-pool": "^0.52.0", + "@opentelemetry/instrumentation-graphql": "^0.56.0", + "@opentelemetry/instrumentation-grpc": "^0.208.0", + "@opentelemetry/instrumentation-hapi": "^0.55.1", + "@opentelemetry/instrumentation-http": "^0.208.0", + "@opentelemetry/instrumentation-ioredis": "^0.57.0", + "@opentelemetry/instrumentation-kafkajs": "^0.18.1", + "@opentelemetry/instrumentation-knex": "^0.53.1", + "@opentelemetry/instrumentation-koa": "^0.57.1", + "@opentelemetry/instrumentation-lru-memoizer": "^0.53.1", + "@opentelemetry/instrumentation-memcached": "^0.52.1", + "@opentelemetry/instrumentation-mongodb": "^0.62.0", + "@opentelemetry/instrumentation-mongoose": "^0.55.1", + "@opentelemetry/instrumentation-mysql": "^0.55.0", + "@opentelemetry/instrumentation-mysql2": "^0.55.1", + "@opentelemetry/instrumentation-nestjs-core": "^0.55.0", + "@opentelemetry/instrumentation-net": "^0.53.0", + "@opentelemetry/instrumentation-openai": "^0.7.1", + "@opentelemetry/instrumentation-oracledb": "^0.34.1", + "@opentelemetry/instrumentation-pg": "^0.61.2", + "@opentelemetry/instrumentation-pino": "^0.55.1", + "@opentelemetry/instrumentation-redis": "^0.57.2", + "@opentelemetry/instrumentation-restify": "^0.54.0", + "@opentelemetry/instrumentation-router": "^0.53.0", + "@opentelemetry/instrumentation-runtime-node": "^0.22.0", + "@opentelemetry/instrumentation-socket.io": "^0.55.1", + "@opentelemetry/instrumentation-tedious": "^0.28.0", + "@opentelemetry/instrumentation-undici": "^0.19.0", + "@opentelemetry/instrumentation-winston": "^0.53.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.32.0", + "@opentelemetry/resource-detector-aws": "^2.9.0", + "@opentelemetry/resource-detector-azure": "^0.17.0", + "@opentelemetry/resource-detector-container": "^0.8.0", + "@opentelemetry/resource-detector-gcp": "^0.44.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-node": "^0.208.0" + }, + "dependencies": { + "@opentelemetry/instrumentation-aws-sdk": { + "version": "0.64.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.64.1.tgz", + "integrity": "sha512-A8joPAuHwvwrkG5UpH7OYhzkeYznNBiG3o1TKoZ7yvyXU/q4CNxnZ7vzZBEpt9OocptCe6X/YyBENFSa0axqiw==", + "requires": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "@opentelemetry/instrumentation-fastify": { + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.53.1.tgz", + "integrity": "sha512-tTa84J9rcrl4iTHdJDwirrNbM4prgJH+MF0iMlVLu++6gZg8TTfmYYqDiKPWBgdXB4M+bnlCkvgag36uV34uwA==", + "requires": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + } + }, + "@opentelemetry/instrumentation-knex": { + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.53.1.tgz", + "integrity": "sha512-tIW3gqVC8d9CCE+oxPO63WNvC+5PKC/LrPrYWFobii5afUpHJV+0pfyt08okAFBHztzT0voMOEPGkLKoacZRXQ==", + "requires": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + } + }, + "@opentelemetry/instrumentation-pg": { + "version": "0.61.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.61.2.tgz", + "integrity": "sha512-l1tN4dX8Ig1bKzMu81Q1EBXWFRy9wqchXbeHDRniJsXYND5dC8u1Uhah7wz1zZta3fbBWflP2mJZcDPWNsAMRg==", + "requires": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.6" + } + } } }, "@opentelemetry/context-async-hooks": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.26.0.tgz", - "integrity": "sha512-HedpXXYzzbaoutw6DFLWLDket2FwLkLpil4hGCZ1xYEIMTcivdfwEOISgdbLEWyG3HW52gTq2V9mOVJrONgiwg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz", + "integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==", "requires": {} }, "@opentelemetry/core": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.26.0.tgz", - "integrity": "sha512-1iKxXXE8415Cdv0yjG3G6hQnB5eVEsJce3QaawX8SjDn0mAS0ZM8fAbZZJD4ajvhC15cePvosSCut404KrIIvQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", "requires": { - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/exporter-logs-otlp-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.53.0.tgz", - "integrity": "sha512-x5ygAQgWAQOI+UOhyV3z9eW7QU2dCfnfOuIBiyYmC2AWr74f6x/3JBnP27IAcEx6aihpqBYWKnpoUTztkVPAZw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-AmZDKFzbq/idME/yq68M155CJW1y056MNBekH9OZewiZKaqgwYN4VYfn3mXVPftYsfrCM2r4V6tS8H2LmfiDCg==", "requires": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/sdk-logs": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/sdk-logs": "0.208.0" } }, "@opentelemetry/exporter-logs-otlp-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.53.0.tgz", - "integrity": "sha512-cSRKgD/n8rb+Yd+Cif6EnHEL/VZg1o8lEcEwFji1lwene6BdH51Zh3feAD9p2TyVoBKrl6Q9Zm2WltSp2k9gWQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.208.0.tgz", + "integrity": "sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==", "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/sdk-logs": "0.53.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/sdk-logs": "0.208.0" } }, "@opentelemetry/exporter-logs-otlp-proto": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.53.0.tgz", - "integrity": "sha512-jhEcVL1deeWNmTUP05UZMriZPSWUBcfg94ng7JuBb1q2NExgnADQFl1VQQ+xo62/JepK+MxQe4xAwlsDQFbISA==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.208.0.tgz", + "integrity": "sha512-Wy8dZm16AOfM7yddEzSFzutHZDZ6HspKUODSUJVjyhnZFMBojWDjSNgduyCMlw6qaxJYz0dlb0OEcb4Eme+BfQ==", "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-trace-base": "2.2.0" + } + }, + "@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-YbEnk7jjYmvhIwp2xJGkEvdgnayrA2QSr28R1LR1klDPvCxsoQPxE6TokDbQpoCEhD3+KmJVEXfb4EeEQxjymg==", + "requires": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + } + }, + "@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.208.0.tgz", + "integrity": "sha512-QZ3TrI90Y0i1ezWQdvreryjY0a5TK4J9gyDLIyhLBwV+EQUvyp5wR7TFPKCAexD4TDSWM0t3ulQDbYYjVtzTyA==", + "requires": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + } + }, + "@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.208.0.tgz", + "integrity": "sha512-CvvVD5kRDmRB/uSMalvEF6kiamY02pB46YAqclHtfjJccNZFxbkkXkMMmcJ7NgBFa5THmQBNVQ2AHyX29nRxOw==", + "requires": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" + } + }, + "@opentelemetry/exporter-prometheus": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.208.0.tgz", + "integrity": "sha512-Rgws8GfIfq2iNWCD3G1dTD9xwYsCof1+tc5S5X0Ahdb5CrAPE+k5P70XCWHqrFFurVCcKaHLJ/6DjIBHWVfLiw==", + "requires": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-metrics": "2.2.0" } }, "@opentelemetry/exporter-trace-otlp-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.53.0.tgz", - "integrity": "sha512-m6KSh6OBDwfDjpzPVbuJbMgMbkoZfpxYH2r262KckgX9cMYvooWXEKzlJYsNDC6ADr28A1rtRoUVRwNfIN4tUg==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.208.0.tgz", + "integrity": "sha512-E/eNdcqVUTAT7BC+e8VOw/krqb+5rjzYkztMZ/o+eyJl+iEY6PfczPXpwWuICwvsm0SIhBoh9hmYED5Vh5RwIw==", "requires": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" } }, "@opentelemetry/exporter-trace-otlp-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.53.0.tgz", - "integrity": "sha512-m7F5ZTq+V9mKGWYpX8EnZ7NjoqAU7VemQ1E2HAG+W/u0wpY1x0OmbxAXfGKFHCspdJk8UKlwPGrpcB8nay3P8A==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.208.0.tgz", + "integrity": "sha512-jbzDw1q+BkwKFq9yxhjAJ9rjKldbt5AgIy1gmEIJjEV/WRxQ3B6HcLVkwbjJ3RcMif86BDNKR846KJ0tY0aOJA==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" } }, "@opentelemetry/exporter-trace-otlp-proto": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.53.0.tgz", - "integrity": "sha512-T/bdXslwRKj23S96qbvGtaYOdfyew3TjPEKOk5mHjkCmkVl1O9C/YMdejwSsdLdOq2YW30KjR9kVi0YMxZushQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.208.0.tgz", + "integrity": "sha512-q844Jc3ApkZVdWYd5OAl+an3n1XXf3RWHa3Zgmnhw3HpsM3VluEKHckUUEqHPzbwDUx2lhPRVkqK7LsJ/CbDzA==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" } }, "@opentelemetry/exporter-zipkin": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.26.0.tgz", - "integrity": "sha512-PW5R34n3SJHO4t0UetyHKiXL6LixIqWN6lWncg3eRXhKuT30x+b7m5sDJS0kEWRfHeS+kG7uCw2vBzmB2lk3Dw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.2.0.tgz", + "integrity": "sha512-VV4QzhGCT7cWrGasBWxelBjqbNBbyHicWWS/66KoZoe9BzYwFB72SH2/kkc4uAviQlO8iwv2okIJy+/jqqEHTg==", + "requires": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/host-metrics": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/host-metrics/-/host-metrics-0.38.0.tgz", + "integrity": "sha512-5iiVhDLa3siMiq95P9/VUtwwNR4mv5/2q79iwMXDbw2if+kRsTGQhSQTClN+POpXeZIEFDlHl/R2TTZ1XWCdkA==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "systeminformation": "5.23.8" } }, "@opentelemetry/instrumentation": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.53.0.tgz", - "integrity": "sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", + "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@types/shimmer": "^1.2.0", - "import-in-the-middle": "^1.8.1", - "require-in-the-middle": "^7.1.1", - "semver": "^7.5.2", - "shimmer": "^1.2.1" + "@opentelemetry/api-logs": "0.208.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" } }, "@opentelemetry/instrumentation-amqplib": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.42.0.tgz", - "integrity": "sha512-fiuU6OKsqHJiydHWgTRQ7MnIrJ2lEqsdgFtNIH4LbAUJl/5XmrIeoDzDnox+hfkgWK65jsleFuQDtYb5hW1koQ==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.56.0.tgz", + "integrity": "sha512-/orV2zO2K7iGa1TR6lbs170LNNDbeTC6E3JF1EeB+okJ3rB5tl1gHFSjoqEDkQYFprNs5CPitqU8Y4l4S2Pkmg==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0" } }, "@opentelemetry/instrumentation-aws-lambda": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.44.0.tgz", - "integrity": "sha512-6vmr7FJIuopZzsQjEQTp4xWtF6kBp7DhD7pPIN8FN0dKUKyuVraABIpgWjMfelaUPy4rTYUGkYqPluhG0wx8Dw==", + "version": "0.61.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.61.1.tgz", + "integrity": "sha512-leISmqN7/KSCYAKEVOAnQ0NUCa3rigB7ShCVLnYrHr6+7CXPef7C+nvowElMcYTid8egiHKgApR/FaNdlBda3A==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/propagator-aws-xray": "^1.3.1", - "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/aws-lambda": "8.10.143" + "@types/aws-lambda": "^8.10.155" } }, "@opentelemetry/instrumentation-aws-sdk": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.44.0.tgz", - "integrity": "sha512-HIWFg4TDQsayceiikOnruMmyQ0SZYW6WiR+wknWwWVLHC3lHTCpAnqzp5V42ckArOdlwHZu2Jvq2GMSM4Myx3w==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.56.0.tgz", + "integrity": "sha512-Jl2B/FYEb6tBCk9G31CMomKPikGU2g+CEhrGddDI0o1YeNpg3kAO9dExF+w489/IJUGZX6/wudyNvV7z4k9NjQ==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/propagation-utils": "^0.30.11", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/propagation-utils": "^0.31.3", + "@opentelemetry/semantic-conventions": "^1.34.0" + }, + "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "requires": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + } + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, + "import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "requires": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "requires": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + } + } } }, "@opentelemetry/instrumentation-bunyan": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.41.0.tgz", - "integrity": "sha512-NoQS+gcwQ7pzb2PZFyra6bAxDAVXBMmpKxBblEuXJWirGrAksQllg9XTdmqhrwT/KxUYrbVca/lMams7e51ysg==", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.54.0.tgz", + "integrity": "sha512-DnPoHSLcKwQmueW+7OOaXFD/cj1M6hqwTm6P88QdMbln/dqEatLxzt/ACPk4Yb5x4aU3ZLyeLyKxtzfhp76+aw==", "requires": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@types/bunyan": "1.8.9" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@types/bunyan": "1.8.11" } }, "@opentelemetry/instrumentation-cassandra-driver": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.41.0.tgz", - "integrity": "sha512-hvTNcC8qjCQEHZTLAlTmDptjsEGqCKpN+90hHH8Nn/GwilGr5TMSwGrlfstdJuZWyw8HAnRUed6bcjvmHHk2Xw==", + "version": "0.54.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.54.1.tgz", + "integrity": "sha512-wVGI4YrWmaNNtNjg84KTl8sHebG7jm3PHvmZxPl2V/aSskAyQMSxgJZpnv1dmBmJuISc+a8H8daporljbscCcQ==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-connect": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.39.0.tgz", - "integrity": "sha512-pGBiKevLq7NNglMgqzmeKczF4XQMTOUOTkK8afRHMZMnrK3fcETyTH7lVaSozwiOM3Ws+SuEmXZT7DYrrhxGlg==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.52.0.tgz", + "integrity": "sha512-GXPxfNB5szMbV3I9b7kNWSmQBoBzw7MT0ui6iU/p+NIzVx3a06Ri2cdQO7tG9EKb4aKSLmfX9Cw5cKxXqX6Ohg==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/connect": "3.4.36" + "@types/connect": "3.4.38" } }, "@opentelemetry/instrumentation-cucumber": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.9.0.tgz", - "integrity": "sha512-4PQNFnIqnA2WM3ZHpr0xhZpHSqJ5xJ6ppTIzZC7wPqe+ZBpj41vG8B6ieqiPfq+im4QdqbYnzLb3rj48GDEN9g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.24.0.tgz", + "integrity": "sha512-ICHrmax9PwU/Z+fehD0uIjM8W0cEvdToglV1+o76Mgw51HZBVp2Y3mkga1qMPIN5tPMoWUYoYtI4U85rea5HYg==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, "@opentelemetry/instrumentation-dataloader": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.12.0.tgz", - "integrity": "sha512-pnPxatoFE0OXIZDQhL2okF//dmbiWFzcSc8pUg9TqofCLYZySSxDCgQc69CJBo5JnI3Gz1KP+mOjS4WAeRIH4g==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.26.1.tgz", + "integrity": "sha512-S2JAM6lV16tMravuPLd3tJCC6ySb5a//5KgJeXutbTVb/UbSTXcnHSdEtMaAvE2KbazVWyWzcoytLRy6AUOwsw==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-dns": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.39.0.tgz", - "integrity": "sha512-+iPzvXqVdJa67QBuz2tuP0UI3LS1/cMMo6dS7360DDtOQX+sQzkiN+mo3Omn4T6ZRhkTDw6c7uwsHBcmL31+1g==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.52.0.tgz", + "integrity": "sha512-XJvS8PkZec+X6HhOi1xldJydTpmIUAW14+1vyqwAK97LWKXlxmiWst8/fjZ709+CHgshz8i5V37yCHlr6o3pxw==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "semver": "^7.5.4" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-express": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.42.0.tgz", - "integrity": "sha512-YNcy7ZfGnLsVEqGXQPT+S0G1AE46N21ORY7i7yUQyfhGAL4RBjnZUqefMI0NwqIl6nGbr1IpF0rZGoN8Q7x12Q==", + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.57.1.tgz", + "integrity": "sha512-r+ulPbvgG8rGgFFWbJWJpTh7nMzsEYH7rBFNWdFs7ZfVAtgpFijMkRtU7DecIo6ItF8Op+RxogSuk/083W8HKw==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, "@opentelemetry/instrumentation-fastify": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.39.0.tgz", - "integrity": "sha512-SS9uSlKcsWZabhBp2szErkeuuBDgxOUlllwkS92dVaWRnMmwysPhcEgHKB8rUe3BHg/GnZC1eo1hbTZv4YhfoA==", + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.50.0.tgz", + "integrity": "sha512-j30yphIxdt6Wm8dgUoRORSORxlcFX2IxCLV6QZ9G5HtvvMIEP0hA0UnhJ3CDrDHKJRSHCiW8E8piOSbtU+0MLA==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.205.0", "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.205.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.205.0.tgz", + "integrity": "sha512-wBlPk1nFB37Hsm+3Qy73yQSobVn28F4isnWIBvKpd5IUH/eat8bwcL02H9yzmHyyPmukeccSl2mbN5sDQZYnPg==", + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.205.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.205.0.tgz", + "integrity": "sha512-cgvm7tvQdu9Qo7VurJP84wJ7ZV9F6WqDDGZpUc6rUEXwjV7/bXWs0kaYp9v+1Vh1+3TZCD3i6j/lUBcPhu8NhA==", + "requires": { + "@opentelemetry/api-logs": "0.205.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + } + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, + "import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "requires": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "requires": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + } + } } }, "@opentelemetry/instrumentation-fs": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.15.0.tgz", - "integrity": "sha512-JWVKdNLpu1skqZQA//jKOcKdJC66TWKqa2FUFq70rKohvaSq47pmXlnabNO+B/BvLfmidfiaN35XakT5RyMl2Q==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.28.0.tgz", + "integrity": "sha512-FFvg8fq53RRXVBRHZViP+EMxMR03tqzEGpuq55lHNbVPyFklSVfQBN50syPhK5UYYwaStx0eyCtHtbRreusc5g==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-generic-pool": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.39.0.tgz", - "integrity": "sha512-y4v8Y+tSfRB3NNBvHjbjrn7rX/7sdARG7FuK6zR8PGb28CTa0kHpEGCJqvL9L8xkTNvTXo+lM36ajFGUaK1aNw==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.52.0.tgz", + "integrity": "sha512-ISkNcv5CM2IwvsMVL31Tl61/p2Zm2I2NAsYq5SSBgOsOndT0TjnptjufYVScCnD5ZLD1tpl4T3GEYULLYOdIdQ==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-graphql": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.43.0.tgz", - "integrity": "sha512-aI3YMmC2McGd8KW5du1a2gBA0iOMOGLqg4s9YjzwbjFwjlmMNFSK1P3AIg374GWg823RPUGfVTIgZ/juk9CVOA==", + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.56.0.tgz", + "integrity": "sha512-IPvNk8AFoVzTAM0Z399t34VDmGDgwT6rIqCUug8P9oAGerl2/PEIYMPOl/rerPGu+q8gSWdmbFSjgg7PDVRd3Q==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-grpc": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.53.0.tgz", - "integrity": "sha512-Ss338T92yE1UCgr9zXSY3cPuaAy27uQw+wAC5IwsQKCXL5wwkiOgkd+2Ngksa9EGsgUEMwGeHi76bDdHFJ5Rrw==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.208.0.tgz", + "integrity": "sha512-8hFEQRAiOyIWO6LYj7tUfdAgNCuQUdYjLYMItRYlOLGJhshGdGYD7aeNzt2H+HPMDEWnKWqldIHfLTqM7ep7gg==", "requires": { - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/instrumentation-hapi": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.41.0.tgz", - "integrity": "sha512-jKDrxPNXDByPlYcMdZjNPYCvw0SQJjN+B1A+QH+sx+sAHsKSAf9hwFiJSrI6C4XdOls43V/f/fkp9ITkHhKFbQ==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.55.1.tgz", + "integrity": "sha512-Pm1HCHnnijUOGXd+nyJp96CfU8Lb6XdT6H6YvvmXO/NHMb6tV+EjzDRBr9sZ/XQjka9zLCz7jR0js7ut0IJAyg==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, "@opentelemetry/instrumentation-http": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.53.0.tgz", - "integrity": "sha512-H74ErMeDuZfj7KgYCTOFGWF5W9AfaPnqLQQxeFq85+D29wwV2yqHbz2IKLYpkOh7EI6QwDEl7rZCIxjJLyc/CQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.208.0.tgz", + "integrity": "sha512-rhmK46DRWEbQQB77RxmVXGyjs6783crXCnFjYQj+4tDH/Kpv9Rbg3h2kaNyp5Vz2emF1f9HOQQvZoHzwMWOFZQ==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/semantic-conventions": "1.27.0", - "semver": "^7.5.2" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" } }, "@opentelemetry/instrumentation-ioredis": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.43.0.tgz", - "integrity": "sha512-i3Dke/LdhZbiUAEImmRG3i7Dimm/BD7t8pDDzwepSvIQ6s2X6FPia7561gw+64w+nx0+G9X14D7rEfaMEmmjig==", + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.57.0.tgz", + "integrity": "sha512-o/PYGPbfFbS0Sq8EEQC8YUgDMiTGvwoMejPjV2d466yJoii+BUpffGejVQN0hC5V5/GT29m1B1jL+3yruNxwDw==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" } }, "@opentelemetry/instrumentation-kafkajs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.3.0.tgz", - "integrity": "sha512-UnkZueYK1ise8FXQeKlpBd7YYUtC7mM8J0wzUSccEfc/G8UqHQqAzIyYCUOUPUKp8GsjLnWOOK/3hJc4owb7Jg==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.18.1.tgz", + "integrity": "sha512-qM9hk7BIsVWqWJsrCa1fAEcEfutVvwhHO9kk4vpwaTGYR+lPWRk2r5+nEPcM+sIiYBmQNJCef5tEjQpKxTpP0A==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.30.0" } }, "@opentelemetry/instrumentation-knex": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.40.0.tgz", - "integrity": "sha512-6jka2jfX8+fqjEbCn6hKWHVWe++mHrIkLQtaJqUkBt3ZBs2xn1+y0khxiDS0v/mNb0bIKDJWwtpKFfsQDM1Geg==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.53.0.tgz", + "integrity": "sha512-xngn5cH2mVXFmiT1XfQ1aHqq1m4xb5wvU6j9lSgLlihJ1bXzsO543cpDwjrZm2nMrlpddBf55w8+bfS4qDh60g==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.1" } }, "@opentelemetry/instrumentation-koa": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.43.0.tgz", - "integrity": "sha512-lDAhSnmoTIN6ELKmLJBplXzT/Jqs5jGZehuG22EdSMaTwgjMpxMDI1YtlKEhiWPWkrz5LUsd0aOO0ZRc9vn3AQ==", + "version": "0.57.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.57.1.tgz", + "integrity": "sha512-XPjdzgXvMG3YSZvsSgOj0Je0fsmlaBYIFFGJqUn1HRpbrVjdpP45eXI+6yUp48J8N5Qss32WDD5f+2tmV7Xvsg==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.36.0" } }, "@opentelemetry/instrumentation-lru-memoizer": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.40.0.tgz", - "integrity": "sha512-21xRwZsEdMPnROu/QsaOIODmzw59IYpGFmuC4aFWvMj6stA8+Ei1tX67nkarJttlNjoM94um0N4X26AD7ff54A==", + "version": "0.53.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.53.1.tgz", + "integrity": "sha512-L93bPJKFzrObD4FvKpsavYEFTzXFKMmAeRHz7J4lUFc7TPZLouxX3PYW1+YGr/bT1y24H9NLNX66l7BW1s75QA==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-memcached": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.39.0.tgz", - "integrity": "sha512-WfwvKAZ9I1qILRP5EUd88HQjwAAL+trXpCpozjBi4U6a0A07gB3fZ5PFAxbXemSjF5tHk9KVoROnqHvQ+zzFSQ==", + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.52.1.tgz", + "integrity": "sha512-qg92SyWAypSZmX3Lhm2wz4BsovKarkWg9OHm4DPW6fGzmk40eB5voQIuctrBAfsml6gr+vbg4VEBcC1AKRvzzQ==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", "@types/memcached": "^2.2.6" } }, "@opentelemetry/instrumentation-mongodb": { - "version": "0.47.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.47.0.tgz", - "integrity": "sha512-yqyXRx2SulEURjgOQyJzhCECSh5i1uM49NUaq9TqLd6fA7g26OahyJfsr9NE38HFqGRHpi4loyrnfYGdrsoVjQ==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.62.0.tgz", + "integrity": "sha512-hcEEW26ToGVpQGblXk9m3p2cXkBu9j2bcyeevS/ahujr1WodfrItmMldWCEJkmN4+4uMo9pb6jAMhm6bZIMnig==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/sdk-metrics": "^1.9.1", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-mongoose": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.42.0.tgz", - "integrity": "sha512-AnWv+RaR86uG3qNEMwt3plKX1ueRM7AspfszJYVkvkehiicC3bHQA6vWdb6Zvy5HAE14RyFbu9+2hUUjR2NSyg==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.55.1.tgz", + "integrity": "sha512-M2MusLn/31YOt176Y6qXJQcpDuZPmq/fqQ9vIaKb4x/qIJ3oYO2lT45SUMFmZpODEhrpYXgGaEKwG6TGXhlosA==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-mysql": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.41.0.tgz", - "integrity": "sha512-jnvrV6BsQWyHS2qb2fkfbfSb1R/lmYwqEZITwufuRl37apTopswu9izc0b1CYRp/34tUG/4k/V39PND6eyiNvw==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.55.0.tgz", + "integrity": "sha512-tEGaVMzqAlwhoDomaUWOP2H4KkK16m18qq+TZoyvcSe9O21UxnYFWQa87a4kmc7N4Q6Q70L/YhwDt+fC+NDRBA==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/mysql": "2.15.26" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" } }, "@opentelemetry/instrumentation-mysql2": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.41.0.tgz", - "integrity": "sha512-REQB0x+IzVTpoNgVmy5b+UnH1/mDByrneimP6sbDHkp1j8QOl1HyWOrBH/6YWR0nrbU3l825Em5PlybjT3232g==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.55.1.tgz", + "integrity": "sha512-/cw7TzEmeaCQ5xi+FwrCWQUlY8v9RXjN5tqtb0D1sgBedfiV6DvW+dlMl1jo6Nkx9eSHmGcDy9IjyR0frHpKLg==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@opentelemetry/sql-common": "^0.40.1" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" } }, "@opentelemetry/instrumentation-nestjs-core": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.40.0.tgz", - "integrity": "sha512-WF1hCUed07vKmf5BzEkL0wSPinqJgH7kGzOjjMAiTGacofNXjb/y4KQ8loj2sNsh5C/NN7s1zxQuCgbWbVTGKg==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.55.0.tgz", + "integrity": "sha512-JFLNhbbEGnnQrMKOYoXx0nNk5N9cPeghu4xP/oup40a7VaSeYruyOiFbg9nkbS4ZQiI8aMuRqUT3Mo4lQjKEKg==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.30.0" } }, "@opentelemetry/instrumentation-net": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.39.0.tgz", - "integrity": "sha512-rixHoODfI/Cx1B0mH1BpxCT0bRSxktuBDrt9IvpT2KSEutK5hR0RsRdgdz/GKk+BQ4u+IG6godgMSGwNQCueEA==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.53.0.tgz", + "integrity": "sha512-d8tU5z0fx28z622RwVwU4zfNt40EKxzEcQcaPzch/CqpkKNAlvBOW/1K9OkjNdydpsKqxpMkbjvo3tY6PD1EMA==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + } + }, + "@opentelemetry/instrumentation-openai": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-openai/-/instrumentation-openai-0.7.1.tgz", + "integrity": "sha512-QDnnAYxByJoJ3jMly/EwRbXhnfZpGigfBcHyPcgWEMR4bfawJZhdOdFi1GVcC4ImdS7fGaYQOTX1WW24mftISg==", + "requires": { + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + } + }, + "@opentelemetry/instrumentation-oracledb": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-oracledb/-/instrumentation-oracledb-0.34.1.tgz", + "integrity": "sha512-RI5EV3ZIkHA748dPm4hwLkUnqYU/rrBcq+qA5cNks0dZaAgsu46XMA/MEPcubrBSsgaG1NAIG78P9NLZs2gN/A==", + "requires": { + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@types/oracledb": "6.5.2" } }, "@opentelemetry/instrumentation-pg": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.44.0.tgz", - "integrity": "sha512-oTWVyzKqXud1BYEGX1loo2o4k4vaU1elr3vPO8NZolrBtFvQ34nx4HgUaexUDuEog00qQt+MLR5gws/p+JXMLQ==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.55.0.tgz", + "integrity": "sha512-yfJ5bYE7CnkW/uNsnrwouG/FR7nmg09zdk2MSs7k0ZOMkDDAE3WBGpVFFApGgNu2U+gtzLgEzOQG4I/X+60hXw==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@opentelemetry/sql-common": "^0.40.1", - "@types/pg": "8.6.1", + "@opentelemetry/sql-common": "^0.41.0", + "@types/pg": "8.15.4", "@types/pg-pool": "2.0.6" }, "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "requires": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + } + }, "@types/pg": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", - "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "version": "8.15.4", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz", + "integrity": "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==", "requires": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, + "import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "requires": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "requires": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + } } } }, "@opentelemetry/instrumentation-pino": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.42.0.tgz", - "integrity": "sha512-SoX6FzucBfTuFNMZjdurJhcYWq2ve8/LkhmyVLUW31HpIB45RF1JNum0u4MkGisosDmXlK4njomcgUovShI+WA==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.55.1.tgz", + "integrity": "sha512-rt35H5vvP9KA1xrMrJGsnqwcVxyt8dher04pR64gvX4rxLwsmijUF1cEMbPZ2O8jXpeV8nAIzGHBnWEYp5ILNA==", "requires": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/core": "^1.25.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-redis": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.42.0.tgz", - "integrity": "sha512-jZBoqve0rEC51q0HuhjtZVq1DtUvJHzEJ3YKGvzGar2MU1J4Yt5+pQAQYh1W4jSoDyKeaI4hyeUdWM5N0c2lqA==", + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.57.2.tgz", + "integrity": "sha512-vD1nzOUDOPjnvDCny7fmRSX/hMTFzPUCZKADF5tQ5DvBqlOEV/de/tOkwvIwo9YX956EBMT+8qSjhd7qPXFkRw==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/redis-common": "^0.38.2", "@opentelemetry/semantic-conventions": "^1.27.0" } }, - "@opentelemetry/instrumentation-redis-4": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.42.0.tgz", - "integrity": "sha512-NaD+t2JNcOzX/Qa7kMy68JbmoVIV37fT/fJYzLKu2Wwd+0NCxt+K2OOsOakA8GVg8lSpFdbx4V/suzZZ2Pvdjg==", + "@opentelemetry/instrumentation-restify": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.54.0.tgz", + "integrity": "sha512-V6kCoAtU8jLuUi9hr3IEWVTHr8d8s4wObV1DlI/A+VzYToK1W4Zv1SI8x3hiF0yR1poRjOY6rl91Q427HHTMww==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, - "@opentelemetry/instrumentation-restify": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.41.0.tgz", - "integrity": "sha512-gKEo+X/wVKUBuD2WDDlF7SlDNBHMWjSQoLxFCsGqeKgHR0MGtwMel8uaDGg9LJ83nKqYy+7Vl/cDFxjba6H+/w==", + "@opentelemetry/instrumentation-router": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.53.0.tgz", + "integrity": "sha512-3gF9jJ7C3lwlCOer1KzKKdpLr6/c7yOZBP44KI+Xi/TqiZjhsfUlHjetzC6BLDjkSk1DnIGyf+YzJR4aF5dJBQ==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0", + "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, - "@opentelemetry/instrumentation-router": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.40.0.tgz", - "integrity": "sha512-bRo4RaclGFiKtmv/N1D0MuzO7DuxbeqMkMCbPPng6mDwzpHAMpHz/K/IxJmF+H1Hi/NYXVjCKvHGClageLe9eA==", + "@opentelemetry/instrumentation-runtime-node": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.22.0.tgz", + "integrity": "sha512-27aodhzdWqPuPVWM2UsLYz2gl6yLRqLP7Z6Kn6ukUx/I+9oruaztJkLtYg4SqCrm/7Nsv9FIly7gO3/ZyDIMPg==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-socket.io": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.42.0.tgz", - "integrity": "sha512-xB5tdsBzuZyicQTO3hDzJIpHQ7V1BYJ6vWPWgl19gWZDBdjEGc3HOupjkd3BUJyDoDhbMEHGk2nNlkUU99EfkA==", + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.55.1.tgz", + "integrity": "sha512-KQaOvZlw7NpA/VDRJdm45FIdzt4hXrDhvtmLU5a2AttcTI9e/VpVg4Y/LPOXM+o29VkKxETZzJfRlOJEIHl+uQ==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/instrumentation-tedious": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.14.0.tgz", - "integrity": "sha512-ofq7pPhSqvRDvD2FVx3RIWPj76wj4QubfrbqJtEx0A+fWoaYxJOCIQ92tYJh28elAmjMmgF/XaYuJuBhBv5J3A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.28.0.tgz", + "integrity": "sha512-nQ9k1Bdk2yG4SPRuHZ+QVcc3YMm2sfsBV1MQIc/Y/OcN83Q+jA7gXgYgYIblQ1wI+/RtKlJpdl6hobAXuj+pSA==", "requires": { - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.33.0", "@types/tedious": "^4.0.14" } }, "@opentelemetry/instrumentation-undici": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.6.0.tgz", - "integrity": "sha512-ABJBhm5OdhGmbh0S/fOTE4N69IZ00CsHC5ijMYfzbw3E5NwLgpQk5xsljaECrJ8wz1SfXbO03FiSuu5AyRAkvQ==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.19.0.tgz", + "integrity": "sha512-Pst/RhR61A2OoZQZkn6OLpdVpXp6qn3Y92wXa6umfJe9rV640r4bc6SWvw4pPN6DiQqPu2c8gnSSZPDtC6JlpQ==", "requires": { - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.24.0" } }, "@opentelemetry/instrumentation-winston": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.40.0.tgz", - "integrity": "sha512-eMk2tKl86YJ8/yHvtDbyhrE35/R0InhO9zuHTflPx8T0+IvKVUhPV71MsJr32sImftqeOww92QHt4Jd+a5db4g==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.53.0.tgz", + "integrity": "sha512-yF9v0DphyG715er1HG1pbweNUSygvc22xw2s2Y8E8oaEMJo2/nH3Ww/8c4K6gdI/6xvi2unla1KQBCYN4uCo8w==", "requires": { - "@opentelemetry/api-logs": "^0.53.0", - "@opentelemetry/instrumentation": "^0.53.0" + "@opentelemetry/api-logs": "^0.208.0", + "@opentelemetry/instrumentation": "^0.208.0" } }, "@opentelemetry/otlp-exporter-base": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.53.0.tgz", - "integrity": "sha512-UCWPreGQEhD6FjBaeDuXhiMf6kkBODF0ZQzrk/tuQcaVDJ+dDQ/xhJp192H9yWnKxVpEjFrSSLnpqmX4VwX+eA==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.208.0.tgz", + "integrity": "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-transformer": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-transformer": "0.208.0" } }, "@opentelemetry/otlp-grpc-exporter-base": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.53.0.tgz", - "integrity": "sha512-F7RCN8VN+lzSa4fGjewit8Z5fEUpY/lmMVy5EWn2ZpbAabg3EE3sCLuTNfOiooNGnmvzimUPruoeqeko/5/TzQ==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.208.0.tgz", + "integrity": "sha512-fGvAg3zb8fC0oJAzfz7PQppADI2HYB7TSt/XoCaBJFi1mSquNUjtHXEoviMgObLAa1NRIgOC1lsV1OUKi+9+lQ==", "requires": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/otlp-exporter-base": "0.53.0", - "@opentelemetry/otlp-transformer": "0.53.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/otlp-exporter-base": "0.208.0", + "@opentelemetry/otlp-transformer": "0.208.0" } }, "@opentelemetry/otlp-transformer": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.53.0.tgz", - "integrity": "sha512-rM0sDA9HD8dluwuBxLetUmoqGJKSAbWenwD65KY9iZhUxdBHRLrIdrABfNDP7aiTjcgK8XFyTn5fhDz7N+W6DA==", - "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-metrics": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.208.0.tgz", + "integrity": "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==", + "requires": { + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" } }, "@opentelemetry/propagation-utils": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.30.11.tgz", - "integrity": "sha512-rY4L/2LWNk5p/22zdunpqVmgz6uN419DsRTw5KFMa6u21tWhXS8devlMy4h8m8nnS20wM7r6yYweCNNKjgLYJw==", + "version": "0.31.12", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.31.12.tgz", + "integrity": "sha512-VLdEdHYYbIWGSo6RO5qvnHE3b/OrmuO3+6yiWo/ghrQ+PTkBqFL85/kw4lpCayFGAFCfVsAWsU51OFgQHdPKmQ==", "requires": {} }, - "@opentelemetry/propagator-aws-xray": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-aws-xray/-/propagator-aws-xray-1.26.0.tgz", - "integrity": "sha512-Sex+JyEZ/xX328TArBqQjh1NZSfNyw5NdASUIi9hnPsnMBMSBaDe7B9JRnXv0swz7niNyAnXa6MY7yOCV76EvA==", - "requires": { - "@opentelemetry/core": "1.26.0" - } - }, "@opentelemetry/propagator-b3": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.26.0.tgz", - "integrity": "sha512-vvVkQLQ/lGGyEy9GT8uFnI047pajSOVnZI2poJqVGD3nJ+B9sFGdlHNnQKophE3lHfnIH0pw2ubrCTjZCgIj+Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.2.0.tgz", + "integrity": "sha512-9CrbTLFi5Ee4uepxg2qlpQIozoJuoAZU5sKMx0Mn7Oh+p7UrgCiEV6C02FOxxdYVRRFQVCinYR8Kf6eMSQsIsw==", "requires": { - "@opentelemetry/core": "1.26.0" + "@opentelemetry/core": "2.2.0" } }, "@opentelemetry/propagator-jaeger": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.26.0.tgz", - "integrity": "sha512-DelFGkCdaxA1C/QA0Xilszfr0t4YbGd3DjxiCDPh34lfnFr+VkkrjV9S8ZTJvAzfdKERXhfOxIKBoGPJwoSz7Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.2.0.tgz", + "integrity": "sha512-FfeOHOrdhiNzecoB1jZKp2fybqmqMPJUXe2ZOydP7QzmTPYcfPeuaclTLYVhK3HyJf71kt8sTl92nV4YIaLaKA==", "requires": { - "@opentelemetry/core": "1.26.0" + "@opentelemetry/core": "2.2.0" } }, "@opentelemetry/redis-common": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", - "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==" + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==" }, "@opentelemetry/resource-detector-alibaba-cloud": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.29.1.tgz", - "integrity": "sha512-Qshebw6azBuKUqGkVgambZlLS6Xh+LCoLXep1oqW1RSzSOHQxGYDsPs99v8NzO65eJHHOu8wc2yKsWZQAgYsSw==", + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.32.0.tgz", + "integrity": "sha512-W+n4ZIbNndOaW6xlGeW7afKQeCMNlOHsSflGRLkzjnSfAl2tWJU5Mhr6hf/t6m8uhic71psHx/CoFQMsRQKnvQ==", "requires": { - "@opentelemetry/resources": "^1.0.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" } }, "@opentelemetry/resource-detector-aws": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-1.6.1.tgz", - "integrity": "sha512-A/3lqx9xoew7sFi+AVUUVr6VgB7UJ5qqddkKR3gQk9hWLm1R7HUXVJG09cLcZ7DMNpX13DohPRGmHE/vp1vafw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-2.9.0.tgz", + "integrity": "sha512-2dk1TuuImatD8n0OyBgghucluGcj2XtnortmJdLH0OffM7cVtat4h7Dcg8IZvP7WrMjbP4ZQQ2cpD1Fhvx6BsA==", "requires": { - "@opentelemetry/core": "^1.0.0", - "@opentelemetry/resources": "^1.10.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.27.0" } }, "@opentelemetry/resource-detector-azure": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.2.11.tgz", - "integrity": "sha512-XepvQfTXWyHAoAziCfXGwYbSZL0LHtFk5iuKKN2VE2vzcoiw5Tepi0Qafuwb7CCtpQRReao4H7E29MFbCmh47g==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.17.0.tgz", + "integrity": "sha512-JGNPW+Om8MNiVOK1Jl5jg3znGJQP7YeGsgRQiegftqEZj0th8e1Uf6U5s6H672KBT442WDGOG0a4du5xJgJB5w==", "requires": { - "@opentelemetry/core": "^1.25.1", - "@opentelemetry/resources": "^1.10.1", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.37.0" } }, "@opentelemetry/resource-detector-container": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.4.1.tgz", - "integrity": "sha512-v0bvO6RxYtbxvY/HwqrPQnZ4UtP4nBq4AOyS30iqV2vEtiLTY1gNTbNvTF1lwN/gg/g5CY1tRSrHcYODDOv0vw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.8.0.tgz", + "integrity": "sha512-nq0DlvJuKtnQWTqK3kwvYiaWnHgErpdS60e/JA50btD0CDqMq0vkl1xd6YFC7PvcPsOdiwXINRP5J/GncF70UQ==", "requires": { - "@opentelemetry/resources": "^1.10.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" } }, "@opentelemetry/resource-detector-gcp": { - "version": "0.29.11", - "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.29.11.tgz", - "integrity": "sha512-07wJx4nyxD/c2z3n70OQOg8fmoO/baTsq8uU+f7tZaehRNQx76MPkRbV2L902N40Z21SPIG8biUZ30OXE9tOIg==", + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.44.0.tgz", + "integrity": "sha512-sj9WSSjMyZJDP7DSmfQpsfivM2sQECwhjAmK6V97uVAeJiXSMiPhfo3fZi0Hpu+GQQ1Wb09qQIkwkMjwr0MH/g==", "requires": { - "@opentelemetry/core": "^1.0.0", - "@opentelemetry/resources": "^1.0.0", - "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", "gcp-metadata": "^6.0.0" } }, "@opentelemetry/resources": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.26.0.tgz", - "integrity": "sha512-CPNYchBE7MBecCSVy0HKpUISEeJOniWqcHaAHpmasZ3j9o6V3AyBzhRc90jdmemq0HOxDr6ylhUbDhBqqPpeNw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", + "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/sdk-logs": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.53.0.tgz", - "integrity": "sha512-dhSisnEgIj/vJZXZV6f6KcTnyLDx/VuQ6l3ejuZpMpPlh9S1qMHiZU9NMmOkVkwwHkMy3G6mEBwdP23vUZVr4g==", + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.208.0.tgz", + "integrity": "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==", "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0" + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0" } }, "@opentelemetry/sdk-metrics": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.26.0.tgz", - "integrity": "sha512-0SvDXmou/JjzSDOjUmetAAvcKQW6ZrvosU0rkbDGpXvvZN+pQF6JbK/Kd4hNdK4q/22yeruqvukXEJyySTzyTQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.2.0.tgz", + "integrity": "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0" } }, "@opentelemetry/sdk-node": { - "version": "0.53.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.53.0.tgz", - "integrity": "sha512-0hsxfq3BKy05xGktwG8YdGdxV978++x40EAKyKr1CaHZRh8uqVlXnclnl7OMi9xLMJEcXUw7lGhiRlArFcovyg==", - "requires": { - "@opentelemetry/api-logs": "0.53.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/exporter-logs-otlp-grpc": "0.53.0", - "@opentelemetry/exporter-logs-otlp-http": "0.53.0", - "@opentelemetry/exporter-logs-otlp-proto": "0.53.0", - "@opentelemetry/exporter-trace-otlp-grpc": "0.53.0", - "@opentelemetry/exporter-trace-otlp-http": "0.53.0", - "@opentelemetry/exporter-trace-otlp-proto": "0.53.0", - "@opentelemetry/exporter-zipkin": "1.26.0", - "@opentelemetry/instrumentation": "0.53.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/sdk-logs": "0.53.0", - "@opentelemetry/sdk-metrics": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "@opentelemetry/sdk-trace-node": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.208.0.tgz", + "integrity": "sha512-pbAqpZ7zTMFuTf3YecYsecsto/mheuvnK2a/jgstsE5ynWotBjgF5bnz5500W9Xl2LeUfg04WMt63TWtAgzRMw==", + "requires": { + "@opentelemetry/api-logs": "0.208.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/exporter-logs-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-logs-otlp-http": "0.208.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.208.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.208.0", + "@opentelemetry/exporter-prometheus": "0.208.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.208.0", + "@opentelemetry/exporter-trace-otlp-http": "0.208.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.208.0", + "@opentelemetry/exporter-zipkin": "2.2.0", + "@opentelemetry/instrumentation": "0.208.0", + "@opentelemetry/propagator-b3": "2.2.0", + "@opentelemetry/propagator-jaeger": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/sdk-logs": "0.208.0", + "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0", + "@opentelemetry/sdk-trace-node": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/sdk-trace-base": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.26.0.tgz", - "integrity": "sha512-olWQldtvbK4v22ymrKLbIcBi9L2SpMO84sCPY54IVsJhP9fRsxJT194C/AVaAuJzLE30EdhhM1VmvVYR7az+cw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz", + "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==", "requires": { - "@opentelemetry/core": "1.26.0", - "@opentelemetry/resources": "1.26.0", - "@opentelemetry/semantic-conventions": "1.27.0" + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/sdk-trace-node": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.26.0.tgz", - "integrity": "sha512-Fj5IVKrj0yeUwlewCRwzOVcr5avTuNnMHWf7GPc1t6WaT78J6CJyF3saZ/0RkZfdeNO8IcBl/bNcWMVZBMRW8Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.2.0.tgz", + "integrity": "sha512-+OaRja3f0IqGG2kptVeYsrZQK9nKRSpfFrKtRBq4uh6nIB8bTBgaGvYQrQoRrQWQMA5dK5yLhDMDc0dvYvCOIQ==", "requires": { - "@opentelemetry/context-async-hooks": "1.26.0", - "@opentelemetry/core": "1.26.0", - "@opentelemetry/propagator-b3": "1.26.0", - "@opentelemetry/propagator-jaeger": "1.26.0", - "@opentelemetry/sdk-trace-base": "1.26.0", - "semver": "^7.5.2" + "@opentelemetry/context-async-hooks": "2.2.0", + "@opentelemetry/core": "2.2.0", + "@opentelemetry/sdk-trace-base": "2.2.0" } }, "@opentelemetry/semantic-conventions": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz", - "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==" + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==" }, "@opentelemetry/sql-common": { - "version": "0.40.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", - "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", "requires": { - "@opentelemetry/core": "^1.1.0" + "@opentelemetry/core": "^2.0.0" } }, "@pkgjs/parseargs": { @@ -26850,9 +27507,9 @@ } }, "@types/aws-lambda": { - "version": "8.10.143", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.143.tgz", - "integrity": "sha512-u5vzlcR14ge/4pMTTMDQr3MF0wEe38B2F9o84uC4F43vN5DGTy63npRrB6jQhyt+C0lGv4ZfiRcRkqJoZuPnmg==" + "version": "8.10.159", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", + "integrity": "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg==" }, "@types/babel__core": { "version": "7.20.5", @@ -26896,9 +27553,9 @@ } }, "@types/bunyan": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.9.tgz", - "integrity": "sha512-ZqS9JGpBxVOvsawzmVt30sP++gSQMTejCkIAQ3VdadOcRE8izTyW66hufvwLeH+YEGP6Js2AW7Gz+RMyvrEbmw==", + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz", + "integrity": "sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==", "requires": { "@types/node": "*" } @@ -26922,9 +27579,9 @@ } }, "@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "requires": { "@types/node": "*" } @@ -27044,9 +27701,9 @@ "dev": true }, "@types/mysql": { - "version": "2.15.26", - "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", - "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", "requires": { "@types/node": "*" } @@ -27068,10 +27725,18 @@ "form-data": "^4.0.4" } }, + "@types/oracledb": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@types/oracledb/-/oracledb-6.5.2.tgz", + "integrity": "sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==", + "requires": { + "@types/node": "*" + } + }, "@types/pg": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.4.tgz", - "integrity": "sha512-uYA7UMVzDFpJobCrqwW/iWkFmvizy6knIUgr0Quaw7K1Le3ZnF7hI3bKqFoxPZ+fju1Sc7zdTvOl9YfFZPcmeA==", + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", "requires": { "@types/node": "*", "pg-protocol": "*", @@ -27092,11 +27757,6 @@ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", "dev": true }, - "@types/shimmer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", - "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==" - }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -27300,9 +27960,9 @@ } }, "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==" + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==" }, "acorn-import-attributes": { "version": "1.9.5", @@ -27707,11 +28367,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bintrees": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", - "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" - }, "bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -28690,15 +29345,6 @@ } } }, - "fastify-metrics": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/fastify-metrics/-/fastify-metrics-10.2.0.tgz", - "integrity": "sha512-mP977Soe47Cxp0HW7fEAvrU90K3+xkfSAkcxlXhkv4AXvfe1bf8ng82bbLjw1mj+1nFRQG3XBs0jSa7+W7J6Ag==", - "requires": { - "fastify-plugin": "^4.3.0", - "prom-client": "^14.1.0" - } - }, "fastify-plugin": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", @@ -28858,6 +29504,11 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, + "forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==" + }, "fs-extra": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", @@ -28904,11 +29555,12 @@ } }, "gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "requires": { - "gaxios": "^6.0.0", + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, @@ -29021,6 +29673,11 @@ "type-fest": "^0.20.2" } }, + "google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==" + }, "gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -29088,11 +29745,11 @@ } }, "https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" } }, @@ -29132,11 +29789,11 @@ } }, "import-in-the-middle": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", - "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.1.tgz", + "integrity": "sha512-bruMpJ7xz+9jwGzrwEhWgvRrlKRYCRDBrfU+ur3FcasYXLJDxTruJ//8g2Noj+QFyRBeqbpj8Bhn4Fbw6HjvhA==", "requires": { - "acorn": "^8.8.2", + "acorn": "^8.14.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^1.2.2", "module-details-from-path": "^1.0.3" @@ -30269,9 +30926,9 @@ "dev": true }, "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==" }, "ms": { "version": "2.1.2", @@ -30882,14 +31539,6 @@ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==" }, - "prom-client": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz", - "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==", - "requires": { - "tdigest": "^0.1.1" - } - }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -31132,19 +31781,18 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-in-the-middle": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.4.0.tgz", - "integrity": "sha512-X34iHADNbNDfr6OTStIAHWSAvvKQRYgLO6duASaVf7J2VA3lvmNYboAHOuLC2huav1IwgZJtyEcJCKVzFxOSMQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", "requires": { "debug": "^4.3.5", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.8" + "module-details-from-path": "^1.0.3" }, "dependencies": { "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "requires": { "ms": "^2.1.3" } @@ -31349,11 +31997,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -31589,6 +32232,11 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "systeminformation": { + "version": "5.23.8", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.23.8.tgz", + "integrity": "sha512-Osd24mNKe6jr/YoXLLK3k8TMdzaxDffhpCxgkfgBHcapykIkd50HXThM3TCEuHO2pPuCsSx2ms/SunqhU5MmsQ==" + }, "tar-fs": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", @@ -31615,14 +32263,6 @@ "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==" }, - "tdigest": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", - "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", - "requires": { - "bintrees": "1.0.2" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", diff --git a/package.json b/package.json index 096a69064..e49314e10 100644 --- a/package.json +++ b/package.json @@ -42,12 +42,18 @@ "@isaacs/ttlcache": "^1.4.1", "@kubernetes/client-node": "^1.3.0", "@opentelemetry/api": "^1.8.0", - "@opentelemetry/auto-instrumentations-node": "^0.50.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", + "@opentelemetry/auto-instrumentations-node": "^0.67.3", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.208.0", + "@opentelemetry/exporter-prometheus": "^0.208.0", + "@opentelemetry/host-metrics": "^0.38.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.56.0", + "@opentelemetry/instrumentation-fastify": "^0.50.0", + "@opentelemetry/instrumentation-http": "^0.208.0", + "@opentelemetry/instrumentation-knex": "^0.53.0", + "@opentelemetry/instrumentation-pg": "^0.55.0", + "@opentelemetry/instrumentation-runtime-node": "^0.22.0", + "@opentelemetry/sdk-metrics": "^2.2.0", + "@opentelemetry/sdk-node": "^0.208.0", "@shopify/semaphore": "^3.0.2", "@smithy/node-http-handler": "^2.3.1", "@tus/file-store": "2.0.0", @@ -64,7 +70,6 @@ "crypto-js": "^4.2.0", "dotenv": "^16.0.0", "fastify": "^4.28.1", - "fastify-metrics": "^10.2.0", "fastify-plugin": "^4.5.1", "fastify-xml-body-parser": "^2.2.0", "fs-extra": "^10.0.1", @@ -85,7 +90,6 @@ "pino": "^9.7.0", "pino-logflare": "^0.5.2", "postgres-migrations": "^5.3.0", - "prom-client": "^14.0.1", "xml2js": "^0.6.2" }, "devDependencies": { diff --git a/src/admin-app.ts b/src/admin-app.ts index 9f18b464b..8789c2f88 100644 --- a/src/admin-app.ts +++ b/src/admin-app.ts @@ -1,18 +1,11 @@ import fastify, { FastifyInstance, FastifyServerOptions } from 'fastify' import { routes, plugins, setErrorHandler } from './http' -import { Registry } from 'prom-client' import { getConfig } from './config' +import { handleMetricsRequest } from '@internal/monitoring/otel-metrics' -declare module 'fastify-metrics' { - interface IFastifyMetrics { - getCustomDefaultMetricsRegistries(): Registry[] - getCustomRouteMetricsRegistries(): Registry[] - } -} +const { version, prometheusMetricsEnabled } = getConfig() -const { version } = getConfig() - -const build = (opts: FastifyServerOptions = {}, appInstance?: FastifyInstance): FastifyInstance => { +const build = (opts: FastifyServerOptions = {}): FastifyInstance => { const app = fastify(opts) app.register(plugins.signals) app.register(plugins.adminTenantId) @@ -24,32 +17,9 @@ const build = (opts: FastifyServerOptions = {}, appInstance?: FastifyInstance): app.register(routes.s3Credentials, { prefix: 's3' }) app.register(routes.queue, { prefix: 'queue' }) - let registriesToMerge: Registry[] = [] - - if (appInstance) { - app.get('/metrics', async (req, reply) => { - if (registriesToMerge.length === 0) { - const globalRegistry = appInstance.metrics.client.register - const defaultRegistries = appInstance.metrics.getCustomDefaultMetricsRegistries() - const routeRegistries = appInstance.metrics.getCustomRouteMetricsRegistries() - - registriesToMerge = Array.from( - new Set([globalRegistry, ...defaultRegistries, ...routeRegistries]) - ) - } - - if (registriesToMerge.length === 1) { - const data = await registriesToMerge[0].metrics() - return reply.type(registriesToMerge[0].contentType).send(data) - } - const merged = appInstance.metrics.client.Registry.merge(registriesToMerge) - - const data = await merged.metrics() - - return reply.type(merged.contentType).send(data) - }) - } else { - app.register(plugins.metrics({ enabledEndpoint: true })) + // Register /metrics endpoint - uses OTel Prometheus exporter + if (prometheusMetricsEnabled) { + app.get('/metrics', handleMetricsRequest) } app.get('/version', (_, reply) => { diff --git a/src/app.ts b/src/app.ts index 1e1c58220..b6263ea8b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -46,15 +46,29 @@ const build = (opts: buildOpts = {}): FastifyInstance => { }) } + const excludedRoutesFromMonitoring = [ + '/status', + '/metrics', + '/health', + '/healthcheck', + '/version', + '/documentation', + ] + // add in common schemas app.addSchema(schemas.authSchema) app.addSchema(schemas.errorSchema) app.register(plugins.signals) app.register(plugins.tenantId) - app.register(plugins.metrics({ enabledEndpoint: !isMultitenant })) + app.register( + plugins.metrics({ + enabledEndpoint: !isMultitenant, + excludeRoutes: excludedRoutesFromMonitoring, + }) + ) app.register(plugins.tracing) - app.register(plugins.logRequest({ excludeUrls: ['/status', '/metrics', '/health', '/version'] })) + app.register(plugins.logRequest({ excludeUrls: excludedRoutesFromMonitoring })) app.register(routes.tus, { prefix: 'upload/resumable' }) app.register(routes.bucket, { prefix: 'bucket' }) app.register(routes.object, { prefix: 'object' }) diff --git a/src/config.ts b/src/config.ts index 858a67168..9585eca27 100644 --- a/src/config.ts +++ b/src/config.ts @@ -63,6 +63,7 @@ type StorageConfigType = { uploadFileSizeLimitStandard?: number storageFilePath?: string storageFileEtagAlgorithm: 'mtime' | 'md5' + storageS3InternalTracesEnabled?: boolean storageS3MaxSockets: number storageS3Bucket: string storageS3Endpoint?: string @@ -158,7 +159,6 @@ type StorageConfigType = { tusUseFileVersionSeparator: boolean tusAllowS3Tags: boolean tusLockType: 'postgres' | 's3' - defaultMetricsEnabled: boolean s3ProtocolEnabled: boolean s3ProtocolPrefix: string s3ProtocolAllowForwardedHeader: boolean @@ -173,6 +173,10 @@ type StorageConfigType = { tracingFeatures?: { upload: boolean } + prometheusMetricsEnabled: boolean + prometheusMetricsIncludeTenantId: boolean + otelMetricsEnabled: boolean + otelMetricsExportIntervalMs: number cdnPurgeEndpointURL?: string cdnPurgeEndpointKey?: string @@ -350,6 +354,8 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType { getOptionalConfigFromEnv('STORAGE_S3_MAX_SOCKETS', 'GLOBAL_S3_MAX_SOCKETS') || '200', 10 ), + storageS3InternalTracesEnabled: + getOptionalConfigFromEnv('STORAGE_S3_ENABLED_METRICS') === 'true', storageS3Bucket: getOptionalConfigFromEnv('STORAGE_S3_BUCKET', 'GLOBAL_S3_BUCKET'), storageS3Endpoint: getOptionalConfigFromEnv('STORAGE_S3_ENDPOINT', 'GLOBAL_S3_ENDPOINT'), storageS3ForcePathStyle: @@ -406,9 +412,6 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType { logflareApiKey: getOptionalConfigFromEnv('LOGFLARE_API_KEY'), logflareSourceToken: getOptionalConfigFromEnv('LOGFLARE_SOURCE_TOKEN'), logflareBatchSize: parseInt(getOptionalConfigFromEnv('LOGFLARE_BATCH_SIZE') || '200', 10), - defaultMetricsEnabled: !( - getOptionalConfigFromEnv('DEFAULT_METRICS_ENABLED', 'ENABLE_DEFAULT_METRICS') === 'false' - ), tracingEnabled: getOptionalConfigFromEnv('TRACING_ENABLED') === 'true', tracingMode: getOptionalConfigFromEnv('TRACING_MODE') ?? 'basic', tracingTimeMinDuration: parseFloat( @@ -420,6 +423,16 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType { upload: getOptionalConfigFromEnv('TRACING_FEATURE_UPLOAD') === 'true', }, + // OpenTelemetry Metrics + prometheusMetricsEnabled: getOptionalConfigFromEnv('PROMETHEUS_METRICS_ENABLED') === 'true', + prometheusMetricsIncludeTenantId: + getOptionalConfigFromEnv('PROMETHEUS_METRICS_INCLUDE_TENANT') === 'true', + otelMetricsEnabled: getOptionalConfigFromEnv('OTEL_METRICS_ENABLED') === 'true', + otelMetricsExportIntervalMs: parseInt( + getOptionalConfigFromEnv('OTEL_METRICS_EXPORT_INTERVAL_MS') || '60000', + 10 + ), + // Queue pgQueueEnable: getOptionalConfigFromEnv('PG_QUEUE_ENABLE', 'ENABLE_QUEUE_EVENTS') === 'true', pgQueueEnableWorkers: getOptionalConfigFromEnv('PG_QUEUE_WORKERS_ENABLE') !== 'false', diff --git a/src/http/plugins/log-request.ts b/src/http/plugins/log-request.ts index eb7940532..fae56c2b3 100644 --- a/src/http/plugins/log-request.ts +++ b/src/http/plugins/log-request.ts @@ -1,5 +1,5 @@ import fastifyPlugin from 'fastify-plugin' -import { logSchema, redactQueryParamFromRequest } from '@internal/monitoring' +import { logger, logSchema, redactQueryParamFromRequest } from '@internal/monitoring' import { trace } from '@opentelemetry/api' import { FastifyRequest } from 'fastify/types/request' import { FastifyReply } from 'fastify/types/reply' @@ -20,6 +20,7 @@ declare module 'fastify' { interface FastifyContextConfig { operation?: { type: string } resources?: (req: FastifyRequest) => string[] + logMetadata?: (req: FastifyRequest) => Record } } @@ -126,11 +127,37 @@ function doRequestLog(req: FastifyRequest, options: LogRequestOptions) { const error = (req.raw as any).executionError || req.executionError const tenantId = req.tenantId + let reqMetadata: Record = {} + + if (req.routeOptions.config.logMetadata) { + try { + reqMetadata = req.routeOptions.config.logMetadata(req) + + if (reqMetadata) { + try { + trace.getActiveSpan()?.setAttribute('http.metadata', JSON.stringify(reqMetadata)) + } catch (e) { + // do nothing + logSchema.warning(logger, 'Failed to serialize log metadata', { + type: 'otel', + error: e, + }) + } + } + } catch (e) { + logSchema.error(logger, 'Failed to get log metadata', { + type: 'request', + error: e, + }) + } + } + const buildLogMessage = `${tenantId} | ${rMeth} | ${statusCode} | ${cIP} | ${rId} | ${rUrl} | ${uAgent}` logSchema.request(req.log, buildLogMessage, { type: 'request', req, + reqMetadata, res: options.reply, responseTime: options.responseTime, executionTime: options.executionTime, diff --git a/src/http/plugins/metrics.ts b/src/http/plugins/metrics.ts index 115975cc2..25928f652 100644 --- a/src/http/plugins/metrics.ts +++ b/src/http/plugins/metrics.ts @@ -1,42 +1,137 @@ import fastifyPlugin from 'fastify-plugin' -import { MetricsRegistrar } from '@internal/monitoring/metrics' -import fastifyMetrics from 'fastify-metrics' +import { handleMetricsRequest } from '@internal/monitoring/otel-metrics' +import { + httpRequestDuration, + httpRequestsTotal, + httpRequestSizeBytes, + httpResponseSizeBytes, +} from '@internal/monitoring/metrics' import { getConfig } from '../../config' -const { region, defaultMetricsEnabled } = getConfig() +const { prometheusMetricsEnabled } = getConfig() interface MetricsOptions { enabledEndpoint?: boolean + excludeRoutes?: string[] + groupStatusCodes?: boolean } -export const metrics = ({ enabledEndpoint }: MetricsOptions) => +export const metrics = (options: MetricsOptions = {}) => + fastifyPlugin(async (fastify) => { + // Register HTTP metrics plugin + fastify.register(httpMetrics(options)) + + // Register metrics endpoint if enabled + if (prometheusMetricsEnabled) { + fastify.register(metricsEndpoint(options)) + } + }) + +export const metricsEndpoint = ({ enabledEndpoint }: MetricsOptions) => { + // Metrics endpoint plugin + return fastifyPlugin( + async (fastify) => { + if (enabledEndpoint) { + fastify.get('/metrics', handleMetricsRequest) + } + }, + { name: 'otel-metrics' } + ) +} + +interface HttpMetricsOptions { + /** Routes to exclude from metrics collection */ + excludeRoutes?: string[] + /** Whether to group status codes (2xx, 3xx, etc.) */ + groupStatusCodes?: boolean +} + +/** + * Fastify plugin for collecting HTTP request metrics. + * Records request duration (histogram) and request count (counter) + * using OpenTelemetry with tenant support. + */ +export const httpMetrics = (options: HttpMetricsOptions = {}) => fastifyPlugin( async (fastify) => { - fastify.register(fastifyMetrics, { - endpoint: enabledEndpoint ? '/metrics' : null, - defaultMetrics: { - enabled: defaultMetricsEnabled, - register: MetricsRegistrar, - prefix: 'storage_api_', - labels: { - region, - }, - }, - routeMetrics: { - enabled: defaultMetricsEnabled, - routeBlacklist: ['/metrics', '/status', '/health'], - overrides: { - summary: { - name: 'storage_api_http_request_summary_seconds', - }, - histogram: { - name: 'storage_api_http_request_duration_seconds', - }, - }, - registeredRoutesOnly: true, - groupStatusCodes: true, - }, + const excludeRoutes = options.excludeRoutes || [ + '/metrics', + '/status', + '/health', + '/healthcheck', + ] + const groupStatusCodes = options.groupStatusCodes ?? true + + // Hook into request lifecycle to measure duration + fastify.addHook('onRequest', async (request) => { + // Store start time on request for later use + request.metricsStartTime = process.hrtime.bigint() + }) + + fastify.addHook('onResponse', async (request, reply) => { + const route = request.routeOptions?.url || 'unknown' + + // Skip excluded routes (match start of path) + if (excludeRoutes.some((r) => route === r || route.startsWith(r + '/'))) { + return + } + + const startTime = request.metricsStartTime + if (!startTime) return + + // Calculate duration in seconds + const endTime = process.hrtime.bigint() + const durationNs = endTime - startTime + const durationSeconds = Number(durationNs) / 1e9 + + const method = request.method + const statusCode = groupStatusCodes + ? `${Math.floor(reply.statusCode / 100)}xx` + : String(reply.statusCode) + const tenantId = request.tenantId || '' + + const attributes = { + method, + route, + operation: request.operation?.type || 'unknown', + status_code: statusCode, + tenantId, + } + + // Record metrics + httpRequestDuration.record(durationSeconds, attributes) + httpRequestsTotal.add(1, attributes) + + // Record request size from content-length header + const requestContentLength = request.headers['content-length'] + if (requestContentLength) { + const requestSize = parseInt(requestContentLength, 10) + if (!isNaN(requestSize) && requestSize > 0) { + httpRequestSizeBytes.add(requestSize, attributes) + } + } + + // Record response size from content-length header + const responseContentLength = reply.getHeader('content-length') + if (responseContentLength) { + const responseSize = + typeof responseContentLength === 'string' + ? parseInt(responseContentLength, 10) + : typeof responseContentLength === 'number' + ? responseContentLength + : 0 + if (!isNaN(responseSize) && responseSize > 0) { + httpResponseSizeBytes.add(responseSize, attributes) + } + } }) }, - { name: 'prometheus-metrics' } + { name: 'http-metrics' } ) + +// Extend FastifyRequest to include metricsStartTime +declare module 'fastify' { + interface FastifyRequest { + metricsStartTime?: bigint + } +} diff --git a/src/http/plugins/tracing.ts b/src/http/plugins/tracing.ts index a3859c739..e8f4143e6 100644 --- a/src/http/plugins/tracing.ts +++ b/src/http/plugins/tracing.ts @@ -1,12 +1,8 @@ import fastifyPlugin from 'fastify-plugin' -import { isIP } from 'net' import { getTenantConfig } from '@internal/database' import { getConfig } from '../../config' -import { context, trace } from '@opentelemetry/api' -import { Span, traceCollector } from '@internal/monitoring/otel-processor' -import { ReadableSpan } from '@opentelemetry/sdk-trace-base' -import { logger, logSchema } from '@internal/monitoring' +import { logSchema } from '@internal/monitoring' declare module 'fastify' { interface FastifyRequest { @@ -15,23 +11,13 @@ declare module 'fastify' { } } -const { - isMultitenant, - tracingEnabled, - tracingMode: defaultTracingMode, - tracingReturnServerTimings, - isProduction, - tracingTimeMinDuration, -} = getConfig() - -const enableLogTraces = ['debug', 'logs'].includes(defaultTracingMode || '') +const { isMultitenant, tracingEnabled, tracingMode: defaultTracingMode } = getConfig() export const tracing = fastifyPlugin( async function tracingMode(fastify) { if (!tracingEnabled) { return } - fastify.register(traceServerTime) fastify.addHook('onRequest', async (request) => { try { @@ -41,19 +27,6 @@ export const tracing = fastifyPlugin( } else { request.tracingMode = defaultTracingMode } - - if (!enableLogTraces) { - return - } - - const span = trace.getSpan(context.active()) - - if (span) { - // We collect logs only in full,logs,debug mode - if (request.tracingMode && !['debug'].includes(request.tracingMode)) { - traceCollector.clearTrace(span.spanContext().traceId) - } - } } catch (e) { logSchema.error(request.log, 'failed setting tracing mode', { error: e, type: 'tracing' }) } @@ -61,169 +34,3 @@ export const tracing = fastifyPlugin( }, { name: 'tracing-mode' } ) - -export const traceServerTime = fastifyPlugin( - async function traceServerTime(fastify) { - if (!tracingEnabled || !enableLogTraces) { - return - } - fastify.addHook('onRequest', async (req, res) => { - // Request was aborted before the server finishes to return a response - res.raw.once('close', () => { - const aborted = !res.raw.writableFinished - if (aborted) { - try { - const span = trace.getSpan(context.active()) - const traceId = span?.spanContext().traceId - - span?.setAttribute('res_aborted', true) - - if (traceId) { - const spans = traceCollector.getSpansForTrace(traceId) - if (spans) { - req.serverTimings = spansToServerTimings(spans, true) - } - traceCollector.clearTrace(traceId) - } - } catch (e) { - logSchema.error(logger, 'failed parsing server times on abort', { - error: e, - type: 'otel', - }) - } - } - }) - }) - - fastify.addHook('onResponse', async (request, reply) => { - const traceId = trace.getSpan(context.active())?.spanContext().traceId - - if (request.tracingMode !== 'debug') { - if (traceId) traceCollector.clearTrace(traceId) - return - } - - try { - if (traceId) { - const spans = traceCollector.getSpansForTrace(traceId) - if (spans) { - const serverTimingHeaders = spansToServerTimings(spans, reply.statusCode >= 500) - - request.serverTimings = serverTimingHeaders - - // Return Server-Timing if enabled - if (tracingReturnServerTimings) { - const httpServerTimes = serverTimingHeaders - .flatMap((span) => { - return [span, ...span.children] - }) - .map(({ spanName, duration }) => { - return `${spanName};dur=${duration.toFixed(3)}` // Convert to milliseconds - }) - .join(',') - reply.header('Server-Timing', httpServerTimes) - } - } - } - } catch (e) { - logSchema.error(request.log, 'failed tracing on response', { error: e, type: 'tracing' }) - } finally { - if (traceId) { - traceCollector.clearTrace(traceId) - } - } - }) - - fastify.addHook('onRequestAbort', async (req) => { - const span = trace.getSpan(context.active()) - const traceId = span?.spanContext().traceId - - if (req.tracingMode !== 'debug') { - if (traceId) traceCollector.clearTrace(traceId) - return - } - - try { - span?.setAttribute('req_aborted', true) - - if (traceId) { - const spans = traceCollector.getSpansForTrace(traceId) - if (spans) { - req.serverTimings = spansToServerTimings(spans, true) - } - } - } catch (e) { - logSchema.error(logger, 'failed parsing server times on abort', { error: e, type: 'otel' }) - } finally { - if (traceId) { - traceCollector.clearTrace(traceId) - } - } - }) - }, - { name: 'tracing-server-times' } -) - -function enrichSpanName(spanName: string, span: ReadableSpan) { - if (span.attributes['knex.version']) { - const queryOperation = (span.attributes['db.operation'] as string)?.split(' ').shift() - return ( - `pg_query_` + - queryOperation?.toUpperCase() + - (span.attributes['db.sql.table'] ? '_' + span.attributes['db.sql.table'] : '_postgres') - ) - } - - if (['GET', 'PUT', 'HEAD', 'DELETE', 'POST'].includes(spanName)) { - return `HTTP_${spanName}` - } - - return spanName -} - -function spansToServerTimings( - spans: Span[], - includeChildren = false -): { spanName: string; duration: number; action?: any; host?: string; children: any[] }[] { - const minLatency = isProduction ? tracingTimeMinDuration : 50 - - return spans.flatMap((span) => { - const duration = Math.max(span.item.duration[1], span.item.duration[0]) / 1e6 // Convert nanoseconds to milliseconds - - if (duration >= minLatency || includeChildren) { - let spanName = - span.item.name - .split('->') - .pop() - ?.trimStart() - .replaceAll('\n', '') - .replaceAll(' ', '_') - .replaceAll('-', '_') - .replaceAll('___', '_') - .replaceAll(':', '_') - .replaceAll('_undefined', '') || 'UNKNOWN' - - spanName = enrichSpanName(spanName, span.item) - const hostName = span.item.attributes['net.peer.name'] as string | undefined - - return [ - { - spanName, - duration, - action: span.item.attributes['db.statement'], - error: span.item.attributes.error, - status: span.item.status, - host: hostName - ? isIP(hostName) - ? hostName - : hostName?.split('.').slice(-3).join('.') - : undefined, - children: spansToServerTimings(span.children, true), - }, - ] - } else { - // If the span doesn't meet the minimum latency, only return its children - return spansToServerTimings(span.children) - } - }) -} diff --git a/src/http/routes/object/listObjects.ts b/src/http/routes/object/listObjects.ts index e10f3b405..18aa1013b 100644 --- a/src/http/routes/object/listObjects.ts +++ b/src/http/routes/object/listObjects.ts @@ -4,6 +4,7 @@ import { createDefaultSchema } from '../../routes-helper' import { AuthenticatedRequest } from '../../types' import { objectSchema } from '@storage/schemas' import { ROUTE_OPERATIONS } from '../operations' +import { FastifyRequest } from 'fastify/types/request' const searchRequestParamsSchema = { type: 'object', @@ -57,6 +58,12 @@ export default async function routes(fastify: FastifyInstance) { schema, config: { operation: { type: ROUTE_OPERATIONS.LIST_OBJECTS }, + logMetadata: (req: FastifyRequest) => ({ + prefix: req.body.prefix, + limit: req.body.limit, + offset: req.body.offset, + sortBy: req.body.sortBy, + }), }, }, async (request, response) => { diff --git a/src/http/routes/object/listObjectsV2.ts b/src/http/routes/object/listObjectsV2.ts index 60daf1daa..2612e1224 100644 --- a/src/http/routes/object/listObjectsV2.ts +++ b/src/http/routes/object/listObjectsV2.ts @@ -5,6 +5,7 @@ import { ROUTE_OPERATIONS } from '../operations' import { getConfig } from '../../../config' import { getTenantConfig } from '@internal/database' import { DBMigration } from '@internal/database/migrations' +import { FastifyRequest } from 'fastify/types/request' const { isMultitenant } = getConfig() @@ -52,6 +53,13 @@ export default async function routes(fastify: FastifyInstance) { }, config: { operation: { type: ROUTE_OPERATIONS.LIST_OBJECTS_V2 }, + logMetadata: (req: FastifyRequest) => ({ + prefix: req.body.prefix, + limit: req.body.limit, + cursor: req.body.cursor, + sortBy: req.body.sortBy, + with_delimiter: req.body.with_delimiter, + }), }, }, async (request, response) => { diff --git a/src/http/routes/s3/commands/create-multipart-upload.ts b/src/http/routes/s3/commands/create-multipart-upload.ts index 6914400be..ef676ee98 100644 --- a/src/http/routes/s3/commands/create-multipart-upload.ts +++ b/src/http/routes/s3/commands/create-multipart-upload.ts @@ -1,7 +1,6 @@ import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' -import { S3Backend } from '@storage/backend' import { ERRORS } from '@internal/errors' const CreateMultiPartUploadInput = { @@ -44,9 +43,6 @@ export default function CreateMultipartUpload(s3Router: S3Router) { operation: ROUTE_OPERATIONS.S3_CREATE_MULTIPART, }, async (req, ctx) => { - const s3Protocol = new S3ProtocolHandler(ctx.storage, ctx.tenantId, ctx.owner) - - const metadata = s3Protocol.parseMetadataHeaders(req.Headers) const icebergBucketName = ctx.req.internalIcebergBucketName if (!icebergBucketName) { @@ -58,8 +54,7 @@ export default function CreateMultipartUpload(s3Router: S3Router) { req.Params['*'], undefined, req.Headers?.['content-type'] || 'application/octet-stream', - req.Headers?.['cache-control'] || 'no-cache', - metadata + req.Headers?.['cache-control'] || 'no-cache' ) return { @@ -89,7 +84,7 @@ export default function CreateMultipartUpload(s3Router: S3Router) { CacheControl: req.Headers?.['cache-control'], ContentDisposition: req.Headers?.['content-disposition'], ContentEncoding: req.Headers?.['content-encoding'], - Metadata: metadata, + Metadata: metadata || {}, }) } ) diff --git a/src/http/routes/s3/commands/put-object.ts b/src/http/routes/s3/commands/put-object.ts index 7c0712a4a..88cc73baa 100644 --- a/src/http/routes/s3/commands/put-object.ts +++ b/src/http/routes/s3/commands/put-object.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' +import { MAX_PART_SIZE, S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' import { MultipartFields } from '@fastify/multipart' @@ -83,7 +83,7 @@ export default function PutObject(s3Router: S3Router) { return pipeline( uploadRequest.body, - new ByteLimitTransformStream(uploadRequest.maxFileSize), + new ByteLimitTransformStream(MAX_PART_SIZE), // 5GB limit for iceberg objects ctx.req.streamingSignatureV4 || new PassThrough(), async (fileStream) => { const u = await ctx.req.storage.backend.uploadObject( diff --git a/src/http/routes/s3/commands/upload-part.ts b/src/http/routes/s3/commands/upload-part.ts index efab75244..4b80590fe 100644 --- a/src/http/routes/s3/commands/upload-part.ts +++ b/src/http/routes/s3/commands/upload-part.ts @@ -1,8 +1,13 @@ -import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' +import { S3ProtocolHandler, MAX_PART_SIZE } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' +import { MinChunkTransform } from '@internal/streams' import { pipeline } from 'stream/promises' import { PassThrough, Readable } from 'stream' +import { ByteLimitTransformStream } from '@storage/protocols/s3/byte-limit-stream' + +// S3 Tables requires chunks to be at least 8KB (except for the last chunk) +const S3_TABLES_MIN_CHUNK_SIZE = 8192 const UploadPartInput = { summary: 'Upload Part', @@ -46,6 +51,7 @@ export default function UploadPart(s3Router: S3Router) { }, async (req, ctx) => { const icebergBucketName = ctx.req.internalIcebergBucketName + const minChunkTransform = new MinChunkTransform(S3_TABLES_MIN_CHUNK_SIZE) if (ctx.req.streamingSignatureV4) { const passThrough = new PassThrough() @@ -54,44 +60,52 @@ export default function UploadPart(s3Router: S3Router) { passThrough.destroy(err) }) - return pipeline(passThrough, ctx.req.streamingSignatureV4, async (body) => { - const part = await ctx.req.storage.backend.uploadPart( - icebergBucketName!, - req.Params['*'], - '', - req.Querystring.uploadId, - req.Querystring.partNumber, - body as Readable, - req.Headers?.['x-amz-decoded-content-length'] || req.Headers?.['content-length'], - ctx.signals.body - ) + return pipeline( + passThrough, + new ByteLimitTransformStream(MAX_PART_SIZE), // 5GB max part size + ctx.req.streamingSignatureV4, + minChunkTransform, + async (body) => { + const part = await ctx.req.storage.backend.uploadPart( + icebergBucketName!, + req.Params['*'], + '', + req.Querystring.uploadId, + req.Querystring.partNumber, + body as Readable, + req.Headers?.['x-amz-decoded-content-length'] || req.Headers?.['content-length'], + ctx.signals.body + ) - return { - headers: { - etag: part.ETag || '', - 'Access-Control-Expose-Headers': 'etag', - }, + return { + headers: { + etag: part.ETag || '', + 'Access-Control-Expose-Headers': 'etag', + }, + } } - }) + ) } - const part = await ctx.req.storage.backend.uploadPart( - icebergBucketName!, - req.Params['*'], - '', - req.Querystring.uploadId, - req.Querystring.partNumber, - ctx.req.raw as Readable, - req.Headers?.['content-length'], - ctx.signals.body - ) + return pipeline(ctx.req.raw as Readable, minChunkTransform, async (body) => { + const part = await ctx.req.storage.backend.uploadPart( + icebergBucketName!, + req.Params['*'], + '', + req.Querystring.uploadId, + req.Querystring.partNumber, + body as Readable, + req.Headers?.['content-length'], + ctx.signals.body + ) - return { - headers: { - etag: part.ETag || '', - 'Access-Control-Expose-Headers': 'etag', - }, - } + return { + headers: { + etag: part.ETag || '', + 'Access-Control-Expose-Headers': 'etag', + }, + } + }) } ) @@ -112,19 +126,24 @@ export default function UploadPart(s3Router: S3Router) { passThrough.destroy(err) }) - return pipeline(passThrough, ctx.req.streamingSignatureV4, async (body) => { - return s3Protocol.uploadPart( - { - Body: body as Readable, - UploadId: req.Querystring?.uploadId, - Bucket: req.Params.Bucket, - Key: req.Params['*'], - ContentLength: req.Headers?.['x-amz-decoded-content-length'], - PartNumber: req.Querystring?.partNumber, - }, - { signal: ctx.req.signals.body.signal } - ) - }) + return pipeline( + passThrough, + new ByteLimitTransformStream(MAX_PART_SIZE), + ctx.req.streamingSignatureV4, + async (body) => { + return s3Protocol.uploadPart( + { + Body: body as Readable, + UploadId: req.Querystring?.uploadId, + Bucket: req.Params.Bucket, + Key: req.Params['*'], + ContentLength: req.Headers?.['x-amz-decoded-content-length'], + PartNumber: req.Querystring?.partNumber, + }, + { signal: ctx.req.signals.body.signal } + ) + } + ) } return s3Protocol.uploadPart( diff --git a/src/internal/database/pool.ts b/src/internal/database/pool.ts index cf902cefa..44ce54c9b 100644 --- a/src/internal/database/pool.ts +++ b/src/internal/database/pool.ts @@ -5,10 +5,14 @@ import { logger, logSchema } from '@internal/monitoring' import { getSslSettings } from '@internal/database/ssl' import { wait } from '@internal/concurrency' import { JWTPayload } from 'jose' -import { DbActivePool } from '@internal/monitoring/metrics' +import { + dbActivePool, + dbActiveConnection, + dbInUseConnection, + dbConnectionAcquireTime, +} from '@internal/monitoring/metrics' const { - region, isMultitenant, databaseSSLRootCert, databaseMaxConnections, @@ -79,12 +83,7 @@ const tenantPools = new TTLCache({ export class PoolManager { monitor(signal: AbortSignal) { const monitorInterval = setInterval(() => { - DbActivePool.set( - { - region, - }, - tenantPools.size - ) + dbActivePool.record(tenantPools.size) }, 2000) signal.addEventListener( @@ -187,7 +186,7 @@ class TenantPool implements PoolStrategy { let maxConnection = this.options.maxConnections || databaseMaxConnections if (clusterSize > 0) { - maxConnection = Math.ceil(maxConnection / clusterSize) + maxConnection = Math.ceil(maxConnection / clusterSize) || 2 } if (isSingleUseExternalPool) { @@ -255,8 +254,9 @@ class TenantPool implements PoolStrategy { }) const maxConnections = settings.maxConnections + const tenantId = this.options.tenantId - return knex({ + const pool = knex({ client: 'pg', version: dbPostgresVersion, searchPath: settings.searchPath, @@ -274,5 +274,50 @@ class TenantPool implements PoolStrategy { }, acquireConnectionTimeout: databaseConnectionTimeout, }) + + // Track total connections in pool per tenant + pool.client.pool.on('createSuccess', () => { + dbActiveConnection.add(1, { tenant_id: tenantId }) + }) + + pool.client.pool.on('destroySuccess', () => { + dbActiveConnection.add(-1, { tenant_id: tenantId }) + }) + + // Track in-use connections per tenant + pool.client.pool.on('acquireSuccess', () => { + dbInUseConnection.add(1, { tenant_id: tenantId }) + }) + + pool.client.pool.on('release', () => { + dbInUseConnection.add(-1, { tenant_id: tenantId }) + }) + + // Track connection acquisition time using eventId to correlate requests with completions + const pendingAcquires = new Map() + + pool.client.pool.on('acquireRequest', (eventId: number) => { + pendingAcquires.set(eventId, performance.now()) + }) + + pool.client.pool.on('acquireSuccess', (eventId: number) => { + const startTime = pendingAcquires.get(eventId) + if (startTime !== undefined) { + pendingAcquires.delete(eventId) + const durationSeconds = (performance.now() - startTime) / 1000 + dbConnectionAcquireTime.record(durationSeconds, { tenant_id: tenantId }) + } + }) + + pool.client.pool.on('acquireFail', (eventId: number) => { + const startTime = pendingAcquires.get(eventId) + if (startTime !== undefined) { + pendingAcquires.delete(eventId) + const durationSeconds = (performance.now() - startTime) / 1000 + dbConnectionAcquireTime.record(durationSeconds, { tenant_id: tenantId, failed: 'true' }) + } + }) + + return pool } } diff --git a/src/internal/errors/storage-error.ts b/src/internal/errors/storage-error.ts index f0b727434..cd315c5b4 100644 --- a/src/internal/errors/storage-error.ts +++ b/src/internal/errors/storage-error.ts @@ -1,6 +1,6 @@ import { ErrorCode } from './codes' import { RenderableError, StorageErrorOptions } from './renderable' -import { S3ServiceException } from '@aws-sdk/client-s3' +import type { S3ServiceException } from '@aws-sdk/client-s3' /** * A generic error that should be always thrown for generic exceptions diff --git a/src/internal/http/agent.ts b/src/internal/http/agent.ts index 920919513..4e14594a9 100644 --- a/src/internal/http/agent.ts +++ b/src/internal/http/agent.ts @@ -1,9 +1,9 @@ import Agent, { HttpsAgent } from 'agentkeepalive' import { - HttpPoolErrorGauge, - HttpPoolFreeSocketsGauge, - HttpPoolPendingRequestsGauge, - HttpPoolSocketsGauge, + httpPoolBusySockets, + httpPoolFreeSockets, + httpPoolPendingRequests, + httpPoolErrors, } from '@internal/monitoring/metrics' import { getConfig } from '../../config' @@ -27,7 +27,7 @@ export interface AgentStats { /** * Creates an instrumented agent - * Adding prometheus metrics to the agent + * Adding metrics to the agent */ export function createAgent(name: string, options: { maxSockets: number }): InstrumentedAgent { const agentOptions = { @@ -58,31 +58,17 @@ export function createAgent(name: string, options: { maxSockets: number }): Inst } /** - * Metrics - * - * HttpPoolSockets - * HttpPoolFreeSockets - * HttpPoolPendingRequests - * HttpPoolError - * - * @param name - * @param protocol - * @param stats + * Updates HTTP agent metrics */ function updateHttpAgentMetrics(name: string, protocol: string, stats: AgentStats) { - // Update the metrics with calculated values - HttpPoolSocketsGauge.set({ name, region, protocol }, stats.busySocketCount) - HttpPoolFreeSocketsGauge.set({ name, region, protocol }, stats.freeSocketCount) - HttpPoolPendingRequestsGauge.set({ name, region }, stats.pendingRequestCount) - HttpPoolErrorGauge.set({ name, region, type: 'socket_error', protocol }, stats.errorSocketCount) - HttpPoolErrorGauge.set( - { name, region, type: 'timeout_socket_error', protocol }, - stats.timeoutSocketCount - ) - HttpPoolErrorGauge.set( - { name, region, type: 'create_socket_error', protocol }, - stats.createSocketErrorCount - ) + const baseAttrs = { name, protocol } + + httpPoolBusySockets.record(stats.busySocketCount, baseAttrs) + httpPoolFreeSockets.record(stats.freeSocketCount, baseAttrs) + httpPoolPendingRequests.record(stats.pendingRequestCount, { name, region }) + httpPoolErrors.record(stats.errorSocketCount, { ...baseAttrs, type: 'socket_error' }) + httpPoolErrors.record(stats.timeoutSocketCount, { ...baseAttrs, type: 'timeout_socket_error' }) + httpPoolErrors.record(stats.createSocketErrorCount, { ...baseAttrs, type: 'create_socket_error' }) } export function watchAgent(name: string, protocol: 'http' | 'https', agent: Agent | HttpsAgent) { @@ -95,7 +81,7 @@ export function watchAgent(name: string, protocol: 'http' | 'https', agent: Agen }, 5000) } -// Function to update Prometheus metrics based on the current status of the agent +// Function to update metrics based on the current status of the agent export function gatherHttpAgentStats(status: Agent.AgentStatus) { // Calculate the number of busy sockets by iterating over the `sockets` object let busySocketCount = 0 diff --git a/src/internal/monitoring/event-loop.ts b/src/internal/monitoring/event-loop.ts deleted file mode 100644 index 7d1ac220a..000000000 --- a/src/internal/monitoring/event-loop.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { createHook } from 'node:async_hooks' -import { trace } from '@opentelemetry/api' - -const THRESHOLD_NS = 1e8 // 100ms - -const cache = new Map() - -function init(asyncId: number, type: string, triggerAsyncId: number, resource: any) { - cache.set(asyncId, { - type, - }) -} - -function destroy(asyncId: number) { - cache.delete(asyncId) -} - -function before(asyncId: number) { - const cached = cache.get(asyncId) - - if (!cached) { - return - } - - cache.set(asyncId, { - ...cached, - start: process.hrtime(), - }) -} - -function after(asyncId: number) { - const cached = cache.get(asyncId) - - if (!cached) { - return - } - - cache.delete(asyncId) - - if (!cached.start) { - return - } - - const diff = process.hrtime(cached.start) - const diffNs = diff[0] * 1e9 + diff[1] - - if (diffNs > THRESHOLD_NS) { - const time = diffNs / 1e6 // in ms - - const tracer = trace.getTracer('event-loop-monitor') - const activeSpan = trace.getActiveSpan() - - const newSpan = tracer.startSpan('event-loop-blocked', { - startTime: new Date(new Date().getTime() - time), - attributes: { - asyncType: cached.type, - label: 'EventLoopMonitor', - }, - links: activeSpan ? [{ context: activeSpan.spanContext() }] : undefined, - }) - - newSpan.end() - } -} - -export const eventLoopMonitor = () => { - const hook = createHook({ init, before, after, destroy }) - - return { - enable: () => { - console.log('🥸 Initializing event loop monitor') - - hook.enable() - }, - disable: () => { - console.log('🥸 Disabling event loop monitor') - - hook.disable() - }, - } -} diff --git a/src/internal/monitoring/logger.ts b/src/internal/monitoring/logger.ts index 05c69f455..bfaa038e7 100644 --- a/src/internal/monitoring/logger.ts +++ b/src/internal/monitoring/logger.ts @@ -1,6 +1,6 @@ import pino, { BaseLogger, Logger } from 'pino' import { getConfig } from '../../config' -import { FastifyReply, FastifyRequest } from 'fastify' +import type { FastifyReply, FastifyRequest } from 'fastify' import { URL } from 'node:url' import { normalizeRawError } from '@internal/errors' import { resolve } from 'node:path' @@ -26,6 +26,17 @@ export const baseLogger = pino({ headers: whitelistHeaders(reply.getHeaders()), } }, + reqMetadata(metadata?: Record) { + if (!metadata) { + return undefined + } + + try { + return JSON.stringify(metadata) + } catch { + // no-op + } + }, req(request) { return { region, @@ -58,6 +69,7 @@ export interface RequestLog { type: 'request' req: FastifyRequest res?: FastifyReply + reqMetadata?: Record responseTime: number executionTime?: number error?: Error | unknown diff --git a/src/internal/monitoring/metrics.ts b/src/internal/monitoring/metrics.ts index c1c4090b9..97dad6547 100644 --- a/src/internal/monitoring/metrics.ts +++ b/src/internal/monitoring/metrics.ts @@ -1,95 +1,197 @@ -import client from 'prom-client' - -const Registry = client.Registry -export const MetricsRegistrar = new Registry() - -export const FileUploadStarted = new client.Gauge({ - name: 'storage_api_upload_started', - help: 'Upload started', - labelNames: ['region', 'is_multipart'], -}) - -export const FileUploadedSuccess = new client.Gauge({ - name: 'storage_api_upload_success', - help: 'Successful uploads', - labelNames: ['region', 'is_multipart', 'is_resumable', 'is_standard', 'is_s3'], -}) - -export const DbQueryPerformance = new client.Histogram({ - name: 'storage_api_database_query_performance', - help: 'Database query performance', - labelNames: ['region', 'name'], -}) - -export const QueueJobSchedulingTime = new client.Histogram({ - name: 'storage_api_queue_job_scheduled_time', - help: 'Time taken to schedule a job in the queue', - labelNames: ['region', 'name'], -}) - -export const QueueJobScheduled = new client.Gauge({ - name: 'storage_api_queue_job_scheduled', - help: 'Current number of pending messages in the queue', - labelNames: ['region', 'name'], -}) - -export const QueueJobCompleted = new client.Gauge({ - name: 'storage_api_queue_job_completed', - help: 'Current number of processed messages in the queue', - labelNames: ['region', 'name'], -}) - -export const QueueJobRetryFailed = new client.Gauge({ - name: 'storage_api_queue_job_retry_failed', - help: 'Current number of failed attempts messages in the queue', - labelNames: ['region', 'name'], -}) - -export const QueueJobError = new client.Gauge({ - name: 'storage_api_queue_job_error', - help: 'Current number of errored messages in the queue', - labelNames: ['region', 'name'], -}) - -export const S3UploadPart = new client.Histogram({ - name: 'storage_api_s3_upload_part', - help: 'S3 upload part performance', - labelNames: ['region'], -}) - -export const DbActivePool = new client.Gauge({ - name: 'storage_api_db_pool', - help: 'Number of database pools created', - labelNames: ['region'], -}) - -export const DbActiveConnection = new client.Gauge({ - name: 'storage_api_db_connections', - help: 'Number of database connections', - labelNames: ['region', 'is_external'], -}) - -// Create Prometheus metrics -export const HttpPoolSocketsGauge = new client.Gauge({ - name: 'storage_api_http_pool_busy_sockets', - help: 'Number of busy sockets currently in use', - labelNames: ['name', 'region', 'protocol'], -}) - -export const HttpPoolFreeSocketsGauge = new client.Gauge({ - name: 'storage_api_http_pool_free_sockets', - help: 'Number of free sockets available for reuse', - labelNames: ['name', 'region', 'protocol'], -}) - -export const HttpPoolPendingRequestsGauge = new client.Gauge({ - name: 'storage_api_http_pool_requests', - help: 'Number of pending requests waiting for a socket', - labelNames: ['name', 'region', 'protocol'], -}) - -export const HttpPoolErrorGauge = new client.Gauge({ - name: 'storage_api_http_pool_errors', - help: 'Number of pending requests waiting for a socket', - labelNames: ['name', 'region', 'type', 'protocol'], -}) +import { metrics } from '@opentelemetry/api' +import { + Counter, + Gauge, + Histogram, + UpDownCounter, +} from '@opentelemetry/api/build/src/metrics/Metric' +import { getConfig } from '../../config' + +const { prometheusMetricsIncludeTenantId } = getConfig() + +// Get meter from global API - instruments work once MeterProvider is registered +const meter = metrics.getMeter('storage-api') + +// ============================================================================ +// HTTP Request Metrics +// ============================================================================ +export const httpRequestDuration = withTenantMetricLabels( + meter.createHistogram('http_request_duration_seconds', { + description: 'HTTP request duration in seconds', + unit: 's', + }) +) + +export const httpRequestsTotal = withTenantMetricLabels( + meter.createCounter('http_requests_total', { + description: 'Total number of HTTP requests', + }) +) + +export const httpRequestSizeBytes = withTenantMetricLabels( + meter.createCounter('http_request_size_bytes', { + description: 'Total bytes received in HTTP requests (from content-length header)', + unit: 'bytes', + }) +) + +export const httpResponseSizeBytes = withTenantMetricLabels( + meter.createCounter('http_response_size_bytes', { + description: 'Total bytes sent in HTTP responses (from content-length header)', + unit: 'bytes', + }) +) + +// ============================================================================ +// Upload Metrics +// ============================================================================ +export const fileUploadStarted = withTenantMetricLabels( + meter.createCounter('upload_started', { + description: 'Total uploads started', + }) +) + +export const fileUploadedSuccess = withTenantMetricLabels( + meter.createCounter('upload_success', { + description: 'Total successful uploads', + }) +) + +// ============================================================================ +// Database Metrics +// ============================================================================ +export const dbQueryPerformance = withTenantMetricLabels( + meter.createHistogram('database_query_performance_seconds', { + description: 'Database query performance in seconds', + unit: 's', + }) +) + +export const dbActivePool = withTenantMetricLabels( + meter.createGauge('db_active_local_pools', { + description: 'Number of database pools created', + }) +) + +export const dbActiveConnection = withTenantMetricLabels( + meter.createUpDownCounter('db_connections', { + description: 'Number of database connections in the pool', + }) +) + +export const dbInUseConnection = withTenantMetricLabels( + meter.createUpDownCounter('db_connections_in_use', { + description: 'Number of database connections currently in use', + }) +) + +export const dbConnectionAcquireTime = withTenantMetricLabels( + meter.createHistogram('db_connection_acquire_seconds', { + description: 'Time taken to acquire a database connection from the pool in seconds', + unit: 's', + }) +) + +// ============================================================================ +// Queue Metrics +// ============================================================================ +export const queueJobSchedulingTime = withTenantMetricLabels( + meter.createHistogram('queue_job_scheduled_time_seconds', { + description: 'Time taken to schedule a job in the queue in seconds', + unit: 's', + }) +) + +export const queueJobScheduled = withTenantMetricLabels( + meter.createUpDownCounter('queue_job_scheduled', { + description: 'Current number of pending messages in the queue', + }) +) + +export const queueJobCompleted = withTenantMetricLabels( + meter.createUpDownCounter('queue_job_completed', { + description: 'Current number of processed messages in the queue', + }) +) + +export const queueJobRetryFailed = withTenantMetricLabels( + meter.createUpDownCounter('queue_job_retry_failed', { + description: 'Current number of failed attempts messages in the queue', + }) +) + +export const queueJobError = withTenantMetricLabels( + meter.createUpDownCounter('queue_job_error', { + description: 'Current number of errored messages in the queue', + }) +) + +// ============================================================================ +// S3 Metrics +// ============================================================================ +export const s3UploadPart = withTenantMetricLabels( + meter.createHistogram('s3_upload_part_seconds', { + description: 'S3 upload part performance in seconds', + unit: 's', + }) +) + +// ============================================================================ +// HTTP Pool Metrics +// ============================================================================ +export const httpPoolBusySockets = withTenantMetricLabels( + meter.createGauge('http_pool_busy_sockets', { + description: 'Number of busy sockets currently in use', + }) +) + +export const httpPoolFreeSockets = withTenantMetricLabels( + meter.createGauge('http_pool_free_sockets', { + description: 'Number of free sockets available for reuse', + }) +) + +export const httpPoolPendingRequests = withTenantMetricLabels( + meter.createGauge('http_pool_requests', { + description: 'Number of pending requests waiting for a socket', + }) +) + +export const httpPoolErrors = withTenantMetricLabels( + meter.createGauge('http_pool_errors', { + description: 'Number of socket errors', + }) +) + +function withTenantMetricLabels( + metricType: T +): T { + if ('record' in metricType) { + const originalRecord = metricType.record.bind(metricType) + metricType.record = (value: number, labels?: Record) => { + if (!prometheusMetricsIncludeTenantId) { + delete labels?.tenant_id + delete labels?.tenantId + } + + return originalRecord(value, labels) + } + return metricType + } + + if ('add' in metricType) { + const originalAdd = metricType.add.bind(metricType) + metricType.add = (value: number, labels?: Record) => { + if (!prometheusMetricsIncludeTenantId) { + delete labels?.tenant_id + delete labels?.tenantId + } + + return originalAdd(value, labels) + } + + return metricType + } + + return metricType +} diff --git a/src/internal/monitoring/otel-class-instrumentations.ts b/src/internal/monitoring/otel-class-instrumentations.ts new file mode 100644 index 000000000..5659f8b5a --- /dev/null +++ b/src/internal/monitoring/otel-class-instrumentations.ts @@ -0,0 +1,195 @@ +import { S3Client } from '@aws-sdk/client-s3' +import { Upload } from '@aws-sdk/lib-storage' +import { ClassInstrumentation } from './otel-instrumentation' +import { ObjectStorage } from '@storage/object' +import { Uploader } from '@storage/uploader' +import { Storage } from '@storage/storage' +import { Event as QueueBaseEvent } from '@internal/queue' +import { S3Backend } from '@storage/backend' +import { StorageKnexDB } from '@storage/database' +import { TenantConnection } from '@internal/database' +import { S3Store } from '@tus/s3-store' +import { StreamSplitter } from '@tus/server' +import { PgLock } from '@storage/protocols/tus' +import { Semaphore, Permit } from '@shopify/semaphore' + +export const classInstrumentations = [ + new ClassInstrumentation({ + targetClass: Storage, + enabled: true, + methodsToInstrument: [ + 'findBucket', + 'listBuckets', + 'createBucket', + 'updateBucket', + 'countObjects', + 'deleteBucket', + 'emptyBucket', + 'healthcheck', + ], + }), + new ClassInstrumentation({ + targetClass: ObjectStorage, + enabled: true, + methodsToInstrument: [ + 'uploadNewObject', + 'uploadOverridingObject', + 'deleteObject', + 'deleteObjects', + 'updateObjectMetadata', + 'updateObjectOwner', + 'findObject', + 'findObjects', + 'copyObject', + 'moveObject', + 'searchObjects', + 'listObjectsV2', + 'signObjectUrl', + 'signObjectUrls', + 'signUploadObjectUrl', + 'verifyObjectSignature', + ], + }), + new ClassInstrumentation({ + targetClass: Uploader, + enabled: true, + methodsToInstrument: ['canUpload', 'prepareUpload', 'upload', 'completeUpload'], + }), + new ClassInstrumentation({ + targetClass: QueueBaseEvent, + enabled: true, + methodsToInstrument: ['send', 'batchSend'], + setName: (name, attrs, eventClass) => { + if (attrs.constructor.name) { + return name + '.' + eventClass.constructor.name + } + return name + }, + }), + new ClassInstrumentation({ + targetClass: S3Backend, + enabled: true, + methodsToInstrument: [ + 'getObject', + 'putObject', + 'deleteObject', + 'listObjects', + 'copyObject', + 'headObject', + 'createMultipartUpload', + 'uploadPart', + 'completeMultipartUpload', + 'abortMultipartUpload', + 'listMultipartUploads', + 'listParts', + 'getSignedUrl', + 'createBucket', + 'deleteBucket', + 'listBuckets', + 'getBucketLocation', + 'getBucketVersioning', + 'putBucketVersioning', + 'getBucketLifecycleConfiguration', + 'putBucketLifecycleConfiguration', + 'deleteBucketLifecycle', + 'uploadObject', + 'privateAssetUrl', + ], + }), + new ClassInstrumentation({ + targetClass: StorageKnexDB, + enabled: true, + methodsToInstrument: ['runQuery'], + setName: (name, attrs) => { + if (attrs.queryName) { + return name + '.' + attrs.queryName + } + return name + }, + setAttributes: { + runQuery: (queryName) => { + return { + queryName, + } + }, + }, + }), + new ClassInstrumentation({ + targetClass: TenantConnection, + enabled: true, + methodsToInstrument: ['transaction', 'setScope'], + }), + new ClassInstrumentation({ + targetClass: S3Store, + enabled: true, + methodsToInstrument: [ + 'write', + 'create', + 'remove', + 'getUpload', + 'declareUploadLength', + 'uploadIncompletePart', + 'uploadPart', + 'downloadIncompletePart', + 'uploadParts', + ], + setName: (name) => 'Tus.' + name, + }), + new ClassInstrumentation({ + targetClass: StreamSplitter, + enabled: true, + methodsToInstrument: ['emitEvent'], + setName: (name: string, attrs: any) => { + if (attrs.event) { + return name + '.' + attrs.event + } + return name + }, + setAttributes: { + emitEvent: function (event) { + return { + part: this.part as any, + event, + } + }, + }, + }), + new ClassInstrumentation({ + targetClass: PgLock, + enabled: true, + methodsToInstrument: ['lock', 'unlock', 'acquireLock'], + }), + new ClassInstrumentation({ + targetClass: Semaphore, + enabled: true, + methodsToInstrument: ['acquire'], + }), + new ClassInstrumentation({ + targetClass: Permit, + enabled: true, + methodsToInstrument: ['release'], + }), + new ClassInstrumentation({ + targetClass: S3Client, + enabled: true, + methodsToInstrument: ['send'], + setAttributes: { + send: (command) => { + return { + operation: command.constructor.name as string, + } + }, + }, + setName: (name, attrs) => 'S3.' + attrs.operation, + }), + new ClassInstrumentation({ + targetClass: Upload, + enabled: true, + methodsToInstrument: [ + 'done', + '__uploadUsingPut', + '__createMultipartUpload', + 'markUploadAsAborted', + ], + }), +] diff --git a/src/internal/monitoring/otel-instrumentation.ts b/src/internal/monitoring/otel-instrumentation.ts index e5bf9bbd8..9c8b80cbf 100644 --- a/src/internal/monitoring/otel-instrumentation.ts +++ b/src/internal/monitoring/otel-instrumentation.ts @@ -1,5 +1,53 @@ import { Instrumentation, InstrumentationConfig } from '@opentelemetry/instrumentation' -import { trace, Span, SpanStatusCode, TracerProvider, MeterProvider } from '@opentelemetry/api' +import { + trace, + Span, + SpanStatusCode, + TracerProvider, + MeterProvider, + Context, +} from '@opentelemetry/api' +import { ReadableSpan, SpanProcessor } from '@opentelemetry/sdk-trace-base' +import { Span as SdkSpan } from '@opentelemetry/sdk-trace-base' + +export class TenantSpanProcessor implements SpanProcessor { + private readonly attributesToPropagate: string[] + + constructor(attributesToPropagate: string[] = ['tenant.ref', 'region']) { + this.attributesToPropagate = attributesToPropagate + } + + onStart(span: SdkSpan, parentContext: Context): void { + const parentSpan = trace.getSpan(parentContext) + if (!parentSpan) return + + // Cast to ReadableSpan to access attributes + const parentReadable = parentSpan as unknown as ReadableSpan + const parentAttributes = parentReadable.attributes + + if (!parentAttributes) return + + // Copy specified attributes from parent to child span + for (const attr of this.attributesToPropagate) { + const value = parentAttributes[attr] + if (value !== undefined) { + span.setAttribute(attr, value) + } + } + } + + onEnd(_span: ReadableSpan): void { + // No-op + } + + shutdown(): Promise { + return Promise.resolve() + } + + forceFlush(): Promise { + return Promise.resolve() + } +} interface GenericInstrumentationConfig extends InstrumentationConfig { targetClass: new (...args: any[]) => any diff --git a/src/internal/monitoring/otel-metrics.ts b/src/internal/monitoring/otel-metrics.ts new file mode 100644 index 000000000..9cb5237f6 --- /dev/null +++ b/src/internal/monitoring/otel-metrics.ts @@ -0,0 +1,211 @@ +import { getConfig } from '../../config' +import { metrics } from '@opentelemetry/api' +import { resourceFromAttributes } from '@opentelemetry/resources' +import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions' +import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc' +import { PrometheusExporter } from '@opentelemetry/exporter-prometheus' +import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base' +import { + MeterProvider, + PeriodicExportingMetricReader, + AggregationType, +} from '@opentelemetry/sdk-metrics' +import { HostMetrics } from '@opentelemetry/host-metrics' +import { registerInstrumentations } from '@opentelemetry/instrumentation' +import { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node' +import { StorageNodeInstrumentation } from '@internal/monitoring/system' +import * as grpc from '@grpc/grpc-js' +import * as os from 'os' +import { logger, logSchema } from '@internal/monitoring/logger' +import { FastifyReply, FastifyRequest } from 'fastify' + +const { version, otelMetricsExportIntervalMs, otelMetricsEnabled, region } = getConfig() + +let prometheusExporter: PrometheusExporter | undefined + +/** + * Handles the /metrics endpoint request using OTel Prometheus exporter + */ +export async function handleMetricsRequest( + request: FastifyRequest, + reply: FastifyReply +): Promise { + if (!prometheusExporter) { + reply.status(404).send('Metrics not enabled') + return + } + + const req = request.raw + const res = reply.raw + + reply.hijack() + prometheusExporter.getMetricsRequestHandler(req, res) + + return Promise.resolve() +} + +if (otelMetricsEnabled) { + const headersEnv = process.env.OTEL_EXPORTER_OTLP_METRICS_HEADERS || '' + const otlpEndpoint = + process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT + + const exporterHeaders = headersEnv + .split(',') + .filter(Boolean) + .reduce((all, header) => { + const [name, value] = header.split('=') + all[name] = value + return all + }, {} as Record) + + const grpcMetadata = new grpc.Metadata() + Object.keys(exporterHeaders).forEach((key) => { + grpcMetadata.set(key, exporterHeaders[key]) + }) + + // ============================================================================= + // Initialize MeterProvider at import time (before other modules use metrics) + // ============================================================================= + const instance = os.hostname() + + const resource = resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'storage_api', + [ATTR_SERVICE_VERSION]: version, + 'metric.version': '1', + region, + instance, + }) + + const readers = [] + + // Add OTLP exporter if endpoint is configured (for pushing to collector) + if (otlpEndpoint) { + const otlpExporter = new OTLPMetricExporter({ + url: otlpEndpoint, + compression: process.env.OTEL_EXPORTER_OTLP_COMPRESSION as CompressionAlgorithm, + headers: exporterHeaders, + metadata: grpcMetadata, + }) + + readers.push( + new PeriodicExportingMetricReader({ + exporter: otlpExporter, + exportIntervalMillis: otelMetricsExportIntervalMs, + }) + ) + } + + // Always add Prometheus exporter for /metrics endpoint + prometheusExporter = new PrometheusExporter({ + prefix: 'storage_api', + preventServerStart: true, // We'll handle the endpoint in Fastify + withResourceConstantLabels: /^(region|instance|metric\.version)$/, + }) + readers.push(prometheusExporter) + + // Bucket boundaries for duration histograms (in seconds) + // Provides good resolution from 1ms to 10s + const durationBuckets = [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10] + + const meterProvider = new MeterProvider({ + resource, + readers, + views: [ + { + instrumentName: 'storage_api_http_request_duration_seconds', + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { boundaries: durationBuckets }, + }, + }, + { + instrumentName: 'storage_api_database_query_performance_seconds', + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { boundaries: durationBuckets }, + }, + }, + { + instrumentName: 'storage_api_queue_job_scheduled_time_seconds', + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { boundaries: durationBuckets }, + }, + }, + { + instrumentName: 'storage_api_s3_upload_part_seconds', + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { boundaries: durationBuckets }, + }, + }, + { + instrumentName: 'storage_api_db_connection_acquire_seconds', + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { boundaries: durationBuckets }, + }, + }, + ], + }) + + // Register as global provider IMMEDIATELY so metrics.ts instruments work + metrics.setGlobalMeterProvider(meterProvider) + + logger.info( + { type: 'otel-metrics', otlpEndpoint, exportIntervalMs: otelMetricsExportIntervalMs }, + '[OTel Metrics] Initializing' + ) + + if (otlpEndpoint) { + logSchema.info(logger, '[OTel Metrics] OTLP exporter configured', { + type: 'otel-metrics', + }) + } + + // Initialize host metrics for Node.js runtime metrics + const hostMetrics = new HostMetrics({ + meterProvider, + name: 'storage-api-host-metrics', + }) + hostMetrics.start() + + // Register Node.js runtime instrumentations + registerInstrumentations({ + meterProvider, + instrumentations: [ + // Official OTel: event loop delay/time/utilization, GC, heap spaces + new RuntimeNodeInstrumentation(), + // Custom: event loop lag, CPU, handles, process start time, external memory, file descriptors + new StorageNodeInstrumentation({ + labels: { region, instance }, + }), + ], + }) + + logSchema.info(logger, '[OTel Metrics] Initialized successfully', { + type: 'otel-metrics', + }) + + // Graceful shutdown + const shutdown = async () => { + logSchema.info(logger, '[OTel Metrics] Stopping', { + type: 'otel-metrics', + }) + + try { + await meterProvider.shutdown() + logSchema.info(logger, '[OTel Metrics] Shutdown complete', { + type: 'otel-metrics', + }) + } catch (error) { + logSchema.error(logger, '[OTel Metrics] Shutdown error', { + type: 'otel-metrics', + error: error, + }) + } + } + + process.once('SIGTERM', shutdown) + process.once('SIGINT', shutdown) +} diff --git a/src/internal/monitoring/otel-processor.ts b/src/internal/monitoring/otel-processor.ts deleted file mode 100644 index d13fa2533..000000000 --- a/src/internal/monitoring/otel-processor.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base' -import TTLCache from '@isaacs/ttlcache' - -interface Trace { - id: string - rootSpanId: string - spans: Span[] -} - -export interface Span { - item: ReadableSpan - children: Span[] -} - -export class TraceCollectorSpanProcessor implements SpanProcessor { - private traces: TTLCache - - constructor() { - this.traces = new TTLCache({ - ttl: 120 * 1000, // 120 seconds TTL - noUpdateTTL: true, - noDisposeOnSet: true, - }) - } - - export() { - // no-op - } - - onStart(span: ReadableSpan): void { - const traceId = span.spanContext().traceId - const spanId = span.spanContext().spanId - - // No action needed on start - if (!span.parentSpanId) { - const hasTrace = this.traces.has(traceId) - - if (!hasTrace) { - this.traces.set(traceId, { - id: traceId, - spans: [ - { - item: span, - children: [], - }, - ], - rootSpanId: spanId, - }) - } - - return - } - - const trace = this.traces.get(traceId) - - if (trace) { - this.addChildSpan(trace.spans, span.parentSpanId, { item: span, children: [] }) - } - } - - onEnd(span: ReadableSpan): void { - // no-op - } - - shutdown(): Promise { - this.traces.clear() - return Promise.resolve() - } - - forceFlush(): Promise { - this.traces.clear() - return Promise.resolve() - } - - getSpansForTrace(traceId: string): Span[] { - return this.traces.get(traceId)?.spans || [] - } - - clearTrace(traceId: string): void { - this.traces.delete(traceId) - } - - private addChildSpan(spans: Span[], parentId: string, childSpan: Span): void { - for (const span of spans) { - if (span.item.spanContext().spanId === parentId) { - span.children.push(childSpan) - return - } - if (span.children.length > 0) { - this.addChildSpan(span.children, parentId, childSpan) - } - } - } -} - -export const traceCollector = new TraceCollectorSpanProcessor() diff --git a/src/internal/monitoring/otel-tracing.ts b/src/internal/monitoring/otel-tracing.ts new file mode 100644 index 000000000..720aeb94a --- /dev/null +++ b/src/internal/monitoring/otel-tracing.ts @@ -0,0 +1,178 @@ +import { getConfig } from '../../config' + +const { + version, + requestTraceHeader, + isMultitenant, + requestXForwardedHostRegExp, + tenantId: defaultTenantId, + region, + storageS3InternalTracesEnabled, +} = getConfig() + +import { NodeSDK } from '@opentelemetry/sdk-node' +import { resourceFromAttributes } from '@opentelemetry/resources' +import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions' +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc' +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' +import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base' +import { SpanExporter, BatchSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base' +import * as grpc from '@grpc/grpc-js' +import { logger, logSchema } from '@internal/monitoring/logger' +import { registerInstrumentations } from '@opentelemetry/instrumentation' +import { trace } from '@opentelemetry/api' +import { TenantSpanProcessor } from '@internal/monitoring/otel-instrumentation' + +const tracingEnabled = process.env.TRACING_ENABLED === 'true' +const headersEnv = process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS || '' + +const exporterHeaders = headersEnv + .split(',') + .filter(Boolean) + .reduce((all, header) => { + const [name, value] = header.split('=') + all[name] = value + return all + }, {} as Record) + +const grpcMetadata = new grpc.Metadata() +Object.keys(exporterHeaders).forEach((key) => { + grpcMetadata.set(key, exporterHeaders[key]) +}) + +const endpoint = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT +let traceExporter: SpanExporter | undefined = undefined + +if (tracingEnabled && endpoint) { + // Create an OTLP trace exporter + traceExporter = new OTLPTraceExporter({ + url: endpoint, + compression: process.env.OTEL_EXPORTER_OTLP_COMPRESSION as CompressionAlgorithm, + headers: exporterHeaders, + metadata: grpcMetadata, + }) +} + +// Create a BatchSpanProcessor using the trace exporter +const batchProcessor = traceExporter ? new BatchSpanProcessor(traceExporter) : undefined + +const spanProcessors: SpanProcessor[] = [] + +if (tracingEnabled) { + spanProcessors.push(new TenantSpanProcessor()) +} + +if (batchProcessor) { + spanProcessors.push(batchProcessor) +} + +if (tracingEnabled && spanProcessors.length > 0) { + // Configure the OpenTelemetry Node SDK + const sdk = new NodeSDK({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'storage', + [ATTR_SERVICE_VERSION]: version, + }), + spanProcessors: spanProcessors, + traceExporter, + instrumentations: [ + getNodeAutoInstrumentations({ + '@opentelemetry/instrumentation-http': { + enabled: true, + ignoreIncomingRequestHook: (req) => { + const ignoreRoutes = ['/metrics', '/status', '/health', '/healthcheck'] + return ignoreRoutes.some((url) => req.url?.includes(url)) ?? false + }, + ignoreOutgoingRequestHook: (req) => { + // Skip OTEL instrumentation for S3 Tables requests to avoid injecting + // unsupported headers (baggage, traceparent, tracestate) + const host = req.hostname || req.host || '' + return host.includes('.s3tables.') || host.includes('--table-s3') + }, + startIncomingSpanHook: (req) => { + let tenantId = '' + if (isMultitenant) { + if (requestXForwardedHostRegExp) { + const serverRequest = req + const xForwardedHost = serverRequest.headers['x-forwarded-host'] + if (typeof xForwardedHost !== 'string') return {} + const result = xForwardedHost.match(requestXForwardedHostRegExp) + if (!result) return {} + tenantId = result[1] + } + } else { + tenantId = defaultTenantId + } + + return { + 'tenant.ref': tenantId, + region, + } + }, + headersToSpanAttributes: { + client: { + requestHeaders: requestTraceHeader ? [requestTraceHeader] : [], + }, + server: { + requestHeaders: requestTraceHeader ? [requestTraceHeader] : [], + }, + }, + }, + '@opentelemetry/instrumentation-fs': { + enabled: false, + }, + '@opentelemetry/instrumentation-aws-sdk': { + enabled: storageS3InternalTracesEnabled, + }, + '@opentelemetry/instrumentation-pg': { + enabled: true, + requireParentSpan: true, + }, + '@opentelemetry/instrumentation-fastify': { + enabled: true, + requestHook: (span, req) => { + span.setAttribute('http.method', req.request.method) + span.setAttribute('http.route', req.request.routerPath) + span.setAttribute('tenant.ref', req.request.tenantId) + span.setAttribute('http.operation', req.request.operation) + span.setAttribute('trace.mode', req.request.tracingMode) + }, + }, + '@opentelemetry/instrumentation-knex': { + enabled: true, + }, + }), + ], + }) + + // Initialize the OpenTelemetry Node SDK + sdk.start() + + // Load class instrumentations after SDK starts to avoid loading http/metrics.ts too early + void import('./otel-class-instrumentations').then(({ classInstrumentations }) => { + registerInstrumentations({ + tracerProvider: trace.getTracerProvider(), + instrumentations: classInstrumentations, + }) + }) + + // Gracefully shutdown the SDK on process exit + process.once('SIGTERM', () => { + logSchema.info(logger, '[Otel] Stopping', { + type: 'otel', + }) + sdk + .shutdown() + .then(() => { + logSchema.info(logger, '[Otel] Exited', { + type: 'otel', + }) + }) + .catch((error) => + logSchema.error(logger, '[Otel] Shutdown error', { + type: 'otel', + error: error, + }) + ) + }) +} diff --git a/src/internal/monitoring/otel.ts b/src/internal/monitoring/otel.ts deleted file mode 100644 index 4113d4f62..000000000 --- a/src/internal/monitoring/otel.ts +++ /dev/null @@ -1,358 +0,0 @@ -import { getConfig } from '../../config' - -const { - version, - requestTraceHeader, - isMultitenant, - requestXForwardedHostRegExp, - tenantId: defaultTenantId, - region, -} = getConfig() - -import { S3Client } from '@aws-sdk/client-s3' -import { NodeSDK } from '@opentelemetry/sdk-node' -import { Resource } from '@opentelemetry/resources' -import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions' -import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc' -import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' -import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base' -import { SpanExporter, BatchSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base' -import * as grpc from '@grpc/grpc-js' -import { HttpInstrumentation } from '@opentelemetry/instrumentation-http' -import { logger, logSchema } from '@internal/monitoring/logger' -import { traceCollector } from '@internal/monitoring/otel-processor' -import { ClassInstrumentation } from './otel-instrumentation' -import { ObjectStorage } from '@storage/object' -import { Uploader } from '@storage/uploader' -import { Storage } from '@storage/storage' -import { Event as QueueBaseEvent } from '@internal/queue' -import { S3Backend } from '@storage/backend' -import { StorageKnexDB } from '@storage/database' -import { TenantConnection } from '@internal/database' -import { S3Store } from '@tus/s3-store' -import { Upload } from '@aws-sdk/lib-storage' -import { StreamSplitter } from '@tus/server' -import { PgLock } from '@storage/protocols/tus' -import { Semaphore, Permit } from '@shopify/semaphore' - -const tracingEnabled = process.env.TRACING_ENABLED === 'true' -const headersEnv = process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS || '' -const enableLogTraces = ['debug', 'logs'].includes(process.env.TRACING_MODE || '') - -const exporterHeaders = headersEnv - .split(',') - .filter(Boolean) - .reduce((all, header) => { - const [name, value] = header.split('=') - all[name] = value - return all - }, {} as Record) - -const grpcMetadata = new grpc.Metadata() -Object.keys(exporterHeaders).forEach((key) => { - grpcMetadata.set(key, exporterHeaders[key]) -}) - -const endpoint = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT -let traceExporter: SpanExporter | undefined = undefined - -if (tracingEnabled && endpoint) { - // Create an OTLP trace exporter - traceExporter = new OTLPTraceExporter({ - url: endpoint, - compression: process.env.OTEL_EXPORTER_OTLP_COMPRESSION as CompressionAlgorithm, - headers: exporterHeaders, - metadata: grpcMetadata, - }) -} - -// Create a BatchSpanProcessor using the trace exporter -const batchProcessor = traceExporter ? new BatchSpanProcessor(traceExporter) : undefined - -const spanProcessors: SpanProcessor[] = [] - -if (batchProcessor) { - spanProcessors.push(batchProcessor) -} - -if (enableLogTraces) { - spanProcessors.push(traceCollector) -} - -if (tracingEnabled && spanProcessors.length > 0) { - // Configure the OpenTelemetry Node SDK - const sdk = new NodeSDK({ - resource: new Resource({ - [ATTR_SERVICE_NAME]: 'storage', - [ATTR_SERVICE_VERSION]: version, - }), - spanProcessors: spanProcessors, - traceExporter, - instrumentations: [ - new HttpInstrumentation({ - enabled: true, - ignoreIncomingRequestHook: (req) => { - const ignoreRoutes = ['/metrics', '/status', '/health', '/healthcheck'] - return ignoreRoutes.some((url) => req.url?.includes(url)) ?? false - }, - startIncomingSpanHook: (req) => { - let tenantId = '' - if (isMultitenant) { - if (requestXForwardedHostRegExp) { - const serverRequest = req - const xForwardedHost = serverRequest.headers['x-forwarded-host'] - if (typeof xForwardedHost !== 'string') return {} - const result = xForwardedHost.match(requestXForwardedHostRegExp) - if (!result) return {} - tenantId = result[1] - } - } else { - tenantId = defaultTenantId - } - - return { - 'tenant.ref': tenantId, - region, - } - }, - headersToSpanAttributes: { - client: { - requestHeaders: requestTraceHeader ? [requestTraceHeader] : [], - }, - server: { - requestHeaders: requestTraceHeader ? [requestTraceHeader] : [], - }, - }, - }), - new ClassInstrumentation({ - targetClass: Storage, - enabled: true, - methodsToInstrument: [ - 'findBucket', - 'listBuckets', - 'createBucket', - 'updateBucket', - 'countObjects', - 'deleteBucket', - 'emptyBucket', - 'healthcheck', - ], - }), - new ClassInstrumentation({ - targetClass: ObjectStorage, - enabled: true, - methodsToInstrument: [ - 'uploadNewObject', - 'uploadOverridingObject', - 'deleteObject', - 'deleteObjects', - 'updateObjectMetadata', - 'updateObjectOwner', - 'findObject', - 'findObjects', - 'copyObject', - 'moveObject', - 'searchObjects', - 'listObjectsV2', - 'signObjectUrl', - 'signObjectUrls', - 'signUploadObjectUrl', - 'verifyObjectSignature', - ], - }), - new ClassInstrumentation({ - targetClass: Uploader, - enabled: true, - methodsToInstrument: ['canUpload', 'prepareUpload', 'upload', 'completeUpload'], - }), - new ClassInstrumentation({ - targetClass: QueueBaseEvent, - enabled: true, - methodsToInstrument: ['send', 'batchSend'], - setName: (name, attrs, eventClass) => { - if (attrs.constructor.name) { - return name + '.' + eventClass.constructor.name - } - return name - }, - }), - new ClassInstrumentation({ - targetClass: S3Backend, - enabled: true, - methodsToInstrument: [ - 'getObject', - 'putObject', - 'deleteObject', - 'listObjects', - 'copyObject', - 'headObject', - 'createMultipartUpload', - 'uploadPart', - 'completeMultipartUpload', - 'abortMultipartUpload', - 'listMultipartUploads', - 'listParts', - 'getSignedUrl', - 'createBucket', - 'deleteBucket', - 'listBuckets', - 'getBucketLocation', - 'getBucketVersioning', - 'putBucketVersioning', - 'getBucketLifecycleConfiguration', - 'putBucketLifecycleConfiguration', - 'deleteBucketLifecycle', - 'uploadObject', - 'privateAssetUrl', - ], - }), - new ClassInstrumentation({ - targetClass: StorageKnexDB, - enabled: true, - methodsToInstrument: ['runQuery'], - setName: (name, attrs) => { - if (attrs.queryName) { - return name + '.' + attrs.queryName - } - return name - }, - setAttributes: { - runQuery: (queryName) => { - return { - queryName, - } - }, - }, - }), - new ClassInstrumentation({ - targetClass: TenantConnection, - enabled: true, - methodsToInstrument: ['transaction', 'setScope'], - }), - new ClassInstrumentation({ - targetClass: S3Store, - enabled: true, - methodsToInstrument: [ - 'write', - 'create', - 'remove', - 'getUpload', - 'declareUploadLength', - 'uploadIncompletePart', - 'uploadPart', - 'downloadIncompletePart', - 'uploadParts', - ], - setName: (name) => 'Tus.' + name, - }), - new ClassInstrumentation({ - targetClass: StreamSplitter, - enabled: true, - methodsToInstrument: ['emitEvent'], - setName: (name: string, attrs: any) => { - if (attrs.event) { - return name + '.' + attrs.event - } - return name - }, - setAttributes: { - emitEvent: function (event) { - return { - part: this.part as any, - event, - } - }, - }, - }), - new ClassInstrumentation({ - targetClass: PgLock, - enabled: true, - methodsToInstrument: ['lock', 'unlock', 'acquireLock'], - }), - new ClassInstrumentation({ - targetClass: Semaphore, - enabled: true, - methodsToInstrument: ['acquire'], - }), - new ClassInstrumentation({ - targetClass: Permit, - enabled: true, - methodsToInstrument: ['release'], - }), - new ClassInstrumentation({ - targetClass: S3Client, - enabled: true, - methodsToInstrument: ['send'], - setAttributes: { - send: (command) => { - return { - operation: command.constructor.name as string, - } - }, - }, - setName: (name, attrs) => 'S3.' + attrs.operation, - }), - new ClassInstrumentation({ - targetClass: Upload, - enabled: true, - methodsToInstrument: [ - 'done', - '__uploadUsingPut', - '__createMultipartUpload', - 'markUploadAsAborted', - ], - }), - getNodeAutoInstrumentations({ - '@opentelemetry/instrumentation-http': { - enabled: false, - }, - '@opentelemetry/instrumentation-fs': { - enabled: false, - }, - '@opentelemetry/instrumentation-aws-sdk': { - enabled: true, - }, - '@opentelemetry/instrumentation-pg': { - enabled: true, - requireParentSpan: true, - }, - '@opentelemetry/instrumentation-fastify': { - enabled: true, - requestHook: (span, req) => { - span.setAttribute('http.method', req.request.method) - span.setAttribute('http.route', req.request.routerPath) - span.setAttribute('tenant.ref', req.request.tenantId) - span.setAttribute('http.operation', req.request.operation) - span.setAttribute('trace.mode', req.request.tracingMode) - }, - }, - '@opentelemetry/instrumentation-knex': { - enabled: true, - }, - }), - ], - }) - - // Initialize the OpenTelemetry Node SDK - sdk.start() - - // Gracefully shutdown the SDK on process exit - process.once('SIGTERM', () => { - logSchema.info(logger, '[Otel] Stopping', { - type: 'otel', - }) - sdk - .shutdown() - .then(() => { - logSchema.info(logger, '[Otel] Exited', { - type: 'otel', - }) - }) - .catch((error) => - logSchema.error(logger, '[Otel] Shutdown error', { - type: 'otel', - error: error, - }) - ) - }) -} diff --git a/src/internal/monitoring/system/base-collector.ts b/src/internal/monitoring/system/base-collector.ts new file mode 100644 index 000000000..4b11c329d --- /dev/null +++ b/src/internal/monitoring/system/base-collector.ts @@ -0,0 +1,45 @@ +import { Meter } from '@opentelemetry/api' + +export interface MetricCollector { + enable(): void + disable(): void + updateMetricInstruments(meter: Meter): void +} + +export interface CollectorConfig { + prefix?: string + labels?: Record +} + +export abstract class BaseCollector + implements MetricCollector +{ + protected _config: T + protected _enabled = false + + constructor(config: T) { + this._config = config + } + + get namePrefix(): string { + return this._config.prefix ? `${this._config.prefix}.` : '' + } + + get labels(): Record { + return this._config.labels ?? {} + } + + enable(): void { + this._enabled = true + this.internalEnable() + } + + disable(): void { + this._enabled = false + this.internalDisable() + } + + abstract updateMetricInstruments(meter: Meter): void + protected abstract internalEnable(): void + protected abstract internalDisable(): void +} diff --git a/src/internal/monitoring/system/cpu-collector.ts b/src/internal/monitoring/system/cpu-collector.ts new file mode 100644 index 000000000..346ff1c3a --- /dev/null +++ b/src/internal/monitoring/system/cpu-collector.ts @@ -0,0 +1,49 @@ +import { Meter, Counter } from '@opentelemetry/api' +import { BaseCollector } from './base-collector' + +export class CpuCollector extends BaseCollector { + private _lastCpuUsage = process.cpuUsage() + private _userCounter: Counter | null = null + private _systemCounter: Counter | null = null + + updateMetricInstruments(meter: Meter): void { + this._userCounter = meter.createCounter(`${this.namePrefix}process.cpu.user`, { + description: 'Total user CPU time spent in seconds', + unit: 's', + }) + + this._systemCounter = meter.createCounter(`${this.namePrefix}process.cpu.system`, { + description: 'Total system CPU time spent in seconds', + unit: 's', + }) + + meter + .createObservableCounter(`${this.namePrefix}process.cpu.total`, { + description: 'Total user and system CPU time spent in seconds', + unit: 's', + }) + .addCallback((observable) => { + if (!this._enabled) return + + const cpuUsage = process.cpuUsage() + const userDelta = (cpuUsage.user - this._lastCpuUsage.user) / 1e6 + const systemDelta = (cpuUsage.system - this._lastCpuUsage.system) / 1e6 + + if (userDelta > 0) this._userCounter?.add(userDelta, this.labels) + if (systemDelta > 0) this._systemCounter?.add(systemDelta, this.labels) + + this._lastCpuUsage = cpuUsage + + const totalSeconds = (cpuUsage.user + cpuUsage.system) / 1e6 + observable.observe(totalSeconds, this.labels) + }) + } + + protected internalEnable(): void { + this._lastCpuUsage = process.cpuUsage() + } + + protected internalDisable(): void { + // no-op + } +} diff --git a/src/internal/monitoring/system/file-descriptor-collector.ts b/src/internal/monitoring/system/file-descriptor-collector.ts new file mode 100644 index 000000000..1c68106d1 --- /dev/null +++ b/src/internal/monitoring/system/file-descriptor-collector.ts @@ -0,0 +1,132 @@ +import { Meter } from '@opentelemetry/api' +import { BaseCollector } from './base-collector' +import * as fs from 'fs/promises' +import { exec } from 'child_process' +import { promisify } from 'util' + +const execAsync = promisify(exec) + +/** + * Collector for file descriptor metrics. + * Works on Linux by reading from /proc/self/fd and /proc/self/limits. + * On other platforms, metrics will not be collected. + */ +export class FileDescriptorCollector extends BaseCollector { + private _maxFds: number | null = null + private _openFds: number | null = null + private _updateInterval: NodeJS.Timeout | null = null + + updateMetricInstruments(meter: Meter): void { + // Open file descriptors gauge + meter + .createObservableGauge(`${this.namePrefix}process.open_fds`, { + description: 'Number of open file descriptors', + }) + .addCallback((observable) => { + if (!this._enabled || this._openFds === null) return + observable.observe(this._openFds, this.labels) + }) + + // Max file descriptors gauge + meter + .createObservableGauge(`${this.namePrefix}process.max_fds`, { + description: 'Maximum number of file descriptors allowed', + }) + .addCallback((observable) => { + if (!this._enabled || this._maxFds === null) return + observable.observe(this._maxFds, this.labels) + }) + } + + /** + * Get the number of open file descriptors + * On macOS: counts entries in /dev/fd + * On Linux: counts entries in /proc/self/fd + */ + private async getOpenFileDescriptors(): Promise { + try { + // Both macOS (/dev/fd) and Linux (/proc/self/fd) support directory-based FD counting + const fdPath = process.platform === 'darwin' ? '/dev/fd' : '/proc/self/fd' + + if (process.platform === 'darwin' || process.platform === 'linux') { + const fds = await fs.readdir(fdPath) + // Subtract 1 because readdir itself opens an FD + return Math.max(0, fds.length - 1) + } + + return null + } catch { + return null + } + } + + /** + * Get the maximum number of file descriptors + * On macOS: uses ulimit -n command + * On Linux: parses /proc/self/limits + */ + private async getMaxFileDescriptors(): Promise { + if (this._maxFds !== null) { + return this._maxFds + } + + try { + // macOS: use ulimit -n command + if (process.platform === 'darwin') { + const { stdout } = await execAsync('ulimit -n') + const limit = parseInt(stdout.trim(), 10) + if (!isNaN(limit)) { + this._maxFds = limit + return limit + } + return null + } + + // Linux: read from /proc/self/limits + if (process.platform === 'linux') { + const limits = await fs.readFile('/proc/self/limits', 'utf8') + const lines = limits.split('\n') + + for (const line of lines) { + if (line.startsWith('Max open files')) { + const parts = line.split(/\s+/) + const softLimit = parseInt(parts[3], 10) + if (!isNaN(softLimit)) { + this._maxFds = softLimit + return softLimit + } + } + } + } + + return null + } catch { + return null + } + } + + protected internalEnable(): void { + this._maxFds = null + this._openFds = null + + // Update metrics periodically + this.updateMetrics().catch(() => { + // Ignore errors + }) + this._updateInterval = setInterval(() => this.updateMetrics().catch(() => {}), 5000) + } + + protected internalDisable(): void { + if (this._updateInterval) { + clearInterval(this._updateInterval) + this._updateInterval = null + } + this._maxFds = null + this._openFds = null + } + + private async updateMetrics(): Promise { + this._maxFds = await this.getMaxFileDescriptors() + this._openFds = await this.getOpenFileDescriptors() + } +} diff --git a/src/internal/monitoring/system/handles-collector.ts b/src/internal/monitoring/system/handles-collector.ts new file mode 100644 index 000000000..f4c74ac76 --- /dev/null +++ b/src/internal/monitoring/system/handles-collector.ts @@ -0,0 +1,36 @@ +import { Meter } from '@opentelemetry/api' +import { BaseCollector } from './base-collector' + +export class HandlesCollector extends BaseCollector { + updateMetricInstruments(meter: Meter): void { + meter + .createObservableGauge(`${this.namePrefix}nodejs.active_handles.total`, { + description: 'Number of active libuv handles', + }) + .addCallback((observable) => { + if (!this._enabled) return + // @ts-expect-error - _getActiveHandles is not in types but exists + const handles = process._getActiveHandles?.() || [] + observable.observe(handles.length, this.labels) + }) + + meter + .createObservableGauge(`${this.namePrefix}nodejs.active_requests.total`, { + description: 'Number of active libuv requests', + }) + .addCallback((observable) => { + if (!this._enabled) return + // @ts-expect-error - _getActiveRequests is not in types but exists + const requests = process._getActiveRequests?.() || [] + observable.observe(requests.length, this.labels) + }) + } + + protected internalEnable(): void { + // no-op + } + + protected internalDisable(): void { + // no-op + } +} diff --git a/src/internal/monitoring/system/index.ts b/src/internal/monitoring/system/index.ts new file mode 100644 index 000000000..7b190c86f --- /dev/null +++ b/src/internal/monitoring/system/index.ts @@ -0,0 +1,6 @@ +export { StorageNodeInstrumentation, StorageNodeInstrumentationConfig } from './instrumentation' +export { BaseCollector, MetricCollector, CollectorConfig } from './base-collector' +export { CpuCollector } from './cpu-collector' +export { HandlesCollector } from './handles-collector' +export { ProcessStartCollector } from './process-start-collector' +export { ExternalMemoryCollector } from './memory-collector' diff --git a/src/internal/monitoring/system/instrumentation.ts b/src/internal/monitoring/system/instrumentation.ts new file mode 100644 index 000000000..378ee9320 --- /dev/null +++ b/src/internal/monitoring/system/instrumentation.ts @@ -0,0 +1,82 @@ +import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation' +import { MetricCollector, CollectorConfig } from './base-collector' +import { CpuCollector } from './cpu-collector' +import { HandlesCollector } from './handles-collector' +import { ProcessStartCollector } from './process-start-collector' +import { ExternalMemoryCollector } from './memory-collector' +import { FileDescriptorCollector } from './file-descriptor-collector' + +export interface StorageNodeInstrumentationConfig extends InstrumentationConfig, CollectorConfig {} + +const DEFAULT_CONFIG: StorageNodeInstrumentationConfig = { + prefix: '', + labels: {}, +} + +/** + * Custom Node.js runtime instrumentation that provides metrics + * not covered by @opentelemetry/instrumentation-runtime-node: + * - Event loop lag (setImmediate measurement) + * - CPU usage (user, system, total) + * - Active handles and requests + * - Process start time + * - External memory, ArrayBuffers, RSS + * - File descriptors (open and max, Linux only) + * + * Use alongside RuntimeNodeInstrumentation for complete coverage. + */ +export class StorageNodeInstrumentation extends InstrumentationBase { + private _collectors: MetricCollector[] = [] + + constructor(config: StorageNodeInstrumentationConfig = {}) { + const mergedConfig = { ...DEFAULT_CONFIG, ...config } + super('@storage/instrumentation-node', '1.0.0', mergedConfig) + + const collectorConfig: CollectorConfig = { + prefix: mergedConfig.prefix, + labels: mergedConfig.labels, + } + + this._collectors = [ + new CpuCollector(collectorConfig), + new HandlesCollector(collectorConfig), + new ProcessStartCollector(collectorConfig), + new ExternalMemoryCollector(collectorConfig), + new FileDescriptorCollector(collectorConfig), + ] + + // Enable collectors if instrumentation is enabled (matches RuntimeNodeInstrumentation pattern) + if (this._config.enabled) { + for (const collector of this._collectors) { + collector.enable() + } + } + } + + init() { + // Not instrumenting or patching a Node.js module + } + + // Called when a new MeterProvider is set + override _updateMetricInstruments() { + if (!this._collectors) return + for (const collector of this._collectors) { + collector.updateMetricInstruments(this.meter) + } + } + + override enable() { + super.enable() + if (!this._collectors) return + for (const collector of this._collectors) { + collector.enable() + } + } + + override disable() { + super.disable() + for (const collector of this._collectors) { + collector.disable() + } + } +} diff --git a/src/internal/monitoring/system/memory-collector.ts b/src/internal/monitoring/system/memory-collector.ts new file mode 100644 index 000000000..f68b15ff2 --- /dev/null +++ b/src/internal/monitoring/system/memory-collector.ts @@ -0,0 +1,63 @@ +import { Meter } from '@opentelemetry/api' +import { BaseCollector } from './base-collector' + +export class ExternalMemoryCollector extends BaseCollector { + updateMetricInstruments(meter: Meter): void { + meter + .createObservableGauge(`${this.namePrefix}nodejs.memory.external`, { + description: 'Node.js external memory size in bytes', + unit: 'By', + }) + .addCallback((observable) => { + if (!this._enabled) return + try { + const mem = process.memoryUsage() + if (mem.external !== undefined) { + observable.observe(mem.external, this.labels) + } + } catch { + // ignore errors + } + }) + + meter + .createObservableGauge(`${this.namePrefix}nodejs.memory.array_buffers`, { + description: 'Node.js ArrayBuffers memory size in bytes', + unit: 'By', + }) + .addCallback((observable) => { + if (!this._enabled) return + try { + const mem = process.memoryUsage() + if (mem.arrayBuffers !== undefined) { + observable.observe(mem.arrayBuffers, this.labels) + } + } catch { + // ignore errors + } + }) + + meter + .createObservableGauge(`${this.namePrefix}nodejs.memory.rss`, { + description: 'Resident Set Size - total memory allocated for the process', + unit: 'By', + }) + .addCallback((observable) => { + if (!this._enabled) return + try { + const mem = process.memoryUsage() + observable.observe(mem.rss, this.labels) + } catch { + // ignore errors + } + }) + } + + protected internalEnable(): void { + // no-op + } + + protected internalDisable(): void { + // no-op + } +} diff --git a/src/internal/monitoring/system/process-start-collector.ts b/src/internal/monitoring/system/process-start-collector.ts new file mode 100644 index 000000000..ddcc1e2a1 --- /dev/null +++ b/src/internal/monitoring/system/process-start-collector.ts @@ -0,0 +1,26 @@ +import { Meter } from '@opentelemetry/api' +import { BaseCollector } from './base-collector' + +const START_TIME_SECONDS = Math.round(Date.now() / 1000 - process.uptime()) + +export class ProcessStartCollector extends BaseCollector { + updateMetricInstruments(meter: Meter): void { + meter + .createObservableGauge(`${this.namePrefix}process.start_time`, { + description: 'Start time of the process since unix epoch in seconds', + unit: 's', + }) + .addCallback((observable) => { + if (!this._enabled) return + observable.observe(START_TIME_SECONDS, this.labels) + }) + } + + protected internalEnable(): void { + // no-op + } + + protected internalDisable(): void { + // no-op + } +} diff --git a/src/internal/queue/event.ts b/src/internal/queue/event.ts index 033e827be..7c4e138c9 100644 --- a/src/internal/queue/event.ts +++ b/src/internal/queue/event.ts @@ -1,7 +1,7 @@ import { Queue } from './queue' import PgBoss, { Job, SendOptions, WorkOptions, Queue as PgBossQueue } from 'pg-boss' import { getConfig } from '../../config' -import { QueueJobScheduled, QueueJobSchedulingTime } from '@internal/monitoring/metrics' +import { queueJobScheduled, queueJobSchedulingTime } from '@internal/monitoring/metrics' import { logger, logSchema } from '@internal/monitoring' import { getTenantConfig } from '@internal/database' import { ERRORS } from '@internal/errors' @@ -272,7 +272,7 @@ export class Event> { } } - const timer = QueueJobSchedulingTime.startTimer() + const startTime = process.hrtime.bigint() const sendOptions = constructor.getSendOptions(this.payload) || {} if (this.payload.scheduleAt) { @@ -302,7 +302,7 @@ export class Event> { }, }) - QueueJobScheduled.inc({ + queueJobScheduled.add(1, { name: constructor.getQueueName(), }) @@ -336,7 +336,8 @@ export class Event> { }, }) } finally { - timer({ + const duration = Number(process.hrtime.bigint() - startTime) / 1e9 + queueJobSchedulingTime.record(duration, { name: constructor.getQueueName(), }) } diff --git a/src/internal/queue/queue.ts b/src/internal/queue/queue.ts index 657d6b632..ea023fc6d 100644 --- a/src/internal/queue/queue.ts +++ b/src/internal/queue/queue.ts @@ -3,10 +3,12 @@ import { ERRORS } from '@internal/errors' import { QueueDB } from '@internal/queue/database' import { getConfig } from '../../config' import { logger, logSchema } from '../monitoring' -import { QueueJobRetryFailed, QueueJobCompleted, QueueJobError } from '../monitoring/metrics' +import { queueJobRetryFailed, queueJobCompleted, queueJobError } from '../monitoring/metrics' import { Event } from './event' import { Semaphore } from '@shopify/semaphore' +const { region } = getConfig() + //eslint-disable-next-line @typescript-eslint/no-explicit-any type SubclassOfBaseClass = (new (payload: any) => Event) & { [K in keyof typeof Event]: (typeof Event)[K] @@ -347,11 +349,11 @@ export abstract class Queue { await event.handle(job, { signal: queueOpts.signal }) await this.pgBoss?.complete(event.getQueueName(), job.id) - QueueJobCompleted.inc({ + queueJobCompleted.add(1, { name: event.getQueueName(), }) } catch (e) { - QueueJobRetryFailed.inc({ + queueJobRetryFailed.add(1, { name: event.getQueueName(), }) @@ -367,7 +369,7 @@ export abstract class Queue { return } if (dbJob.retryCount >= dbJob.retryLimit) { - QueueJobError.inc({ + queueJobError.add(1, { name: event.getQueueName(), }) } diff --git a/src/internal/streams/index.ts b/src/internal/streams/index.ts index dcff245a4..4ee1f6b39 100644 --- a/src/internal/streams/index.ts +++ b/src/internal/streams/index.ts @@ -2,3 +2,4 @@ export * from './stream-speed' export * from './byte-counter' export * from './hash-stream' export * from './monitor' +export * from './min-chunk' diff --git a/src/internal/streams/min-chunk.ts b/src/internal/streams/min-chunk.ts new file mode 100644 index 000000000..c3911a2eb --- /dev/null +++ b/src/internal/streams/min-chunk.ts @@ -0,0 +1,38 @@ +import { Transform, TransformCallback } from 'stream' + +/** + * A transform stream that buffers data until it has at least minChunkSize bytes + * before pushing downstream. This is useful for S3 Tables which requires + * chunks to be at least 8KB (except for the last chunk). + */ +export class MinChunkTransform extends Transform { + private buffer: Buffer = Buffer.alloc(0) + + constructor(private readonly minChunkSize: number) { + super() + } + + _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) { + try { + this.buffer = Buffer.concat([this.buffer, chunk]) + + // Push complete chunks of minChunkSize + while (this.buffer.length >= this.minChunkSize) { + this.push(this.buffer.subarray(0, this.minChunkSize)) + this.buffer = this.buffer.subarray(this.minChunkSize) + } + + callback() + } catch (err) { + callback(err as Error) + } + } + + _flush(callback: TransformCallback) { + // Push remaining data (last chunk can be smaller than minChunkSize) + if (this.buffer.length > 0) { + this.push(this.buffer) + } + callback() + } +} diff --git a/src/start/server.ts b/src/start/server.ts index 29c76b598..71061284d 100644 --- a/src/start/server.ts +++ b/src/start/server.ts @@ -1,4 +1,6 @@ -import '@internal/monitoring/otel' +import '@internal/monitoring/otel-tracing' +import '@internal/monitoring/otel-metrics' + import { FastifyInstance } from 'fastify' import { IncomingMessage, Server, ServerResponse } from 'node:http' @@ -201,14 +203,11 @@ async function httpAdminServer( ) { const { adminRequestIdHeader, adminPort, host } = getConfig() - const adminApp = buildAdmin( - { - logger, - disableRequestLogging: true, - requestIdHeader: adminRequestIdHeader, - }, - app - ) + const adminApp = buildAdmin({ + logger, + disableRequestLogging: true, + requestIdHeader: adminRequestIdHeader, + }) const closePromise = createServerClosedPromise(adminApp.server, () => { logSchema.info(logger, '[Admin Server] Exited', { diff --git a/src/storage/backend/s3/adapter.ts b/src/storage/backend/s3/adapter.ts index a718e14d5..c8d86de96 100644 --- a/src/storage/backend/s3/adapter.ts +++ b/src/storage/backend/s3/adapter.ts @@ -423,10 +423,12 @@ export class S3Backend implements StorageBackendAdapter { Key: withOptionalVersion(key, version), CacheControl: cacheControl, ContentType: contentType, - Metadata: { - ...metadata, - Version: version || '', - }, + Metadata: metadata + ? { + ...metadata, + Version: version || '', + } + : undefined, }) const resp = await this.client.send(createMultiPart) diff --git a/src/storage/database/knex.ts b/src/storage/database/knex.ts index c9a5ca59e..55c5f5c30 100644 --- a/src/storage/database/knex.ts +++ b/src/storage/database/knex.ts @@ -19,13 +19,13 @@ import { } from './adapter' import { DatabaseError } from 'pg' import { TenantConnection } from '@internal/database' -import { DbQueryPerformance } from '@internal/monitoring/metrics' +import { dbQueryPerformance } from '@internal/monitoring/metrics' import { hashStringToInt } from '@internal/hashing' import { DBMigration, tenantHasMigrations } from '@internal/database/migrations' import { getConfig } from '../../config' import { isUuid } from '../limits' -const { isMultitenant } = getConfig() +const { isMultitenant, region } = getConfig() /** * Database @@ -1026,9 +1026,13 @@ export class StorageKnexDB implements Database { queryName: string, fn: T ): Promise>> { - const timer = DbQueryPerformance.startTimer({ - name: queryName, - }) + const startTime = process.hrtime.bigint() + const recordDuration = () => { + const duration = Number(process.hrtime.bigint() - startTime) / 1e9 + dbQueryPerformance.record(duration, { + name: queryName, + }) + } let tnx = this.options.tnx @@ -1062,14 +1066,14 @@ export class StorageKnexDB implements Database { } } - timer() + recordDuration() return result } catch (e) { if (needsNewTransaction) { await tnx.rollback() } - timer() + recordDuration() throw e } } diff --git a/src/storage/protocols/s3/s3-handler.ts b/src/storage/protocols/s3/s3-handler.ts index 32d79deaf..1bc955313 100644 --- a/src/storage/protocols/s3/s3-handler.ts +++ b/src/storage/protocols/s3/s3-handler.ts @@ -31,6 +31,8 @@ import { logger, logSchema } from '@internal/monitoring' const { storageS3Region, storageS3Bucket } = getConfig() +export const MAX_PART_SIZE = 5 * 1024 * 1024 * 1024 // 5GB + export class S3ProtocolHandler { constructor( protected readonly storage: Storage, diff --git a/src/storage/uploader.ts b/src/storage/uploader.ts index 40af9aa32..343aef8f9 100644 --- a/src/storage/uploader.ts +++ b/src/storage/uploader.ts @@ -2,7 +2,7 @@ import { randomUUID } from 'crypto' import { FastifyRequest } from 'fastify' import { ERRORS } from '@internal/errors' -import { FileUploadedSuccess, FileUploadStarted } from '@internal/monitoring/metrics' +import { fileUploadedSuccess, fileUploadStarted } from '@internal/monitoring/metrics' import { ObjectMetadata, StorageBackendAdapter } from './backend' import { getFileSizeLimit, isEmptyFolder } from './limits' @@ -79,8 +79,9 @@ export class Uploader { */ async prepareUpload(options: Omit) { await this.canUpload(options) - FileUploadStarted.inc({ - is_multipart: Boolean(options.uploadType).toString(), + fileUploadStarted.add(1, { + uploadType: options.uploadType, + tenantId: this.db.tenantId, }) return randomUUID() @@ -236,11 +237,9 @@ export class Uploader { await Promise.all(events) - FileUploadedSuccess.inc({ - is_multipart: uploadType === 'resumable' ? 1 : 0, - is_resumable: uploadType === 'resumable' ? 1 : 0, - is_standard: uploadType === 'standard' ? 1 : 0, - is_s3: uploadType === 's3' ? 1 : 0, + fileUploadedSuccess.add(1, { + uploadType, + tenantId: this.db.tenantId, }) return { obj: newObject, isNew, metadata: objectMetadata }