@better-logger/core 0.7.0 โ 0.8.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 +170 -216
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# better-logger
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Track what your app *did*, not what it *said*.**
|
|
4
4
|
|
|
5
5
|
Execution flow debugger for modern apps. Zero deps. Works everywhere. <10KB.
|
|
6
6
|
|
|
@@ -8,11 +8,9 @@ Execution flow debugger for modern apps. Zero deps. Works everywhere. <10KB.
|
|
|
8
8
|
npm install @better-logger/core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Stop debugging like this:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
```ts
|
|
13
|
+
```typescript
|
|
16
14
|
console.log('start')
|
|
17
15
|
console.log('user', user)
|
|
18
16
|
console.log('after db')
|
|
@@ -21,273 +19,229 @@ console.log('done')
|
|
|
21
19
|
|
|
22
20
|
And trying to mentally reconstruct what happened, in what order, and how long each thing took.
|
|
23
21
|
|
|
24
|
-
Your app is not a list of messages.
|
|
22
|
+
## Your app is not a list of messages. It's a flow.
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import { better } from '@better-logger/core'
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
// Replace console.log โ zero learning curve
|
|
28
|
+
better.log('User created', { email: 'test@example.com' })
|
|
29
|
+
better.log.warn('Slow query detected', { duration: 250 })
|
|
30
|
+
better.log.error('Payment failed', error)
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
// When you need structure
|
|
33
|
+
const flow = better.flow('user-onboarding', { tags: ['auth'] })
|
|
34
|
+
const step = flow.step('create-user', { email })
|
|
35
|
+
await createUser(email)
|
|
36
|
+
step.success()
|
|
37
|
+
flow.success()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**What you get:**
|
|
31
41
|
|
|
32
42
|
```
|
|
33
43
|
๐ [flow:user-onboarding] [auth] (tid: a1b2c3d4)
|
|
34
44
|
โ create-user
|
|
35
45
|
data: { email: "test@example.com" }
|
|
36
46
|
โ create-user (45ms)
|
|
37
|
-
|
|
38
|
-
โ generate-ai-profile (410ms)
|
|
39
|
-
โ save-db
|
|
40
|
-
โ save-db (error: timeout)
|
|
41
|
-
๐ [flow:user-onboarding] failed (532ms)
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
```ts
|
|
45
|
-
import { createFlow } from '@better-logger/core'
|
|
46
|
-
|
|
47
|
-
const flow = createFlow('user-onboarding', { tags: ['auth'] })
|
|
48
|
-
|
|
49
|
-
const s1 = flow.step('create-user', { email })
|
|
50
|
-
await createUser(email)
|
|
51
|
-
s1.success()
|
|
52
|
-
|
|
53
|
-
const s2 = flow.step('save-db')
|
|
54
|
-
await saveUser()
|
|
55
|
-
s2.fail(new Error('timeout'))
|
|
56
|
-
|
|
57
|
-
flow.fail(new Error('save-db failed'))
|
|
47
|
+
๐ [flow:user-onboarding] success (45ms)
|
|
58
48
|
```
|
|
59
49
|
|
|
60
|
-
You didn't write logs.
|
|
61
|
-
|
|
62
|
-
You defined the **execution**.
|
|
63
|
-
|
|
64
|
-
better-logger turns your code into a timeline of what actually happened.
|
|
65
|
-
|
|
66
|
-
Output is deferred until `flow.success()` / `flow.fail()` โ one atomic write, zero interleaving, even in async chaos.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
50
|
## Why this exists
|
|
71
51
|
|
|
72
52
|
Debugging today is broken:
|
|
73
53
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
| Problem | better-logger solution |
|
|
55
|
+
|---------|----------------------|
|
|
56
|
+
| `console.log` โ flat noise, no structure | Hierarchical flows with automatic timing |
|
|
57
|
+
| No automatic timing | Every step and flow tracks duration |
|
|
58
|
+
| No context propagation | `flow.setContext()` shares metadata across all steps |
|
|
59
|
+
| Async flows become impossible to follow | Deferred atomic rendering โ one output per flow |
|
|
60
|
+
| Need to learn new API | `better.log()` is `console.log()` โ just add `.log` |
|
|
78
61
|
|
|
79
|
-
|
|
62
|
+
## Quick Start
|
|
80
63
|
|
|
81
|
-
|
|
64
|
+
### 1. Drop-in replacement
|
|
82
65
|
|
|
83
|
-
|
|
66
|
+
Replace `console.log` with `better.log`:
|
|
84
67
|
|
|
85
|
-
|
|
68
|
+
```typescript
|
|
69
|
+
// Before
|
|
70
|
+
console.log('Server started on port 3000')
|
|
71
|
+
console.error('Database connection failed', error)
|
|
86
72
|
|
|
87
|
-
|
|
73
|
+
// After
|
|
74
|
+
import { better } from '@better-logger/core'
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- "where did it fail?"
|
|
93
|
-
- "why is it slow?"
|
|
94
|
-
|
|
95
|
-
You **see**:
|
|
96
|
-
|
|
97
|
-
- ๐ง A full execution narrative
|
|
98
|
-
- โฑ Exact timing for every step
|
|
99
|
-
- ๐ณ Nested flows (real hierarchy, not flat logs)
|
|
100
|
-
- ๐งพ Data at the moment it mattered
|
|
101
|
-
- ๐งต Shared context across the entire flow
|
|
102
|
-
- ๐ท Tags to group and filter
|
|
103
|
-
- ๐งฑ Guaranteed consistency โ no race-condition bugs
|
|
104
|
-
- ๐ Immutable render snapshots โ output can't be corrupted
|
|
105
|
-
|
|
106
|
-
This replaces `console.log` for anything non-trivial.
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Why not just use something else?
|
|
111
|
-
|
|
112
|
-
| Tool | Reality |
|
|
113
|
-
|------|--------|
|
|
114
|
-
| `console.log` | You reconstruct flows manually like it's 2005 |
|
|
115
|
-
| `pino` / `winston` | Built for shipping logs, not understanding execution |
|
|
116
|
-
| `debug` | Namespaces โ structure |
|
|
117
|
-
| OpenTelemetry | Powerful, but heavy and not built for everyday debugging |
|
|
118
|
-
|
|
119
|
-
**@better-logger/core** sits in the missing gap:
|
|
76
|
+
better.log('Server started on port 3000')
|
|
77
|
+
better.log.error('Database connection failed', error)
|
|
78
|
+
```
|
|
120
79
|
|
|
121
|
-
|
|
80
|
+
That's it. You now get structured, timed output for free.
|
|
122
81
|
|
|
123
|
-
|
|
82
|
+
### 2. When you need structure
|
|
124
83
|
|
|
125
|
-
|
|
84
|
+
For important operations, use explicit flows:
|
|
126
85
|
|
|
127
|
-
```
|
|
128
|
-
const flow =
|
|
86
|
+
```typescript
|
|
87
|
+
const flow = better.flow('process-payment', { tags: ['billing'] })
|
|
88
|
+
flow.setContext({ orderId: 'ord-123', userId: 'user-456' })
|
|
129
89
|
|
|
130
|
-
const step = flow.step('
|
|
131
|
-
await
|
|
132
|
-
step.success()
|
|
90
|
+
const step = flow.step('charge-card', { amount: 99.99 })
|
|
91
|
+
const result = await paymentGateway.charge({ amount: 99.99 })
|
|
92
|
+
step.success(result)
|
|
133
93
|
|
|
134
94
|
flow.success()
|
|
95
|
+
better.log(`Payment processed: ${result.transactionId}`)
|
|
135
96
|
```
|
|
136
97
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## How it works
|
|
142
|
-
|
|
143
|
-
```mermaid
|
|
144
|
-
graph TD
|
|
145
|
-
Start[createFlow] --> Step[step]
|
|
146
|
-
Step --> Complete[success / fail]
|
|
147
|
-
Complete --> FlowEnd[flow.success / flow.fail]
|
|
148
|
-
FlowEnd --> Render[Atomic Render]
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## When should you use this
|
|
154
|
-
|
|
155
|
-
Use it when:
|
|
156
|
-
|
|
157
|
-
- your flow has more than 2 steps
|
|
158
|
-
- async logic gets confusing
|
|
159
|
-
- debugging requires more than one `console.log`
|
|
160
|
-
- timing matters
|
|
161
|
-
- you need to know "what ran" and "what didn't"
|
|
98
|
+
### 3. Async made easy
|
|
162
99
|
|
|
163
|
-
|
|
100
|
+
```typescript
|
|
101
|
+
const flow = better.flow('data-export')
|
|
164
102
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
## Advanced
|
|
170
|
-
|
|
171
|
-
### Child Flows
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
const flow = createFlow('request')
|
|
103
|
+
const data = await flow.run('fetch-data', async () => {
|
|
104
|
+
return await db.users.find({})
|
|
105
|
+
})
|
|
175
106
|
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
s.success()
|
|
180
|
-
ai.success()
|
|
107
|
+
const file = await flow.run('generate-file', async () => {
|
|
108
|
+
return await exportToCSV(data)
|
|
109
|
+
})
|
|
181
110
|
|
|
182
111
|
flow.success()
|
|
183
112
|
```
|
|
184
113
|
|
|
185
|
-
|
|
186
|
-
๐ [flow:request] (tid: a1b2c3d4)
|
|
187
|
-
โโ ๐ [flow:ai-call] (tid: x9y8z7w6)
|
|
188
|
-
โ generate
|
|
189
|
-
โ generate (210ms)
|
|
190
|
-
๐ [flow:ai-call] success (215ms)
|
|
191
|
-
๐ [flow:request] success (340ms)
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Context Propagation
|
|
114
|
+
## API Reference
|
|
195
115
|
|
|
196
|
-
|
|
197
|
-
flow.setContext({ userId: 'abc', requestId: 'xyz' })
|
|
198
|
-
// Available across all steps and child flows
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Silent Mode
|
|
202
|
-
|
|
203
|
-
```ts
|
|
204
|
-
const flow = createFlow('task', { enabled: false })
|
|
205
|
-
// Near-zero overhead. All operations are no-ops.
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Max Steps Guard
|
|
116
|
+
### `better.log()` โ The simple way
|
|
209
117
|
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
//
|
|
118
|
+
```typescript
|
|
119
|
+
better.log('message') // Simple message
|
|
120
|
+
better.log('message', data) // Message with data
|
|
121
|
+
better.log.info('message', data) // Info (same as log)
|
|
122
|
+
better.log.warn('message', data) // Warning (auto-tags flow)
|
|
123
|
+
better.log.error('message', error) // Error (fails flow)
|
|
213
124
|
```
|
|
214
125
|
|
|
215
|
-
###
|
|
126
|
+
### `better.flow()` โ The structured way
|
|
216
127
|
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
console.log(toJSON(trace))
|
|
128
|
+
```typescript
|
|
129
|
+
const flow = better.flow('name', {
|
|
130
|
+
tags: ['tag1', 'tag2'], // Indexing labels
|
|
131
|
+
maxSteps: 100, // Safety limit
|
|
132
|
+
initialContext: { key: 'value' } // Shared metadata
|
|
223
133
|
})
|
|
224
|
-
```
|
|
225
134
|
|
|
226
|
-
|
|
135
|
+
flow.setContext({ userId: 'abc' }) // Add context
|
|
136
|
+
flow.getContext() // Get context copy
|
|
227
137
|
|
|
228
|
-
|
|
229
|
-
|
|
138
|
+
flow.step('step-name', data) // Create step
|
|
139
|
+
.success() // Mark success
|
|
140
|
+
.fail(error) // Mark failure
|
|
230
141
|
|
|
231
|
-
|
|
232
|
-
//
|
|
142
|
+
flow.success() // Complete flow
|
|
143
|
+
flow.fail(error) // Fail flow
|
|
233
144
|
```
|
|
234
145
|
|
|
235
|
-
|
|
146
|
+
### `better.flow.run()` โ Async helper
|
|
236
147
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
`createFlow` ยท `step` ยท `success/fail` ยท `child` ยท `toJSON`
|
|
243
|
-
|
|
244
|
-
### Advanced
|
|
245
|
-
Context propagation ยท Tags ยท Inline data snapshots ยท Subscribe event tap ยท Deferred atomic rendering ยท Immutable snapshots
|
|
246
|
-
|
|
247
|
-
### Safety
|
|
248
|
-
Guarded finalization ยท `maxSteps` overflow protection ยท Lifecycle states (`running` โ `completed`) ยท Safe data serializer (circular refs, deep nesting) ยท NoOp singletons (zero-allocation silent mode)
|
|
249
|
-
|
|
250
|
-
---
|
|
251
|
-
|
|
252
|
-
## What's not included
|
|
253
|
-
|
|
254
|
-
- โ Log levels (debug, info, warn)
|
|
255
|
-
- โ Transports (file, HTTP, Elasticsearch)
|
|
256
|
-
- โ SaaS dashboards
|
|
257
|
-
- โ Auto-instrumentation
|
|
258
|
-
|
|
259
|
-
This is a developer debugging tool, not observability infrastructure.
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Roadmap
|
|
264
|
-
|
|
265
|
-
| Version | Focus |
|
|
266
|
-
|---------|-------|
|
|
267
|
-
| **V1** | Core flow debugger โ this release |
|
|
268
|
-
| **V2** | Custom renderers, `flow.run()` async helper, flow sampling |
|
|
269
|
-
| **V3** | Browser DevTools timeline panel |
|
|
270
|
-
| **V4+** | Python / Go / Rust ports, shared tracing schema |
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Organization
|
|
148
|
+
```typescript
|
|
149
|
+
const result = await flow.run('async-step', async () => {
|
|
150
|
+
return await fetchData() // Auto-completes step on success/fail
|
|
151
|
+
})
|
|
152
|
+
```
|
|
275
153
|
|
|
276
|
-
|
|
154
|
+
### Configuration
|
|
277
155
|
|
|
278
|
-
```
|
|
279
|
-
|
|
156
|
+
```typescript
|
|
157
|
+
better.log.setIdleTimeout(200) // Auto-complete timeout (ms)
|
|
158
|
+
better.log.setFlowName('my-app') // Default flow name
|
|
159
|
+
better.log.setDefaultTags(['app', 'v3']) // Tags on all flows
|
|
160
|
+
better.log.flush() // Force complete current flow
|
|
161
|
+
better.setEnabled(false) // Disable all logging
|
|
162
|
+
better.isEnabled() // Check if enabled
|
|
280
163
|
```
|
|
281
164
|
|
|
282
|
-
|
|
165
|
+
## Real-World Examples
|
|
283
166
|
|
|
284
|
-
|
|
167
|
+
We've included 10 comprehensive examples showing better-logger in real applications:
|
|
285
168
|
|
|
286
|
-
|
|
169
|
+
| Example | What it shows |
|
|
170
|
+
|---------|--------------|
|
|
171
|
+
| `01-express-rest-api.js` | Express middleware, CRUD endpoints, error handling |
|
|
172
|
+
| `02-background-job-processor.js` | Job queue, retry logic, nested flows |
|
|
173
|
+
| `03-authentication-flow.js` | Login, token refresh, password reset, security logging |
|
|
174
|
+
| `04-ecommerce-order-processing.js` | Multi-step checkout, inventory, payment, shipping |
|
|
175
|
+
| `05-cli-tool.js` | CLI commands, progress tracking, file processing |
|
|
176
|
+
| `06-api-integration-client.js` | HTTP client, retry logic, rate limiting, batch ops |
|
|
177
|
+
| `07-microservice-distributed-tracing.js` | Trace context, downstream calls, health checks |
|
|
178
|
+
| `08-testing-utilities.js` | Test runner, assertions, performance testing |
|
|
179
|
+
| `09-data-pipeline.js` | ETL pipelines, transforms, validation, aggregation |
|
|
180
|
+
| `10-full-application.js` | Complete Node.js app with all patterns combined |
|
|
287
181
|
|
|
288
|
-
|
|
182
|
+
## Features
|
|
289
183
|
|
|
290
|
-
|
|
184
|
+
### Zero Friction
|
|
185
|
+
- `better.log()` is a drop-in for `console.log()`
|
|
186
|
+
- No configuration needed โ import and use immediately
|
|
187
|
+
- Auto-flow management groups rapid calls together
|
|
188
|
+
- Idle timeout auto-completes flows (100ms default)
|
|
189
|
+
|
|
190
|
+
### Structured Output
|
|
191
|
+
- Hierarchical flows with visual nesting
|
|
192
|
+
- Automatic timing for every step and flow
|
|
193
|
+
- Context propagation across all steps
|
|
194
|
+
- Tags for filtering and grouping
|
|
195
|
+
- JSON export for downstream systems
|
|
196
|
+
|
|
197
|
+
### Production-Grade
|
|
198
|
+
- Zero dependencies โ nothing to break
|
|
199
|
+
- <10KB bundle โ won't bloat your app
|
|
200
|
+
- Works in Node.js 18+, browsers, Edge runtimes
|
|
201
|
+
- Full TypeScript support
|
|
202
|
+
- 100% test coverage
|
|
203
|
+
|
|
204
|
+
### Forgiving
|
|
205
|
+
- Call methods after completion โ silent no-ops
|
|
206
|
+
- Pass any data type โ handled gracefully
|
|
207
|
+
- Circular references โ won't crash
|
|
208
|
+
- Concurrent flows โ no interleaving
|
|
209
|
+
- Error anywhere โ won't break your app
|
|
210
|
+
|
|
211
|
+
## Migration from console.log
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Before
|
|
215
|
+
console.log('User created:', user)
|
|
216
|
+
console.warn('Slow query', { duration: 250 })
|
|
217
|
+
console.error('Payment failed:', error)
|
|
218
|
+
|
|
219
|
+
// After (literally just add "better.")
|
|
220
|
+
import { better } from '@better-logger/core'
|
|
221
|
+
|
|
222
|
+
better.log('User created:', user)
|
|
223
|
+
better.log.warn('Slow query', { duration: 250 })
|
|
224
|
+
better.log.error('Payment failed:', error)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Migration effort:** 10 minutes to replace all console.log. Hours to days to adopt flows strategically where they add value.
|
|
228
|
+
|
|
229
|
+
## What's NOT included
|
|
230
|
+
|
|
231
|
+
- โ Log levels (debug, info, warn, error) โ execution tracing โ log routing
|
|
232
|
+
- โ Transport layers (file, HTTP, Elasticsearch) โ zero-config philosophy
|
|
233
|
+
- โ SaaS dashboards โ we emit data, we don't host it
|
|
234
|
+
- โ Auto-instrumentation โ devs control what they trace
|
|
235
|
+
|
|
236
|
+
## Package Health
|
|
237
|
+
|
|
238
|
+
| Metric | Value |
|
|
239
|
+
|--------|-------|
|
|
240
|
+
| Bundle size | <10KB minified |
|
|
241
|
+
| Dependencies | 0 |
|
|
242
|
+
| Test coverage | 100% |
|
|
243
|
+
| TypeScript | Full support |
|
|
244
|
+
| Runtimes | Node 18+, Browser, Edge |
|
|
291
245
|
|
|
292
246
|
## License
|
|
293
247
|
|
package/package.json
CHANGED