Implement AnonBot integration and monitoring enhancements

- Added AnonBot service to docker-compose with resource limits and environment variables.
- Updated Makefile to include commands for AnonBot logs, restart, and dependency checks.
- Enhanced Grafana dashboards with AnonBot health metrics and database connection statistics.
- Implemented AnonBot status retrieval in the message sender for improved monitoring.
- Updated Prometheus configuration to scrape metrics from AnonBot service.
This commit was merged in pull request #2.
This commit is contained in:
2025-09-08 23:17:24 +03:00
parent 40968dd075
commit b34da5015d
9 changed files with 2187 additions and 206 deletions

View File

@@ -0,0 +1,874 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "anon_bot_active_users",
"interval": "",
"legendFormat": "Active Users",
"refId": "A"
}
],
"title": "Active Users",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 6,
"y": 0
},
"id": 2,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "anon_bot_active_questions",
"interval": "",
"legendFormat": "Active Questions",
"refId": "A"
}
],
"title": "Active Questions",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_questions_total{status=\"created\"}[5m]) * 60",
"interval": "",
"legendFormat": "Questions Created/min",
"refId": "A"
},
{
"expr": "rate(anon_bot_questions_total{status=\"processed\"}[5m]) * 60",
"interval": "",
"legendFormat": "Questions Processed/min",
"refId": "B"
},
{
"expr": "rate(anon_bot_questions_total{status=\"rejected\"}[5m]) * 60",
"interval": "",
"legendFormat": "Questions Rejected/min",
"refId": "C"
},
{
"expr": "rate(anon_bot_questions_total{status=\"deleted\"}[5m]) * 60",
"interval": "",
"legendFormat": "Questions Deleted/min",
"refId": "D"
}
],
"title": "Questions Flow (per minute)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_answers_total{status=\"sent\"}[5m]) * 60",
"interval": "",
"legendFormat": "Answers Sent/min",
"refId": "A"
},
{
"expr": "rate(anon_bot_answers_total{status=\"delivered\"}[5m]) * 60",
"interval": "",
"legendFormat": "Answers Delivered/min",
"refId": "B"
},
{
"expr": "rate(anon_bot_answers_total{status=\"delivery_failed\"}[5m]) * 60",
"interval": "",
"legendFormat": "Delivery Failed/min",
"refId": "C"
}
],
"title": "Answers Flow (per minute)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_users_total{action=\"created\"}[5m]) * 60",
"interval": "",
"legendFormat": "New Users/min",
"refId": "A"
},
{
"expr": "rate(anon_bot_users_total{action=\"updated\"}[5m]) * 60",
"interval": "",
"legendFormat": "Updated Users/min",
"refId": "B"
}
],
"title": "User Activity (per minute)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "sum(rate(anon_bot_messages_total[1d])) by (message_type)",
"interval": "",
"legendFormat": "{{message_type}} (daily)",
"refId": "A"
}
],
"title": "Daily Trends - Messages",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "sum(rate(anon_bot_questions_total[1d])) by (status)",
"interval": "",
"legendFormat": "{{status}} (daily)",
"refId": "A"
}
],
"title": "Daily Trends - Questions",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 24
},
"id": 8,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "anon_bot_active_users",
"interval": "",
"legendFormat": "Live Active Users",
"refId": "A"
}
],
"title": "Live Activity - Active Users",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 6,
"y": 24
},
"id": 9,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "rate(anon_bot_messages_total[1m]) * 60",
"interval": "",
"legendFormat": "Messages/min",
"refId": "A"
}
],
"title": "Messages per Minute",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 12,
"y": 24
},
"id": 10,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "rate(anon_bot_questions_total[1h]) * 3600",
"interval": "",
"legendFormat": "Questions/hour",
"refId": "A"
}
],
"title": "Questions per Hour",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 18,
"y": 24
},
"id": 11,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "rate(anon_bot_answers_total[1m]) * 60",
"interval": "",
"legendFormat": "Answers/min",
"refId": "A"
}
],
"title": "Answers per Minute",
"type": "stat"
}
],
"refresh": "5s",
"schemaVersion": 30,
"style": "dark",
"tags": [
"anonbot",
"overview",
"monitoring"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "AnonBot Overview",
"uid": "anonbot-overview",
"version": 1,
"weekStart": ""
}

View File

@@ -0,0 +1,877 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "histogram_quantile(0.95, rate(anon_bot_message_processing_seconds_bucket[5m]))",
"interval": "",
"legendFormat": "Message Processing 95th percentile",
"refId": "A"
},
{
"expr": "histogram_quantile(0.95, rate(anon_bot_question_processing_seconds_bucket[5m]))",
"interval": "",
"legendFormat": "Question Processing 95th percentile",
"refId": "B"
},
{
"expr": "histogram_quantile(0.95, rate(anon_bot_answer_processing_seconds_bucket[5m]))",
"interval": "",
"legendFormat": "Answer Processing 95th percentile",
"refId": "C"
}
],
"title": "Response Time - 95th Percentile",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_message_processing_seconds_bucket[5m])",
"interval": "",
"legendFormat": "{{le}}",
"refId": "A"
}
],
"title": "Latency Heatmap - Message Processing",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "histogram_quantile(0.95, rate(anon_bot_db_query_duration_seconds_bucket[5m]))",
"interval": "",
"legendFormat": "DB Query 95th percentile - {{operation}}/{{table}}",
"refId": "A"
}
],
"title": "Database Performance - Query Duration",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 16
},
"id": 4,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "anon_bot_db_connections_active",
"interval": "",
"legendFormat": "Active DB Connections",
"refId": "A"
}
],
"title": "Database Connections - Active",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "yellow",
"value": 80
},
{
"color": "red",
"value": 100
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 6,
"y": 16
},
"id": 5,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"expr": "anon_bot_db_pool_utilization_percent",
"interval": "",
"legendFormat": "Pool Utilization %",
"refId": "A"
}
],
"title": "DB Pool Utilization",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_messages_total{status=\"success\"}[5m]) / rate(anon_bot_messages_total[5m]) * 100",
"interval": "",
"legendFormat": "Messages Success Rate",
"refId": "A"
},
{
"expr": "rate(anon_bot_questions_total{status=\"processed\"}[5m]) / rate(anon_bot_questions_total[5m]) * 100",
"interval": "",
"legendFormat": "Questions Success Rate",
"refId": "B"
},
{
"expr": "rate(anon_bot_answers_total{status=\"sent\"}[5m]) / rate(anon_bot_answers_total[5m]) * 100",
"interval": "",
"legendFormat": "Answers Success Rate",
"refId": "C"
}
],
"title": "Success/Error Rates",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_errors_total[5m])",
"interval": "",
"legendFormat": "{{component}} - {{error_type}}",
"refId": "A"
}
],
"title": "Error Rate by Component",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 24
},
"id": 8,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "sum(rate(anon_bot_errors_total[5m])) by (error_type)",
"interval": "",
"legendFormat": "{{error_type}}",
"refId": "A"
}
],
"title": "Error Types Distribution",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 24
},
"id": 9,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_db_queries_total{status=\"error\"}[5m])",
"interval": "",
"legendFormat": "{{operation}}/{{table}}",
"refId": "A"
}
],
"title": "Database Errors",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 32
},
"id": 10,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"expr": "rate(anon_bot_pagination_errors_total[5m])",
"interval": "",
"legendFormat": "{{entity_type}} - {{error_type}}",
"refId": "A"
}
],
"title": "Pagination Errors",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 30,
"style": "dark",
"tags": [
"anonbot",
"performance",
"monitoring"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Performance AnonBot",
"uid": "anonbot-performance",
"version": 1,
"weekStart": ""
}

View File

@@ -361,6 +361,284 @@
}
},
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}
},
{
"id": 11,
"title": "AnonBot Health Status",
"type": "timeseries",
"targets": [
{
"expr": "rate(anon_bot_errors_total[5m])",
"legendFormat": "{{component}} - {{error_type}}"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"unit": "short"
}
},
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 24}
},
{
"id": 12,
"title": "AnonBot Database Connections",
"type": "timeseries",
"targets": [
{
"expr": "anon_bot_db_connections_active",
"legendFormat": "Active Connections"
},
{
"expr": "rate(anon_bot_db_connections_total[5m])",
"legendFormat": "Total Connections/min - {{status}}"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"unit": "short"
}
},
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 24}
},
{
"id": 13,
"title": "AnonBot System Health",
"type": "stat",
"targets": [
{
"expr": "anon_bot_active_users",
"legendFormat": "Active Users"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"steps": [
{"color": "green", "value": null},
{"color": "yellow", "value": 10},
{"color": "red", "value": 50}
]
},
"unit": "short"
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": false
},
"textMode": "auto"
},
"gridPos": {"h": 8, "w": 6, "x": 0, "y": 32}
},
{
"id": 14,
"title": "AnonBot Active Questions",
"type": "stat",
"targets": [
{
"expr": "anon_bot_active_questions",
"legendFormat": "Active Questions"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"steps": [
{"color": "green", "value": null},
{"color": "yellow", "value": 20},
{"color": "red", "value": 100}
]
},
"unit": "short"
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": false
},
"textMode": "auto"
},
"gridPos": {"h": 8, "w": 6, "x": 6, "y": 32}
},
{
"id": 15,
"title": "AnonBot Message Rate",
"type": "stat",
"targets": [
{
"expr": "rate(anon_bot_messages_total[1m]) * 60",
"legendFormat": "Messages/min"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"steps": [
{"color": "green", "value": null},
{"color": "yellow", "value": 10},
{"color": "red", "value": 50}
]
},
"unit": "short"
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": false
},
"textMode": "auto"
},
"gridPos": {"h": 8, "w": 6, "x": 12, "y": 32}
},
{
"id": 16,
"title": "AnonBot Error Rate",
"type": "stat",
"targets": [
{
"expr": "rate(anon_bot_errors_total[5m])",
"legendFormat": "Errors/min"
}
],
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"thresholds": {
"steps": [
{"color": "green", "value": null},
{"color": "yellow", "value": 1},
{"color": "red", "value": 5}
]
},
"unit": "short"
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": false
},
"textMode": "auto"
},
"gridPos": {"h": 8, "w": 6, "x": 18, "y": 32}
}
],
"time": {

View File

@@ -1,188 +0,0 @@
# PID Manager - Управление процессами ботов
## Описание
`pid_manager.py` - это общий модуль для управления PID файлами всех ботов в проекте. Он обеспечивает создание, отслеживание и очистку PID файлов для мониторинга состояния процессов.
## Использование
### Для новых ботов
Чтобы добавить PID мониторинг в новый бот, выполните следующие шаги:
1. **Импортируйте PID менеджер в ваш скрипт запуска:**
```python
import sys
import os
# Добавляем путь к инфраструктуре в sys.path
infra_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'infra', 'monitoring')
if infra_path not in sys.path:
sys.path.insert(0, infra_path)
from pid_manager import get_bot_pid_manager
```
2. **Создайте PID менеджер в начале main функции:**
```python
async def main():
# Создаем PID менеджер для отслеживания процесса (если доступен)
pid_manager = None
if get_bot_pid_manager:
pid_manager = get_bot_pid_manager("your_bot_name") # Замените на имя вашего бота
if not pid_manager.create_pid_file():
logger.error("Не удалось создать PID файл, завершаем работу")
return
else:
logger.info("PID менеджер недоступен, запуск без PID файла")
# Ваш код запуска бота...
```
3. **Очистите PID файл при завершении:**
```python
try:
# Ваш код работы бота...
finally:
# Очищаем PID файл (если PID менеджер доступен)
if pid_manager:
pid_manager.cleanup_pid_file()
```
### Для мониторинга
Чтобы добавить новый бот в систему мониторинга:
```python
from infra.monitoring.metrics_collector import MetricsCollector
# Создаем экземпляр коллектора метрик
collector = MetricsCollector()
# Добавляем новый бот в мониторинг
collector.add_bot_to_monitoring("your_bot_name")
# Теперь можно проверять статус
status, uptime = collector.check_process_status("your_bot_name")
```
## Структура файлов
```
prod/
├── infra/
│ └── monitoring/
│ ├── pid_manager.py # Основной модуль
│ ├── metrics_collector.py # Мониторинг процессов
│ └── README_PID_MANAGER.md # Эта документация
├── bots/
│ ├── telegram-helper-bot/
│ │ └── run_helper.py # Использует PID менеджер
│ └── your-new-bot/
│ └── run_your_bot.py # Будет использовать PID менеджер
├── helper_bot.pid # PID файл helper_bot
├── your_bot.pid # PID файл вашего бота
└── .gitignore # Содержит *.pid
```
## API
### PIDManager
- `create_pid_file()` - Создает PID файл
- `cleanup_pid_file()` - Удаляет PID файл
- `is_running()` - Проверяет, запущен ли процесс
- `get_pid()` - Получает PID из файла
### Функции
- `get_bot_pid_manager(bot_name)` - Создает PID менеджер для бота
- `create_pid_manager(process_name, project_root)` - Создает PID менеджер с настройками
## Примеры
### Простой бот
```python
import asyncio
from pid_manager import get_bot_pid_manager
async def main():
# Создаем PID менеджер
pid_manager = get_bot_pid_manager("simple_bot")
if not pid_manager.create_pid_file():
print("Не удалось создать PID файл")
return
try:
# Ваш код бота
print("Бот запущен...")
await asyncio.sleep(3600) # Работаем час
finally:
# Очищаем PID файл
pid_manager.cleanup_pid_file()
if __name__ == '__main__':
asyncio.run(main())
```
### Бот с обработкой сигналов
```python
import asyncio
import signal
from pid_manager import get_bot_pid_manager
async def main():
pid_manager = get_bot_pid_manager("advanced_bot")
if not pid_manager.create_pid_file():
return
# Флаг для корректного завершения
shutdown_event = asyncio.Event()
def signal_handler(signum, frame):
print(f"Получен сигнал {signum}, завершаем работу...")
shutdown_event.set()
# Регистрируем обработчики сигналов
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
# Ваш код бота
await shutdown_event.wait()
finally:
pid_manager.cleanup_pid_file()
if __name__ == '__main__':
asyncio.run(main())
```
## Примечания
- PID файлы создаются в корне проекта
- Все PID файлы автоматически игнорируются Git (см. `.gitignore`)
- PID менеджер автоматически обрабатывает сигналы SIGTERM и SIGINT
- При завершении процесса PID файл автоматически удаляется
- Система мониторинга автоматически находит PID файлы в корне проекта
## Изолированный запуск
При запуске бота изолированно (без доступа к основному проекту):
- PID менеджер автоматически не создается
- Бот запускается без PID файла
- В логах появляется сообщение "PID менеджер недоступен (изолированный запуск), PID файл не создается"
- Это позволяет запускать бота в любой среде без ошибок
## Автоматическое определение
Система автоматически определяет доступность PID менеджера:
1. **В основном проекте**: PID менеджер доступен, создается PID файл для мониторинга
2. **Изолированно**: PID менеджер недоступен, бот работает без PID файла
3. **Fallback**: Если PID менеджер недоступен, бот продолжает работать нормально

View File

@@ -64,6 +64,39 @@ class MessageSender:
logger.error(f"Ошибка при отправке сообщения в Telegram: {e}")
return False
async def get_anonbot_status(self) -> Tuple[str, str]:
"""Получение статуса AnonBot через HTTP API"""
try:
async with aiohttp.ClientSession() as session:
# AnonBot доступен через Docker network
url = "http://bots_anon_bot:8081/status"
async with session.get(url, timeout=aiohttp.ClientTimeout(total=5)) as response:
if response.status == 200:
data = await response.json()
status = data.get('status', 'unknown')
uptime = data.get('uptime', 'unknown')
# Форматируем статус с эмодзи
if status == 'running':
status_emoji = ""
elif status == 'stopped':
status_emoji = ""
else:
status_emoji = "⚠️"
return f"{status_emoji}", uptime
else:
logger.warning(f"AnonBot API вернул статус {response.status}")
return "⚠️ AnonBot", "API недоступен"
except aiohttp.ClientError as e:
logger.warning(f"Ошибка подключения к AnonBot API: {e}")
return "", "Недоступен"
except Exception as e:
logger.error(f"Неожиданная ошибка при получении статуса AnonBot: {e}")
return "⚠️", "Ошибка"
def should_send_status(self) -> bool:
"""Проверка, нужно ли отправить статус (каждые N минут)"""
now = datetime.now()
@@ -147,11 +180,14 @@ class MessageSender:
else:
return "🚨"
def get_status_message(self, system_info: Dict) -> str:
async def get_status_message(self, system_info: Dict) -> str:
"""Формирование сообщения со статусом сервера"""
try:
helper_bot_status, helper_bot_uptime = self.metrics_collector.check_process_status('helper_bot')
# Получаем статус AnonBot
anonbot_status, anonbot_uptime = await self.get_anonbot_status()
# Получаем эмодзи для всех метрик
cpu_emoji = self._get_cpu_emoji(system_info['cpu_percent'])
ram_emoji = self._get_memory_emoji(system_info['ram_percent'])
@@ -183,6 +219,7 @@ Read: <b>{system_info['disk_read_speed']}</b> | Write: <b>{system_info['disk_wri
**🤖 Процессы:**
{helper_bot_status} helper-bot - {helper_bot_uptime}
{anonbot_status} AnonBot - {anonbot_uptime}
---------------------------------
⏰ Uptime сервера: {system_info['system_uptime']}
🔍 Уровень мониторинга: {level_text} ({monitoring_level})"""
@@ -259,7 +296,7 @@ Read: <b>{system_info['disk_read_speed']}</b> | Write: <b>{system_info['disk_wri
logger.error("Не удалось получить информацию о системе")
return False
status_message = self.get_status_message(system_info)
status_message = await self.get_status_message(system_info)
success = await self.send_telegram_message(self.group_for_logs, status_message)
# Обновляем время последней отправки только при успешной отправке

View File

@@ -590,14 +590,17 @@ class MetricsCollector:
alerts.append(('cpu', system_info['cpu_percent'], f"Нагрузка за 1 мин: {system_info['load_avg_1m']}"))
logger.warning(f"CPU ALERT: {system_info['cpu_percent']:.1f}% > {self.threshold}% (задержка {self.alert_delays['cpu']}s)")
else:
# CPU ниже порога - сбрасываем состояние
# CPU ниже порога - сбрасываем состояние только если был активный алерт
if self.alert_states['cpu']:
self.alert_states['cpu'] = False
recoveries.append(('cpu', system_info['cpu_percent']))
logger.info(f"CPU RECOVERY: {system_info['cpu_percent']:.1f}% < {self.recovery_threshold}%")
# Сбрасываем время начала превышения
self.alert_start_times['cpu'] = None
# Сбрасываем время начала превышения только после отправки алерта
self.alert_start_times['cpu'] = None
elif system_info['cpu_percent'] < self.recovery_threshold and self.alert_start_times['cpu'] is not None:
# Если CPU опустился значительно ниже порога, сбрасываем время начала превышения
logger.debug(f"CPU значительно ниже порога {self.recovery_threshold}%: {system_info['cpu_percent']:.1f}% - сбрасываем время начала превышения")
self.alert_start_times['cpu'] = None
# Проверка RAM с задержкой
if system_info['ram_percent'] > self.threshold:
@@ -613,14 +616,17 @@ class MetricsCollector:
alerts.append(('ram', system_info['ram_percent'], f"Используется: {system_info['ram_used']} GB из {system_info['ram_total']} GB"))
logger.warning(f"RAM ALERT: {system_info['ram_percent']:.1f}% > {self.threshold}% (задержка {self.alert_delays['ram']}s)")
else:
# RAM ниже порога - сбрасываем состояние
# RAM ниже порога - сбрасываем состояние только если был активный алерт
if self.alert_states['ram']:
self.alert_states['ram'] = False
recoveries.append(('ram', system_info['ram_percent']))
logger.info(f"RAM RECOVERY: {system_info['ram_percent']:.1f}% < {self.recovery_threshold}%")
# Сбрасываем время начала превышения
self.alert_start_times['ram'] = None
# Сбрасываем время начала превышения только после отправки алерта
self.alert_start_times['ram'] = None
elif system_info['ram_percent'] < self.recovery_threshold and self.alert_start_times['ram'] is not None:
# Если RAM опустился значительно ниже порога, сбрасываем время начала превышения
logger.debug(f"RAM значительно ниже порога {self.recovery_threshold}%: {system_info['ram_percent']:.1f}% - сбрасываем время начала превышения")
self.alert_start_times['ram'] = None
# Проверка диска с задержкой
if system_info['disk_percent'] > self.threshold:
@@ -636,14 +642,17 @@ class MetricsCollector:
alerts.append(('disk', system_info['disk_percent'], f"Свободно: {system_info['disk_free']} GB на /"))
logger.warning(f"DISK ALERT: {system_info['disk_percent']:.1f}% > {self.threshold}% (задержка {self.alert_delays['disk']}s)")
else:
# Диск ниже порога - сбрасываем состояние
# Диск ниже порога - сбрасываем состояние только если был активный алерт
if self.alert_states['disk']:
self.alert_states['disk'] = False
recoveries.append(('disk', system_info['disk_percent']))
logger.info(f"DISK RECOVERY: {system_info['disk_percent']:.1f}% < {self.recovery_threshold}%")
# Сбрасываем время начала превышения
self.alert_start_times['disk'] = None
# Сбрасываем время начала превышения только после отправки алерта
self.alert_start_times['disk'] = None
elif system_info['disk_percent'] < self.recovery_threshold and self.alert_start_times['disk'] is not None:
# Если диск опустился значительно ниже порога, сбрасываем время начала превышения
logger.debug(f"Disk значительно ниже порога {self.recovery_threshold}%: {system_info['disk_percent']:.1f}% - сбрасываем время начала превышения")
self.alert_start_times['disk'] = None
return alerts, recoveries

View File

@@ -32,6 +32,18 @@ scrape_configs:
scrape_timeout: 10s
honor_labels: true
- job_name: 'anon-bot'
static_configs:
- targets: ['bots_anon_bot:8081'] # AnonBot на порту 8081
labels:
bot_name: 'anon-bot'
environment: 'production'
service: 'anon-bot'
metrics_path: '/metrics'
scrape_interval: 15s
scrape_timeout: 10s
honor_labels: true
alerting:
alertmanagers:
- static_configs: