loggily 0.3.0 → 0.4.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.
Files changed (46) hide show
  1. package/README.md +67 -22
  2. package/package.json +24 -11
  3. package/src/context.ts +26 -11
  4. package/src/core.ts +118 -72
  5. package/src/file-writer.ts +12 -6
  6. package/src/index.browser.ts +9 -1
  7. package/src/index.ts +9 -1
  8. package/src/tracing.ts +11 -3
  9. package/src/worker.ts +119 -132
  10. package/.github/workflows/docs.yml +0 -58
  11. package/.github/workflows/release.yml +0 -31
  12. package/.github/workflows/test.yml +0 -20
  13. package/CHANGELOG.md +0 -45
  14. package/CLAUDE.md +0 -299
  15. package/CONTRIBUTING.md +0 -58
  16. package/benchmarks/overhead.ts +0 -267
  17. package/bun.lock +0 -479
  18. package/docs/api-reference.md +0 -400
  19. package/docs/benchmarks.md +0 -106
  20. package/docs/comparison.md +0 -315
  21. package/docs/conditional-logging-research.md +0 -159
  22. package/docs/guide.md +0 -205
  23. package/docs/migration-from-debug.md +0 -310
  24. package/docs/migration-from-pino.md +0 -178
  25. package/docs/migration-from-winston.md +0 -179
  26. package/docs/site/.vitepress/config.ts +0 -67
  27. package/docs/site/api/configuration.md +0 -94
  28. package/docs/site/api/index.md +0 -61
  29. package/docs/site/api/logger.md +0 -99
  30. package/docs/site/api/worker.md +0 -120
  31. package/docs/site/api/writers.md +0 -69
  32. package/docs/site/guide/getting-started.md +0 -143
  33. package/docs/site/guide/journey.md +0 -203
  34. package/docs/site/guide/migration-from-debug.md +0 -24
  35. package/docs/site/guide/spans.md +0 -139
  36. package/docs/site/guide/why.md +0 -55
  37. package/docs/site/guide/workers.md +0 -113
  38. package/docs/site/guide/zero-overhead.md +0 -87
  39. package/docs/site/index.md +0 -54
  40. package/tests/features.test.ts +0 -552
  41. package/tests/logger.test.ts +0 -944
  42. package/tests/tracing.test.ts +0 -618
  43. package/tests/universal.test.ts +0 -107
  44. package/tests/worker.test.ts +0 -590
  45. package/tsconfig.json +0 -20
  46. package/vitest.config.ts +0 -10
@@ -1,310 +0,0 @@
1
- # Migration from debug
2
-
3
- Step-by-step guide for migrating from the `debug` package to `loggily`.
4
-
5
- ## Why Migrate?
6
-
7
- | Feature | debug | loggily |
8
- | ------------------ | ------------------- | ------------------------------------------- |
9
- | Log levels | No (namespace only) | Yes (trace, debug, info, warn, error) |
10
- | Structured data | No (printf-style) | Yes (JSON objects) |
11
- | Performance | Good | Better (conditional logging skips arg eval) |
12
- | Timing/spans | No | Built-in spans with auto-timing |
13
- | JSON output | No | Yes (production/TRACE_FORMAT=json) |
14
- | Zero-cost disabled | No | Yes (optional chaining pattern) |
15
-
16
- ## Quick Migration
17
-
18
- ### Before (debug)
19
-
20
- ```typescript
21
- import createDebug from "debug"
22
-
23
- const debug = createDebug("myapp")
24
- const debugDb = createDebug("myapp:db")
25
-
26
- debug("starting server on port %d", 3000)
27
- debugDb("query: %s, params: %o", sql, params)
28
- ```
29
-
30
- ### After (loggily)
31
-
32
- ```typescript
33
- import { createLogger } from "loggily"
34
-
35
- const log = createLogger("myapp")
36
- const dbLog = log.logger("db")
37
-
38
- log.info("starting server", { port: 3000 })
39
- dbLog.debug("query", { sql, params })
40
- ```
41
-
42
- ## Pattern Mapping
43
-
44
- ### Basic Logging
45
-
46
- ```typescript
47
- // debug
48
- debug("message")
49
- debug("message %s", value)
50
- debug("message %d items", count)
51
- debug("object: %o", obj)
52
- debug("json: %j", data)
53
-
54
- // loggily
55
- log.debug("message")
56
- log.debug(`message ${value}`)
57
- log.debug("message", { items: count })
58
- log.debug("object", { obj })
59
- log.debug("data", { data })
60
- ```
61
-
62
- ### Namespaces
63
-
64
- ```typescript
65
- // debug - separate instances
66
- const debug = createDebug("myapp")
67
- const debugDb = createDebug("myapp:db")
68
- const debugCache = createDebug("myapp:cache")
69
-
70
- // loggily - hierarchy via .logger()
71
- const log = createLogger("myapp")
72
- const dbLog = log.logger("db") // myapp:db
73
- const cacheLog = log.logger("cache") // myapp:cache
74
- ```
75
-
76
- ### Environment Variables
77
-
78
- | debug | loggily | Effect |
79
- | ---------------- | ----------------- | -------------------------------------- |
80
- | `DEBUG=*` | `DEBUG=*` | Enable all debug output |
81
- | `DEBUG=myapp*` | `DEBUG=myapp` | Enable debug for namespace |
82
- | `DEBUG=myapp:db` | `DEBUG=myapp:db` | Enable specific namespace |
83
- | `DEBUG=*,-noisy` | `DEBUG=*,-noisy` | Exclude specific namespace |
84
- | N/A | `LOG_LEVEL=debug` | Set log level without namespace filter |
85
- | N/A | `TRACE=1` | Enable span timing |
86
- | N/A | `TRACE=myapp:db` | Enable spans for namespace |
87
-
88
- ### Conditional Enabling
89
-
90
- ```typescript
91
- // debug - checks if enabled
92
- if (debug.enabled) {
93
- debug("expensive: %o", computeExpensive())
94
- }
95
-
96
- // loggily - optional chaining (cleaner, faster)
97
- log.debug?.(`expensive: ${computeExpensive()}`)
98
- ```
99
-
100
- ## Common Patterns
101
-
102
- ### Printf-style to Template Literals
103
-
104
- ```typescript
105
- // debug (printf-style)
106
- debug("user %s logged in from %s", username, ip)
107
- debug("processed %d items in %dms", count, duration)
108
-
109
- // loggily (template literals or structured)
110
- log.info(`user ${username} logged in from ${ip}`)
111
- // or structured (preferred)
112
- log.info("user logged in", { username, ip })
113
- ```
114
-
115
- ### Objects and JSON
116
-
117
- ```typescript
118
- // debug
119
- debug("config: %O", config) // multi-line
120
- debug("data: %o", data) // single-line
121
- debug("json: %j", obj) // JSON
122
-
123
- // loggily (always structured JSON)
124
- log.debug("config", { config })
125
- log.debug("data", { data })
126
- log.debug("obj", { obj })
127
- ```
128
-
129
- ### Error Logging
130
-
131
- ```typescript
132
- // debug
133
- debug("error: %s", err.message)
134
- debug("stack: %s", err.stack)
135
-
136
- // loggily (Error objects handled automatically)
137
- log.error(err) // Extracts message, stack, code
138
- log.error(err, { context: "additional info" })
139
- ```
140
-
141
- ### Timing Operations
142
-
143
- ```typescript
144
- // debug (manual timing)
145
- const start = Date.now()
146
- await doWork()
147
- debug("operation took %dms", Date.now() - start)
148
-
149
- // loggily (built-in spans)
150
- {
151
- using span = log.span("operation")
152
- await doWork()
153
- }
154
- // Automatic: SPAN myapp:operation (234ms)
155
-
156
- // With data
157
- {
158
- using span = log.span("import", { file: "data.csv" })
159
- span.spanData.rowCount = await importFile()
160
- }
161
- // SPAN myapp:import (1234ms) {rowCount: 500, file: "data.csv"}
162
- ```
163
-
164
- ### Extending/Inheriting
165
-
166
- ```typescript
167
- // debug - new instance required
168
- const debug = createDebug("myapp")
169
- const debugReq = createDebug("myapp:request")
170
-
171
- // loggily - props inherited
172
- const log = createLogger("myapp", { version: "1.0" })
173
- const reqLog = log.logger("request", { requestId: "abc" })
174
- // reqLog has both version and requestId
175
- ```
176
-
177
- ## Migration Checklist
178
-
179
- ### 1. Update Dependencies
180
-
181
- ```bash
182
- # Remove debug
183
- bun remove debug @types/debug
184
-
185
- # Add loggily
186
- bun add loggily
187
- ```
188
-
189
- ### 2. Update Imports
190
-
191
- ```typescript
192
- // Before
193
- import createDebug from "debug"
194
-
195
- // After
196
- import { createLogger } from "loggily"
197
- ```
198
-
199
- ### 3. Replace Debug Instances
200
-
201
- ```typescript
202
- // Before
203
- const debug = createDebug("myapp")
204
-
205
- // After
206
- const log = createLogger("myapp")
207
- ```
208
-
209
- ### 4. Update Log Calls
210
-
211
- | Pattern | Before | After |
212
- | ----------- | ---------------------------- | -------------------------- |
213
- | Simple | `debug('msg')` | `log.debug('msg')` |
214
- | With values | `debug('msg %s', v)` | `log.debug(\`msg ${v}\`)` |
215
- | Structured | `debug('data %o', d)` | `log.debug('data', { d })` |
216
- | Error | `debug('err %s', e.message)` | `log.error(e)` |
217
-
218
- ### 5. Update Environment
219
-
220
- ```bash
221
- # Before
222
- DEBUG=myapp* node app.js
223
-
224
- # After (DEBUG env var still works)
225
- DEBUG=myapp node app.js
226
- # Or set level globally without namespace filter
227
- LOG_LEVEL=debug node app.js
228
- # Or for spans
229
- TRACE=1 LOG_LEVEL=debug node app.js
230
- ```
231
-
232
- ### 6. Add Log Levels
233
-
234
- Debug package has only on/off. Add appropriate levels:
235
-
236
- ```typescript
237
- // Choose appropriate level based on purpose
238
- log.trace("...") // Very verbose, hot paths
239
- log.debug("...") // Development debugging
240
- log.info("...") // Normal operation
241
- log.warn("...") // Recoverable issues
242
- log.error("...") // Failures
243
- ```
244
-
245
- ### 7. Convert Timing to Spans
246
-
247
- ```typescript
248
- // Before
249
- const start = Date.now()
250
- await operation()
251
- debug("done in %dms", Date.now() - start)
252
-
253
- // After
254
- {
255
- using span = log.span("operation")
256
- await operation()
257
- }
258
- ```
259
-
260
- ### 8. Use Optional Chaining (Recommended)
261
-
262
- `createLogger()` returns `undefined` for disabled levels -- just use `?.`:
263
-
264
- ```typescript
265
- const log = createLogger("myapp")
266
-
267
- // Optional chaining skips argument evaluation when level is disabled
268
- log.debug?.(`expensive: ${computeState()}`)
269
- log.trace?.(() => `very expensive: ${JSON.stringify(bigObj)}`)
270
- ```
271
-
272
- ## Verification
273
-
274
- After migration, verify:
275
-
276
- 1. **Development output works**: `LOG_LEVEL=debug bun run app`
277
- 2. **Production JSON works**: `NODE_ENV=production bun run app`
278
- 3. **Spans work**: `TRACE=1 bun run app`
279
- 4. **Level filtering works**: `LOG_LEVEL=warn bun run app` (should hide info/debug)
280
-
281
- ## Gotchas
282
-
283
- ### Namespace Filtering
284
-
285
- loggily supports `DEBUG=myapp` for namespace filtering (like the `debug` package). It also supports negative patterns: `DEBUG=myapp,-myapp:noisy`. For span-specific namespace filtering, use `TRACE=myapp:db`.
286
-
287
- ### Printf Format Strings
288
-
289
- debug uses printf-style `%s`, `%d`, `%o`. loggily uses template literals or structured data. Search for `%s`, `%d`, `%o`, `%j`, `%O` to find calls that need conversion.
290
-
291
- ### No Automatic Coloring by Namespace
292
-
293
- debug auto-assigns colors to namespaces. loggily uses level-based colors. If you need namespace distinction, include it in the log output or use the `name` property.
294
-
295
- ### enabled Property
296
-
297
- debug has `.enabled` property. loggily uses level comparison:
298
-
299
- ```typescript
300
- // debug
301
- if (debug.enabled) { ... }
302
-
303
- // loggily
304
- import { getLogLevel } from 'loggily'
305
- const LEVELS = { trace: 0, debug: 1, info: 2, warn: 3, error: 4, silent: 5 }
306
- if (LEVELS.debug >= LEVELS[getLogLevel()]) { ... }
307
-
308
- // Or use conditional logger with optional chaining (preferred)
309
- log.debug?.('msg')
310
- ```
@@ -1,178 +0,0 @@
1
- # Migration from Pino
2
-
3
- Step-by-step guide for migrating from Pino to loggily.
4
-
5
- ## Why Migrate?
6
-
7
- | Feature | Pino | loggily |
8
- | ------------------------- | ---------------------- | ----------------------------- |
9
- | Log levels | Yes (7 levels) | Yes (5 levels + silent) |
10
- | Structured data | Yes (JSON) | Yes (JSON + pretty console) |
11
- | Disabled call overhead | ~0.5ns (noop) | ~2.5ns (?. proxy) |
12
- | Disabled + expensive args | 129ns (args evaluated) | **3.6ns (args skipped)** |
13
- | Built-in spans/tracing | No | Yes (with `using` keyword) |
14
- | Child loggers | Yes | Yes |
15
- | Pretty print | Via pino-pretty | Built-in |
16
- | Bundle size | ~14KB + transports | ~3KB |
17
- | Browser support | Via pino/browser | Built-in (conditional export) |
18
-
19
- ## Quick Migration
20
-
21
- ### Before (Pino)
22
-
23
- ```typescript
24
- import pino from "pino"
25
-
26
- const logger = pino({ level: "info" })
27
- const child = logger.child({ module: "db" })
28
-
29
- logger.info({ port: 3000 }, "server started")
30
- child.debug({ query: sql, params }, "executing query")
31
- ```
32
-
33
- ### After (loggily)
34
-
35
- ```typescript
36
- import { createLogger } from "loggily"
37
-
38
- const log = createLogger("myapp")
39
- const dbLog = log.logger("db")
40
-
41
- log.info?.("server started", { port: 3000 })
42
- dbLog.debug?.("executing query", { query: sql, params })
43
- ```
44
-
45
- ## Pattern Mapping
46
-
47
- ### Logger Creation
48
-
49
- ```typescript
50
- // Pino
51
- const logger = pino()
52
- const logger = pino({ level: "debug" })
53
- const logger = pino({ name: "myapp" })
54
-
55
- // loggily
56
- const log = createLogger("myapp")
57
- setLogLevel("debug") // Global level
58
- ```
59
-
60
- ### Log Calls
61
-
62
- ```typescript
63
- // Pino — data object first, then message
64
- logger.info({ userId: 42 }, "user logged in")
65
- logger.info("simple message")
66
- logger.error({ err }, "request failed")
67
- logger.error(err, "request failed") // Error serialization
68
-
69
- // loggily — message first, then data
70
- log.info?.("user logged in", { userId: 42 })
71
- log.info?.("simple message")
72
- log.error?.(err, { context: "request" }) // Error object handled
73
- log.error?.(err) // Extracts message, stack, code
74
- ```
75
-
76
- ### Child Loggers
77
-
78
- ```typescript
79
- // Pino
80
- const child = logger.child({ requestId: "abc" })
81
- child.info("handling request")
82
-
83
- // loggily — two patterns
84
- // 1. Context fields (like Pino's child)
85
- const child = log.child({ requestId: "abc" })
86
- child.info?.("handling request") // includes requestId
87
-
88
- // 2. Namespace (extends the logger name)
89
- const dbLog = log.logger("db") // name: "myapp:db"
90
- ```
91
-
92
- ### Levels
93
-
94
- | Pino Level | Value | loggily Level |
95
- | ---------- | ----: | ------------------------- |
96
- | trace | 10 | trace |
97
- | debug | 20 | debug |
98
- | info | 30 | info |
99
- | warn | 40 | warn |
100
- | error | 50 | error |
101
- | fatal | 60 | error (no separate fatal) |
102
- | silent | ∞ | silent |
103
-
104
- ### Transports / Writers
105
-
106
- ```typescript
107
- // Pino transports
108
- const logger = pino({
109
- transport: {
110
- target: "pino/file",
111
- options: { destination: "/tmp/app.log" },
112
- },
113
- })
114
-
115
- // loggily writers
116
- import { addWriter, createFileWriter } from "loggily"
117
-
118
- const writer = createFileWriter("/tmp/app.log")
119
- addWriter((formatted) => writer.write(formatted))
120
- ```
121
-
122
- ### Serializers
123
-
124
- ```typescript
125
- // Pino serializers
126
- const logger = pino({
127
- serializers: {
128
- req: pino.stdSerializers.req,
129
- err: pino.stdSerializers.err,
130
- },
131
- })
132
-
133
- // loggily — handle in data parameter
134
- log.info?.("request", {
135
- method: req.method,
136
- url: req.url,
137
- statusCode: res.statusCode,
138
- })
139
- log.error?.(err) // Built-in Error serialization
140
- ```
141
-
142
- ### Timing
143
-
144
- ```typescript
145
- // Pino (manual)
146
- const start = Date.now()
147
- await operation()
148
- logger.info({ duration: Date.now() - start }, "operation complete")
149
-
150
- // loggily (built-in spans)
151
- {
152
- using span = log.span("operation")
153
- await operation()
154
- span.spanData.rowCount = 500
155
- }
156
- // Automatic: SPAN myapp:operation (234ms) {rowCount: 500}
157
- ```
158
-
159
- ## Environment Variables
160
-
161
- | Pino | loggily | Effect |
162
- | --------------------- | --------------------- | ------------------------------------- |
163
- | `LOG_LEVEL=debug` | `LOG_LEVEL=debug` | Set minimum level |
164
- | N/A | `DEBUG=myapp` | Namespace filter (auto-enables debug) |
165
- | N/A | `TRACE=1` | Enable span output |
166
- | N/A | `LOG_FORMAT=json` | Force JSON output |
167
- | `NODE_ENV=production` | `NODE_ENV=production` | Auto-enable JSON |
168
-
169
- ## Migration Checklist
170
-
171
- 1. **Update dependencies**: `bun remove pino pino-pretty && bun add loggily`
172
- 2. **Update imports**: `import pino from "pino"` → `import { createLogger } from "loggily"`
173
- 3. **Swap argument order**: Pino uses `(data, message)`, loggily uses `(message, data)`
174
- 4. **Replace `logger.child()`** with `.child()` (context) or `.logger()` (namespace)
175
- 5. **Convert transports** to writers via `addWriter()`
176
- 6. **Add `?.`** to all log calls for zero-overhead disabled logging
177
- 7. **Convert manual timing** to spans with `using`
178
- 8. **Replace `fatal`** with `error` (add a custom label in data if needed)
@@ -1,179 +0,0 @@
1
- # Migration from Winston
2
-
3
- Step-by-step guide for migrating from Winston to loggily.
4
-
5
- ## Why Migrate?
6
-
7
- | Feature | Winston | loggily |
8
- | ------------------------- | ----------------------- | ----------------------------- |
9
- | Log levels | Customizable | 5 fixed levels + silent |
10
- | Structured data | Yes (metadata) | Yes (data parameter) |
11
- | Disabled call overhead | ~372ns | **~2.5ns** (?. pattern) |
12
- | Disabled + expensive args | ~741ns (args evaluated) | **~3.6ns (args skipped)** |
13
- | Built-in spans/tracing | No | Yes (with `using` keyword) |
14
- | Transports | Rich ecosystem | Writers + file writer |
15
- | Pretty print | Via formats | Built-in |
16
- | Bundle size | ~60KB + transports | ~3KB |
17
- | Browser support | Via browser transport | Built-in (conditional export) |
18
-
19
- ## Quick Migration
20
-
21
- ### Before (Winston)
22
-
23
- ```typescript
24
- import winston from "winston"
25
-
26
- const logger = winston.createLogger({
27
- level: "info",
28
- format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
29
- transports: [new winston.transports.Console()],
30
- })
31
-
32
- logger.info("server started", { port: 3000 })
33
- logger.error("request failed", { error: err.message })
34
- ```
35
-
36
- ### After (loggily)
37
-
38
- ```typescript
39
- import { createLogger } from "loggily"
40
-
41
- const log = createLogger("myapp")
42
-
43
- log.info?.("server started", { port: 3000 })
44
- log.error?.(err) // Automatic Error handling
45
- ```
46
-
47
- ## Pattern Mapping
48
-
49
- ### Logger Creation
50
-
51
- ```typescript
52
- // Winston
53
- const logger = winston.createLogger({
54
- level: "info",
55
- format: winston.format.json(),
56
- transports: [new winston.transports.Console()],
57
- })
58
-
59
- // loggily
60
- const log = createLogger("myapp")
61
- // Level, format, and output configured via env vars or API:
62
- // LOG_LEVEL=info, LOG_FORMAT=json, NODE_ENV=production
63
- ```
64
-
65
- ### Log Calls
66
-
67
- ```typescript
68
- // Winston — message first, metadata spread or second arg
69
- logger.info("starting", { port: 3000 })
70
- logger.info({ message: "starting", port: 3000 })
71
- logger.error("failed", { error: err.message, stack: err.stack })
72
-
73
- // loggily — message + optional data
74
- log.info?.("starting", { port: 3000 })
75
- log.error?.(err) // Error: auto-extracts message, stack, code
76
- log.error?.(err, { context: "startup" }) // With extra context
77
- ```
78
-
79
- ### Levels
80
-
81
- | Winston Level | loggily Level |
82
- | ------------- | ----------------------- |
83
- | error | error |
84
- | warn | warn |
85
- | info | info |
86
- | http | info (no separate http) |
87
- | verbose | debug |
88
- | debug | debug |
89
- | silly | trace |
90
-
91
- ### Child Loggers
92
-
93
- ```typescript
94
- // Winston — child loggers via defaultMeta
95
- const childLogger = logger.child({ requestId: "abc" })
96
- childLogger.info("processing")
97
-
98
- // loggily — two patterns
99
- const child = log.child({ requestId: "abc" }) // Context fields
100
- const dbLog = log.logger("db") // Namespace: myapp:db
101
- ```
102
-
103
- ### Transports / Writers
104
-
105
- ```typescript
106
- // Winston transports
107
- const logger = winston.createLogger({
108
- transports: [new winston.transports.Console(), new winston.transports.File({ filename: "app.log" })],
109
- })
110
-
111
- // loggily writers
112
- import { addWriter, createFileWriter } from "loggily"
113
-
114
- // Console output is built-in (default)
115
- // File output via createFileWriter
116
- const writer = createFileWriter("/tmp/app.log")
117
- const unsub = addWriter((formatted) => writer.write(formatted))
118
-
119
- // Custom writer (e.g., send to external service)
120
- addWriter((formatted, level) => {
121
- if (level === "error") sendToAlertService(formatted)
122
- })
123
- ```
124
-
125
- ### Formats
126
-
127
- ```typescript
128
- // Winston — format combinators
129
- const logger = winston.createLogger({
130
- format: winston.format.combine(
131
- winston.format.timestamp(),
132
- winston.format.colorize(),
133
- winston.format.printf(({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`),
134
- ),
135
- })
136
-
137
- // loggily — built-in formats
138
- // Development: colorized console with timestamp (default)
139
- // Production: JSON (NODE_ENV=production or LOG_FORMAT=json)
140
- // No configuration needed
141
- ```
142
-
143
- ### Timing
144
-
145
- ```typescript
146
- // Winston (manual profiling)
147
- logger.profile("operation")
148
- await doWork()
149
- logger.profile("operation") // logs duration
150
-
151
- // loggily (built-in spans)
152
- {
153
- using span = log.span("operation")
154
- await doWork()
155
- }
156
- // Automatic: SPAN myapp:operation (234ms)
157
- ```
158
-
159
- ## Environment Variables
160
-
161
- | Winston | loggily | Effect |
162
- | ------------------------ | --------------------- | ------------------ |
163
- | N/A (configured in code) | `LOG_LEVEL=debug` | Set minimum level |
164
- | N/A | `DEBUG=myapp` | Namespace filter |
165
- | N/A | `TRACE=1` | Enable span output |
166
- | N/A | `LOG_FORMAT=json` | Force JSON output |
167
- | `NODE_ENV=production` | `NODE_ENV=production` | Auto-enable JSON |
168
-
169
- ## Migration Checklist
170
-
171
- 1. **Update dependencies**: `bun remove winston` and `bun add loggily`
172
- 2. **Update imports**: `import winston from "winston"` → `import { createLogger } from "loggily"`
173
- 3. **Replace `createLogger()`**: Winston's options → `createLogger("name")` + env vars
174
- 4. **Convert transports** to `addWriter()` + optional `createFileWriter()`
175
- 5. **Remove format configuration** — built-in formats handle dev/prod automatically
176
- 6. **Add `?.`** to all log calls for zero-overhead disabled logging
177
- 7. **Map custom levels**: http→info, verbose→debug, silly→trace
178
- 8. **Convert `logger.profile()`** to spans with `using`
179
- 9. **Replace `logger.child()`** with `.child()` (context) or `.logger()` (namespace)