@@ -82,8 +82,8 @@ const db = await tenants.getDbAsync('tenant-123');
8282const sharedDb = await tenants .getSharedDbAsync ();
8383```
8484
85- #### Health Checks
86- Verificar saúde dos pools e conexões.
85+ #### ~~ Health Checks~~ (Concluído v1.1.0)
86+ ~~ Verificar saúde dos pools e conexões.~~
8787
8888``` typescript
8989const manager = createTenantManager (config );
@@ -93,54 +93,81 @@ const health = await manager.healthCheck();
9393// {
9494// healthy: true,
9595// pools: [
96- // { tenantId: 'abc', status: 'ok', connections : 5 },
97- // { tenantId: 'def', status: 'degraded', connections: 1 },
96+ // { tenantId: 'abc', status: 'ok', totalConnections : 5, idleConnections: 3 },
97+ // { tenantId: 'def', status: 'degraded', totalConnections: 5, waitingRequests: 2 },
9898// ],
9999// sharedDb: 'ok',
100- // timestamp: '2024-01-15T10:30:00Z'
100+ // sharedDbResponseTimeMs: 12,
101+ // totalPools: 2,
102+ // degradedPools: 1,
103+ // unhealthyPools: 0,
104+ // timestamp: '2024-01-15T10:30:00Z',
105+ // durationMs: 45
101106// }
102107
103108// Endpoint para load balancers
104109app .get (' /health' , async (req , res ) => {
105110 const health = await manager .healthCheck ();
106111 res .status (health .healthy ? 200 : 503 ).json (health );
107112});
113+
114+ // Verificar tenants específicos
115+ const health = await manager .healthCheck ({
116+ tenantIds: [' tenant-1' , ' tenant-2' ],
117+ ping: true ,
118+ pingTimeoutMs: 3000 ,
119+ includeShared: true ,
120+ });
108121```
109122
110- #### Métricas Prometheus
111- Expor métricas no formato Prometheus para monitoramento.
123+ #### ~~ Métricas Agnósticas (Zero Deps)~~ (Concluído v1.1.0)
124+ ~~ Expor métricas em formato agnóstico - usuário integra com Prometheus/Datadog/etc.~~
125+
126+ > ** Filosofia** : Zero dependências extras, zero overhead de tracking contínuo.
127+ > Dados coletados sob demanda via ` getMetrics() ` .
112128
113129``` typescript
114- import { defineConfig } from ' drizzle-multitenant' ;
130+ // Coleta métricas sob demanda (zero overhead quando não chamado)
131+ const metrics = manager .getMetrics ();
132+ // {
133+ // pools: {
134+ // total: 15,
135+ // maxPools: 50,
136+ // tenants: [
137+ // { tenantId: 'abc', schemaName: 'tenant_abc', connections: { total: 10, idle: 7, waiting: 0 } },
138+ // { tenantId: 'def', schemaName: 'tenant_def', connections: { total: 10, idle: 3, waiting: 2 } },
139+ // ],
140+ // },
141+ // shared: { connections: { total: 10, idle: 8, waiting: 0 } },
142+ // timestamp: '2024-01-15T10:30:00Z',
143+ // }
115144
116- export default defineConfig ({
117- // ...
118- metrics: {
119- enabled: true ,
120- prefix: ' drizzle_multitenant' ,
121- },
145+ // Usuário formata para Prometheus se quiser
146+ import { Gauge } from ' prom-client' ;
147+
148+ const poolGauge = new Gauge ({ name: ' drizzle_pool_count' , help: ' Active pools' });
149+ const connectionsGauge = new Gauge ({
150+ name: ' drizzle_connections' ,
151+ help: ' Connections by tenant' ,
152+ labelNames: [' tenant' , ' state' ]
122153});
123154
124- // Endpoint para Prometheus
125155app .get (' /metrics' , async (req , res ) => {
126156 const metrics = manager .getMetrics ();
157+
158+ poolGauge .set (metrics .pools .total );
159+ for (const pool of metrics .pools .tenants ) {
160+ connectionsGauge .labels (pool .tenantId , ' idle' ).set (pool .connections .idle );
161+ connectionsGauge .labels (pool .tenantId , ' active' ).set (pool .connections .total - pool .connections .idle );
162+ }
163+
127164 res .set (' Content-Type' , ' text/plain' );
128- res .send (metrics );
165+ res .send (await register . metrics () );
129166});
130167```
131168
132- Métricas expostas:
133- ```
134- drizzle_multitenant_pool_count 15
135- drizzle_multitenant_pool_connections_active{tenant="abc"} 3
136- drizzle_multitenant_pool_connections_idle{tenant="abc"} 7
137- drizzle_multitenant_query_duration_seconds_bucket{le="0.1"} 1024
138- drizzle_multitenant_pool_evictions_total 42
139- drizzle_multitenant_errors_total{type="connection"} 3
140- ```
141-
142- #### Structured Logging
143- Integração com loggers populares (pino, winston).
169+ #### Hooks para Observabilidade
170+ Hooks existentes já suportam integração com qualquer logger/APM.
144171
145172``` typescript
146173import pino from ' pino' ;
@@ -150,25 +177,24 @@ const logger = pino({ level: 'info' });
150177export default defineConfig ({
151178 // ...
152179 hooks: {
153- logger: {
154- provider: logger ,
155- level: ' info' ,
156- // Logs estruturados automaticamente
157- // { tenant: 'abc', event: 'pool_created', duration: 45 }
158- },
159180 onPoolCreated : (tenantId ) => {
160- logger .info ({ tenant: tenantId }, ' Pool created' );
181+ logger .info ({ tenant: tenantId , event: ' pool_created' }, ' Pool created' );
182+ },
183+ onPoolEvicted : (tenantId ) => {
184+ logger .info ({ tenant: tenantId , event: ' pool_evicted' }, ' Pool evicted' );
185+ },
186+ onError : (tenantId , error ) => {
187+ logger .error ({ tenant: tenantId , error: error .message }, ' Pool error' );
161188 },
162189 },
163190});
164191```
165192
166193** Checklist v1.1.0:**
167194- [x] Retry logic com backoff exponencial
168- - [ ] ` manager.healthCheck() ` API
169- - [ ] Métricas Prometheus
170- - [ ] Integração com pino/winston
171- - [x] Testes unitários e integração (retry: 20 testes)
195+ - [x] ` manager.healthCheck() ` API
196+ - [x] ` manager.getMetrics() ` API (dados crus, zero deps)
197+ - [x] Testes unitários e integração (retry: 20 testes, healthCheck: 11 testes, getMetrics: 7 testes)
172198
173199---
174200
@@ -808,10 +834,10 @@ const stats = await adminQuery
808834
809835| Feature | Esforço | Versão | Status |
810836| ---------| ---------| --------| --------|
811- | Health check API | 2h | v1.1.0 | Pendente |
837+ | ~ ~Health check API~~ | 2h | v1.1.0 | ** Concluído** |
838+ | ~~`getMetrics ()` API~~ | 1h | v1.1.0 | ** Concluído** |
812839| Schema name sanitization | 1h | v1.2.0 | Pendente |
813840| CLI interativo básico | 4h | v1.5.0 | Pendente |
814- | Structured logging hook | 2h | v1.1.0 | Pendente |
815841| Tenant clone (schema only) | 4h | v1.5.0 | Pendente |
816842| ~ ~CLI migrationsTable config~~ | 1h | v1.0.3 | ** Concluído** |
817843| ~ ~TenantDbFactory para singletons~~ | 2h | v1.0.3 | ** Concluído** |
0 commit comments