Skip to content

Commit 82e9ce2

Browse files
committed
feat: add Prometheus metrics example and documentation
- Introduced a new example for Prometheus metrics under `examples/metrics-prometheus`. - Updated README and Chinese README to include Prometheus metrics in examples. - Added new example documentation for Aedes Basic, Aedes WebSocket, AsyncAPI Standalone, AsyncAPI + Elysia, Lifecycle Events, Kafka Bridge, and Service Push. - Enhanced handler limits documentation to reference the new metrics example. - Updated metrics documentation to include runnable example instructions. - Added new metrics to track dispatch duration, publish duration, in-flight handlers, and error phases.
1 parent 4437410 commit 82e9ce2

34 files changed

Lines changed: 631 additions & 8 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ See the [Getting Started guide](https://mqttkit.keyp.dev/getting-started) for ro
8989

9090
## Examples
9191

92-
Runnable examples under [`examples/`](./examples) cover the basic TCP / WebSocket broker, lifecycle events, service push, Kafka bridge, schema validation, MQTT 5 RPC, and AsyncAPI docs (standalone HTTP or shared Elysia port).
92+
Runnable examples under [`examples/`](./examples) cover the basic TCP / WebSocket broker, lifecycle events, service push, Kafka bridge, schema validation, MQTT 5 RPC, AsyncAPI docs (standalone HTTP or shared Elysia port), and Prometheus metrics.
9393

9494
```bash
9595
bun install

README.zh-CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ router、middleware、events、RPC、Kafka 桥接等详见 [快速开始](https:
8989

9090
## 示例
9191

92-
[`examples/`](./examples) 下有可运行示例:TCP / WebSocket broker、lifecycle events、service push、Kafka bridge、schema 校验、MQTT 5 RPC、AsyncAPI 文档(独立 HTTP 或与 Elysia 复用端口)。
92+
[`examples/`](./examples) 下有可运行示例:TCP / WebSocket broker、lifecycle events、service push、Kafka bridge、schema 校验、MQTT 5 RPC、AsyncAPI 文档(独立 HTTP 或与 Elysia 复用端口)、Prometheus 指标
9393

9494
```bash
9595
bun install

bun.lock

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/.vitepress/config.ts

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,67 @@ const zhSidebarGroups = GUIDE_SECTIONS.map((section) => ({
108108
items: section.topics.map((topic) => ({ text: topic.zh, link: `/zh/${topic.id}` })),
109109
}))
110110

111+
type ExampleEntry = {
112+
id: string
113+
en: string
114+
zh: string
115+
}
116+
117+
const EXAMPLE_SECTIONS: { en: string; zh: string; items: ExampleEntry[] }[] = [
118+
{
119+
en: 'Getting Started',
120+
zh: '入门',
121+
items: [
122+
{ id: 'aedes-basic', en: 'Aedes Basic (TCP)', zh: 'Aedes 基础 (TCP)' },
123+
{ id: 'aedes-ws', en: 'Aedes WebSocket', zh: 'Aedes WebSocket' },
124+
{ id: 'events', en: 'Lifecycle Events', zh: '生命周期事件' },
125+
],
126+
},
127+
{
128+
en: 'Message Handling',
129+
zh: '消息处理',
130+
items: [
131+
{ id: 'schema-validation', en: 'Schema Validation', zh: 'Schema 校验' },
132+
{ id: 'rpc', en: 'MQTT 5 RPC', zh: 'MQTT 5 RPC' },
133+
],
134+
},
135+
{
136+
en: 'Integration',
137+
zh: '集成',
138+
items: [
139+
{ id: 'service-push', en: 'Service Push', zh: 'Service Push' },
140+
{ id: 'kafka-bridge', en: 'Kafka Bridge', zh: 'Kafka Bridge' },
141+
{ id: 'asyncapi-docs', en: 'AsyncAPI Standalone', zh: 'AsyncAPI 独立服务' },
142+
{ id: 'asyncapi-elysia', en: 'AsyncAPI + Elysia', zh: 'AsyncAPI + Elysia' },
143+
],
144+
},
145+
{
146+
en: 'Observability',
147+
zh: '可观测性',
148+
items: [
149+
{ id: 'metrics-prometheus', en: 'Prometheus Metrics', zh: 'Prometheus 指标' },
150+
],
151+
},
152+
]
153+
154+
const enExampleSidebar = [
155+
{ text: 'Overview', link: '/examples/' },
156+
...EXAMPLE_SECTIONS.map((section) => ({
157+
text: section.en,
158+
collapsed: false,
159+
items: section.items.map((item) => ({ text: item.en, link: `/examples/${item.id}` })),
160+
})),
161+
]
162+
163+
const zhExampleSidebar = [
164+
{ text: '总览', link: '/zh/examples/' },
165+
...EXAMPLE_SECTIONS.map((section) => ({
166+
text: section.zh,
167+
collapsed: false,
168+
items: section.items.map((item) => ({ text: item.zh, link: `/zh/examples/${item.id}` })),
169+
})),
170+
]
171+
111172
export default withMermaid({
112173
title: 'mqttkit',
113174
description:
@@ -152,12 +213,15 @@ export default withMermaid({
152213
lang: 'en-US',
153214
themeConfig: {
154215
nav: [
155-
{ text: 'Guide', link: '/getting-started' },
216+
{ text: 'Guide', link: '/getting-started', activeMatch: '^/(?!examples|changelog)' },
217+
{ text: 'Examples', link: '/examples/', activeMatch: '^/examples/' },
156218
{ text: 'Packages', link: `${GITHUB_REPO}/tree/main/packages` },
157-
{ text: 'Examples', link: `${GITHUB_REPO}/tree/main/examples` },
158219
{ text: 'Changelog', link: '/changelog' },
159220
],
160-
sidebar: enSidebarGroups,
221+
sidebar: {
222+
'/examples/': enExampleSidebar,
223+
'/': enSidebarGroups,
224+
},
161225
editLink: {
162226
pattern: `${GITHUB_REPO}/edit/main/docs/:path`,
163227
text: 'Edit this page on GitHub',
@@ -173,12 +237,13 @@ export default withMermaid({
173237
link: '/zh/',
174238
themeConfig: {
175239
nav: [
176-
{ text: '指南', link: '/zh/getting-started' },
240+
{ text: '指南', link: '/zh/getting-started', activeMatch: '^/zh/(?!examples|changelog)' },
241+
{ text: '示例', link: '/zh/examples/', activeMatch: '^/zh/examples/' },
177242
{ text: '包', link: `${GITHUB_REPO}/tree/main/packages` },
178-
{ text: '示例', link: `${GITHUB_REPO}/tree/main/examples` },
179243
{ text: '更新日志', link: '/zh/changelog' },
180244
],
181245
sidebar: {
246+
'/zh/examples/': zhExampleSidebar,
182247
'/zh/': zhSidebarGroups,
183248
},
184249
outline: { label: '本页目录' },

docs/changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
sidebar: false
3+
aside: false
4+
---
5+
16
<!--@include: ../CHANGELOG.md-->

docs/examples/aedes-basic.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Aedes Basic (TCP)
2+
3+
Smallest possible mqttkit app: Aedes TCP broker, username-based auth, audit middleware, and a route that enforces `params.uid === principal.uid` on publish.
4+
5+
```bash
6+
bun run --cwd examples/aedes-basic dev
7+
```
8+
9+
Listens on `mqtt://localhost:1883`. Connect with any MQTT client.
10+
11+
## Source
12+
13+
<<< ../../examples/aedes-basic/src/index.ts
14+
15+
[View on GitHub](https://github.com/keyp-dev/mqttkit/tree/main/examples/aedes-basic)

docs/examples/aedes-ws.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Aedes WebSocket
2+
3+
Same as Aedes Basic but TCP is disabled and the broker listens on `ws://localhost:8888/mqtt`. Useful for browser-based MQTT clients (`mqtt.js` over WebSocket).
4+
5+
```bash
6+
bun run --cwd examples/aedes-ws dev
7+
```
8+
9+
## Source
10+
11+
<<< ../../examples/aedes-ws/src/index.ts
12+
13+
[View on GitHub](https://github.com/keyp-dev/mqttkit/tree/main/examples/aedes-ws)

docs/examples/asyncapi-docs.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# AsyncAPI Standalone
2+
3+
Generates AsyncAPI 3.0 from registered routes and serves browsable docs on its own HTTP server. One TypeBox schema powers runtime validation, static `ctx.body` typing, and AsyncAPI payload at once.
4+
5+
```bash
6+
bun run --cwd examples/asyncapi-docs dev
7+
```
8+
9+
- MQTT: `mqtt://localhost:1883`
10+
- AsyncAPI JSON: `http://localhost:9000/asyncapi.json`
11+
- AsyncAPI YAML: `http://localhost:9000/asyncapi.yaml`
12+
- Rendered docs: `http://localhost:9000/docs`
13+
14+
## Source
15+
16+
::: code-group
17+
<<< ../../examples/asyncapi-docs/src/index.ts [index.ts]
18+
<<< ../../examples/asyncapi-docs/src/zod.ts [zod.ts]
19+
:::
20+
21+
[View on GitHub](https://github.com/keyp-dev/mqttkit/tree/main/examples/asyncapi-docs)

docs/examples/asyncapi-elysia.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# AsyncAPI + Elysia
2+
3+
Shares one `node:http` server between MQTT-over-WebSocket (handled by aedes) and an Elysia HTTP app that serves AsyncAPI docs. Useful when you don't want two separate ports.
4+
5+
```bash
6+
bun run --cwd examples/asyncapi-elysia dev
7+
```
8+
9+
Everything lives on `:3300` — MQTT WS on `/mqtt`, AsyncAPI HTTP routes alongside.
10+
11+
## Source
12+
13+
<<< ../../examples/asyncapi-elysia/src/index.ts
14+
15+
[View on GitHub](https://github.com/keyp-dev/mqttkit/tree/main/examples/asyncapi-elysia)

docs/examples/events.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Lifecycle Events
2+
3+
Demonstrates broker-level events: `client`, `clientReady`, `clientDisconnect`, `keepaliveTimeout`, `publish`, `subscribe`, etc. Each event is logged with `app.on(name, handler)` — handy for connection tracing and debugging.
4+
5+
```bash
6+
bun run --cwd examples/events dev
7+
```
8+
9+
Listens on `mqtt://localhost:1884` and `ws://localhost:8889/mqtt`.
10+
11+
## Source
12+
13+
<<< ../../examples/events/src/index.ts
14+
15+
[View on GitHub](https://github.com/keyp-dev/mqttkit/tree/main/examples/events) · [Events guide](../events)

0 commit comments

Comments
 (0)