@jmlq/logger-plugin-fs 0.1.0-alpha.1 → 0.1.0-alpha.10

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 (118) hide show
  1. package/README.md +229 -0
  2. package/architecture.md +426 -0
  3. package/dist/application/dto/index.d.ts +1 -0
  4. package/dist/application/dto/index.js +17 -0
  5. package/dist/application/dto/rotate-if-needed.request.d.ts +10 -0
  6. package/dist/application/dto/rotate-if-needed.request.js +2 -0
  7. package/dist/application/factory/create-fs-datasource.factory.d.ts +16 -0
  8. package/dist/application/factory/create-fs-datasource.factory.js +51 -0
  9. package/dist/application/factory/index.d.ts +1 -0
  10. package/dist/application/factory/index.js +17 -0
  11. package/dist/application/use-cases/append-log.use-case.d.ts +30 -0
  12. package/dist/application/use-cases/append-log.use-case.js +39 -0
  13. package/dist/application/use-cases/ensure-directory.use-case.d.ts +58 -0
  14. package/dist/application/use-cases/ensure-directory.use-case.js +64 -0
  15. package/dist/application/use-cases/find-logs-use-case.d.ts +17 -0
  16. package/dist/application/use-cases/find-logs-use-case.js +64 -0
  17. package/dist/application/use-cases/index.d.ts +5 -0
  18. package/dist/application/use-cases/index.js +21 -0
  19. package/dist/application/use-cases/persist-log.use-case.d.ts +96 -0
  20. package/dist/application/use-cases/persist-log.use-case.js +105 -0
  21. package/dist/application/use-cases/rotate-if-needed.use-case.d.ts +55 -0
  22. package/dist/application/use-cases/rotate-if-needed.use-case.js +61 -0
  23. package/dist/domain/model/index.d.ts +1 -0
  24. package/dist/domain/model/index.js +17 -0
  25. package/dist/domain/model/log-entry.model.d.ts +8 -0
  26. package/dist/domain/model/log-entry.model.js +2 -0
  27. package/dist/domain/ports/file/file-path.port.d.ts +38 -0
  28. package/dist/domain/ports/file/file-path.port.js +2 -0
  29. package/dist/domain/ports/file/file-rotator.port.d.ts +42 -0
  30. package/dist/domain/ports/file/file-rotator.port.js +2 -0
  31. package/dist/domain/ports/file/index.d.ts +2 -0
  32. package/dist/domain/ports/file/index.js +18 -0
  33. package/dist/domain/ports/file/log-stream-writer.port.d.ts +70 -0
  34. package/dist/domain/ports/file/log-stream-writer.port.js +2 -0
  35. package/dist/domain/ports/filesystem-provider.port.d.ts +61 -0
  36. package/dist/domain/ports/filesystem-provider.port.js +2 -0
  37. package/dist/domain/ports/index.d.ts +5 -0
  38. package/dist/domain/ports/index.js +21 -0
  39. package/dist/domain/ports/logs/find/index.d.ts +2 -0
  40. package/dist/domain/ports/logs/find/index.js +18 -0
  41. package/dist/domain/ports/logs/find/log-file-line-reader.port.d.ts +3 -0
  42. package/dist/domain/ports/logs/find/log-file-line-reader.port.js +2 -0
  43. package/dist/domain/ports/logs/find/log-file-numerator.port.d.ts +3 -0
  44. package/dist/domain/ports/logs/find/log-file-numerator.port.js +2 -0
  45. package/dist/domain/ports/logs/index.d.ts +2 -0
  46. package/dist/domain/ports/logs/index.js +18 -0
  47. package/dist/domain/ports/logs/log-datasource.port.d.ts +10 -0
  48. package/dist/domain/ports/logs/log-datasource.port.js +2 -0
  49. package/dist/domain/ports/system-clock.port.d.ts +8 -0
  50. package/dist/domain/ports/system-clock.port.js +2 -0
  51. package/dist/domain/request/index.d.ts +2 -0
  52. package/dist/domain/request/index.js +18 -0
  53. package/dist/domain/request/log-filter.request.d.ts +9 -0
  54. package/dist/domain/request/log-filter.request.js +2 -0
  55. package/dist/domain/request/save-log.request.d.ts +7 -0
  56. package/dist/domain/request/save-log.request.js +2 -0
  57. package/dist/domain/response/index.d.ts +1 -0
  58. package/dist/domain/response/index.js +17 -0
  59. package/dist/domain/response/log.response.d.ts +8 -0
  60. package/dist/domain/response/log.response.js +2 -0
  61. package/dist/domain/types/fs-rotation-by.type.d.ts +8 -0
  62. package/dist/domain/types/fs-rotation-by.type.js +2 -0
  63. package/dist/domain/types/index.d.ts +1 -0
  64. package/dist/domain/types/index.js +17 -0
  65. package/dist/domain/value-objects/file-name-pattern.vo.d.ts +36 -0
  66. package/dist/domain/value-objects/file-name-pattern.vo.js +53 -0
  67. package/dist/domain/value-objects/file-path.vo.d.ts +91 -0
  68. package/dist/domain/value-objects/file-path.vo.js +100 -0
  69. package/dist/domain/value-objects/file-rotation-policy.vo.d.ts +51 -0
  70. package/dist/domain/value-objects/file-rotation-policy.vo.js +76 -0
  71. package/dist/domain/value-objects/file-size.vo.d.ts +75 -0
  72. package/dist/domain/value-objects/file-size.vo.js +114 -0
  73. package/dist/domain/value-objects/index.d.ts +5 -0
  74. package/dist/domain/value-objects/index.js +21 -0
  75. package/dist/domain/value-objects/log-level.vo.d.ts +8 -0
  76. package/dist/domain/value-objects/log-level.vo.js +13 -0
  77. package/dist/index.d.ts +3 -13
  78. package/dist/index.js +10 -38
  79. package/dist/infrastructure/adapters/file-rotator.adapter.d.ts +79 -0
  80. package/dist/infrastructure/adapters/file-rotator.adapter.js +171 -0
  81. package/dist/infrastructure/adapters/fileSystem-datasource.adapter.d.ts +26 -0
  82. package/dist/infrastructure/adapters/fileSystem-datasource.adapter.js +45 -0
  83. package/dist/infrastructure/adapters/filesystem-log-file-enumerator.adapter.d.ts +6 -0
  84. package/dist/infrastructure/adapters/filesystem-log-file-enumerator.adapter.js +54 -0
  85. package/dist/infrastructure/adapters/filesystem-log-file-line-reader.adapter.d.ts +4 -0
  86. package/dist/infrastructure/adapters/filesystem-log-file-line-reader.adapter.js +53 -0
  87. package/dist/infrastructure/adapters/filesystem-provider.adapter.d.ts +122 -0
  88. package/dist/infrastructure/adapters/filesystem-provider.adapter.js +182 -0
  89. package/dist/infrastructure/adapters/index.d.ts +8 -0
  90. package/dist/infrastructure/adapters/index.js +24 -0
  91. package/dist/infrastructure/adapters/log-stream-writer.adapter.d.ts +80 -0
  92. package/dist/infrastructure/adapters/log-stream-writer.adapter.js +163 -0
  93. package/dist/infrastructure/adapters/system-clock.adapter.d.ts +25 -0
  94. package/dist/infrastructure/adapters/system-clock.adapter.js +30 -0
  95. package/dist/infrastructure/adapters/system-file-path.adapter.d.ts +47 -0
  96. package/dist/infrastructure/adapters/system-file-path.adapter.js +141 -0
  97. package/dist/infrastructure/errors/file-operation.error.d.ts +28 -0
  98. package/dist/infrastructure/errors/file-operation.error.js +54 -0
  99. package/dist/infrastructure/errors/index.d.ts +1 -0
  100. package/dist/infrastructure/errors/index.js +17 -0
  101. package/dist/infrastructure/errors/types/file-operation-error-options.type.d.ts +8 -0
  102. package/dist/infrastructure/errors/types/file-operation-error-options.type.js +2 -0
  103. package/dist/infrastructure/errors/types/file-operation.type.d.ts +1 -0
  104. package/dist/infrastructure/errors/types/file-operation.type.js +2 -0
  105. package/dist/infrastructure/errors/types/fs-error-scope.type.d.ts +1 -0
  106. package/dist/infrastructure/errors/types/fs-error-scope.type.js +2 -0
  107. package/dist/infrastructure/errors/types/index.d.ts +3 -0
  108. package/dist/infrastructure/errors/types/index.js +19 -0
  109. package/dist/infrastructure/filesystem/index.d.ts +1 -0
  110. package/dist/infrastructure/filesystem/index.js +17 -0
  111. package/dist/infrastructure/filesystem/types/filesystem-datasource-options.type.d.ts +45 -0
  112. package/dist/infrastructure/filesystem/types/filesystem-datasource-options.type.js +2 -0
  113. package/dist/infrastructure/filesystem/types/filesystem-rotation.type.d.ts +12 -0
  114. package/dist/infrastructure/filesystem/types/filesystem-rotation.type.js +2 -0
  115. package/dist/infrastructure/filesystem/types/index.d.ts +2 -0
  116. package/dist/infrastructure/filesystem/types/index.js +18 -0
  117. package/install.md +520 -0
  118. package/package.json +40 -12
package/install.md ADDED
@@ -0,0 +1,520 @@
1
+ # Instalación y Configuración - @jmlq/logger-plugin-fs
2
+
3
+ ## Introducción Técnica
4
+
5
+ `@jmlq/logger-plugin-fs` es un plugin para el sistema de logging `@jmlq/logger` que proporciona persistencia en sistema de archivos con capacidades avanzadas de rotación. Implementa Clean Architecture y está diseñado para aplicaciones Node.js que requieren logging persistente con gestión automática de archivos.
6
+
7
+ El plugin se integra como un datasource del logger principal, permitiendo escribir logs en archivos con políticas de rotación configurables (diaria, por tamaño, o sin rotación). Incluye funcionalidades como creación automática de directorios, serialización personalizable y callbacks para eventos de rotación.
8
+
9
+ ## Instalación
10
+
11
+ ### Dependencias Requeridas
12
+
13
+ ```bash
14
+ npm install @jmlq/logger @jmlq/logger-plugin-fs
15
+ ```
16
+
17
+ ### Dependencias
18
+
19
+ El plugin requiere como peer dependency:
20
+
21
+ - `@jmlq/logger` >= 0.1.0-alpha.12
22
+
23
+ ## Configuración del FileSystemDatasource
24
+
25
+ ### Factory Principal
26
+
27
+ El plugin proporciona la función `createFsDatasource` que actúa como factory principal:
28
+
29
+ ```typescript
30
+ import { createFsDatasource } from '@jmlq/logger-plugin-fs';
31
+ import { IFilesystemDatasourceOptions } from '@jmlq/logger-plugin-fs';
32
+
33
+ const datasource = createFsDatasource(options: IFilesystemDatasourceOptions);
34
+ ```
35
+
36
+ ### Parámetros de Configuración
37
+
38
+ #### IFilesystemDatasourceOptions
39
+
40
+ ```typescript
41
+ interface IFilesystemDatasourceOptions {
42
+ basePath: string; // OBLIGATORIO
43
+ mkdir?: boolean; // Opcional, default: undefined
44
+ fileNamePattern?: string; // Opcional, default: "app-{yyyy}{MM}{dd}.log"
45
+ rotation?: IFileRotationConfig; // Opcional
46
+ serializer?: IFsSerializer; // Opcional
47
+ onRotate?: (oldPath: FilePath, newPath: FilePath) => void | Promise<void>;
48
+ onError?: (error: Error) => void | Promise<void>;
49
+ }
50
+ ```
51
+
52
+ #### Descripción de Parámetros
53
+
54
+ - **`basePath`** (string): Directorio base donde se crearán los archivos de log. Es el único parámetro obligatorio.
55
+
56
+ - **`mkdir`** (boolean, opcional): Si es `true`, crea automáticamente el directorio `basePath` usando `fs.mkdir({ recursive: true })` si no existe.
57
+
58
+ - **`fileNamePattern`** (string, opcional): Patrón para nombres de archivo. Default: `"app-{yyyy}{MM}{dd}.log"`. Admite placeholders:
59
+
60
+ - `{yyyy}` - Año de 4 dígitos
61
+ - `{MM}` - Mes de 2 dígitos (01-12)
62
+ - `{dd}` - Día de 2 dígitos (01-31)
63
+
64
+ - **`rotation`** (IFileRotationConfig, opcional): Configuración de política de rotación.
65
+
66
+ - **`serializer`** (IFsSerializer, opcional): Estrategia personalizada de serialización de logs a string.
67
+
68
+ - **`onRotate`** (función, opcional): Callback ejecutado cuando se rota un archivo. Útil para notificaciones o envío a servicios externos.
69
+
70
+ - **`onError`** (función, opcional): Callback centralizado para manejo de errores del datasource.
71
+
72
+ ## Política de Rotación (RotationPolicy)
73
+
74
+ ### Configuración IFileRotationConfig
75
+
76
+ ```typescript
77
+ interface IFileRotationConfig {
78
+ by: FsRotationBy; // "none" | "day" | "size"
79
+ maxSizeMB?: number; // Solo para by: "size"
80
+ maxFiles?: number; // Número máximo de archivos rotados a mantener
81
+ }
82
+ ```
83
+
84
+ ### Tipos de Rotación Soportados
85
+
86
+ #### 1. Sin Rotación (`"none"`)
87
+
88
+ ```typescript
89
+ const datasource = createFsDatasource({
90
+ basePath: "./logs",
91
+ rotation: {
92
+ by: "none",
93
+ },
94
+ });
95
+ ```
96
+
97
+ El archivo crece indefinidamente sin rotación.
98
+
99
+ #### 2. Rotación Diaria (`"day"`)
100
+
101
+ ```typescript
102
+ const datasource = createFsDatasource({
103
+ basePath: "./logs",
104
+ fileNamePattern: "app-{yyyy}-{MM}-{dd}.log",
105
+ rotation: {
106
+ by: "day",
107
+ maxFiles: 7, // Mantener últimos 7 días
108
+ },
109
+ });
110
+ ```
111
+
112
+ Crea un archivo nuevo cada día basado en el patrón de fecha.
113
+
114
+ #### 3. Rotación por Tamaño (`"size"`)
115
+
116
+ ```typescript
117
+ const datasource = createFsDatasource({
118
+ basePath: "./logs",
119
+ rotation: {
120
+ by: "size",
121
+ maxSizeMB: 10, // OBLIGATORIO para rotación por tamaño
122
+ maxFiles: 5, // Mantener últimos 5 archivos
123
+ },
124
+ });
125
+ ```
126
+
127
+ **Importante**: Para `by: "size"`, el parámetro `maxSizeMB` debe ser un número positivo.
128
+
129
+ ## Serialización Personalizada
130
+
131
+ ### Interface IFsSerializer
132
+
133
+ ```typescript
134
+ interface IFsSerializer {
135
+ serialize(entry: unknown): string;
136
+ }
137
+ ```
138
+
139
+ ### Implementación de Serializer Personalizado
140
+
141
+ ```typescript
142
+ const customSerializer: IFsSerializer = {
143
+ serialize(log: any): string {
144
+ // Ejemplo: formato personalizado con timestamp ISO
145
+ const timestamp = new Date(log.timestamp).toISOString();
146
+ return `[${timestamp}] ${log.level.toUpperCase()}: ${log.message}\n`;
147
+ },
148
+ };
149
+
150
+ const datasource = createFsDatasource({
151
+ basePath: "./logs",
152
+ serializer: customSerializer,
153
+ });
154
+ ```
155
+
156
+ ## Ejemplos Técnicos Completos
157
+
158
+ ### Configuración Básica
159
+
160
+ ```typescript
161
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
162
+ import { LoggerFactory } from "@jmlq/logger";
163
+
164
+ // Crear datasource con configuración mínima
165
+ const fsDatasource = createFsDatasource({
166
+ basePath: "./logs",
167
+ mkdir: true,
168
+ });
169
+
170
+ // Integrar con LoggerFactory
171
+ const logger = LoggerFactory.create({
172
+ datasources: [fsDatasource],
173
+ });
174
+
175
+ // Uso básico
176
+ logger.info("Aplicación iniciada");
177
+ logger.error("Error de conexión a base de datos");
178
+ ```
179
+
180
+ ### Configuración con Rotación por Día y Callbacks
181
+
182
+ ```typescript
183
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
184
+ import { LoggerFactory } from "@jmlq/logger";
185
+ import { FilePath } from "@jmlq/logger-plugin-fs";
186
+
187
+ const fsDatasource = createFsDatasource({
188
+ basePath: "./logs/production",
189
+ fileNamePattern: "app-{yyyy}-{MM}-{dd}.log",
190
+ mkdir: true,
191
+ rotation: {
192
+ by: "day",
193
+ maxFiles: 30, // Mantener logs de últimos 30 días
194
+ },
195
+ serializer: {
196
+ serialize(log: any): string {
197
+ return (
198
+ JSON.stringify({
199
+ timestamp: new Date(log.timestamp).toISOString(),
200
+ level: log.level,
201
+ message: log.message,
202
+ ...log.extra,
203
+ }) + "\n"
204
+ );
205
+ },
206
+ },
207
+ onRotate: async (oldPath: FilePath, newPath: FilePath) => {
208
+ console.log(
209
+ `Log rotado: ${oldPath.absolutePath} → ${newPath.absolutePath}`
210
+ );
211
+ // Aquí podrías enviar el archivo a S3, comprimir, etc.
212
+ },
213
+ onError: async (error: Error) => {
214
+ console.error("Error en filesystem datasource:", error.message);
215
+ // Enviar métricas de error, notificar administradores, etc.
216
+ },
217
+ });
218
+
219
+ const logger = LoggerFactory.create({
220
+ datasources: [fsDatasource],
221
+ });
222
+ ```
223
+
224
+ ### Configuración con Rotación por Tamaño
225
+
226
+ ```typescript
227
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
228
+ import { LoggerFactory } from "@jmlq/logger";
229
+
230
+ const fsDatasource = createFsDatasource({
231
+ basePath: "./logs/high-volume",
232
+ fileNamePattern: "app.log",
233
+ mkdir: true,
234
+ rotation: {
235
+ by: "size",
236
+ maxSizeMB: 50, // Rotar cuando el archivo alcance 50MB
237
+ maxFiles: 10, // Mantener últimos 10 archivos rotados
238
+ },
239
+ });
240
+
241
+ const logger = LoggerFactory.create({
242
+ datasources: [fsDatasource],
243
+ });
244
+
245
+ // Para aplicaciones con alto volumen de logs
246
+ for (let i = 0; i < 10000; i++) {
247
+ logger.debug(`Procesando registro ${i}`, {
248
+ userId: i,
249
+ operation: "bulk-process",
250
+ });
251
+ }
252
+
253
+ // Forzar escritura al archivo
254
+ await fsDatasource.flush();
255
+ ```
256
+
257
+ ## Uso en Frameworks
258
+
259
+ ### Integración con Express
260
+
261
+ ```typescript
262
+ import express from "express";
263
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
264
+ import { LoggerFactory, LogLevel } from "@jmlq/logger";
265
+
266
+ // Configurar datasource para Express
267
+ const fsDatasource = createFsDatasource({
268
+ basePath: "./logs/express",
269
+ fileNamePattern: "express-{yyyy}-{MM}-{dd}.log",
270
+ mkdir: true,
271
+ rotation: {
272
+ by: "day",
273
+ maxFiles: 15,
274
+ },
275
+ serializer: {
276
+ serialize(log: any): string {
277
+ return `${new Date(log.timestamp).toISOString()} [${log.level}] ${
278
+ log.message
279
+ }\n`;
280
+ },
281
+ },
282
+ });
283
+
284
+ const logger = LoggerFactory.create({
285
+ datasources: [fsDatasource],
286
+ });
287
+
288
+ const app = express();
289
+
290
+ // Middleware de logging
291
+ app.use((req, res, next) => {
292
+ logger.info(`${req.method} ${req.path}`, {
293
+ ip: req.ip,
294
+ userAgent: req.get("User-Agent"),
295
+ });
296
+ next();
297
+ });
298
+
299
+ // Manejo de errores con logging
300
+ app.use(
301
+ (
302
+ err: Error,
303
+ req: express.Request,
304
+ res: express.Response,
305
+ next: express.NextFunction
306
+ ) => {
307
+ logger.error("Error en aplicación Express", {
308
+ error: err.message,
309
+ stack: err.stack,
310
+ url: req.url,
311
+ method: req.method,
312
+ });
313
+ res.status(500).json({ error: "Internal Server Error" });
314
+ }
315
+ );
316
+
317
+ app.listen(3000, () => {
318
+ logger.info("Servidor Express iniciado en puerto 3000");
319
+ });
320
+
321
+ // Cerrar correctamente el datasource al terminar la aplicación
322
+ process.on("SIGINT", async () => {
323
+ logger.info("Cerrando aplicación...");
324
+ await fsDatasource.flush();
325
+ await fsDatasource.dispose();
326
+ process.exit(0);
327
+ });
328
+ ```
329
+
330
+ ### Integración con NestJS
331
+
332
+ ```typescript
333
+ import { Injectable, Module, OnModuleDestroy } from "@nestjs/common";
334
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
335
+ import { LoggerFactory, ILogDatasource } from "@jmlq/logger";
336
+
337
+ @Injectable()
338
+ export class LoggingService implements OnModuleDestroy {
339
+ private readonly fsDatasource: ILogDatasource;
340
+ private readonly logger: any;
341
+
342
+ constructor() {
343
+ this.fsDatasource = createFsDatasource({
344
+ basePath: "./logs/nestjs",
345
+ fileNamePattern: "nest-{yyyy}-{MM}-{dd}.log",
346
+ mkdir: true,
347
+ rotation: {
348
+ by: "day",
349
+ maxFiles: 30,
350
+ },
351
+ serializer: {
352
+ serialize(log: any): string {
353
+ return (
354
+ JSON.stringify({
355
+ timestamp: new Date(log.timestamp).toISOString(),
356
+ level: log.level,
357
+ message: log.message,
358
+ context: log.context || "Application",
359
+ ...log.extra,
360
+ }) + "\n"
361
+ );
362
+ },
363
+ },
364
+ onError: async (error: Error) => {
365
+ console.error("[FS Logger Plugin]", error.message);
366
+ },
367
+ });
368
+
369
+ this.logger = LoggerFactory.create({
370
+ datasources: [this.fsDatasource],
371
+ });
372
+ }
373
+
374
+ log(message: string, context?: string, extra?: any) {
375
+ this.logger.info(message, { context, ...extra });
376
+ }
377
+
378
+ error(message: string, trace?: string, context?: string, extra?: any) {
379
+ this.logger.error(message, { trace, context, ...extra });
380
+ }
381
+
382
+ warn(message: string, context?: string, extra?: any) {
383
+ this.logger.warn(message, { context, ...extra });
384
+ }
385
+
386
+ debug(message: string, context?: string, extra?: any) {
387
+ this.logger.debug(message, { context, ...extra });
388
+ }
389
+
390
+ async onModuleDestroy() {
391
+ await this.fsDatasource.flush();
392
+ await this.fsDatasource.dispose();
393
+ }
394
+ }
395
+
396
+ @Module({
397
+ providers: [LoggingService],
398
+ exports: [LoggingService],
399
+ })
400
+ export class LoggingModule {}
401
+ ```
402
+
403
+ ## Variables de Entorno
404
+
405
+ El plugin no maneja variables de entorno directamente. Para usarlas, mapéalas manualmente en la configuración:
406
+
407
+ ```typescript
408
+ import { createFsDatasource } from "@jmlq/logger-plugin-fs";
409
+
410
+ const fsDatasource = createFsDatasource({
411
+ basePath: process.env.LOG_DIR || "./logs",
412
+ mkdir: process.env.NODE_ENV !== "development",
413
+ fileNamePattern: process.env.LOG_FILE_PATTERN || "app-{yyyy}-{MM}-{dd}.log",
414
+ rotation: {
415
+ by: (process.env.LOG_ROTATION_TYPE as any) || "day",
416
+ maxSizeMB: process.env.LOG_MAX_SIZE_MB
417
+ ? parseInt(process.env.LOG_MAX_SIZE_MB)
418
+ : undefined,
419
+ maxFiles: process.env.LOG_MAX_FILES
420
+ ? parseInt(process.env.LOG_MAX_FILES)
421
+ : 7,
422
+ },
423
+ });
424
+ ```
425
+
426
+ Ejemplo de archivo `.env`:
427
+
428
+ ```env
429
+ LOG_DIR=./logs/production
430
+ LOG_FILE_PATTERN=myapp-{yyyy}-{MM}-{dd}.log
431
+ LOG_ROTATION_TYPE=day
432
+ LOG_MAX_FILES=30
433
+ # Para rotación por tamaño:
434
+ # LOG_ROTATION_TYPE=size
435
+ # LOG_MAX_SIZE_MB=100
436
+ ```
437
+
438
+ ## Consideraciones Técnicas
439
+
440
+ ### Permisos del Sistema de Archivos
441
+
442
+ - Asegúrate de que el proceso Node.js tenga permisos de escritura en el directorio `basePath`.
443
+ - Para producción, considera usar directorios como `/var/log/tu-app` en sistemas Unix.
444
+ - En contenedores Docker, monta volúmenes para persistir los logs:
445
+
446
+ ```dockerfile
447
+ VOLUME ["/app/logs"]
448
+ ```
449
+
450
+ ### Gestión de Recursos
451
+
452
+ #### Flush Explícito
453
+
454
+ ```typescript
455
+ // Forzar escritura de buffers pendientes
456
+ await datasource.flush();
457
+ ```
458
+
459
+ #### Cierre Correcto
460
+
461
+ ```typescript
462
+ // Cerrar streams y liberar recursos
463
+ await datasource.dispose();
464
+ ```
465
+
466
+ #### Manejo de Shutdown Graceful
467
+
468
+ ```typescript
469
+ process.on("SIGTERM", async () => {
470
+ await datasource.flush();
471
+ await datasource.dispose();
472
+ process.exit(0);
473
+ });
474
+ ```
475
+
476
+ ### Rendimiento y Recomendaciones
477
+
478
+ - **Rotación por tamaño**: Más eficiente para aplicaciones con volumen variable de logs.
479
+ - **Rotación diaria**: Mejor para aplicaciones con logs predecibles y análisis temporal.
480
+ - **Serializer personalizado**: Optimiza el formato según tus necesidades de análisis posterior.
481
+ - **Callbacks `onRotate`**: Úsalos para automatizar tareas como compresión o envío a servicios externos.
482
+ - **Callback `onError`**: Implementa logging secundario o métricas de monitoreo.
483
+
484
+ ### Limitaciones Conocidas
485
+
486
+ - El plugin funciona únicamente con Node.js (no browser).
487
+ - La rotación por tamaño requiere especificar `maxSizeMB` obligatoriamente.
488
+ - Los placeholders en `fileNamePattern` están limitados a: `{yyyy}`, `{MM}`, `{dd}`.
489
+ - La rotación se basa en la fecha del sistema local.
490
+
491
+ ## Troubleshooting
492
+
493
+ ### Error: "maxSizeMB must be positive for size rotation"
494
+
495
+ Especifica `maxSizeMB` mayor a 0 cuando uses `rotation.by = "size"`:
496
+
497
+ ```typescript
498
+ rotation: {
499
+ by: 'size',
500
+ maxSizeMB: 10 // Obligatorio y > 0
501
+ }
502
+ ```
503
+
504
+ ### Error: Permisos insuficientes
505
+
506
+ Verifica permisos del directorio:
507
+
508
+ ```bash
509
+ chmod 755 /ruta/a/logs
510
+ chown node:node /ruta/a/logs
511
+ ```
512
+
513
+ ### Logs no aparecen inmediatamente
514
+
515
+ Llama `flush()` para forzar escritura:
516
+
517
+ ```typescript
518
+ logger.info("Mensaje importante");
519
+ await datasource.flush(); // Fuerza escritura inmediata
520
+ ```
package/package.json CHANGED
@@ -1,22 +1,50 @@
1
1
  {
2
2
  "name": "@jmlq/logger-plugin-fs",
3
- "version": "0.1.0-alpha.1",
4
- "author": "MLahuasi",
3
+ "description": "Filesystem plugin for JMLQ Logger implementing Clean Architecture principles.",
4
+ "version": "0.1.0-alpha.10",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
7
  "scripts": {
11
- "build": "tsc -p tsconfig.json",
12
- "prepublishOnly": "pnpm build"
8
+ "dev": "rimraf dist && mkdir dist && tsc -p tsconfig.json",
9
+ "build": "rimraf dist && mkdir dist && tsc -p tsconfig.build.json",
10
+ "prepublishOnly": "npm run build",
11
+ "test": "jest --passWithNoTests",
12
+ "test:watch": "jest --watch",
13
+ "test:coverage": "jest --coverage",
14
+ "example:help": "tsx examples/index.example.ts help",
15
+ "example:all": "tsx examples/index.example.ts",
16
+ "example:value-objects": "tsx examples/index.example.ts value-objects",
17
+ "example:infrastructure-adapters": "tsx examples/index.example.ts infrastructure-adapters",
18
+ "example:application-use-cases": "tsx examples/index.example.ts application-use-cases",
19
+ "example:application-services": "tsx examples/index.example.ts application-services",
20
+ "example:application-factories": "tsx examples/index.example.ts application-factories"
13
21
  },
22
+ "keywords": [
23
+ "logger",
24
+ "filesystem",
25
+ "clean-architecture",
26
+ "typescript"
27
+ ],
28
+ "author": "MLahuasi",
29
+ "license": "MIT",
14
30
  "devDependencies": {
15
- "@types/node": "^24.3.0",
16
- "tsx": "^4.20.5",
17
- "typescript": "^5.9.2"
31
+ "@swc/core": "^1.3.95",
32
+ "@swc/jest": "^0.2.29",
33
+ "@types/bcryptjs": "^2.4.5",
34
+ "@types/jest": "^29.5.8",
35
+ "@types/node": "^20.8.10",
36
+ "jest": "^29.7.0",
37
+ "rimraf": "^6.1.2",
38
+ "tsx": "^4.1.4",
39
+ "typescript": "^5.2.2"
18
40
  },
19
- "peerDependencies": {
20
- "@jmlq/logger": "^0.1.0-alpha.0"
41
+ "files": [
42
+ "dist",
43
+ "README.md",
44
+ "architecture.md",
45
+ "install.md"
46
+ ],
47
+ "dependencies": {
48
+ "@jmlq/logger": "^0.1.0-alpha.20"
21
49
  }
22
50
  }