@jmlq/logger 0.1.0-alpha.1 → 0.1.0-alpha.11

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.
Files changed (142) hide show
  1. package/README.md +307 -0
  2. package/architecture.md +171 -0
  3. package/dist/examples/data-source-service.example.d.ts +3 -0
  4. package/dist/examples/data-source-service.example.js +174 -0
  5. package/dist/examples/flush-buffers-use-case.example.d.ts +3 -0
  6. package/dist/examples/flush-buffers-use-case.example.js +60 -0
  7. package/dist/examples/get-logs-use-case.example.d.ts +3 -0
  8. package/dist/examples/get-logs-use-case.example.js +110 -0
  9. package/dist/examples/index.example.d.ts +8 -0
  10. package/dist/examples/index.example.js +116 -0
  11. package/dist/examples/logger-factory.example.d.ts +39 -0
  12. package/dist/examples/logger-factory.example.js +158 -0
  13. package/dist/examples/normalize-message.example.d.ts +3 -0
  14. package/dist/examples/normalize-message.example.js +80 -0
  15. package/dist/examples/pii-redactor.example.d.ts +3 -0
  16. package/dist/examples/pii-redactor.example.js +129 -0
  17. package/dist/examples/save-log-use-case.example.d.ts +3 -0
  18. package/dist/examples/save-log-use-case.example.js +150 -0
  19. package/dist/examples/to-log-level.example.d.ts +3 -0
  20. package/dist/examples/to-log-level.example.js +49 -0
  21. package/dist/examples/to-pii-regex.example.d.ts +3 -0
  22. package/dist/examples/to-pii-regex.example.js +75 -0
  23. package/dist/{presentation/factory/index.d.ts → src/application/factory/create-logger.d.ts} +1 -1
  24. package/dist/src/application/factory/create-logger.js +29 -0
  25. package/dist/src/application/factory/index.d.ts +1 -0
  26. package/dist/{config → src/application/factory}/index.js +1 -2
  27. package/dist/src/application/factory/logger.factory.d.ts +12 -0
  28. package/dist/src/application/factory/logger.factory.js +74 -0
  29. package/dist/src/application/index.d.ts +2 -0
  30. package/dist/{presentation → src/application}/index.js +1 -0
  31. package/dist/src/application/use-cases/flush-buffers.use-case.d.ts +6 -0
  32. package/dist/src/application/use-cases/flush-buffers.use-case.js +13 -0
  33. package/dist/src/application/use-cases/get-logs.use-case.d.ts +8 -0
  34. package/dist/src/application/use-cases/get-logs.use-case.js +24 -0
  35. package/dist/src/application/use-cases/index.d.ts +3 -0
  36. package/dist/src/application/use-cases/index.js +19 -0
  37. package/dist/src/application/use-cases/save-log.use-case.d.ts +8 -0
  38. package/dist/src/application/use-cases/save-log.use-case.js +26 -0
  39. package/dist/src/domain/index.d.ts +6 -0
  40. package/dist/src/domain/index.js +22 -0
  41. package/dist/src/domain/ports/create-logger-options.port.d.ts +7 -0
  42. package/dist/{config/interfaces/index.js → src/domain/ports/create-logger-options.port.js} +0 -1
  43. package/dist/src/domain/ports/index.d.ts +6 -0
  44. package/dist/src/domain/ports/index.js +22 -0
  45. package/dist/src/domain/ports/log-datasource.port.d.ts +9 -0
  46. package/dist/src/domain/ports/log-datasource.port.js +2 -0
  47. package/dist/src/domain/ports/logger-factory-config.port.d.ts +28 -0
  48. package/dist/src/domain/ports/logger-factory-config.port.js +2 -0
  49. package/dist/src/domain/ports/logger-service.port.d.ts +19 -0
  50. package/dist/src/domain/ports/logger-service.port.js +2 -0
  51. package/dist/src/domain/ports/logger.port.d.ts +10 -0
  52. package/dist/src/domain/ports/logger.port.js +2 -0
  53. package/dist/src/domain/ports/pii-redactor.port.d.ts +5 -0
  54. package/dist/src/domain/ports/pii-redactor.port.js +2 -0
  55. package/dist/src/domain/request/get-logs-filter.props.d.ts +9 -0
  56. package/dist/src/domain/request/get-logs-filter.props.js +2 -0
  57. package/dist/src/domain/request/index.d.ts +5 -0
  58. package/dist/src/domain/request/index.js +21 -0
  59. package/dist/src/domain/request/log.props.d.ts +7 -0
  60. package/dist/src/domain/request/log.props.js +2 -0
  61. package/dist/src/domain/request/pii-options.props.d.ts +8 -0
  62. package/dist/src/domain/request/pii-options.props.js +2 -0
  63. package/dist/src/domain/request/pii-replacement.props.d.ts +5 -0
  64. package/dist/src/domain/request/pii-replacement.props.js +2 -0
  65. package/dist/src/domain/request/save-log.props.d.ts +7 -0
  66. package/dist/src/domain/request/save-log.props.js +2 -0
  67. package/dist/src/domain/response/index.d.ts +1 -0
  68. package/dist/{domain/services → src/domain/response}/index.js +1 -1
  69. package/dist/src/domain/response/log.response.d.ts +7 -0
  70. package/dist/src/domain/response/log.response.js +2 -0
  71. package/dist/src/domain/services/index.d.ts +4 -0
  72. package/dist/{index.js → src/domain/services/index.js} +4 -4
  73. package/dist/src/domain/services/log-level.service.d.ts +2 -0
  74. package/dist/src/domain/services/log-level.service.js +27 -0
  75. package/dist/src/domain/services/message-normalizer.service.d.ts +3 -0
  76. package/dist/src/domain/services/message-normalizer.service.js +8 -0
  77. package/dist/src/domain/services/pii-pattern.service.d.ts +2 -0
  78. package/dist/src/domain/services/pii-pattern.service.js +13 -0
  79. package/dist/src/domain/services/pii-redactor.d.ts +10 -0
  80. package/dist/src/domain/services/pii-redactor.js +68 -0
  81. package/dist/src/domain/services/pii-redactor.service.d.ts +10 -0
  82. package/dist/src/domain/services/pii-redactor.service.js +68 -0
  83. package/dist/src/domain/types/index.d.ts +1 -0
  84. package/dist/src/domain/types/index.js +17 -0
  85. package/dist/src/domain/types/log-message.type.d.ts +1 -0
  86. package/dist/src/domain/types/log-message.type.js +2 -0
  87. package/dist/src/domain/value-objects/index.d.ts +1 -0
  88. package/dist/src/domain/value-objects/index.js +17 -0
  89. package/dist/src/domain/value-objects/log-level.vo.d.ts +8 -0
  90. package/dist/src/domain/value-objects/log-level.vo.js +13 -0
  91. package/dist/src/index.d.ts +6 -0
  92. package/dist/src/index.js +22 -0
  93. package/dist/src/infrastructure/datasources/in-memory-log.datasource.d.ts +1 -0
  94. package/dist/src/infrastructure/datasources/in-memory-log.datasource.js +2 -0
  95. package/dist/src/infrastructure/datasources/index.d.ts +1 -0
  96. package/dist/src/infrastructure/datasources/index.js +17 -0
  97. package/dist/src/infrastructure/services/data-source-error-handler.type.d.ts +5 -0
  98. package/dist/src/infrastructure/services/data-source-error-handler.type.js +2 -0
  99. package/dist/src/infrastructure/services/datasource.service.d.ts +15 -0
  100. package/dist/src/infrastructure/services/datasource.service.js +63 -0
  101. package/dist/src/infrastructure/services/index.d.ts +2 -0
  102. package/dist/src/infrastructure/services/index.js +18 -0
  103. package/dist/tests/application/factory/logger-factory.spec.d.ts +1 -0
  104. package/dist/tests/application/factory/logger-factory.spec.js +161 -0
  105. package/dist/tests/application/use-cases/flush-buffers.use-case.spec.d.ts +1 -0
  106. package/dist/tests/application/use-cases/flush-buffers.use-case.spec.js +38 -0
  107. package/dist/tests/application/use-cases/get-logs.use-case.spec.d.ts +1 -0
  108. package/dist/tests/application/use-cases/get-logs.use-case.spec.js +114 -0
  109. package/dist/tests/application/use-cases/save-log.use-case.spec.d.ts +1 -0
  110. package/dist/tests/application/use-cases/save-log.use-case.spec.js +138 -0
  111. package/dist/tests/domain/services/log-level.service.spec.d.ts +1 -0
  112. package/dist/tests/domain/services/log-level.service.spec.js +68 -0
  113. package/dist/tests/domain/services/normalize-message.spec.d.ts +1 -0
  114. package/dist/tests/domain/services/normalize-message.spec.js +83 -0
  115. package/dist/tests/domain/services/pii-redactor.spec.d.ts +1 -0
  116. package/dist/tests/domain/services/pii-redactor.spec.js +170 -0
  117. package/dist/tests/domain/services/to-pii-regex.spec.d.ts +1 -0
  118. package/dist/tests/domain/services/to-pii-regex.spec.js +82 -0
  119. package/dist/tests/infrastructure/services/datasource.service.spec.d.ts +1 -0
  120. package/dist/tests/infrastructure/services/datasource.service.spec.js +128 -0
  121. package/dist/tests/test-utils/create-pii-redactor-mock.d.ts +5 -0
  122. package/dist/tests/test-utils/create-pii-redactor-mock.js +10 -0
  123. package/install.md +367 -0
  124. package/package.json +33 -10
  125. package/dist/Composite/index.d.ts +0 -9
  126. package/dist/Composite/index.js +0 -23
  127. package/dist/Factory/index.d.ts +0 -5
  128. package/dist/Factory/index.js +0 -23
  129. package/dist/config/index.d.ts +0 -2
  130. package/dist/config/interfaces/index.d.ts +0 -67
  131. package/dist/config/types/index.d.ts +0 -10
  132. package/dist/config/types/index.js +0 -13
  133. package/dist/domain/services/index.d.ts +0 -1
  134. package/dist/domain/services/pii-redactor.d.ts +0 -27
  135. package/dist/domain/services/pii-redactor.js +0 -139
  136. package/dist/index.d.ts +0 -4
  137. package/dist/interfaces/index.d.ts +0 -35
  138. package/dist/interfaces/index.js +0 -13
  139. package/dist/presentation/factory/index.js +0 -74
  140. package/dist/presentation/index.d.ts +0 -1
  141. /package/dist/{domain → src/infrastructure}/index.d.ts +0 -0
  142. /package/dist/{domain → src/infrastructure}/index.js +0 -0
package/README.md ADDED
@@ -0,0 +1,307 @@
1
+ # @jmlq/logger
2
+
3
+ Sistema de logging modular y extensible con **Arquitectura Limpia**. Soporta múltiples destinos (archivos, MongoDB, PostgreSQL) y enmascarado automático de datos sensibles (PII).
4
+
5
+ ## 📦 Instalación
6
+
7
+ ```bash
8
+ # Core del logger
9
+ npm install @jmlq/logger
10
+
11
+ # Plugins opcionales (instala según necesites)
12
+ npm install @jmlq/logger-plugin-fs # Para archivos
13
+ npm install @jmlq/logger-plugin-mongo # Para MongoDB
14
+ npm install @jmlq/logger-plugin-postgresql # Para PostgreSQL
15
+ ```
16
+
17
+ ## 🚀 Uso Básico
18
+
19
+ ### Configuración Simple
20
+
21
+ ```typescript
22
+ import { LoggerFactory, LogLevel } from "@jmlq/logger";
23
+
24
+ // Crear un datasource en memoria (para testing/desarrollo)
25
+ const memoryDatasource = {
26
+ name: "memory",
27
+ async save(log) {
28
+ console.log("LOG:", log);
29
+ },
30
+ async find(filter) {
31
+ return [];
32
+ },
33
+ async flush() {},
34
+ async dispose() {},
35
+ };
36
+
37
+ // Crear el logger
38
+ const logger = LoggerFactory.create({
39
+ datasources: memoryDatasource,
40
+ minLevel: LogLevel.INFO,
41
+ redactorOptions: {
42
+ enabled: true,
43
+ deep: true,
44
+ includeDefaults: true,
45
+ },
46
+ });
47
+
48
+ // Usar el logger
49
+ await logger.info("Usuario conectado", {
50
+ userId: "123",
51
+ email: "user@example.com",
52
+ });
53
+ await logger.error("Error en el sistema", {
54
+ error: "Database connection failed",
55
+ });
56
+ ```
57
+
58
+ ### Con Múltiples Datasources
59
+
60
+ ```typescript
61
+ import { LoggerFactory } from "@jmlq/logger";
62
+ import { FileSystemDatasource } from "@jmlq/logger-plugin-fs";
63
+ import { MongoDatasource } from "@jmlq/logger-plugin-mongo";
64
+
65
+ const logger = LoggerFactory.create({
66
+ datasources: [
67
+ new FileSystemDatasource({ basePath: "./logs" }),
68
+ new MongoDatasource({ url: "mongodb://localhost:27017", dbName: "logs" }),
69
+ ],
70
+ minLevel: LogLevel.INFO,
71
+ });
72
+
73
+ await logger.warn("Latencia alta", { endpoint: "/api/users", duration: 850 });
74
+ ```
75
+
76
+ ## 🎯 Características Principales
77
+
78
+ ### Niveles de Log
79
+
80
+ - `TRACE` (0) - Información muy detallada
81
+ - `DEBUG` (1) - Información de depuración
82
+ - `INFO` (2) - Información general
83
+ - `WARN` (3) - Advertencias
84
+ - `ERROR` (4) - Errores
85
+ - `FATAL` (5) - Errores críticos
86
+
87
+ ### Enmascarado PII Automático
88
+
89
+ El logger detecta y enmascara automáticamente datos sensibles:
90
+
91
+ ```typescript
92
+ await logger.info("Pago procesado", {
93
+ email: "user@example.com", // → user@[EMAIL]
94
+ card: "4111-1111-1111-1111", // → ****-****-****-****
95
+ password: "secret123", // → [REDACTED]
96
+ });
97
+ ```
98
+
99
+ ### Filtros y Consultas
100
+
101
+ ```typescript
102
+ // Obtener logs de errores de las últimas 24 horas
103
+ const errors = await logger.getLogs({
104
+ levelMin: LogLevel.ERROR,
105
+ since: Date.now() - 24 * 60 * 60 * 1000,
106
+ limit: 50,
107
+ });
108
+
109
+ // Buscar logs que contengan "usuario"
110
+ const userLogs = await logger.getLogs({
111
+ query: "usuario",
112
+ limit: 100,
113
+ });
114
+ ```
115
+
116
+ ## 🔧 Configuración con Variables de Entorno
117
+
118
+ ```env
119
+ # Nivel mínimo de logs
120
+ LOG_LEVEL=info
121
+
122
+ # Filesystem
123
+ LOGGER_FS_PATH=./logs
124
+
125
+ # MongoDB
126
+ MONGO_URL=mongodb://localhost:27017
127
+ MONGO_DB_NAME=logs
128
+
129
+ # PostgreSQL
130
+ POSTGRES_URL=postgresql://user:pass@localhost:5432/logs
131
+
132
+ # PII Protection
133
+ LOGGER_PII_ENABLED=true
134
+ ```
135
+
136
+ ## 📁 Ejemplos Prácticos
137
+
138
+ El proyecto incluye ejemplos completos en el directorio [`examples/`](examples/):
139
+
140
+ ```bash
141
+ # Ver todos los ejemplos disponibles
142
+ npm run example:help
143
+
144
+ # Ejecutar ejemplos específicos
145
+ npm run example:factories # LoggerFactory
146
+ npm run example:use-cases # SaveLog, GetLogs, FlushBuffers
147
+ npm run example:domain-services # PII, normalización
148
+ npm run example:all # Todos los ejemplos
149
+ ```
150
+
151
+ ### Ejemplo Express
152
+
153
+ ```typescript
154
+ import express from "express";
155
+ import { LoggerFactory, LogLevel } from "@jmlq/logger";
156
+
157
+ const app = express();
158
+ const logger = LoggerFactory.create({
159
+ datasources: /* tu datasource */,
160
+ minLevel: LogLevel.INFO
161
+ });
162
+
163
+ app.use(async (req, res, next) => {
164
+ await logger.info("Request iniciado", {
165
+ method: req.method,
166
+ url: req.url,
167
+ ip: req.ip
168
+ });
169
+ next();
170
+ });
171
+
172
+ app.get("/users/:id", async (req, res) => {
173
+ try {
174
+ await logger.info("Obteniendo usuario", { userId: req.params.id });
175
+ // ... tu lógica
176
+ res.json({ user: data });
177
+ } catch (error) {
178
+ await logger.error("Error al obtener usuario", {
179
+ userId: req.params.id,
180
+ error: error.message
181
+ });
182
+ res.status(500).json({ error: "Internal server error" });
183
+ }
184
+ });
185
+ ```
186
+
187
+ ### Ejemplo NestJS
188
+
189
+ ```typescript
190
+ @Injectable()
191
+ export class AppService {
192
+ constructor(@Inject("LOGGER") private readonly logger: ILoggerService) {}
193
+
194
+ async createUser(userData: any) {
195
+ await this.logger.info("Creando usuario", { userData });
196
+ try {
197
+ // ... lógica
198
+ await this.logger.info("Usuario creado", { userId: result.id });
199
+ return result;
200
+ } catch (error) {
201
+ await this.logger.error("Error creando usuario", {
202
+ error: error.message,
203
+ });
204
+ throw error;
205
+ }
206
+ }
207
+ }
208
+ ```
209
+
210
+ ## 🏗️ Arquitectura
211
+
212
+ El paquete sigue **Arquitectura Limpia**:
213
+
214
+ ```
215
+ src/
216
+ ├─ domain/ # Reglas de negocio puras
217
+ │ ├─ entities/
218
+ │ ├─ value-objects/ # LogLevel
219
+ │ ├─ services/ # PiiRedactor, MessageNormalizer
220
+ │ ├─ ports/ # Interfaces/contratos
221
+ │ └─ types/
222
+ ├─ application/ # Casos de uso
223
+ │ ├─ use-cases/ # SaveLog, GetLogs, FlushBuffers
224
+ │ └─ factory/ # LoggerFactory
225
+ └─ infrastructure/ # Implementaciones concretas
226
+ └─ services/ # DataSourceService (composite)
227
+ ```
228
+
229
+ ### Casos de Uso Principales
230
+
231
+ - **[`SaveLogUseCase`](src/application/use-cases/save-log.use-case.ts)** - Guarda logs aplicando filtros de nivel y PII
232
+ - **[`GetLogsUseCase`](src/application/use-cases/get-logs.use-case.ts)** - Recupera logs con filtros
233
+ - **[`FlushBuffersUseCase`](src/application/use-cases/flush-buffers.use-case.ts)** - Vacía buffers de datasources
234
+
235
+ ### Servicios de Dominio
236
+
237
+ - **[`PiiRedactor`](src/domain/services/pii-redactor.service.ts)** - Enmascara datos sensibles
238
+ - **[`MessageNormalizer`](src/domain/services/message-normalizer.service.ts)** - Normaliza mensajes de log
239
+ - **[`LogLevelService`](src/domain/services/log-level.service.ts)** - Maneja niveles de log
240
+
241
+ ## 🔌 Plugins Disponibles
242
+
243
+ | Plugin | Descripción | NPM |
244
+ | -------------------------------- | -------------------------- | --------------------------------------------------------------- |
245
+ | `@jmlq/logger-plugin-fs` | Persistencia en archivos | [npm](https://npmjs.com/package/@jmlq/logger-plugin-fs) |
246
+ | `@jmlq/logger-plugin-mongo` | Persistencia en MongoDB | [npm](https://npmjs.com/package/@jmlq/logger-plugin-mongo) |
247
+ | `@jmlq/logger-plugin-postgresql` | Persistencia en PostgreSQL | [npm](https://npmjs.com/package/@jmlq/logger-plugin-postgresql) |
248
+
249
+ ## 🧪 Testing
250
+
251
+ ```typescript
252
+ import { LoggerFactory, LogLevel } from "@jmlq/logger";
253
+
254
+ describe("Logger Tests", () => {
255
+ it("debe enmascarar PII correctamente", async () => {
256
+ const logs: any[] = [];
257
+ const mockDatasource = {
258
+ name: "mock",
259
+ async save(log: any) {
260
+ logs.push(log);
261
+ },
262
+ async find() {
263
+ return [];
264
+ },
265
+ async flush() {},
266
+ async dispose() {},
267
+ };
268
+
269
+ const logger = LoggerFactory.create({
270
+ datasources: mockDatasource,
271
+ redactorOptions: { enabled: true },
272
+ });
273
+
274
+ await logger.info("Usuario: user@example.com");
275
+
276
+ expect(logs[0].message).not.toContain("user@example.com");
277
+ expect(logs[0].message).toContain("[EMAIL]");
278
+ });
279
+ });
280
+ ```
281
+
282
+ ## 🚨 Troubleshooting
283
+
284
+ **Error: No datasources válidos**
285
+
286
+ - Asegúrate de configurar al menos un datasource
287
+ - Verifica las variables de entorno
288
+
289
+ **MongoDB no conecta**
290
+
291
+ - Verifica la URL de conexión
292
+ - Incluye `authSource=admin` si usas usuarios root
293
+
294
+ **Alto uso de memoria**
295
+
296
+ - Implementa límites en las consultas
297
+ - Usa `flush()` periódicamente para vaciar buffers
298
+
299
+ ## 📄 Más Información
300
+
301
+ - **[Arquitectura Detallada](./architecture.md)** - Documentación técnica completa
302
+ - **[Guía de Instalación](./install.md)** - Configuración paso a paso
303
+ - **[Ejemplos](./examples/)** - Códigos de ejemplo funcionales
304
+
305
+ ## 📝 Licencia
306
+
307
+ MIT © Mauricio Lahuasi
@@ -0,0 +1,171 @@
1
+ # Arquitectura del Paquete @jmlq/logger
2
+
3
+ ## Visión General
4
+
5
+ El paquete `@jmlq/logger` está diseñado siguiendo los principios de **Arquitectura Limpia**, proporcionando un sistema de logging extensible y desacoplado que permite registrar logs en múltiples destinos mediante plugins y soporta enmascarado de datos sensibles (PII - Personally Identifiable Information).
6
+
7
+ ## Principios de Diseño
8
+
9
+ - **Separación de responsabilidades**: Cada capa tiene una responsabilidad específica
10
+ - **Inversión de dependencias**: Las capas internas no dependen de las externas
11
+ - **Extensibilidad**: Sistema de plugins para diferentes adaptadores de persistencia
12
+ - **Testabilidad**: Arquitectura que facilita la creación de pruebas unitarias
13
+ - **Configurabilidad**: Múltiples opciones de configuración mediante variables de entorno
14
+
15
+ ## Estructura de Capas
16
+
17
+ ### 📁 Domain (Capa de Dominio)
18
+
19
+ La capa más interna que contiene la lógica de negocio pura, sin dependencias externas.
20
+
21
+ #### **Entities & Value Objects**
22
+
23
+ - [`LogLevelVo`](src/domain/value-objects/log-level.vo.ts): Objeto de valor que representa los niveles de log
24
+
25
+ #### **Ports (Interfaces)**
26
+
27
+ - [`ILoggerPort`](src/domain/ports/logger.port.ts): Contrato principal del logger
28
+ - [`ILogDatasourcePort`](src/domain/ports/log-datasource.port.ts): Contrato para fuentes de datos
29
+ - [`ILoggerServicePort`](src/domain/ports/logger-service.port.ts): Contrato para servicios de logging
30
+ - [`IPiiRedactorPort`](src/domain/ports/pii-redactor.port.ts): Contrato para enmascarado PII
31
+ - [`ILoggerFactoryConfigPort`](src/domain/ports/logger-factory-config.port.ts): Contrato de configuración del factory
32
+
33
+ #### **Services (Servicios de Dominio)**
34
+
35
+ - [`LogLevelService`](src/domain/services/log-level.service.ts): Lógica para manejo de niveles de log
36
+ - [`MessageNormalizerService`](src/domain/services/message-normalizer.service.ts): Normalización de mensajes
37
+ - [`PiiPatternService`](src/domain/services/pii-pattern.service.ts): Gestión de patrones PII
38
+ - [`PiiRedactorService`](src/domain/services/pii-redactor.service.ts): Enmascarado de datos sensibles
39
+
40
+ #### **Types & DTOs**
41
+
42
+ - **Request**: [`SaveLogProps`](src/domain/request/save-log.props.ts), [`GetLogsFilterProps`](src/domain/request/get-logs-filter.props.ts), [`PiiOptionsProps`](src/domain/request/pii-options.props.ts)
43
+ - **Response**: [`LogResponse`](src/domain/response/log.response.ts)
44
+ - **Types**: [`LogMessageType`](src/domain/types/log-message.type.ts)
45
+
46
+ ### 📁 Application (Capa de Aplicación)
47
+
48
+ Orquesta la lógica de negocio y coordina los casos de uso.
49
+
50
+ #### **Use Cases**
51
+
52
+ - [`SaveLogUseCase`](src/application/use-cases/save-log.use-case.ts): Guarda logs en los datasources configurados
53
+ - [`GetLogsUseCase`](src/application/use-cases/get-logs.use-case.ts): Recupera logs con filtros
54
+ - [`FlushBuffersUseCase`](src/application/use-cases/flush-buffers.use-case.ts): Vacía buffers de los datasources
55
+
56
+ #### **Factory**
57
+
58
+ - [`LoggerFactory`](src/application/factory/logger.factory.ts): Factory para crear instancias del logger
59
+
60
+ ### 📁 Infrastructure (Capa de Infraestructura)
61
+
62
+ Implementaciones concretas de los contratos definidos en el dominio.
63
+
64
+ #### **Services**
65
+
66
+ - [`DatasourceService`](src/infrastructure/services/datasource.service.ts): Implementación del servicio de datasource
67
+ - [`DataSourceErrorHandlerType`](src/infrastructure/services/data-source-error-handler.type.ts): Manejo de errores de datasources
68
+
69
+ ## Flujo de Dependencias
70
+
71
+ ```txt
72
+ Infrastructure → Application → Domain
73
+ ```
74
+
75
+ - **Domain**: No depende de nada, contiene la lógica de negocio pura
76
+ - **Application**: Depende solo del Domain, orquesta los casos de uso
77
+ - **Infrastructure**: Depende del Domain y Application, implementa los contratos
78
+
79
+ ## Patrones Implementados
80
+
81
+ ### **Factory Pattern**
82
+
83
+ El [`LoggerFactory`](src/application/factory/logger.factory.ts) centraliza la creación de instancias del logger con las configuraciones apropiadas.
84
+
85
+ ### **Port-Adapter Pattern**
86
+
87
+ Los ports en el domain definen contratos que son implementados por adaptadores en infrastructure.
88
+
89
+ ### **Use Case Pattern**
90
+
91
+ Cada operación principal está encapsulada en un caso de uso específico con un método `execute()`.
92
+
93
+ ### **Dependency Injection**
94
+
95
+ Las dependencias se inyectan a través de constructores, facilitando el testing y la flexibilidad.
96
+
97
+ ## Sistema de Plugins
98
+
99
+ El logger soporta múltiples adaptadores de persistencia:
100
+
101
+ - **Filesystem**: `@jmlq/logger-plugin-fs`
102
+ - **MongoDB**: `@jmlq/logger-plugin-mongo`
103
+ - **PostgreSQL**: `@jmlq/logger-plugin-postgresql`
104
+
105
+ Cada plugin implementa los ports definidos en el domain.
106
+
107
+ ## Características Principales
108
+
109
+ ### **PII (Personally Identifiable Information)**
110
+
111
+ - Enmascarado automático de datos sensibles
112
+ - Patrones configurables y extensibles
113
+ - Soporte para patrones por defecto y personalizados
114
+
115
+ ### **Niveles de Log**
116
+
117
+ - debug, info, warn, error, fatal
118
+ - Configuración de nivel mínimo por entorno
119
+
120
+ ### **Múltiples Datasources**
121
+
122
+ - Soporte simultáneo para múltiples backends
123
+ - Configuración opcional de cada adaptador
124
+
125
+ ### **Configuración Flexible**
126
+
127
+ - Variables de entorno
128
+ - Configuración programática
129
+ - Políticas de retención de datos
130
+
131
+ ## Ejemplo de Uso
132
+
133
+ ```typescript
134
+ import { LoggerBootstrap } from "@jmlq/logger";
135
+
136
+ const logger = await LoggerBootstrap.create({
137
+ minLevel: "debug",
138
+ pii: {
139
+ enabled: true,
140
+ includeDefaults: true,
141
+ deep: true,
142
+ },
143
+ adapters: {
144
+ fs: { basePath: "./logs" },
145
+ mongo: { url: "mongodb://localhost:27017", dbName: "logs" },
146
+ },
147
+ });
148
+
149
+ await logger.info("User logged in", {
150
+ userId: "12345",
151
+ email: "user@example.com",
152
+ });
153
+ ```
154
+
155
+ ## Testing
156
+
157
+ La arquitectura facilita el testing mediante:
158
+
159
+ > - Interfaces claramente definidas
160
+ > - Servicios desacoplados
161
+ > - Casos de uso aislados
162
+ > - Mocks sencillos de implementar
163
+
164
+ ## Consideraciones de Rendimiento
165
+
166
+ > - Buffers para escritura asíncrona
167
+ > - Políticas de rotación de archivos
168
+ > - Retención configurable de datos
169
+ > - Procesamiento asíncrono de logs
170
+
171
+ Esta arquitectura asegura mantenibilidad, extensibilidad y testabilidad del sistema de logging, siguiendo las mejores prácticas de clean architecture.
@@ -0,0 +1,3 @@
1
+ export declare class DataSourceServiceExample {
2
+ static Main(): Promise<void>;
3
+ }
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // 🧩 Ejemplo realista de cómo un cliente podría integrar DataSourceService
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DataSourceServiceExample = void 0;
7
+ const src_1 = require("src");
8
+ const infrastructure_1 = require("src/infrastructure");
9
+ /**
10
+ * InMemoryLogDatasource
11
+ *
12
+ * Implementación simple de ILogDatasource que almacena los logs en memoria.
13
+ * Útil para:
14
+ * - Tests
15
+ * - Ejemplos / demos
16
+ * - Entornos de desarrollo
17
+ */
18
+ class InMemoryLogDatasource {
19
+ constructor() {
20
+ this.name = "in-memory";
21
+ this.logs = [];
22
+ }
23
+ /**
24
+ * Guarda un log en memoria.
25
+ * No aplica lógica especial, solo hace push al arreglo interno.
26
+ */
27
+ async save(log) {
28
+ // Suponemos que ILogResponse es compatible con ILogProps.
29
+ // Si en tu dominio ILogResponse tiene campos extra (ej: id),
30
+ // aquí podrías generarlos.
31
+ this.logs.push(log);
32
+ }
33
+ /**
34
+ * Devuelve los logs almacenados en memoria.
35
+ * Por simplicidad, se ignora el filtro. Puedes adaptar esta parte cuando
36
+ * tengas definido el shape completo de IGetLogsFilterProps.
37
+ */
38
+ async find(_filter) {
39
+ // Retornamos una copia para evitar mutación externa.
40
+ return [...this.logs];
41
+ }
42
+ /**
43
+ * Limpia todos los logs almacenados.
44
+ */
45
+ async flush() {
46
+ this.logs.length = 0;
47
+ }
48
+ /**
49
+ * Libera recursos.
50
+ * En este caso es equivalente a flush(), pero queda listo
51
+ * por si en el futuro necesitas lógica adicional.
52
+ */
53
+ async dispose() {
54
+ await this.flush();
55
+ }
56
+ }
57
+ /**
58
+ * AppLoggerService
59
+ *
60
+ * Servicio de logging de la aplicación que:
61
+ * - Usa DataSourceService (composite) debajo.
62
+ * - Configura múltiples datasources.
63
+ * - Centraliza el manejo de errores del logger vía errorHandler.
64
+ */
65
+ class AppLoggerService {
66
+ constructor() {
67
+ // 1️⃣ Definimos los datasources que usará la app
68
+ const datasources = [
69
+ new InMemoryLogDatasource(), // para debugging / tests / fallback
70
+ new HttpLogDatasource(// datasource custom del cliente
71
+ process.env.LOG_API_URL ?? "https://logs.my-api.com/events"),
72
+ ];
73
+ // 2️⃣ Definimos un error handler centralizado para errores del logger
74
+ const errorHandler = (info) => {
75
+ // Aquí el cliente podría usar su propio logger de infra (pino, winston, etc).
76
+ // En este ejemplo usamos console.error por simplicidad.
77
+ // IMPORTANTE: este logger NO debe depender de @jmlq/logger para evitar ciclos.
78
+ console.error("[AppLoggerService] Error en datasource de logger", {
79
+ op: info.operation,
80
+ datasource: info.datasourceName,
81
+ error: info.reason,
82
+ });
83
+ };
84
+ // 3️⃣ Creamos el DataSourceService composite con los datasources y el handler
85
+ this.dataSourceService = new infrastructure_1.DataSourceService(datasources, errorHandler);
86
+ }
87
+ // ----------------------------------------------------------------------------
88
+ // API pública del logger de la app (lo que realmente usa el cliente)
89
+ // ----------------------------------------------------------------------------
90
+ async info(message, meta) {
91
+ await this.log(src_1.LogLevel.INFO, message, meta);
92
+ }
93
+ async warn(message, meta) {
94
+ await this.log(src_1.LogLevel.WARN, message, meta);
95
+ }
96
+ async error(message, meta) {
97
+ await this.log(src_1.LogLevel.ERROR, message, meta);
98
+ }
99
+ async debug(message, meta) {
100
+ await this.log(src_1.LogLevel.DEBUG, message, meta);
101
+ }
102
+ async log(level, message, meta) {
103
+ const log = {
104
+ level,
105
+ message,
106
+ timestamp: Date.now(),
107
+ meta,
108
+ };
109
+ await this.dataSourceService.save(log);
110
+ }
111
+ /**
112
+ * Métodos opcionales para flush/dispose (por ejemplo, en shutdown de la app).
113
+ */
114
+ async flush() {
115
+ await this.dataSourceService.flush();
116
+ }
117
+ async dispose() {
118
+ await this.dataSourceService.dispose();
119
+ }
120
+ }
121
+ // ============================================================================
122
+ // 🌐 Ejemplo de datasource HTTP implementado por el cliente
123
+ // (no forma parte del core, lo crea el consumidor usando ILogDatasource)
124
+ // ============================================================================
125
+ class HttpLogDatasource {
126
+ constructor(endpoint) {
127
+ this.endpoint = endpoint;
128
+ this.name = "http";
129
+ }
130
+ async save(log) {
131
+ // Aquí el cliente puede usar fetch, axios, got, etc.
132
+ // Lo dejamos como pseudo-código para no acoplar dependencias reales.
133
+ const body = JSON.stringify(log);
134
+ await fetch(this.endpoint, {
135
+ method: "POST",
136
+ headers: { "Content-Type": "application/json" },
137
+ body,
138
+ });
139
+ }
140
+ }
141
+ // ============================================================================
142
+ // 🚀 Example runner: cómo el cliente lo usaría en su app
143
+ // ============================================================================
144
+ class DataSourceServiceExample {
145
+ static async Main() {
146
+ console.log("=== 🧩 Ejemplo REAL de uso: AppLoggerService sobre DataSourceService ===\n");
147
+ // 1️⃣ Crear instancia de logger de aplicación
148
+ const logger = new AppLoggerService();
149
+ // 2️⃣ Loguear eventos típicos de una app
150
+ console.log("📝 Enviando logs de ejemplo...\n");
151
+ await logger.info("Servidor iniciado", {
152
+ port: 3000,
153
+ env: process.env.NODE_ENV ?? "development",
154
+ });
155
+ await logger.info("Usuario autenticado", {
156
+ userId: "12345",
157
+ method: "password",
158
+ });
159
+ await logger.error("Error al procesar pedido", {
160
+ orderId: "ORD-999",
161
+ reason: "Stock insuficiente",
162
+ });
163
+ await logger.warn("Latencia alta detectada en /payments", {
164
+ p95_ms: 850,
165
+ });
166
+ console.log("✅ Logs enviados. Si algún datasource falla, el error handler los captura.\n");
167
+ // 3️⃣ Ejemplo de uso en shutdown de la app
168
+ console.log("🧹 Realizando flush() y dispose() del logger...\n");
169
+ await logger.flush();
170
+ await logger.dispose();
171
+ console.log("🏁 Ejemplo real completado.\n");
172
+ }
173
+ }
174
+ exports.DataSourceServiceExample = DataSourceServiceExample;
@@ -0,0 +1,3 @@
1
+ export declare class FlushBuffersUseCaseExample {
2
+ static Main(): Promise<void>;
3
+ }