Files
dofus-manager/docs/architecture/19-monitoring-observability.md
2026-01-19 08:52:38 +01:00

132 lines
2.6 KiB
Markdown

# 19. Monitoring & Observability
## Structured Logging (Pino)
```typescript
// src/lib/server/logger.ts
import pino from 'pino';
const isDev = process.env.NODE_ENV === 'development';
export const logger = pino({
level: process.env.LOG_LEVEL ?? (isDev ? 'debug' : 'info'),
transport: isDev
? {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname',
},
}
: undefined,
formatters: {
level: (label) => ({ level: label }),
},
base: {
env: process.env.NODE_ENV,
version: process.env.APP_VERSION ?? '0.0.0',
},
redact: {
paths: ['password', 'token', 'authorization'],
censor: '[REDACTED]',
},
});
export const dbLogger = logger.child({ module: 'database' });
export const apiLogger = logger.child({ module: 'api' });
```
## Health Check Endpoint
```typescript
// src/server/functions/health.ts
import { createServerFn } from '@tanstack/react-start/server';
import { db } from '@/lib/server/db';
interface HealthStatus {
status: 'healthy' | 'degraded' | 'unhealthy';
timestamp: string;
version: string;
checks: {
database: boolean;
cache: boolean;
};
}
export const getHealth = createServerFn({ method: 'GET' }).handler(
async (): Promise<HealthStatus> => {
const checks = {
database: false,
cache: true,
};
try {
await db.$queryRaw`SELECT 1`;
checks.database = true;
} catch {
// Database check failed
}
const allHealthy = Object.values(checks).every(Boolean);
return {
status: allHealthy ? 'healthy' : 'degraded',
timestamp: new Date().toISOString(),
version: process.env.APP_VERSION ?? '0.0.0',
checks,
};
}
);
```
## Application Metrics
```typescript
// src/lib/server/metrics.ts
class MetricsCollector {
private startTime = Date.now();
private data = {
requests: { total: 0, errors: 0 },
database: { queries: 0, slowQueries: 0 },
cache: { hits: 0, misses: 0 },
};
incrementRequest(isError = false): void {
this.data.requests.total++;
if (isError) this.data.requests.errors++;
}
incrementDbQuery(isSlow = false): void {
this.data.database.queries++;
if (isSlow) this.data.database.slowQueries++;
}
incrementCacheHit(): void {
this.data.cache.hits++;
}
incrementCacheMiss(): void {
this.data.cache.misses++;
}
getMetrics() {
return {
...this.data,
uptime: Math.floor((Date.now() - this.startTime) / 1000),
};
}
}
export const metrics = new MetricsCollector();
```
---