@abdokouta/react-logger 1.0.0
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 +559 -0
- package/config/logger.config.ts +171 -0
- package/dist/index.d.cts +1231 -0
- package/dist/index.d.ts +1231 -0
- package/dist/index.js +906 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +886 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
# @abdokouta/logger
|
|
2
|
+
|
|
3
|
+
Laravel-inspired logging system for Refine with multiple channels, transporters, and formatters.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multiple Channels**: Console, Storage (localStorage), and Silent
|
|
8
|
+
- **Pluggable Transporters**: Route logs to different destinations
|
|
9
|
+
- **Customizable Formatters**: Pretty (with colors/emoji), JSON, or Simple
|
|
10
|
+
- **Contextual Logging**: Add persistent context to all logs
|
|
11
|
+
- **React Hooks**: `useLogger()` and `useLoggerContext()` for easy integration
|
|
12
|
+
- **TypeScript**: Full type safety with comprehensive JSDoc documentation
|
|
13
|
+
- **Browser Compatible**: Works in all modern browsers
|
|
14
|
+
- **Dependency Injection**: Integrates with @abdokouta/container
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @abdokouta/logger
|
|
20
|
+
# or
|
|
21
|
+
yarn add @abdokouta/logger
|
|
22
|
+
# or
|
|
23
|
+
pnpm add @abdokouta/logger
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### 1. Configure the Module
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Module } from '@abdokouta/container';
|
|
32
|
+
import { LoggerModule, defineConfig } from '@abdokouta/logger';
|
|
33
|
+
import { ConsoleTransporter, StorageTransporter } from '@abdokouta/logger';
|
|
34
|
+
import { LogLevel } from '@abdokouta/logger';
|
|
35
|
+
|
|
36
|
+
@Module({
|
|
37
|
+
imports: [
|
|
38
|
+
LoggerModule.forRoot(
|
|
39
|
+
defineConfig({
|
|
40
|
+
default: 'console',
|
|
41
|
+
channels: {
|
|
42
|
+
console: {
|
|
43
|
+
transporters: [new ConsoleTransporter()],
|
|
44
|
+
context: { app: 'my-app', env: 'production' },
|
|
45
|
+
},
|
|
46
|
+
storage: {
|
|
47
|
+
transporters: [new StorageTransporter({ maxEntries: 500 })],
|
|
48
|
+
},
|
|
49
|
+
errors: {
|
|
50
|
+
transporters: [
|
|
51
|
+
new ConsoleTransporter({ level: LogLevel.Error }),
|
|
52
|
+
new StorageTransporter({ key: 'error-logs' }),
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
),
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
export class AppModule {}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Use in Services
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Injectable, Inject } from '@abdokouta/container';
|
|
67
|
+
import { LoggerService } from '@abdokouta/logger';
|
|
68
|
+
|
|
69
|
+
@Injectable()
|
|
70
|
+
export class UserService {
|
|
71
|
+
constructor(
|
|
72
|
+
@Inject(LoggerService) private logger: LoggerService
|
|
73
|
+
) {}
|
|
74
|
+
|
|
75
|
+
async createUser(data: UserData) {
|
|
76
|
+
this.logger.info('Creating user', { email: data.email });
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const user = await this.db.users.create(data);
|
|
80
|
+
this.logger.info('User created', { userId: user.id });
|
|
81
|
+
return user;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
this.logger.error('Failed to create user', { error });
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async auditAction(action: string) {
|
|
89
|
+
// Use specific channel
|
|
90
|
+
const auditLogger = this.logger.channel('audit');
|
|
91
|
+
auditLogger.info('User action', { action });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 3. Use in React Components
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { useLogger } from '@abdokouta/logger';
|
|
100
|
+
|
|
101
|
+
function MyComponent() {
|
|
102
|
+
const logger = useLogger();
|
|
103
|
+
|
|
104
|
+
const handleClick = () => {
|
|
105
|
+
logger.info('Button clicked', { timestamp: Date.now() });
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
return <button onClick={handleClick}>Click me</button>;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Configuration
|
|
113
|
+
|
|
114
|
+
### LoggerModuleOptions
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
interface LoggerModuleOptions {
|
|
118
|
+
/** Default channel name */
|
|
119
|
+
default: string;
|
|
120
|
+
|
|
121
|
+
/** Channel configurations */
|
|
122
|
+
channels: Record<string, LoggerConfig>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface LoggerConfig {
|
|
126
|
+
/** Transporters for this channel */
|
|
127
|
+
transporters?: TransporterInterface[];
|
|
128
|
+
|
|
129
|
+
/** Initial shared context */
|
|
130
|
+
context?: Record<string, unknown>;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Using defineConfig
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { defineConfig } from '@abdokouta/logger';
|
|
138
|
+
|
|
139
|
+
export const loggerConfig = defineConfig({
|
|
140
|
+
default: 'console',
|
|
141
|
+
channels: {
|
|
142
|
+
console: {
|
|
143
|
+
transporters: [new ConsoleTransporter()],
|
|
144
|
+
context: { app: 'my-app' },
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Using Presets
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { defineConfig, consolePreset, silentPreset } from '@abdokouta/logger';
|
|
154
|
+
|
|
155
|
+
// Console preset (development)
|
|
156
|
+
export const devConfig = defineConfig({
|
|
157
|
+
...consolePreset,
|
|
158
|
+
channels: {
|
|
159
|
+
...consolePreset.channels,
|
|
160
|
+
console: {
|
|
161
|
+
...consolePreset.channels.console,
|
|
162
|
+
context: { app: 'my-app', env: 'dev' },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Silent preset (testing)
|
|
168
|
+
export const testConfig = defineConfig(silentPreset);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Channels
|
|
172
|
+
|
|
173
|
+
### Console Channel
|
|
174
|
+
|
|
175
|
+
Logs to the browser console with colors and emoji.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
{
|
|
179
|
+
console: {
|
|
180
|
+
transporters: [new ConsoleTransporter()],
|
|
181
|
+
},
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Storage Channel
|
|
186
|
+
|
|
187
|
+
Persists logs to localStorage.
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
{
|
|
191
|
+
storage: {
|
|
192
|
+
transporters: [
|
|
193
|
+
new StorageTransporter({
|
|
194
|
+
key: 'app-logs',
|
|
195
|
+
maxEntries: 500,
|
|
196
|
+
}),
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Error Channel
|
|
203
|
+
|
|
204
|
+
Multiple transporters for error handling.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
{
|
|
208
|
+
errors: {
|
|
209
|
+
transporters: [
|
|
210
|
+
new ConsoleTransporter({ level: LogLevel.Error }),
|
|
211
|
+
new StorageTransporter({ key: 'error-logs', maxEntries: 200 }),
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Silent Channel
|
|
218
|
+
|
|
219
|
+
Disables logging (useful for testing).
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
{
|
|
223
|
+
silent: {
|
|
224
|
+
transporters: [new SilentTransporter()],
|
|
225
|
+
},
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## API Reference
|
|
230
|
+
|
|
231
|
+
### LoggerService
|
|
232
|
+
|
|
233
|
+
Main service for logging operations.
|
|
234
|
+
|
|
235
|
+
#### Methods
|
|
236
|
+
|
|
237
|
+
- `channel(name?: string): LoggerInterface` - Get a specific channel
|
|
238
|
+
- `debug(message, context?)` - Log debug message
|
|
239
|
+
- `info(message, context?)` - Log info message
|
|
240
|
+
- `warn(message, context?)` - Log warning message
|
|
241
|
+
- `error(message, context?)` - Log error message
|
|
242
|
+
- `fatal(message, context?)` - Log fatal message
|
|
243
|
+
- `withContext(context)` - Add persistent context
|
|
244
|
+
- `withoutContext(keys?)` - Remove context
|
|
245
|
+
- `getChannelNames()` - Get all channel names
|
|
246
|
+
- `hasChannel(name)` - Check if channel exists
|
|
247
|
+
- `isChannelActive(name?)` - Check if channel is active
|
|
248
|
+
|
|
249
|
+
### Logger
|
|
250
|
+
|
|
251
|
+
Core logger class (used internally by LoggerService).
|
|
252
|
+
|
|
253
|
+
#### Methods
|
|
254
|
+
|
|
255
|
+
- `debug(message, context?)` - Log debug message
|
|
256
|
+
- `info(message, context?)` - Log info message
|
|
257
|
+
- `warn(message, context?)` - Log warning message
|
|
258
|
+
- `error(message, context?)` - Log error message
|
|
259
|
+
- `fatal(message, context?)` - Log fatal message
|
|
260
|
+
- `withContext(context)` - Add persistent context
|
|
261
|
+
- `withoutContext(keys?)` - Remove context
|
|
262
|
+
- `getTransporters()` - Get all transporters
|
|
263
|
+
- `getContext()` - Get current context
|
|
264
|
+
|
|
265
|
+
## Transporters
|
|
266
|
+
|
|
267
|
+
### ConsoleTransporter
|
|
268
|
+
|
|
269
|
+
Outputs to browser console with colors and emoji.
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
new ConsoleTransporter({
|
|
273
|
+
formatter: new PrettyFormatter(), // default
|
|
274
|
+
level: LogLevel.Debug, // minimum level
|
|
275
|
+
})
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### StorageTransporter
|
|
279
|
+
|
|
280
|
+
Persists logs to localStorage.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
new StorageTransporter({
|
|
284
|
+
key: 'logger:entries', // localStorage key
|
|
285
|
+
maxEntries: 100, // max entries to keep
|
|
286
|
+
formatter: new JsonFormatter(), // default
|
|
287
|
+
level: LogLevel.Debug, // minimum level
|
|
288
|
+
})
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### SilentTransporter
|
|
292
|
+
|
|
293
|
+
No-op transporter (discards all logs).
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
new SilentTransporter()
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Formatters
|
|
300
|
+
|
|
301
|
+
### PrettyFormatter
|
|
302
|
+
|
|
303
|
+
Colorful output with emoji (default for console).
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
new PrettyFormatter()
|
|
307
|
+
// Output: 🐛 [DEBUG] [14:30:00.000] Hello world {userId: 42}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### JsonFormatter
|
|
311
|
+
|
|
312
|
+
JSON output (default for storage).
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
new JsonFormatter()
|
|
316
|
+
// Output: {"level":"info","message":"Hello","timestamp":"...","context":{}}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### SimpleFormatter
|
|
320
|
+
|
|
321
|
+
Plain text output.
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
new SimpleFormatter()
|
|
325
|
+
// Output: [DEBUG] [2026-03-28T14:30:00.000Z] Hello world {userId: 42}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## React Hooks
|
|
329
|
+
|
|
330
|
+
### useLogger
|
|
331
|
+
|
|
332
|
+
Access logger service in components.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import { useLogger } from '@abdokouta/logger';
|
|
336
|
+
|
|
337
|
+
function MyComponent() {
|
|
338
|
+
const logger = useLogger();
|
|
339
|
+
|
|
340
|
+
// Use default channel
|
|
341
|
+
logger.info('Component rendered');
|
|
342
|
+
|
|
343
|
+
// Use specific channel
|
|
344
|
+
const errorLogger = useLogger('errors');
|
|
345
|
+
errorLogger.error('Something went wrong');
|
|
346
|
+
|
|
347
|
+
return <div>Hello</div>;
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### useLoggerContext
|
|
352
|
+
|
|
353
|
+
Manage logger context in components.
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
import { useLoggerContext, useLogger } from '@abdokouta/logger';
|
|
357
|
+
|
|
358
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
359
|
+
// Add userId to all logs in this component
|
|
360
|
+
useLoggerContext({ userId, component: 'UserProfile' });
|
|
361
|
+
|
|
362
|
+
const logger = useLogger();
|
|
363
|
+
|
|
364
|
+
const handleUpdate = () => {
|
|
365
|
+
// This log will include { userId, component: 'UserProfile' }
|
|
366
|
+
logger.info('Updating profile');
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
return <button onClick={handleUpdate}>Update</button>;
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Common Patterns
|
|
374
|
+
|
|
375
|
+
### Contextual Logging
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
@Injectable()
|
|
379
|
+
export class AuthService {
|
|
380
|
+
constructor(
|
|
381
|
+
@Inject(LoggerService) private logger: LoggerService
|
|
382
|
+
) {}
|
|
383
|
+
|
|
384
|
+
async login(email: string, password: string) {
|
|
385
|
+
// Add request context
|
|
386
|
+
this.logger.withContext({ email, action: 'login' });
|
|
387
|
+
|
|
388
|
+
this.logger.info('Login attempt');
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
const user = await this.authenticate(email, password);
|
|
392
|
+
this.logger.info('Login successful', { userId: user.id });
|
|
393
|
+
return user;
|
|
394
|
+
} catch (error) {
|
|
395
|
+
this.logger.error('Login failed', { error });
|
|
396
|
+
throw error;
|
|
397
|
+
} finally {
|
|
398
|
+
// Clean up context
|
|
399
|
+
this.logger.withoutContext(['email', 'action']);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Error Logging
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
@Injectable()
|
|
409
|
+
export class PaymentService {
|
|
410
|
+
constructor(
|
|
411
|
+
@Inject(LoggerService) private logger: LoggerService
|
|
412
|
+
) {}
|
|
413
|
+
|
|
414
|
+
async processPayment(orderId: string, amount: number) {
|
|
415
|
+
const errorLogger = this.logger.channel('errors');
|
|
416
|
+
|
|
417
|
+
try {
|
|
418
|
+
const result = await this.chargeCard(orderId, amount);
|
|
419
|
+
this.logger.info('Payment processed', { orderId, amount });
|
|
420
|
+
return result;
|
|
421
|
+
} catch (error) {
|
|
422
|
+
errorLogger.error('Payment failed', {
|
|
423
|
+
orderId,
|
|
424
|
+
amount,
|
|
425
|
+
error: error.message,
|
|
426
|
+
stack: error.stack,
|
|
427
|
+
});
|
|
428
|
+
throw error;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Audit Logging
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
@Injectable()
|
|
438
|
+
export class UserService {
|
|
439
|
+
constructor(
|
|
440
|
+
@Inject(LoggerService) private logger: LoggerService
|
|
441
|
+
) {}
|
|
442
|
+
|
|
443
|
+
async updateUser(userId: string, data: Partial<User>) {
|
|
444
|
+
const auditLogger = this.logger.channel('audit');
|
|
445
|
+
|
|
446
|
+
auditLogger.info('User update started', {
|
|
447
|
+
userId,
|
|
448
|
+
changes: Object.keys(data),
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
const user = await this.db.users.update(userId, data);
|
|
452
|
+
|
|
453
|
+
auditLogger.info('User update completed', {
|
|
454
|
+
userId,
|
|
455
|
+
changes: data,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
return user;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Environment-Based Configuration
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { defineConfig, consolePreset, silentPreset } from '@abdokouta/logger';
|
|
467
|
+
|
|
468
|
+
export const getLoggerConfig = () => {
|
|
469
|
+
const env = process.env.NODE_ENV || 'development';
|
|
470
|
+
|
|
471
|
+
if (env === 'production') {
|
|
472
|
+
return defineConfig({
|
|
473
|
+
default: 'console',
|
|
474
|
+
channels: {
|
|
475
|
+
console: {
|
|
476
|
+
transporters: [new ConsoleTransporter({ level: LogLevel.Warn })],
|
|
477
|
+
},
|
|
478
|
+
errors: {
|
|
479
|
+
transporters: [
|
|
480
|
+
new ConsoleTransporter({ level: LogLevel.Error }),
|
|
481
|
+
new StorageTransporter({ key: 'error-logs' }),
|
|
482
|
+
],
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (env === 'test') {
|
|
489
|
+
return defineConfig(silentPreset);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Development
|
|
493
|
+
return defineConfig({
|
|
494
|
+
...consolePreset,
|
|
495
|
+
channels: {
|
|
496
|
+
...consolePreset.channels,
|
|
497
|
+
console: {
|
|
498
|
+
...consolePreset.channels.console,
|
|
499
|
+
context: { env: 'dev' },
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
};
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Best Practices
|
|
507
|
+
|
|
508
|
+
1. **Use Appropriate Log Levels**: Debug for development, Info for important events, Warn for issues, Error for failures, Fatal for critical errors
|
|
509
|
+
2. **Add Context**: Include relevant data to make logs useful
|
|
510
|
+
3. **Use Channels**: Separate concerns (console, storage, errors, audit)
|
|
511
|
+
4. **Clean Up Context**: Remove sensitive data after logging
|
|
512
|
+
5. **Handle Errors Gracefully**: Always catch and log errors
|
|
513
|
+
6. **Use Structured Logging**: Include structured data in context
|
|
514
|
+
7. **Monitor Storage**: Set appropriate maxEntries for StorageTransporter
|
|
515
|
+
|
|
516
|
+
## TypeScript Support
|
|
517
|
+
|
|
518
|
+
Full TypeScript support with comprehensive types:
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import type {
|
|
522
|
+
LoggerInterface,
|
|
523
|
+
LoggerServiceInterface,
|
|
524
|
+
LoggerModuleOptions,
|
|
525
|
+
LoggerConfig,
|
|
526
|
+
LogEntry,
|
|
527
|
+
LogLevel,
|
|
528
|
+
TransporterInterface,
|
|
529
|
+
FormatterInterface,
|
|
530
|
+
} from '@abdokouta/logger';
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Browser Compatibility
|
|
534
|
+
|
|
535
|
+
This package works in all modern browsers that support:
|
|
536
|
+
- localStorage API
|
|
537
|
+
- console API
|
|
538
|
+
- ES2020 features
|
|
539
|
+
|
|
540
|
+
No polyfills required for modern browsers (Chrome 80+, Firefox 75+, Safari 13.1+, Edge 80+).
|
|
541
|
+
|
|
542
|
+
## License
|
|
543
|
+
|
|
544
|
+
MIT
|
|
545
|
+
|
|
546
|
+
## Contributing
|
|
547
|
+
|
|
548
|
+
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
|
|
549
|
+
|
|
550
|
+
## Support
|
|
551
|
+
|
|
552
|
+
- [Documentation](https://refine.dev/docs)
|
|
553
|
+
- [Discord](https://discord.gg/refine)
|
|
554
|
+
- [GitHub Issues](https://github.com/refinedev/refine/issues)
|
|
555
|
+
|
|
556
|
+
## Related Packages
|
|
557
|
+
|
|
558
|
+
- [@abdokouta/cache](../cache) - Multi-driver cache system
|
|
559
|
+
- [@abdokouta/redis](../redis) - Redis connection management
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Configuration
|
|
3
|
+
*
|
|
4
|
+
* Unified logger configuration following Laravel and NestJS patterns.
|
|
5
|
+
* All logging channels and settings are defined in a single config object.
|
|
6
|
+
*
|
|
7
|
+
* @module config/logger
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import loggerConfig from '@abdokouta/logger/config/logger.config';
|
|
12
|
+
*
|
|
13
|
+
* LoggerModule.forRoot(loggerConfig);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
LogLevel,
|
|
19
|
+
SilentTransporter,
|
|
20
|
+
ConsoleTransporter,
|
|
21
|
+
StorageTransporter,
|
|
22
|
+
} from "@abdokouta/logger";
|
|
23
|
+
import type { LoggerModuleOptions } from "@abdokouta/logger";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Logger configuration
|
|
27
|
+
*
|
|
28
|
+
* Single unified configuration object that automatically adapts to your environment.
|
|
29
|
+
* Uses environment variables for configuration, similar to Laravel's config/logging.php
|
|
30
|
+
*
|
|
31
|
+
* Environment Variables:
|
|
32
|
+
* - LOG_CHANNEL: Default channel (default: 'console')
|
|
33
|
+
* - LOG_LEVEL: Minimum log level (default: 'debug')
|
|
34
|
+
* - APP_NAME: Application name for context (default: 'refine-app')
|
|
35
|
+
* - NODE_ENV: Environment (development/production/test)
|
|
36
|
+
* - LOG_STORAGE_MAX_ENTRIES: Max storage entries (default: 500)
|
|
37
|
+
*/
|
|
38
|
+
const loggerConfig: LoggerModuleOptions = {
|
|
39
|
+
/*
|
|
40
|
+
|--------------------------------------------------------------------------
|
|
41
|
+
| Default Log Channel
|
|
42
|
+
|--------------------------------------------------------------------------
|
|
43
|
+
|
|
|
44
|
+
| This option defines the default log channel that will be used to write
|
|
45
|
+
| messages to the logs. The name specified in this option should match
|
|
46
|
+
| one of the channels defined in the "channels" configuration array.
|
|
47
|
+
|
|
|
48
|
+
*/
|
|
49
|
+
default: process.env.LOG_CHANNEL || "console",
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
|--------------------------------------------------------------------------
|
|
53
|
+
| Log Channels
|
|
54
|
+
|--------------------------------------------------------------------------
|
|
55
|
+
|
|
|
56
|
+
| Here you may configure the log channels for your application. Each
|
|
57
|
+
| channel can have multiple transporters for different outputs.
|
|
58
|
+
|
|
|
59
|
+
*/
|
|
60
|
+
channels: {
|
|
61
|
+
/**
|
|
62
|
+
* Console Channel
|
|
63
|
+
*
|
|
64
|
+
* Logs to the console/terminal. Good for development.
|
|
65
|
+
*/
|
|
66
|
+
console: {
|
|
67
|
+
transporters: [
|
|
68
|
+
new ConsoleTransporter({
|
|
69
|
+
level:
|
|
70
|
+
(process.env.LOG_LEVEL as unknown as LogLevel) || LogLevel.Debug,
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
context: {
|
|
74
|
+
app: process.env.APP_NAME || "refine-app",
|
|
75
|
+
env: process.env.NODE_ENV || "development",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Storage Channel
|
|
81
|
+
*
|
|
82
|
+
* Persists logs to storage (localStorage/sessionStorage in browser).
|
|
83
|
+
* Good for debugging and audit trails.
|
|
84
|
+
*/
|
|
85
|
+
storage: {
|
|
86
|
+
transporters: [
|
|
87
|
+
new StorageTransporter({
|
|
88
|
+
key: "app-logs",
|
|
89
|
+
maxEntries: Number(process.env.LOG_STORAGE_MAX_ENTRIES) || 500,
|
|
90
|
+
}),
|
|
91
|
+
],
|
|
92
|
+
context: {
|
|
93
|
+
app: process.env.APP_NAME || "refine-app",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Combined Channel
|
|
99
|
+
*
|
|
100
|
+
* Logs to both console and storage.
|
|
101
|
+
* Good for production environments.
|
|
102
|
+
*/
|
|
103
|
+
combined: {
|
|
104
|
+
transporters: [
|
|
105
|
+
new ConsoleTransporter({
|
|
106
|
+
level: LogLevel.Info,
|
|
107
|
+
}),
|
|
108
|
+
new StorageTransporter({
|
|
109
|
+
key: "app-logs",
|
|
110
|
+
maxEntries: 1000,
|
|
111
|
+
}),
|
|
112
|
+
],
|
|
113
|
+
context: {
|
|
114
|
+
app: process.env.APP_NAME || "refine-app",
|
|
115
|
+
env: process.env.NODE_ENV || "production",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Error Channel
|
|
121
|
+
*
|
|
122
|
+
* Only logs errors and critical messages.
|
|
123
|
+
* Useful for error monitoring and alerting.
|
|
124
|
+
*/
|
|
125
|
+
errors: {
|
|
126
|
+
transporters: [
|
|
127
|
+
new ConsoleTransporter({
|
|
128
|
+
level: LogLevel.Error,
|
|
129
|
+
}),
|
|
130
|
+
new StorageTransporter({
|
|
131
|
+
key: "error-logs",
|
|
132
|
+
maxEntries: 200,
|
|
133
|
+
}),
|
|
134
|
+
],
|
|
135
|
+
context: {
|
|
136
|
+
app: process.env.APP_NAME || "refine-app",
|
|
137
|
+
channel: "errors",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Audit Channel
|
|
143
|
+
*
|
|
144
|
+
* For audit trails and compliance logging.
|
|
145
|
+
* Stores all logs without console output.
|
|
146
|
+
*/
|
|
147
|
+
audit: {
|
|
148
|
+
transporters: [
|
|
149
|
+
new StorageTransporter({
|
|
150
|
+
key: "audit-logs",
|
|
151
|
+
maxEntries: 1000,
|
|
152
|
+
}),
|
|
153
|
+
],
|
|
154
|
+
context: {
|
|
155
|
+
app: process.env.APP_NAME || "refine-app",
|
|
156
|
+
channel: "audit",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Silent Channel
|
|
162
|
+
*
|
|
163
|
+
* Disables all logging. Useful for testing.
|
|
164
|
+
*/
|
|
165
|
+
silent: {
|
|
166
|
+
transporters: [new SilentTransporter()],
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default loggerConfig;
|