@feizk/logger 1.6.0 → 2.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 CHANGED
@@ -1,6 +1,17 @@
1
1
  # @feizk/logger
2
2
 
3
- A simple logger package with colored outputs and timestamps.
3
+ A lightweight, pluggable logger with colored outputs, structured logging, and transport support.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Zero dependencies** - No external runtime dependencies
8
+ - 🎨 **Colored output** - ANSI color codes for terminal output
9
+ - 📊 **6 log levels** - trace, debug, info, warn, error, fatal
10
+ - 📝 **Structured logging** - JSON mode for production environments
11
+ - 🔌 **Pluggable transports** - Add custom transports (files, databases, etc.)
12
+ - 👶 **Child loggers** - Create prefixed loggers with merged context
13
+ - ⏱️ **Custom timestamps** - Presets (iso, locale) or custom format
14
+ - 🎯 **Type-safe** - Full TypeScript support
4
15
 
5
16
  ## Installation
6
17
 
@@ -15,85 +26,156 @@ import { Logger } from '@feizk/logger';
15
26
 
16
27
  const logger = new Logger();
17
28
 
18
- logger.info('This is an info message');
29
+ logger.info('Hello, world!');
19
30
  logger.warn('This is a warning');
20
31
  logger.error('This is an error');
21
- logger.debug('This is a debug message');
32
+ logger.debug('Debug information');
33
+ logger.trace('Very detailed trace');
34
+ logger.fatal('Critical error!');
22
35
  ```
23
36
 
24
- ### Options
37
+ ## Options
38
+
39
+ | Option | Type | Default | Description |
40
+ | -------------- | -------------------------------------------------------------- | ----------- | ---------------------------- |
41
+ | `level` | `'trace' \| 'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal'` | `'debug'` | Minimum log level to output |
42
+ | `silent` | `boolean` | `false` | Suppress all console output |
43
+ | `enableColors` | `boolean` | `true` | Enable colored output |
44
+ | `timestamp` | `'iso' \| 'locale' \| (date: Date) => string` | `'iso'` | Timestamp format |
45
+ | `json` | `boolean` | `false` | Output logs as JSON |
46
+ | `formatter` | `(entry: LogEntry) => string` | `undefined` | Custom log formatter |
47
+ | `transports` | `Transport[]` | `[]` | Initial transports to attach |
48
+ | `prefix` | `string` | `undefined` | Prefix for all log messages |
49
+ | `context` | `Record<string, unknown>` | `{}` | Initial context metadata |
50
+
51
+ ## API
52
+
53
+ ### Logger Methods
25
54
 
26
- Customize the logger with constructor options:
55
+ - `trace(...args)` - Log a trace message (most verbose)
56
+ - `debug(...args)` - Log a debug message
57
+ - `info(...args)` - Log an info message
58
+ - `warn(...args)` - Log a warning message
59
+ - `error(...args)` - Log an error message
60
+ - `fatal(...args)` - Log a fatal message (most severe)
61
+ - `setLevel(level)` - Set the minimum log level
62
+ - `getLevel()` - Get the current log level
63
+ - `addTransport(transport)` - Add a custom transport
64
+ - `removeTransport(transport)` - Remove a transport
65
+ - `child(options)` - Create a child logger
66
+ - `destroy()` - Destroy the logger and all transports
67
+
68
+ ### Log Levels
69
+
70
+ Logs are filtered by severity. The order from least to most severe:
71
+
72
+ 1. `trace` - Very detailed debugging information
73
+ 2. `debug` - Detailed information for debugging
74
+ 3. `info` - General informational messages
75
+ 4. `warn` - Warning conditions
76
+ 5. `error` - Error conditions
77
+ 6. `fatal` - Critical errors
78
+
79
+ ## Advanced Usage
80
+
81
+ ### Custom Timestamp
27
82
 
28
83
  ```typescript
29
84
  const logger = new Logger({
30
- enableColors: true, // Default: true
31
- formatTimestamp: undefined, // Custom timestamp formatter function, Default: ISO format
32
- formatLog: undefined, // Custom log formatter function, Default: undefined
33
- level: 'debug', // 'debug' | 'info' | 'warn' | 'error', Default: 'debug'
34
- discord: {
35
- enable: false, // Enable Discord transport
36
- webhookURL: '', // Discord webhook URL
37
- formatEmbed: undefined, // Custom embed formatter function
38
- },
85
+ timestamp: 'locale', // or 'iso' (default)
86
+ });
87
+
88
+ // Custom format
89
+ const logger = new Logger({
90
+ timestamp: (date) => date.toISOString(),
39
91
  });
40
92
  ```
41
93
 
42
- #### Examples
94
+ ### Custom Formatter
43
95
 
44
96
  ```typescript
45
- // Disable colors
46
- const noColorLogger = new Logger({ enableColors: false });
47
-
48
- // Use locale timestamp
49
- const localeLogger = new Logger({
50
- formatTimestamp: (types) => [types.Locale, new Date().toLocaleString()],
97
+ const logger = new Logger({
98
+ formatter: (entry) =>
99
+ `[${entry.timestamp}] [${entry.level.toUpperCase()}] ${entry.args.join(' ')}`,
51
100
  });
101
+ ```
52
102
 
53
- // Custom timestamp
54
- const customLogger = new Logger({
55
- formatTimestamp: () => [TIMESTAMP_TYPES.Custom, 'custom-time'],
56
- });
103
+ ### JSON Structured Logging
57
104
 
58
- // Filter logs below info level
59
- const infoLogger = new Logger({ level: 'info' });
60
- infoLogger.debug('Not logged');
61
- infoLogger.info('Logged'); // and higher
105
+ ```typescript
106
+ const logger = new Logger({ json: true });
107
+ logger.info('User logged in', { userId: '123' });
108
+ // Output: {"level":"info","timestamp":"2024-01-01T00:00:00.000Z","message":"User logged in","context":{"userId":"123"}}
109
+ ```
62
110
 
63
- // Change level dynamically
64
- logger.setLevel('error');
111
+ ### Child Logger
65
112
 
66
- // Enable Discord transport
67
- const discordLogger = new Logger({
68
- discord: {
69
- enable: true,
70
- webhookURL: 'https://discord.com/api/webhooks/123456789/abcdef',
71
- },
113
+ ```typescript
114
+ const parent = new Logger({ prefix: 'app', context: { version: '1.0.0' } });
115
+
116
+ const child = parent.child({
117
+ prefix: 'api',
118
+ context: { endpoint: '/users' },
72
119
  });
73
- discordLogger.error('This will be sent to Discord');
74
-
75
- // Custom embed formatting
76
- const customDiscordLogger = new Logger({
77
- discord: {
78
- enable: true,
79
- webhookURL: 'https://discord.com/api/webhooks/123456789/abcdef',
80
- formatEmbed: (level, timestamp, message) => ({
81
- title: `${level} - Custom`,
82
- description: `**Timestamp:** ${timestamp}\n**Message:** ${message}`,
83
- color: 0xff0000, // Red
84
- }),
85
- },
120
+
121
+ child.info('Request received');
122
+ // Output includes prefix "app:api" and merged context
123
+ ```
124
+
125
+ ### Pluggable Transports
126
+
127
+ ```typescript
128
+ import { Logger, type Transport, type LogEntry } from '@feizk/logger';
129
+
130
+ // Create a custom transport
131
+ class FileTransport implements Transport {
132
+ private stream: WriteStream;
133
+
134
+ constructor(path: string) {
135
+ this.stream = createWriteStream(path);
136
+ }
137
+
138
+ log(entry: LogEntry): void {
139
+ this.stream.write(JSON.stringify(entry) + '\n');
140
+ }
141
+
142
+ destroy(): void {
143
+ this.stream.end();
144
+ }
145
+ }
146
+
147
+ // Use the transport
148
+ const logger = new Logger();
149
+ logger.addTransport(new FileTransport('/var/log/app.log'));
150
+ logger.info('This will be logged to the file');
151
+ ```
152
+
153
+ ## Migration from v1.x
154
+
155
+ ### Discord Transport
156
+
157
+ Discord transport has been moved to a separate package. Use `@feizk/logger-discord` instead:
158
+
159
+ ```typescript
160
+ // v1.x
161
+ const logger = new Logger({
162
+ discord: { enable: true, webhookURL: '...' },
86
163
  });
164
+
165
+ // v2.x
166
+ import { Logger } from '@feizk/logger';
167
+ import { DiscordTransport } from '@feizk/logger-discord';
168
+
169
+ const logger = new Logger();
170
+ logger.addTransport(new DiscordTransport({ webhookURL: '...' }));
87
171
  ```
88
172
 
89
- ## API
173
+ ### Removed Options
90
174
 
91
- ### Logger
175
+ - `discord` - Use `@feizk/logger-discord` instead
176
+ - `formatTimestamp` - Use `timestamp` instead
177
+ - `formatLog` - Use `formatter` instead
92
178
 
93
- - `info(...args: unknown[])`: Logs an info message.
94
- - `warn(...args: unknown[])`: Logs a warning message.
95
- - `error(...args: unknown[])`: Logs an error message.
96
- - `debug(...args: unknown[])`: Logs a debug message.
97
- - `setLevel(level: LogLevel)`: Sets the minimum log level for filtering messages.
179
+ ## License
98
180
 
99
- All messages include a timestamp and are colored accordingly (unless disabled via options).
181
+ MIT
package/dist/index.d.mts CHANGED
@@ -1,70 +1,211 @@
1
- type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
- type TimestampType = 'iso' | 'locale' | 'custom';
3
- interface TimestampTypes {
4
- ISO: 'iso';
5
- Locale: 'locale';
6
- Custom: 'custom';
1
+ /**
2
+ * Log levels ordered by severity.
3
+ * - trace: Very detailed debugging information
4
+ * - debug: Detailed information for debugging
5
+ * - info: General informational messages
6
+ * - warn: Warning conditions
7
+ * - error: Error conditions
8
+ * - fatal: Critical errors that may terminate the application
9
+ */
10
+ type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
11
+ /**
12
+ * A structured log entry passed to transports and formatters.
13
+ */
14
+ interface LogEntry {
15
+ /** The log level of this entry */
16
+ level: LogLevel;
17
+ /** ISO 8601 formatted timestamp */
18
+ timestamp: string;
19
+ /** Original arguments passed to the log method */
20
+ args: unknown[];
21
+ /** Optional prefix from the logger hierarchy */
22
+ prefix?: string;
23
+ /** Context metadata attached to the logger */
24
+ context: Record<string, unknown>;
7
25
  }
8
- interface DiscordOptions {
9
- enable: boolean;
10
- webhookURL: string;
11
- formatEmbed?: (level: LogLevel, timestamp: string, message: string) => Record<string, unknown>;
26
+ /**
27
+ * Pluggable transport interface.
28
+ * Implement this interface to create custom log transports.
29
+ */
30
+ interface Transport {
31
+ /**
32
+ * Called for each log entry.
33
+ * @param entry - The structured log entry
34
+ */
35
+ log(entry: LogEntry): void | Promise<void>;
36
+ /**
37
+ * Optional cleanup method called when the logger is destroyed.
38
+ */
39
+ destroy?(): void | Promise<void>;
12
40
  }
41
+ /**
42
+ * Timestamp option: preset string or custom formatter function.
43
+ * - 'iso': ISO 8601 format (default)
44
+ * - 'locale': Localized date/time string
45
+ * - function: Custom formatter
46
+ */
47
+ type TimestampOption = 'iso' | 'locale' | ((date: Date) => string);
48
+ /**
49
+ * Custom formatter function for log output.
50
+ * @param entry - The structured log entry
51
+ * @returns The formatted string to output to console
52
+ */
53
+ type Formatter = (entry: LogEntry) => string;
54
+ /**
55
+ * Options for creating a child logger.
56
+ */
57
+ interface ChildLoggerOptions {
58
+ /** Prefix to prepend to log messages */
59
+ prefix?: string;
60
+ /** Additional context metadata */
61
+ context?: Record<string, unknown>;
62
+ /** Override log level for this child logger */
63
+ level?: LogLevel;
64
+ /** Override silent mode for this child logger */
65
+ silent?: boolean;
66
+ }
67
+ /**
68
+ * Main logger configuration options.
69
+ */
13
70
  interface LoggerOptions {
14
- enableColors?: boolean;
15
- formatTimestamp?: (types: TimestampTypes, date?: Date) => [TimestampType, string];
16
- formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
71
+ /** Minimum log level to output (default: 'debug') */
17
72
  level?: LogLevel;
18
- discord?: DiscordOptions;
73
+ /** Suppress all console output (default: false) */
74
+ silent?: boolean;
75
+ /** Enable colored output (default: true) */
76
+ enableColors?: boolean;
77
+ /** Timestamp format (default: 'iso') */
78
+ timestamp?: TimestampOption;
79
+ /** Custom formatter for log output */
80
+ formatter?: Formatter;
81
+ /** Output logs as JSON (default: false) */
82
+ json?: boolean;
83
+ /** Initial transports to attach */
84
+ transports?: Transport[];
85
+ /** Prefix for all log messages */
86
+ prefix?: string;
87
+ /** Initial context metadata */
88
+ context?: Record<string, unknown>;
19
89
  }
20
90
 
21
91
  /**
22
- * A simple logger with colored outputs and timestamps.
92
+ * A lightweight, pluggable logger with colored outputs, structured logging, and transport support.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * import { Logger } from '@feizk/logger';
97
+ *
98
+ * const logger = new Logger();
99
+ *
100
+ * logger.info('Hello, world!');
101
+ * logger.warn('This is a warning');
102
+ * logger.error('This is an error');
103
+ * ```
23
104
  */
24
105
  declare class Logger {
25
- private options;
26
- private level;
27
- constructor(options?: LoggerOptions);
106
+ private readonly options;
107
+ private readonly transports;
108
+ private readonly prefix?;
109
+ private readonly context;
28
110
  /**
29
- * Sets the minimum log level for filtering messages.
30
- * @param level - The log level to set.
111
+ * Create a new Logger instance.
112
+ * @param options - Configuration options
31
113
  */
32
- setLevel(level: LogLevel): void;
114
+ constructor(options?: LoggerOptions);
33
115
  /**
34
- * Sends a log message to Discord via webhook if configured.
35
- * @param level - The log level.
36
- * @param timestamp - The formatted timestamp.
37
- * @param args - The log arguments.
116
+ * Log a trace message (most verbose).
117
+ * @param args - Arguments to log
38
118
  */
39
- private sendToDiscord;
119
+ trace(...args: unknown[]): void;
40
120
  /**
41
- * Checks if a log level should be output based on the current log level.
42
- * @param level - The log level to check.
43
- * @returns True if the message should be logged.
121
+ * Log a debug message.
122
+ * @param args - Arguments to log
44
123
  */
45
- private shouldLog;
124
+ debug(...args: unknown[]): void;
46
125
  /**
47
- * Logs an info message.
48
- * @param args - The arguments to log.
126
+ * Log an info message.
127
+ * @param args - Arguments to log
49
128
  */
50
129
  info(...args: unknown[]): void;
51
130
  /**
52
- * Logs a warning message.
53
- * @param args - The arguments to log.
131
+ * Log a warning message.
132
+ * @param args - Arguments to log
54
133
  */
55
134
  warn(...args: unknown[]): void;
56
135
  /**
57
- * Logs an error message.
58
- * @param args - The arguments to log.
136
+ * Log an error message.
137
+ * @param args - Arguments to log
59
138
  */
60
139
  error(...args: unknown[]): void;
61
140
  /**
62
- * Logs a debug message.
63
- * @param args - The arguments to log.
141
+ * Log a fatal message (most severe).
142
+ * @param args - Arguments to log
64
143
  */
65
- debug(...args: unknown[]): void;
144
+ fatal(...args: unknown[]): void;
145
+ /**
146
+ * Set the minimum log level.
147
+ * @param level - The log level to set
148
+ */
149
+ setLevel(level: LogLevel): void;
150
+ /**
151
+ * Get the current log level.
152
+ * @returns The current log level
153
+ */
154
+ getLevel(): LogLevel;
155
+ /**
156
+ * Add a transport to the logger.
157
+ * @param transport - The transport to add
158
+ */
159
+ addTransport(transport: Transport): void;
160
+ /**
161
+ * Remove a transport from the logger.
162
+ * @param transport - The transport to remove
163
+ */
164
+ removeTransport(transport: Transport): void;
165
+ /**
166
+ * Create a child logger with additional prefix and context.
167
+ * @param options - Child logger options
168
+ * @returns A new Logger instance
169
+ */
170
+ child(options?: ChildLoggerOptions): Logger;
171
+ /**
172
+ * Destroy the logger and all its transports.
173
+ * Calls destroy() on all registered transports.
174
+ */
175
+ destroy(): Promise<void>;
176
+ /**
177
+ * Core logging method - all public methods delegate here.
178
+ * @param level - The log level
179
+ * @param args - The arguments to log
180
+ */
181
+ private log;
182
+ /**
183
+ * Write a log entry to the console.
184
+ * @param level - The log level
185
+ * @param entry - The log entry
186
+ */
187
+ private writeToConsole;
188
+ /**
189
+ * Dispatch a log entry to a transport.
190
+ * @param transport - The transport
191
+ * @param entry - The log entry
192
+ */
193
+ private dispatchToTransport;
194
+ /**
195
+ * Check if a log level should be output.
196
+ * @param level - The log level to check
197
+ * @returns True if the message should be logged
198
+ */
199
+ private shouldLog;
66
200
  }
67
201
 
68
- declare const TIMESTAMP_TYPES: TimestampTypes;
202
+ /**
203
+ * Log level priorities ordered by severity (lower = less severe).
204
+ */
205
+ declare const LOG_LEVEL_PRIORITIES: Record<LogLevel, number>;
206
+ /**
207
+ * Text labels for log levels.
208
+ */
209
+ declare const LEVEL_LABELS: Record<LogLevel, string>;
69
210
 
70
- export { type DiscordOptions, type LogLevel, Logger, type LoggerOptions, TIMESTAMP_TYPES, type TimestampType, type TimestampTypes };
211
+ export { type ChildLoggerOptions, type Formatter, LEVEL_LABELS, LOG_LEVEL_PRIORITIES, type LogEntry, type LogLevel, Logger, type LoggerOptions, type TimestampOption, type Transport };