@engjts/nexus 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
- package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
- package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
- package/dist/advanced/playground/playground.d.ts +19 -0
- package/dist/advanced/playground/playground.d.ts.map +1 -1
- package/dist/advanced/playground/playground.js +70 -0
- package/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/playground/types.d.ts +20 -0
- package/dist/advanced/playground/types.d.ts.map +1 -1
- package/dist/core/application.d.ts +14 -0
- package/dist/core/application.d.ts.map +1 -1
- package/dist/core/application.js +173 -71
- package/dist/core/application.js.map +1 -1
- package/dist/core/context-pool.d.ts +2 -13
- package/dist/core/context-pool.d.ts.map +1 -1
- package/dist/core/context-pool.js +7 -45
- package/dist/core/context-pool.js.map +1 -1
- package/dist/core/context.d.ts +108 -5
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +449 -53
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/middleware.d.ts +6 -0
- package/dist/core/middleware.d.ts.map +1 -1
- package/dist/core/middleware.js +83 -84
- package/dist/core/middleware.js.map +1 -1
- package/dist/core/performance/fast-json.d.ts +149 -0
- package/dist/core/performance/fast-json.d.ts.map +1 -0
- package/dist/core/performance/fast-json.js +473 -0
- package/dist/core/performance/fast-json.js.map +1 -0
- package/dist/core/router/file-router.d.ts +20 -7
- package/dist/core/router/file-router.d.ts.map +1 -1
- package/dist/core/router/file-router.js +41 -13
- package/dist/core/router/file-router.js.map +1 -1
- package/dist/core/router/index.d.ts +6 -0
- package/dist/core/router/index.d.ts.map +1 -1
- package/dist/core/router/index.js +33 -6
- package/dist/core/router/index.js.map +1 -1
- package/dist/core/router/radix-tree.d.ts +4 -1
- package/dist/core/router/radix-tree.d.ts.map +1 -1
- package/dist/core/router/radix-tree.js +7 -3
- package/dist/core/router/radix-tree.js.map +1 -1
- package/dist/core/serializer.d.ts +251 -0
- package/dist/core/serializer.d.ts.map +1 -0
- package/dist/core/serializer.js +290 -0
- package/dist/core/serializer.js.map +1 -0
- package/dist/core/types.d.ts +39 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -170
- package/src/advanced/playground/types.ts +0 -20
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1335
- package/src/core/context-pool.ts +0 -127
- package/src/core/context.ts +0 -412
- package/src/core/index.ts +0 -80
- package/src/core/middleware.ts +0 -262
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -594
- package/src/core/router/index.ts +0 -227
- package/src/core/router/radix-tree.ts +0 -226
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -574
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -264
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
|
@@ -1,696 +0,0 @@
|
|
|
1
|
-
# Alert Channel Adapters
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Alert System di Nexus menggunakan **Adapter Pattern** untuk mendukung berbagai notification channels secara modular dan extensible. Kamu bisa:
|
|
6
|
-
|
|
7
|
-
- ✅ Menggunakan built-in adapters (Slack, Discord, Telegram, Email, PagerDuty, Webhook)
|
|
8
|
-
- ✅ Membuat custom adapter dengan mudah
|
|
9
|
-
- ✅ Register/unregister adapters secara dinamis
|
|
10
|
-
- ✅ Validasi konfigurasi per channel
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Built-in Adapters
|
|
15
|
-
|
|
16
|
-
### 1. Slack Adapter
|
|
17
|
-
|
|
18
|
-
Mengirim alert ke Slack channel via Webhook.
|
|
19
|
-
|
|
20
|
-
**Configuration:**
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
const observability = new ObservabilityCenter({
|
|
24
|
-
alerting: {
|
|
25
|
-
enabled: true,
|
|
26
|
-
channels: {
|
|
27
|
-
slack: {
|
|
28
|
-
webhookUrl: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
alerts: [
|
|
32
|
-
{
|
|
33
|
-
name: 'High Error Rate',
|
|
34
|
-
condition: 'error_rate > 0.05',
|
|
35
|
-
window: '5m',
|
|
36
|
-
threshold: 0.05,
|
|
37
|
-
channels: ['slack']
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Get Webhook URL:**
|
|
45
|
-
1. Go to Slack Workspace Settings → Apps & Integrations
|
|
46
|
-
2. Create Incoming Webhooks
|
|
47
|
-
3. Copy the Webhook URL
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
### 2. Telegram Adapter ✨
|
|
52
|
-
|
|
53
|
-
Mengirim alert ke Telegram chat.
|
|
54
|
-
|
|
55
|
-
**Configuration:**
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
const observability = new ObservabilityCenter({
|
|
59
|
-
alerting: {
|
|
60
|
-
enabled: true,
|
|
61
|
-
channels: {
|
|
62
|
-
telegram: {
|
|
63
|
-
botToken: 'YOUR_BOT_TOKEN',
|
|
64
|
-
chatId: 'YOUR_CHAT_ID'
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
alerts: [
|
|
68
|
-
{
|
|
69
|
-
name: 'Server Down',
|
|
70
|
-
condition: 'uptime < 1',
|
|
71
|
-
window: '1m',
|
|
72
|
-
threshold: 1,
|
|
73
|
-
channels: ['telegram']
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Setup Telegram Bot:**
|
|
81
|
-
|
|
82
|
-
1. Talk to BotFather on Telegram
|
|
83
|
-
- Search for `@BotFather`
|
|
84
|
-
- Send `/start`
|
|
85
|
-
- Send `/newbot`
|
|
86
|
-
- Follow instructions to create bot
|
|
87
|
-
- Copy the bot token
|
|
88
|
-
|
|
89
|
-
2. Get Chat ID
|
|
90
|
-
- Send a message to your bot
|
|
91
|
-
- Visit `https://api.telegram.org/bot{BOT_TOKEN}/getUpdates`
|
|
92
|
-
- Find your chat ID in the response
|
|
93
|
-
|
|
94
|
-
3. Set environment variables
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklmnoPQRstUVwxyz
|
|
98
|
-
TELEGRAM_CHAT_ID=987654321
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Message Format:**
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
🚨 Alert: Server Down
|
|
105
|
-
|
|
106
|
-
Condition: uptime < 1
|
|
107
|
-
Current Value: 0
|
|
108
|
-
Time: 2025-12-03T10:30:00.000Z
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### 3. Discord Adapter ✨
|
|
114
|
-
|
|
115
|
-
Mengirim alert ke Discord channel.
|
|
116
|
-
|
|
117
|
-
**Configuration:**
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
const observability = new ObservabilityCenter({
|
|
121
|
-
alerting: {
|
|
122
|
-
enabled: true,
|
|
123
|
-
channels: {
|
|
124
|
-
discord: {
|
|
125
|
-
webhookUrl: 'https://discord.com/api/webhooks/YOUR/WEBHOOK/URL'
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
alerts: [
|
|
129
|
-
{
|
|
130
|
-
name: 'High Memory Usage',
|
|
131
|
-
condition: 'memory_usage > 0.9',
|
|
132
|
-
window: '1m',
|
|
133
|
-
threshold: 0.9,
|
|
134
|
-
channels: ['discord']
|
|
135
|
-
}
|
|
136
|
-
]
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Get Webhook URL:**
|
|
142
|
-
|
|
143
|
-
1. Open Discord server and go to channel settings
|
|
144
|
-
2. Go to Integrations → Webhooks
|
|
145
|
-
3. Create Webhook
|
|
146
|
-
4. Copy the Webhook URL
|
|
147
|
-
|
|
148
|
-
**Message Format:**
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
🚨 Alert: High Memory Usage
|
|
152
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
153
|
-
Condition: memory_usage > 0.9
|
|
154
|
-
Current Value: 0.92
|
|
155
|
-
Time: 2025-12-03T10:30:00.000Z
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
### 4. Webhook Adapter
|
|
161
|
-
|
|
162
|
-
Generic HTTP endpoint untuk custom integration.
|
|
163
|
-
|
|
164
|
-
**Configuration:**
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
const observability = new ObservabilityCenter({
|
|
168
|
-
alerting: {
|
|
169
|
-
enabled: true,
|
|
170
|
-
channels: {
|
|
171
|
-
webhook: {
|
|
172
|
-
url: 'https://your-service.com/alerts'
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
alerts: [
|
|
176
|
-
{
|
|
177
|
-
name: 'Database Error',
|
|
178
|
-
condition: 'db_errors > 10',
|
|
179
|
-
window: '5m',
|
|
180
|
-
threshold: 10,
|
|
181
|
-
channels: ['webhook']
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**Payload yang dikirim:**
|
|
189
|
-
|
|
190
|
-
```json
|
|
191
|
-
{
|
|
192
|
-
"alert": "Database Error",
|
|
193
|
-
"condition": "db_errors > 10",
|
|
194
|
-
"value": 15,
|
|
195
|
-
"timestamp": 1701619200000
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
### 5. Email Adapter
|
|
202
|
-
|
|
203
|
-
Mengirim alert via email.
|
|
204
|
-
|
|
205
|
-
**Configuration:**
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
const observability = new ObservabilityCenter({
|
|
209
|
-
alerting: {
|
|
210
|
-
enabled: true,
|
|
211
|
-
channels: {
|
|
212
|
-
email: {
|
|
213
|
-
recipients: ['admin@example.com', 'ops@example.com']
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
alerts: [
|
|
217
|
-
{
|
|
218
|
-
name: 'Critical Error',
|
|
219
|
-
condition: 'error_rate > 0.5',
|
|
220
|
-
window: '1m',
|
|
221
|
-
threshold: 0.5,
|
|
222
|
-
channels: ['email']
|
|
223
|
-
}
|
|
224
|
-
]
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
**Note:** Default implementation adalah console logging. Untuk production, kamu perlu extend adapter untuk integrate dengan email service seperti SendGrid atau Mailgun.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
### 6. PagerDuty Adapter
|
|
234
|
-
|
|
235
|
-
Integration dengan PagerDuty untuk incident management.
|
|
236
|
-
|
|
237
|
-
**Configuration:**
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
const observability = new ObservabilityCenter({
|
|
241
|
-
alerting: {
|
|
242
|
-
enabled: true,
|
|
243
|
-
channels: {
|
|
244
|
-
pagerduty: {
|
|
245
|
-
routingKey: 'YOUR_PAGERDUTY_ROUTING_KEY'
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
alerts: [
|
|
249
|
-
{
|
|
250
|
-
name: 'Service Down',
|
|
251
|
-
condition: 'uptime < 1',
|
|
252
|
-
window: '1m',
|
|
253
|
-
threshold: 1,
|
|
254
|
-
channels: ['pagerduty']
|
|
255
|
-
}
|
|
256
|
-
]
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Note:** Default implementation adalah console logging. Untuk production, extend adapter dengan PagerDuty Events API v2.
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
### 7. Console Adapter
|
|
266
|
-
|
|
267
|
-
Testing dan debugging alerts tanpa external dependencies.
|
|
268
|
-
|
|
269
|
-
**Configuration:**
|
|
270
|
-
|
|
271
|
-
```typescript
|
|
272
|
-
const observability = new ObservabilityCenter({
|
|
273
|
-
alerting: {
|
|
274
|
-
enabled: true,
|
|
275
|
-
channels: {
|
|
276
|
-
console: {} // No config needed
|
|
277
|
-
},
|
|
278
|
-
alerts: [
|
|
279
|
-
{
|
|
280
|
-
name: 'Test Alert',
|
|
281
|
-
condition: 'test > 1',
|
|
282
|
-
window: '1m',
|
|
283
|
-
threshold: 1,
|
|
284
|
-
channels: ['console']
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Output:**
|
|
292
|
-
|
|
293
|
-
```
|
|
294
|
-
[ALERT] 2025-12-03T10:30:00.000Z
|
|
295
|
-
Name: Test Alert
|
|
296
|
-
Condition: test > 1
|
|
297
|
-
Current Value: 2
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Custom Alert Adapters
|
|
303
|
-
|
|
304
|
-
### Creating a Custom Adapter
|
|
305
|
-
|
|
306
|
-
Implement `AlertChannelAdapter` interface:
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
import { AlertChannelAdapter, AlertDefinition } from './nexus/advanced/observability';
|
|
310
|
-
|
|
311
|
-
class SlackCommandsAdapter implements AlertChannelAdapter {
|
|
312
|
-
async send(alert: AlertDefinition, value: any, config: any): Promise<void> {
|
|
313
|
-
// Your implementation
|
|
314
|
-
console.log(`Sending alert: ${alert.name}`);
|
|
315
|
-
|
|
316
|
-
// Call your custom API
|
|
317
|
-
await fetch('https://slack.com/custom-endpoint', {
|
|
318
|
-
method: 'POST',
|
|
319
|
-
body: JSON.stringify({ alert: alert.name, value })
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
validate(config: any): boolean {
|
|
324
|
-
// Validate configuration
|
|
325
|
-
return config.webhookUrl && typeof config.webhookUrl === 'string';
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Register Custom Adapter
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
const observability = new ObservabilityCenter({
|
|
334
|
-
alerting: { enabled: true, channels: {} }
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
// Get adapter registry
|
|
338
|
-
const registry = observability.alertManager?.getAdapterRegistry();
|
|
339
|
-
|
|
340
|
-
// Register custom adapter
|
|
341
|
-
const customAdapter = new SlackCommandsAdapter();
|
|
342
|
-
registry?.register('slack-commands', customAdapter);
|
|
343
|
-
|
|
344
|
-
// Now use it in alerts
|
|
345
|
-
const observability2 = new ObservabilityCenter({
|
|
346
|
-
alerting: {
|
|
347
|
-
enabled: true,
|
|
348
|
-
channels: {
|
|
349
|
-
'slack-commands': { webhookUrl: 'https://...' }
|
|
350
|
-
},
|
|
351
|
-
alerts: [
|
|
352
|
-
{
|
|
353
|
-
name: 'Custom Alert',
|
|
354
|
-
condition: 'value > 100',
|
|
355
|
-
window: '5m',
|
|
356
|
-
threshold: 100,
|
|
357
|
-
channels: ['slack-commands']
|
|
358
|
-
}
|
|
359
|
-
]
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## Multiple Channels
|
|
367
|
-
|
|
368
|
-
Kirim satu alert ke multiple channels sekaligus:
|
|
369
|
-
|
|
370
|
-
```typescript
|
|
371
|
-
const observability = new ObservabilityCenter({
|
|
372
|
-
alerting: {
|
|
373
|
-
enabled: true,
|
|
374
|
-
channels: {
|
|
375
|
-
slack: { webhookUrl: 'https://hooks.slack.com/...' },
|
|
376
|
-
telegram: { botToken: 'YOUR_TOKEN', chatId: 'YOUR_CHAT_ID' },
|
|
377
|
-
discord: { webhookUrl: 'https://discord.com/api/webhooks/...' },
|
|
378
|
-
webhook: { url: 'https://your-service.com/alerts' }
|
|
379
|
-
},
|
|
380
|
-
alerts: [
|
|
381
|
-
{
|
|
382
|
-
name: 'Critical System Alert',
|
|
383
|
-
condition: 'error_rate > 0.5',
|
|
384
|
-
window: '1m',
|
|
385
|
-
threshold: 0.5,
|
|
386
|
-
channels: ['slack', 'telegram', 'discord', 'webhook'] // All 4!
|
|
387
|
-
}
|
|
388
|
-
]
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Channel Configuration Validation
|
|
396
|
-
|
|
397
|
-
Setiap adapter melakukan validasi konfigurasi sebelum mengirim alert:
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
// Invalid Slack config - alert tidak dikirim
|
|
401
|
-
const observability = new ObservabilityCenter({
|
|
402
|
-
alerting: {
|
|
403
|
-
enabled: true,
|
|
404
|
-
channels: {
|
|
405
|
-
slack: {
|
|
406
|
-
webhookUrl: 'not-a-valid-url' // ❌ Invalid
|
|
407
|
-
}
|
|
408
|
-
},
|
|
409
|
-
alerts: [/* ... */]
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
// Console output: "Invalid configuration for channel: slack"
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## Common Patterns
|
|
419
|
-
|
|
420
|
-
### Pattern 1: Multi-severity Alerts
|
|
421
|
-
|
|
422
|
-
```typescript
|
|
423
|
-
const observability = new ObservabilityCenter({
|
|
424
|
-
alerting: {
|
|
425
|
-
enabled: true,
|
|
426
|
-
channels: {
|
|
427
|
-
slack: { webhookUrl: process.env.SLACK_WEBHOOK_URL! },
|
|
428
|
-
telegram: {
|
|
429
|
-
botToken: process.env.TELEGRAM_BOT_TOKEN!,
|
|
430
|
-
chatId: process.env.TELEGRAM_CHAT_ID!
|
|
431
|
-
}
|
|
432
|
-
},
|
|
433
|
-
alerts: [
|
|
434
|
-
// WARNING - Slack only
|
|
435
|
-
{
|
|
436
|
-
name: 'Warning: High Memory',
|
|
437
|
-
condition: 'memory > 0.7',
|
|
438
|
-
window: '5m',
|
|
439
|
-
threshold: 0.7,
|
|
440
|
-
channels: ['slack']
|
|
441
|
-
},
|
|
442
|
-
// CRITICAL - Slack + Telegram
|
|
443
|
-
{
|
|
444
|
-
name: 'Critical: Server Down',
|
|
445
|
-
condition: 'uptime < 1',
|
|
446
|
-
window: '1m',
|
|
447
|
-
threshold: 1,
|
|
448
|
-
channels: ['slack', 'telegram']
|
|
449
|
-
},
|
|
450
|
-
// EMERGENCY - All channels
|
|
451
|
-
{
|
|
452
|
-
name: 'Emergency: Database Disconnected',
|
|
453
|
-
condition: 'db_connected < 1',
|
|
454
|
-
window: '1m',
|
|
455
|
-
threshold: 1,
|
|
456
|
-
channels: ['slack', 'telegram', 'discord', 'webhook']
|
|
457
|
-
}
|
|
458
|
-
]
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Pattern 2: Environment-based Channels
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
const channels = {
|
|
467
|
-
slack: { webhookUrl: process.env.SLACK_WEBHOOK_URL! },
|
|
468
|
-
// Add Telegram only in production
|
|
469
|
-
...(process.env.NODE_ENV === 'production' && {
|
|
470
|
-
telegram: {
|
|
471
|
-
botToken: process.env.TELEGRAM_BOT_TOKEN!,
|
|
472
|
-
chatId: process.env.TELEGRAM_CHAT_ID!
|
|
473
|
-
}
|
|
474
|
-
}),
|
|
475
|
-
// Add Discord in staging and production
|
|
476
|
-
...(process.env.NODE_ENV !== 'development' && {
|
|
477
|
-
discord: { webhookUrl: process.env.DISCORD_WEBHOOK_URL! }
|
|
478
|
-
})
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
const observability = new ObservabilityCenter({
|
|
482
|
-
alerting: {
|
|
483
|
-
enabled: true,
|
|
484
|
-
channels,
|
|
485
|
-
alerts: [/* ... */]
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### Pattern 3: Custom adapter dengan Redis
|
|
491
|
-
|
|
492
|
-
```typescript
|
|
493
|
-
import { AlertChannelAdapter, AlertDefinition } from './nexus/advanced/observability';
|
|
494
|
-
import Redis from 'redis';
|
|
495
|
-
|
|
496
|
-
class RedisAlertAdapter implements AlertChannelAdapter {
|
|
497
|
-
private redis: Redis.RedisClient;
|
|
498
|
-
|
|
499
|
-
constructor(redisClient: Redis.RedisClient) {
|
|
500
|
-
this.redis = redisClient;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
async send(alert: AlertDefinition, value: any, config: any): Promise<void> {
|
|
504
|
-
// Store alert di Redis queue untuk processing asynchronous
|
|
505
|
-
await this.redis.lpush(
|
|
506
|
-
'alerts:queue',
|
|
507
|
-
JSON.stringify({
|
|
508
|
-
alert: alert.name,
|
|
509
|
-
value,
|
|
510
|
-
timestamp: Date.now(),
|
|
511
|
-
channel: config.queueName
|
|
512
|
-
})
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
validate(config: any): boolean {
|
|
517
|
-
return config.queueName && typeof config.queueName === 'string';
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// Usage
|
|
522
|
-
const redis = Redis.createClient();
|
|
523
|
-
const customAdapter = new RedisAlertAdapter(redis);
|
|
524
|
-
|
|
525
|
-
const observability = new ObservabilityCenter({
|
|
526
|
-
alerting: { enabled: true, channels: {} }
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
observability.alertManager?.getAdapterRegistry()?.register('redis', customAdapter);
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
---
|
|
533
|
-
|
|
534
|
-
## Adapter Registry API
|
|
535
|
-
|
|
536
|
-
### Get all registered adapters
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
const registry = observability.alertManager?.getAdapterRegistry();
|
|
540
|
-
const names = registry?.getNames();
|
|
541
|
-
// ['slack', 'webhook', 'email', 'pagerduty', 'telegram', 'discord', 'console']
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
### Check if adapter exists
|
|
545
|
-
|
|
546
|
-
```typescript
|
|
547
|
-
const has = registry?.has('telegram');
|
|
548
|
-
// true
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
### Unregister adapter
|
|
552
|
-
|
|
553
|
-
```typescript
|
|
554
|
-
registry?.unregister('console');
|
|
555
|
-
// Now console alerts won't work
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
---
|
|
559
|
-
|
|
560
|
-
## Error Handling
|
|
561
|
-
|
|
562
|
-
Adapter otomatis handle errors:
|
|
563
|
-
|
|
564
|
-
```typescript
|
|
565
|
-
// Invalid channel config
|
|
566
|
-
// → Warning logged, alert skipped for that channel
|
|
567
|
-
|
|
568
|
-
// Adapter throws error
|
|
569
|
-
// → Error logged, continues to next channel
|
|
570
|
-
|
|
571
|
-
// Invalid webhook URL
|
|
572
|
-
// → Validation fails, alert skipped
|
|
573
|
-
|
|
574
|
-
// Network timeout
|
|
575
|
-
// → Fetch error caught, logged
|
|
576
|
-
|
|
577
|
-
try {
|
|
578
|
-
await observability.alertManager?.checkAndTrigger('Test Alert', 100);
|
|
579
|
-
} catch (error) {
|
|
580
|
-
console.error('Alert check failed:', error);
|
|
581
|
-
}
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
---
|
|
585
|
-
|
|
586
|
-
## Best Practices
|
|
587
|
-
|
|
588
|
-
### 1. Validate Configurations
|
|
589
|
-
|
|
590
|
-
```typescript
|
|
591
|
-
// ❌ BAD - No validation
|
|
592
|
-
const alerting = {
|
|
593
|
-
channels: {
|
|
594
|
-
telegram: {
|
|
595
|
-
botToken: '', // Empty!
|
|
596
|
-
chatId: '' // Empty!
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
// ✅ GOOD - Validate before using
|
|
602
|
-
const alerting = {
|
|
603
|
-
channels: {
|
|
604
|
-
telegram: {
|
|
605
|
-
botToken: process.env.TELEGRAM_BOT_TOKEN!,
|
|
606
|
-
chatId: process.env.TELEGRAM_CHAT_ID!
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
if (!alerting.channels.telegram.botToken) {
|
|
612
|
-
throw new Error('TELEGRAM_BOT_TOKEN is required');
|
|
613
|
-
}
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
### 2. Use Adapter Registry for Runtime Changes
|
|
617
|
-
|
|
618
|
-
```typescript
|
|
619
|
-
// Add new channel dynamically
|
|
620
|
-
const newAdapter = new TelegramAlertAdapter();
|
|
621
|
-
observability.alertManager?.getAdapterRegistry()?.register('telegram-prod', newAdapter);
|
|
622
|
-
|
|
623
|
-
// Update alerts to use new channel
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### 3. Test Adapters
|
|
627
|
-
|
|
628
|
-
```typescript
|
|
629
|
-
// Use console adapter for testing
|
|
630
|
-
const testObservability = new ObservabilityCenter({
|
|
631
|
-
alerting: {
|
|
632
|
-
enabled: true,
|
|
633
|
-
channels: {
|
|
634
|
-
console: {}
|
|
635
|
-
},
|
|
636
|
-
alerts: [
|
|
637
|
-
{
|
|
638
|
-
name: 'Test',
|
|
639
|
-
condition: 'value > 1',
|
|
640
|
-
window: '1m',
|
|
641
|
-
threshold: 1,
|
|
642
|
-
channels: ['console']
|
|
643
|
-
}
|
|
644
|
-
]
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
|
|
648
|
-
// Check output before using real channels
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
### 4. Graceful Fallbacks
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
const channels = {
|
|
655
|
-
slack: { webhookUrl: process.env.SLACK_WEBHOOK_URL },
|
|
656
|
-
// Fallback ke console jika Slack tidak available
|
|
657
|
-
...(process.env.SLACK_WEBHOOK_URL ? {} : { console: {} })
|
|
658
|
-
};
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
---
|
|
662
|
-
|
|
663
|
-
## Troubleshooting
|
|
664
|
-
|
|
665
|
-
### Alert tidak terkirim
|
|
666
|
-
|
|
667
|
-
```typescript
|
|
668
|
-
// 1. Check adapter registered
|
|
669
|
-
const adapter = registry?.get('telegram');
|
|
670
|
-
console.log('Adapter exists:', !!adapter);
|
|
671
|
-
|
|
672
|
-
// 2. Check config valid
|
|
673
|
-
const isValid = adapter?.validate(config);
|
|
674
|
-
console.log('Config valid:', isValid);
|
|
675
|
-
|
|
676
|
-
// 3. Check channel configured
|
|
677
|
-
console.log('Channels:', observability.options.alerting?.channels);
|
|
678
|
-
|
|
679
|
-
// 4. Test manual trigger
|
|
680
|
-
await observability.alertManager?.checkAndTrigger('Test Alert', 100);
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
### Custom adapter tidak dikirim
|
|
684
|
-
|
|
685
|
-
```typescript
|
|
686
|
-
// Ensure adapter registered sebelum creating ObservabilityCenter
|
|
687
|
-
registry?.register('custom', customAdapter);
|
|
688
|
-
|
|
689
|
-
// Or register after initialization
|
|
690
|
-
observability.alertManager?.getAdapterRegistry()?.register('custom', customAdapter);
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
---
|
|
694
|
-
|
|
695
|
-
Referensi lengkap tentang Alert System ada di `16-alerts-system.md`. Lihat juga dokumentasi lain untuk fitur yang related! 📚
|
|
696
|
-
|