Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.

Commit f334ea6

Browse files
authored
Add Monitoring dashboard, improve APIs, further cleanup (#75)
1 parent 73acfdf commit f334ea6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+7727
-1221
lines changed

.gitignore

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,15 @@ db/
159159
.vscode/
160160

161161
# JetBrains
162-
.idea/
162+
.idea/
163+
164+
# macOS
165+
.DS_Store
166+
167+
# prometheus
168+
prometheus/
169+
prometheus.yml
170+
!examples/prometheus.yml
171+
172+
# grafana
173+
grafana/

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ RUN echo "Running WebUI tests..." && \
3232

3333
FROM base AS build
3434
WORKDIR /usr/src/app
35+
36+
RUN apt-get update && apt-get install -y git && apt-get clean && rm -rf /var/lib/apt/lists/*
37+
3538
COPY --from=test /usr/src/app/node_modules ./node_modules
3639
COPY --from=test /usr/src/app/webui/node_modules ./webui/node_modules
3740
COPY --from=test /usr/src/app/ ./
@@ -48,7 +51,6 @@ FROM base AS runtime
4851

4952
RUN apt-get update && apt-get install -y \
5053
ffmpeg \
51-
git \
5254
supervisor \
5355
python3 \
5456
python3-pip \

database/schema.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,52 @@ export const commandUsageTable = pgTable("command_usage", {
9090
index("idx_command_usage_command_name").on(table.commandName),
9191
index("idx_command_usage_created_at").on(table.createdAt),
9292
]);
93+
94+
export const botErrorsTable = pgTable("bot_errors", {
95+
id: varchar({ length: 255 }).notNull().primaryKey(),
96+
errorType: varchar({ length: 100 }).notNull(),
97+
errorMessage: varchar({ length: 2000 }).notNull(),
98+
errorStack: varchar(),
99+
commandName: varchar({ length: 255 }),
100+
chatType: varchar({ length: 50 }),
101+
severity: varchar({ length: 20 }).notNull().default('error'),
102+
resolved: boolean().notNull().default(false),
103+
createdAt: timestamp().notNull().defaultNow(),
104+
resolvedAt: timestamp(),
105+
}, (table) => [
106+
index("idx_bot_errors_created_at").on(table.createdAt),
107+
index("idx_bot_errors_error_type").on(table.errorType),
108+
index("idx_bot_errors_resolved").on(table.resolved),
109+
index("idx_bot_errors_severity").on(table.severity),
110+
]);
111+
112+
export const telegramErrorsTable = pgTable("telegram_errors", {
113+
id: varchar({ length: 255 }).notNull().primaryKey(),
114+
errorCode: integer(),
115+
errorDescription: varchar({ length: 1000 }).notNull(),
116+
method: varchar({ length: 100 }),
117+
parameters: varchar(),
118+
retryCount: integer().notNull().default(0),
119+
resolved: boolean().notNull().default(false),
120+
createdAt: timestamp().notNull().defaultNow(),
121+
lastRetryAt: timestamp(),
122+
}, (table) => [
123+
index("idx_telegram_errors_created_at").on(table.createdAt),
124+
index("idx_telegram_errors_error_code").on(table.errorCode),
125+
index("idx_telegram_errors_resolved").on(table.resolved),
126+
]);
127+
128+
export const systemHealthTable = pgTable("system_health", {
129+
id: varchar({ length: 255 }).notNull().primaryKey(),
130+
timestamp: timestamp().notNull().defaultNow(),
131+
botUptime: boolean().notNull(),
132+
databaseConnected: boolean().notNull(),
133+
valkeyConnected: boolean().notNull(),
134+
memoryUsageBytes: integer(),
135+
activeUsers24h: integer(),
136+
commandsLastHour: integer(),
137+
errorRate: real(),
138+
avgResponseTime: integer(),
139+
}, (table) => [
140+
index("idx_system_health_timestamp").on(table.timestamp),
141+
]);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Admin Dashboard
3+
description: Monitor Kowalski through the admin dashboard
4+
icon: Dashboard
5+
---
6+
7+
The suggested method of monitoring Kowalski is through the admin dashboard. You can find it at [http://localhost:3000/admin/monitoring](http://localhost:3000/admin/monitoring), where `localhost:3000` is the URL to your Kowalski instances' WebUI.
8+
9+
At this time, it does not require documentation, though you can [submit an Issue](https://github.com/abocn/TelegramBot/issues) if you need help.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Monitoring
3+
description: Different methods of monitoring Kowalski
4+
icon: ChartColumnIncreasing
5+
---
6+
7+
You can monitor Kowalski's backend easily though a variety of ways. The best way to monitor Kowalski is through the admin dashboard, though we provide a Prometheus-compatible metrics endpoint for those looking to use tools like [Grafana](https://grafana.com/grafana/).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: Prometheus
3+
description: Different methods of monitoring Kowalski
4+
icon: Prometheus
5+
---
6+
7+
You can monitor Kowalski's backend easily though a variety of ways. The best way to monitor Kowalski is through the admin dashboard, though we provide a Prometheus-compatible metrics endpoint for those looking to use tools like [Grafana](https://grafana.com/grafana/).
8+
9+
## Metrics Endpoint
10+
11+
The /metrics endpoint runs on port `3030`, and is bundled as a part of the Telegram bot. Its code lives in the `telegram/api` directory.
12+
13+
You can use this data to build, for instance, a custom Grafana dashboard. Or you could even make your own monitoring dashboard! The choice is really yours.
14+
15+
## Grafana Dashboard
16+
17+
We've included a sample Grafana dashboard in the `examples` directory of the source, which can be a great way to get started with monitoring Kowalski with Prometheus. You can find it named as `examples/monitoring/grafana.json`, and import through the Grafana UI.
18+
19+
An example `docker-compose.monitoring.yml` file has also been provided for a quick-start of Kowalski, Prometheus, and Grafana.

docs/lib/source.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { docs } from '@/.source';
22
import { loader } from 'fumadocs-core/source';
33
import { icons } from 'lucide-react';
4-
import { SiDocker, SiYoutube } from 'react-icons/si';
5-
import { TbSparkles, TbServer } from "react-icons/tb";
4+
import { SiDocker, SiPrometheus, SiYoutube } from 'react-icons/si';
5+
import { TbSparkles, TbServer, TbDashboard } from "react-icons/tb";
66
import { createElement, ElementType } from 'react';
77

88
const customIcons: Record<string, ElementType> = {
99
Docker: SiDocker,
1010
Sparkles: TbSparkles,
1111
Youtube: SiYoutube,
1212
Server: TbServer,
13+
Dashboard: TbDashboard,
14+
Prometheus: SiPrometheus,
1315
};
1416

1517
export const source = loader({

docs/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
"@types/react-dom": "^19.1.9",
2525
"typescript": "^5.9.2",
2626
"@types/mdx": "^2.0.13",
27-
"@tailwindcss/postcss": "^4.1.12",
28-
"tailwindcss": "^4.1.12",
27+
"@tailwindcss/postcss": "^4.1.13",
28+
"tailwindcss": "^4.1.13",
2929
"postcss": "^8.5.6",
30-
"eslint": "^8",
30+
"eslint": "^8.57.1",
3131
"eslint-config-next": "15.5.2"
3232
}
3333
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
services:
2+
kowalski:
3+
build: .
4+
container_name: kowalski
5+
volumes:
6+
- ./telegram/props/lastfm.json:/usr/src/app/telegram/props/lastfm.json
7+
environment:
8+
- NODE_ENV=production
9+
env_file:
10+
- .env
11+
networks:
12+
- kowalski
13+
depends_on:
14+
- postgres
15+
restart: always
16+
postgres:
17+
image: postgres:17
18+
container_name: kowalski-postgres
19+
volumes:
20+
- ./db:/var/lib/postgresql/data
21+
environment:
22+
- POSTGRES_USER=kowalski
23+
- POSTGRES_PASSWORD=kowalski
24+
- POSTGRES_DB=kowalski
25+
networks:
26+
- kowalski
27+
restart: always
28+
valkey:
29+
image: valkey/valkey
30+
container_name: kowalski-valkey
31+
networks:
32+
- kowalski
33+
restart: always
34+
prometheus:
35+
image: prom/prometheus:latest
36+
container_name: kowalski-prometheus
37+
volumes:
38+
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
39+
- ./prometheus:/prometheus
40+
command:
41+
- '--config.file=/etc/prometheus/prometheus.yml'
42+
- '--storage.tsdb.path=/prometheus'
43+
- '--web.console.libraries=/etc/prometheus/console_libraries'
44+
- '--web.console.templates=/etc/prometheus/consoles'
45+
- '--web.enable-lifecycle'
46+
networks:
47+
- kowalski
48+
restart: always
49+
grafana:
50+
image: grafana/grafana
51+
container_name: kowalski-grafana
52+
ports:
53+
- "3001:3000"
54+
networks:
55+
- kowalski
56+
volumes:
57+
- ./grafana:/var/lib/grafana
58+
restart: always
59+
#docs:
60+
# build:
61+
# context: ./docs
62+
# dockerfile: Dockerfile
63+
# container_name: kowalski-docs
64+
# environment:
65+
# - NODE_ENV=production
66+
# networks:
67+
# - kowalski
68+
# restart: always
69+
70+
networks:
71+
kowalski:

0 commit comments

Comments
 (0)