@gravito/monitor 1.0.0-beta.1

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/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # @gravito/monitor
2
+
3
+ Lightweight observability module for Gravito - Health Checks, Metrics, and Tracing.
4
+
5
+ ## Features
6
+
7
+ - 🏥 **Health Checks** - Kubernetes-ready `/health`, `/ready`, `/live` endpoints
8
+ - 📊 **Metrics** - Prometheus-compatible `/metrics` endpoint
9
+ - 🔍 **Tracing** - OpenTelemetry OTLP support (via external Collector)
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ bun add @gravito/monitor
15
+ ```
16
+
17
+ For OpenTelemetry tracing (optional):
18
+
19
+ ```bash
20
+ bun add @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import { PlanetCore } from 'gravito-core'
27
+ import { MonitorOrbit } from '@gravito/monitor'
28
+
29
+ const core = new PlanetCore()
30
+
31
+ core.orbit(new MonitorOrbit({
32
+ health: {
33
+ enabled: true,
34
+ path: '/health',
35
+ readyPath: '/ready',
36
+ livePath: '/live',
37
+ },
38
+ metrics: {
39
+ enabled: true,
40
+ path: '/metrics',
41
+ prefix: 'myapp_',
42
+ },
43
+ tracing: {
44
+ enabled: true,
45
+ serviceName: 'my-gravito-app',
46
+ endpoint: 'http://localhost:4318/v1/traces',
47
+ },
48
+ }))
49
+
50
+ await core.liftoff()
51
+ ```
52
+
53
+ ## Health Checks
54
+
55
+ ### Default Endpoints
56
+
57
+ | Endpoint | Description |
58
+ |----------|-------------|
59
+ | `GET /health` | Full health check with all registered checks |
60
+ | `GET /ready` | Kubernetes readiness probe |
61
+ | `GET /live` | Kubernetes liveness probe |
62
+
63
+ ### Registering Custom Checks
64
+
65
+ ```typescript
66
+ const monitor = core.services.get('monitor')
67
+
68
+ // Register a database check
69
+ monitor.health.register('database', async () => {
70
+ const isConnected = await db.ping()
71
+ return isConnected
72
+ ? { status: 'healthy' }
73
+ : { status: 'unhealthy', message: 'Database disconnected' }
74
+ })
75
+
76
+ // Register a Redis check
77
+ monitor.health.register('redis', async () => {
78
+ const result = await redis.ping()
79
+ return { status: result === 'PONG' ? 'healthy' : 'unhealthy' }
80
+ })
81
+ ```
82
+
83
+ ### Built-in Check Factories
84
+
85
+ ```typescript
86
+ import {
87
+ createDatabaseCheck,
88
+ createRedisCheck,
89
+ createMemoryCheck,
90
+ createHttpCheck
91
+ } from '@gravito/monitor'
92
+
93
+ // Database check
94
+ monitor.health.register('db', createDatabaseCheck(() => db.isConnected()))
95
+
96
+ // Memory check (warns at 90% heap usage)
97
+ monitor.health.register('memory', createMemoryCheck({ maxHeapUsedPercent: 90 }))
98
+
99
+ // External service check
100
+ monitor.health.register('api', createHttpCheck('https://api.example.com/health'))
101
+ ```
102
+
103
+ ### Health Response Format
104
+
105
+ ```json
106
+ {
107
+ "status": "healthy",
108
+ "timestamp": "2024-12-25T12:00:00Z",
109
+ "uptime": 3600,
110
+ "checks": {
111
+ "database": { "status": "healthy", "latency": 5 },
112
+ "redis": { "status": "healthy", "latency": 2 },
113
+ "memory": {
114
+ "status": "healthy",
115
+ "details": { "heapUsedPercent": "45.2" }
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Metrics
122
+
123
+ ### Prometheus Endpoint
124
+
125
+ The `/metrics` endpoint exposes metrics in Prometheus text format:
126
+
127
+ ```
128
+ # HELP myapp_http_requests_total Total HTTP requests
129
+ # TYPE myapp_http_requests_total counter
130
+ myapp_http_requests_total{method="GET",path="/api/users",status="200"} 150
131
+
132
+ # HELP myapp_http_request_duration_seconds HTTP request duration
133
+ # TYPE myapp_http_request_duration_seconds histogram
134
+ myapp_http_request_duration_seconds_bucket{le="0.01"} 50
135
+ myapp_http_request_duration_seconds_bucket{le="0.1"} 120
136
+ myapp_http_request_duration_seconds_sum 12.5
137
+ myapp_http_request_duration_seconds_count 150
138
+ ```
139
+
140
+ ### Custom Metrics
141
+
142
+ ```typescript
143
+ const monitor = core.services.get('monitor')
144
+
145
+ // Counter
146
+ const requestCounter = monitor.metrics.counter({
147
+ name: 'api_requests_total',
148
+ help: 'Total API requests',
149
+ labels: ['endpoint', 'status'],
150
+ })
151
+ requestCounter.inc({ endpoint: '/users', status: '200' })
152
+
153
+ // Gauge
154
+ const activeConnections = monitor.metrics.gauge({
155
+ name: 'active_connections',
156
+ help: 'Current active connections',
157
+ })
158
+ activeConnections.set(42)
159
+ activeConnections.inc()
160
+ activeConnections.dec()
161
+
162
+ // Histogram
163
+ const responseTime = monitor.metrics.histogram({
164
+ name: 'response_time_seconds',
165
+ help: 'Response time in seconds',
166
+ labels: ['endpoint'],
167
+ buckets: [0.01, 0.05, 0.1, 0.5, 1],
168
+ })
169
+ responseTime.observe(0.125, { endpoint: '/users' })
170
+
171
+ // Timer helper
172
+ const stopTimer = responseTime.startTimer({ endpoint: '/users' })
173
+ // ... do work ...
174
+ stopTimer() // Records duration automatically
175
+ ```
176
+
177
+ ## Tracing
178
+
179
+ ### OpenTelemetry Integration
180
+
181
+ @gravito/monitor uses the **OTLP (OpenTelemetry Protocol)** standard. To send traces to different backends:
182
+
183
+ | Backend | Method |
184
+ |---------|--------|
185
+ | **Jaeger** | OTLP Collector → Jaeger |
186
+ | **Zipkin** | OTLP Collector → Zipkin |
187
+ | **AWS X-Ray** | AWS ADOT Collector |
188
+ | **Google Cloud Trace** | GCP OTLP Collector |
189
+ | **Datadog** | Datadog Agent (OTLP) |
190
+
191
+ ### Configuration
192
+
193
+ ```typescript
194
+ new MonitorOrbit({
195
+ tracing: {
196
+ enabled: true,
197
+ serviceName: 'my-app',
198
+ serviceVersion: '1.0.0',
199
+ endpoint: 'http://localhost:4318/v1/traces', // OTLP HTTP
200
+ sampleRate: 1.0, // 100% sampling
201
+ resourceAttributes: {
202
+ 'deployment.environment': 'production',
203
+ },
204
+ },
205
+ })
206
+ ```
207
+
208
+ ### Manual Spans
209
+
210
+ ```typescript
211
+ const tracer = core.services.get('tracing')
212
+
213
+ // Start a span
214
+ const span = tracer.startSpan('process-order', {
215
+ attributes: { 'order.id': '12345' },
216
+ })
217
+
218
+ try {
219
+ // Do work...
220
+ tracer.addEvent(span, 'payment-processed')
221
+ tracer.setAttribute(span, 'order.total', 99.99)
222
+ tracer.endSpan(span, 'ok')
223
+ } catch (error) {
224
+ tracer.endSpan(span, 'error')
225
+ throw error
226
+ }
227
+ ```
228
+
229
+ ### Trace Context Propagation
230
+
231
+ The tracing middleware automatically:
232
+ - Extracts `traceparent` header from incoming requests
233
+ - Injects trace context into outgoing requests
234
+ - Records HTTP method, path, status code
235
+
236
+ ## Kubernetes Integration
237
+
238
+ ### Deployment Example
239
+
240
+ ```yaml
241
+ apiVersion: apps/v1
242
+ kind: Deployment
243
+ metadata:
244
+ name: my-gravito-app
245
+ spec:
246
+ template:
247
+ spec:
248
+ containers:
249
+ - name: app
250
+ image: my-app:latest
251
+ ports:
252
+ - containerPort: 3000
253
+ livenessProbe:
254
+ httpGet:
255
+ path: /live
256
+ port: 3000
257
+ initialDelaySeconds: 5
258
+ periodSeconds: 10
259
+ readinessProbe:
260
+ httpGet:
261
+ path: /ready
262
+ port: 3000
263
+ initialDelaySeconds: 5
264
+ periodSeconds: 5
265
+ ```
266
+
267
+ ### ServiceMonitor for Prometheus
268
+
269
+ ```yaml
270
+ apiVersion: monitoring.coreos.com/v1
271
+ kind: ServiceMonitor
272
+ metadata:
273
+ name: my-gravito-app
274
+ spec:
275
+ selector:
276
+ matchLabels:
277
+ app: my-gravito-app
278
+ endpoints:
279
+ - port: http
280
+ path: /metrics
281
+ interval: 15s
282
+ ```
283
+
284
+ ## Configuration Reference
285
+
286
+ | Option | Type | Default | Description |
287
+ |--------|------|---------|-------------|
288
+ | `health.enabled` | boolean | `true` | Enable health endpoints |
289
+ | `health.path` | string | `/health` | Full health check path |
290
+ | `health.readyPath` | string | `/ready` | Readiness probe path |
291
+ | `health.livePath` | string | `/live` | Liveness probe path |
292
+ | `health.timeout` | number | `5000` | Check timeout (ms) |
293
+ | `health.cacheTtl` | number | `0` | Cache duration (ms) |
294
+ | `metrics.enabled` | boolean | `true` | Enable metrics endpoint |
295
+ | `metrics.path` | string | `/metrics` | Metrics endpoint path |
296
+ | `metrics.prefix` | string | `gravito_` | Metric name prefix |
297
+ | `metrics.defaultMetrics` | boolean | `true` | Collect default metrics |
298
+ | `tracing.enabled` | boolean | `false` | Enable tracing |
299
+ | `tracing.serviceName` | string | `gravito-app` | Service name |
300
+ | `tracing.endpoint` | string | `http://localhost:4318/v1/traces` | OTLP endpoint |
301
+ | `tracing.sampleRate` | number | `1.0` | Sample rate (0.0-1.0) |
302
+
303
+ ## License
304
+
305
+ MIT