@oxog/log 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/LICENSE +21 -0
- package/README.md +297 -0
- package/dist/index.cjs +1893 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1784 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/index.cjs +854 -0
- package/dist/plugins/index.cjs.map +1 -0
- package/dist/plugins/index.js +782 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/transports/index.cjs +853 -0
- package/dist/transports/index.cjs.map +1 -0
- package/dist/transports/index.js +809 -0
- package/dist/transports/index.js.map +1 -0
- package/package.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ersin Koç
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# @oxog/log
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@oxog/log)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
Blazing fast, plugin-based logging for Node.js and browsers with micro-kernel architecture.
|
|
9
|
+
|
|
10
|
+
Part of the [@oxog ecosystem](https://github.com/ersinkoc).
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Six Log Levels**: trace, debug, info, warn, error, fatal
|
|
15
|
+
- **Structured Logging**: Attach metadata objects to log entries
|
|
16
|
+
- **Child Loggers**: Create scoped loggers with bound context
|
|
17
|
+
- **Correlation ID**: Track requests across async operations
|
|
18
|
+
- **Source Location**: Capture file and line number
|
|
19
|
+
- **Performance Timing**: Built-in time/timeEnd utilities
|
|
20
|
+
- **Redaction**: Mask sensitive fields from output
|
|
21
|
+
- **Multiple Formats**: JSON, Pretty, Auto (based on environment)
|
|
22
|
+
- **Multiple Transports**: Console, Stream, File, HTTP, localStorage
|
|
23
|
+
- **Hybrid Sync/Async**: Level-based synchronization with buffering
|
|
24
|
+
- **Browser Support**: Native DevTools integration
|
|
25
|
+
- **Zero Config**: Works out of the box with sensible defaults
|
|
26
|
+
- **TypeScript First**: Full type safety and IntelliSense support
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @oxog/log
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { createLogger } from '@oxog/log';
|
|
38
|
+
|
|
39
|
+
const log = createLogger({ name: 'my-app' });
|
|
40
|
+
|
|
41
|
+
// Simple logging
|
|
42
|
+
log.info('Server started');
|
|
43
|
+
|
|
44
|
+
// Structured logging with data
|
|
45
|
+
log.info({ port: 3000, env: 'production' }, 'Listening');
|
|
46
|
+
|
|
47
|
+
// Child loggers with context
|
|
48
|
+
const dbLog = log.child({ module: 'database' });
|
|
49
|
+
dbLog.info('Connected to database');
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Log Levels
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
log.trace('Detailed debugging'); // 10
|
|
56
|
+
log.debug('Debug information'); // 20
|
|
57
|
+
log.info('Informational'); // 30
|
|
58
|
+
log.warn('Warning'); // 40
|
|
59
|
+
log.error('Error occurred'); // 50
|
|
60
|
+
log.fatal('Fatal error'); // 60
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
### Child Loggers
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const dbLog = log.child({ module: 'database' });
|
|
69
|
+
dbLog.info('Connected');
|
|
70
|
+
|
|
71
|
+
const queryLog = dbLog.child({ operation: 'select' });
|
|
72
|
+
queryLog.debug('Executing query');
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Correlation ID
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const reqLog = log.withCorrelation('req-abc-123');
|
|
79
|
+
reqLog.info('Request received');
|
|
80
|
+
reqLog.info('Processing');
|
|
81
|
+
reqLog.info('Response sent');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Performance Timing
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
log.time('db-query');
|
|
88
|
+
await database.query('SELECT * FROM users');
|
|
89
|
+
log.timeEnd('db-query');
|
|
90
|
+
|
|
91
|
+
// Or use startTimer for more control
|
|
92
|
+
const end = log.startTimer('api-call');
|
|
93
|
+
await fetch('/api/data');
|
|
94
|
+
end();
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Redaction
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const log = createLogger({
|
|
101
|
+
redact: ['password', 'token', 'creditCard']
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
log.info({ user: 'john', password: 'secret123' });
|
|
105
|
+
// Output: {"user":"john","password":"[REDACTED]"}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Multiple Transports
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { createLogger, consoleTransport, fileTransport } from '@oxog/log';
|
|
112
|
+
|
|
113
|
+
const log = createLogger({
|
|
114
|
+
transports: [
|
|
115
|
+
consoleTransport({ colors: true }),
|
|
116
|
+
fileTransport({
|
|
117
|
+
path: './logs/app.log',
|
|
118
|
+
rotate: '1d',
|
|
119
|
+
maxFiles: 7
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Output Formats
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Structured JSON (production)
|
|
129
|
+
const jsonLog = createLogger({ format: 'json' });
|
|
130
|
+
|
|
131
|
+
// Human-readable (development)
|
|
132
|
+
const prettyLog = createLogger({ format: 'pretty' });
|
|
133
|
+
|
|
134
|
+
// Auto-detect based on environment
|
|
135
|
+
const autoLog = createLogger({ format: 'auto' });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Error Handling
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
try {
|
|
142
|
+
const data = await fetchData();
|
|
143
|
+
} catch (error) {
|
|
144
|
+
log.error(error, 'Failed to fetch data');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
log.fatal(new Error('Cannot start'), 'Server error');
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Level Filtering
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const log = createLogger({ level: 'warn' });
|
|
154
|
+
|
|
155
|
+
log.info('This will NOT appear'); // Below minimum level
|
|
156
|
+
log.warn('This WILL appear');
|
|
157
|
+
|
|
158
|
+
// Dynamic level change
|
|
159
|
+
log.setLevel('debug');
|
|
160
|
+
log.info('Now this appears');
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Source Location
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const log = createLogger({ source: true });
|
|
167
|
+
|
|
168
|
+
log.info('Debug me');
|
|
169
|
+
// Output: {"level":30,"file":"server.ts","line":42,"msg":"Debug me"}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Plugin System
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { createLogger, redactPlugin, sourcePlugin } from '@oxog/log';
|
|
176
|
+
|
|
177
|
+
const log = createLogger({
|
|
178
|
+
plugins: [
|
|
179
|
+
redactPlugin(['apiKey', 'secret']),
|
|
180
|
+
sourcePlugin()
|
|
181
|
+
]
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Custom Plugin
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import type { Plugin } from '@oxog/types';
|
|
189
|
+
|
|
190
|
+
const myPlugin: Plugin = {
|
|
191
|
+
name: 'myPlugin',
|
|
192
|
+
version: '1.0.0',
|
|
193
|
+
install(kernel) {
|
|
194
|
+
// Custom logic
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
log.use(myPlugin);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Browser Usage
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { createLogger } from '@oxog/log';
|
|
205
|
+
|
|
206
|
+
const log = createLogger();
|
|
207
|
+
|
|
208
|
+
log.info('Hello from browser!');
|
|
209
|
+
log.warn('Careful!');
|
|
210
|
+
log.error('Something went wrong');
|
|
211
|
+
|
|
212
|
+
// Child loggers use console.group
|
|
213
|
+
const child = log.child({ component: 'Auth' });
|
|
214
|
+
child.info('Checking token');
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Graceful Shutdown
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// Flush buffered logs before shutdown
|
|
221
|
+
await log.flush();
|
|
222
|
+
|
|
223
|
+
// Cleanup and destroy
|
|
224
|
+
await log.close();
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## API Reference
|
|
228
|
+
|
|
229
|
+
### createLogger(options?)
|
|
230
|
+
|
|
231
|
+
Creates a new logger instance.
|
|
232
|
+
|
|
233
|
+
| Option | Type | Default | Description |
|
|
234
|
+
|--------|------|---------|-------------|
|
|
235
|
+
| `name` | `string` | `'app'` | Logger name |
|
|
236
|
+
| `level` | `LogLevelName` | `'info'` | Minimum log level |
|
|
237
|
+
| `format` | `'json' \| 'pretty' \| 'auto'` | `'auto'` | Output format |
|
|
238
|
+
| `transports` | `Transport[]` | `[consoleTransport()]` | Output destinations |
|
|
239
|
+
| `redact` | `string[]` | `[]` | Fields to redact |
|
|
240
|
+
| `source` | `boolean` | `false` | Include source location |
|
|
241
|
+
| `timestamp` | `boolean` | `true` | Include timestamp |
|
|
242
|
+
| `context` | `object` | `{}` | Static context |
|
|
243
|
+
| `plugins` | `Plugin[]` | `[]` | Plugins to load |
|
|
244
|
+
|
|
245
|
+
### Logger Methods
|
|
246
|
+
|
|
247
|
+
#### Logging
|
|
248
|
+
- `trace(msg)` / `trace(obj, msg)` - Trace level
|
|
249
|
+
- `debug(msg)` / `debug(obj, msg)` - Debug level
|
|
250
|
+
- `info(msg)` / `info(obj, msg)` - Info level
|
|
251
|
+
- `warn(msg)` / `warn(obj, msg)` - Warn level
|
|
252
|
+
- `error(msg)` / `error(obj, msg)` / `error(err, msg)` - Error level
|
|
253
|
+
- `fatal(msg)` / `fatal(obj, msg)` / `fatal(err, msg)` - Fatal level
|
|
254
|
+
|
|
255
|
+
#### Context
|
|
256
|
+
- `child(context)` - Create child logger with additional context
|
|
257
|
+
- `withCorrelation(id)` - Create logger with correlation ID
|
|
258
|
+
|
|
259
|
+
#### Timing
|
|
260
|
+
- `time(label)` - Start a timer
|
|
261
|
+
- `timeEnd(label)` - End timer and log duration
|
|
262
|
+
- `startTimer(label)` - Returns stop function
|
|
263
|
+
|
|
264
|
+
#### Plugin Management
|
|
265
|
+
- `use(plugin)` - Register plugin
|
|
266
|
+
- `unregister(name)` - Unregister plugin
|
|
267
|
+
- `hasPlugin(name)` - Check if plugin exists
|
|
268
|
+
- `listPlugins()` - List all plugins
|
|
269
|
+
|
|
270
|
+
#### Lifecycle
|
|
271
|
+
- `flush()` - Flush buffered logs
|
|
272
|
+
- `close()` - Cleanup and close transports
|
|
273
|
+
|
|
274
|
+
#### Level Management
|
|
275
|
+
- `setLevel(level)` - Set minimum level
|
|
276
|
+
- `getLevel()` - Get current level
|
|
277
|
+
- `isLevelEnabled(level)` - Check if level is enabled
|
|
278
|
+
|
|
279
|
+
## Documentation
|
|
280
|
+
|
|
281
|
+
For detailed documentation, see the [docs](./docs) folder:
|
|
282
|
+
|
|
283
|
+
- [Specification](./docs/SPECIFICATION.md) - Full API specification
|
|
284
|
+
- [Implementation](./docs/IMPLEMENTATION.md) - Implementation details
|
|
285
|
+
- [Tasks](./docs/TASKS.md) - Development tasks
|
|
286
|
+
|
|
287
|
+
## Contributing
|
|
288
|
+
|
|
289
|
+
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT - see [LICENSE](./LICENSE) for details.
|
|
294
|
+
|
|
295
|
+
## Author
|
|
296
|
+
|
|
297
|
+
Ersin Koc - [@ersinkoc](https://github.com/ersinkoc)
|