widelogger 0.2.1 → 0.3.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 +29 -14
- package/dist/index.d.ts +17 -17
- package/dist/index.js +71 -67
- package/dist/types.d.ts +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ npm install widelogger
|
|
|
41
41
|
```ts
|
|
42
42
|
import { widelogger } from "widelogger";
|
|
43
43
|
|
|
44
|
-
const {
|
|
44
|
+
const { context, destroy } = widelogger({
|
|
45
45
|
service: "checkout-api",
|
|
46
46
|
defaultEventName: "http_request",
|
|
47
47
|
version: "1.0.0",
|
|
@@ -49,15 +49,23 @@ const { widelog, destroy } = widelogger({
|
|
|
49
49
|
});
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
`widelogger()` returns a `context` function to wrap request lifecycles and a `destroy` function for graceful shutdown. To log fields, import `widelog` directly from the package — it works anywhere inside a `context()` call thanks to `AsyncLocalStorage`.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { widelog } from "widelogger";
|
|
56
|
+
|
|
57
|
+
widelog.set("user.id", userId);
|
|
58
|
+
```
|
|
59
|
+
|
|
52
60
|
### Express
|
|
53
61
|
|
|
54
|
-
Create a
|
|
62
|
+
Create a logger instance once, use middleware to wrap requests in a context, and accumulate fields from anywhere in your codebase by importing `widelog` directly.
|
|
55
63
|
|
|
56
64
|
```ts
|
|
57
65
|
// src/logger.ts
|
|
58
66
|
import { widelogger } from "widelogger";
|
|
59
67
|
|
|
60
|
-
export const {
|
|
68
|
+
export const { context, destroy } = widelogger({
|
|
61
69
|
service: "checkout-api",
|
|
62
70
|
defaultEventName: "http_request",
|
|
63
71
|
});
|
|
@@ -65,10 +73,11 @@ export const { widelog, destroy } = widelogger({
|
|
|
65
73
|
|
|
66
74
|
```ts
|
|
67
75
|
// src/middleware/logging.ts
|
|
68
|
-
import { widelog } from "
|
|
76
|
+
import { widelog } from "widelogger";
|
|
77
|
+
import { context } from "../logger";
|
|
69
78
|
|
|
70
79
|
export const logging = (request, response, next) => {
|
|
71
|
-
|
|
80
|
+
context(
|
|
72
81
|
() =>
|
|
73
82
|
new Promise((resolve) => {
|
|
74
83
|
widelog.set("method", request.method);
|
|
@@ -90,9 +99,9 @@ export const logging = (request, response, next) => {
|
|
|
90
99
|
|
|
91
100
|
```ts
|
|
92
101
|
// src/routes/checkout.ts
|
|
93
|
-
import { widelog } from "
|
|
102
|
+
import { widelog } from "widelogger";
|
|
94
103
|
|
|
95
|
-
export const checkout = (request, response) => {
|
|
104
|
+
export const checkout = async (request, response) => {
|
|
96
105
|
const { userId } = request.body;
|
|
97
106
|
|
|
98
107
|
widelog.set("user.id", userId);
|
|
@@ -109,7 +118,7 @@ export const checkout = (request, response) => {
|
|
|
109
118
|
};
|
|
110
119
|
```
|
|
111
120
|
|
|
112
|
-
The handler doesn't need to know about context setup or flushing — it just imports `widelog` and adds fields. `AsyncLocalStorage` ensures concurrent requests never leak into each other.
|
|
121
|
+
The handler doesn't need to know about context setup or flushing — it just imports `widelog` from the package and adds fields. `AsyncLocalStorage` ensures concurrent requests never leak into each other.
|
|
113
122
|
|
|
114
123
|
### Bun
|
|
115
124
|
|
|
@@ -119,7 +128,7 @@ The same pattern works with Bun's built-in server.
|
|
|
119
128
|
// src/logger.ts
|
|
120
129
|
import { widelogger } from "widelogger";
|
|
121
130
|
|
|
122
|
-
export const {
|
|
131
|
+
export const { context, destroy } = widelogger({
|
|
123
132
|
service: "checkout-api",
|
|
124
133
|
defaultEventName: "http_request",
|
|
125
134
|
});
|
|
@@ -127,7 +136,7 @@ export const { widelog, destroy } = widelogger({
|
|
|
127
136
|
|
|
128
137
|
```ts
|
|
129
138
|
// src/routes/checkout.ts
|
|
130
|
-
import { widelog } from "
|
|
139
|
+
import { widelog } from "widelogger";
|
|
131
140
|
|
|
132
141
|
export const checkout = async (request: Request) => {
|
|
133
142
|
const { userId } = await request.json();
|
|
@@ -149,12 +158,13 @@ export const checkout = async (request: Request) => {
|
|
|
149
158
|
```ts
|
|
150
159
|
// src/server.ts
|
|
151
160
|
import { serve } from "bun";
|
|
152
|
-
import { widelog } from "
|
|
161
|
+
import { widelog } from "widelogger";
|
|
162
|
+
import { context } from "./logger";
|
|
153
163
|
import { checkout } from "./routes/checkout";
|
|
154
164
|
|
|
155
165
|
serve({
|
|
156
166
|
fetch: (request) =>
|
|
157
|
-
|
|
167
|
+
context(async () => {
|
|
158
168
|
const url = new URL(request.url);
|
|
159
169
|
widelog.set("method", request.method);
|
|
160
170
|
widelog.set("path", url.pathname);
|
|
@@ -200,7 +210,7 @@ Events with `status_code >= 500` or `outcome === "error"` are emitted at `error`
|
|
|
200
210
|
|
|
201
211
|
### `widelogger(options)`
|
|
202
212
|
|
|
203
|
-
Creates a logger instance. Returns `{
|
|
213
|
+
Creates a logger instance. Returns `{ context, destroy }`.
|
|
204
214
|
|
|
205
215
|
| Option | Type | Description |
|
|
206
216
|
|--------|------|-------------|
|
|
@@ -212,11 +222,16 @@ Creates a logger instance. Returns `{ widelog, destroy }`.
|
|
|
212
222
|
| `environment` | `string` | Environment name (defaults to `NODE_ENV`) |
|
|
213
223
|
| `level` | `string` | Log level (defaults to `LOG_LEVEL` env or `"info"`) |
|
|
214
224
|
|
|
225
|
+
### `context(fn)`
|
|
226
|
+
|
|
227
|
+
Run a function inside an isolated async context. All `widelog` calls within this function (and any functions it calls) are scoped to this context. Supports both sync and async callbacks.
|
|
228
|
+
|
|
215
229
|
### `widelog`
|
|
216
230
|
|
|
231
|
+
Imported directly from `"widelogger"`. All methods operate on the current async context established by `context()`.
|
|
232
|
+
|
|
217
233
|
| Method | Description |
|
|
218
234
|
|--------|-------------|
|
|
219
|
-
| `context(fn)` | Run a function in an isolated async context |
|
|
220
235
|
| `set(key, value)` | Set a field value (last write wins) |
|
|
221
236
|
| `count(key, amount?)` | Increment a counter (default +1) |
|
|
222
237
|
| `append(key, value)` | Append a value to an array |
|
package/dist/index.d.ts
CHANGED
|
@@ -12,24 +12,24 @@ export interface ErrorFieldsOptions {
|
|
|
12
12
|
prefix?: string;
|
|
13
13
|
includeStack?: boolean;
|
|
14
14
|
}
|
|
15
|
+
export declare const widelog: {
|
|
16
|
+
set: <K extends string>(key: DottedKey<K>, value: FieldValue) => void;
|
|
17
|
+
count: <K extends string>(key: DottedKey<K>, amount?: number) => void;
|
|
18
|
+
append: <K extends string>(key: DottedKey<K>, value: FieldValue) => void;
|
|
19
|
+
max: <K extends string>(key: DottedKey<K>, value: number) => void;
|
|
20
|
+
min: <K extends string>(key: DottedKey<K>, value: number) => void;
|
|
21
|
+
time: {
|
|
22
|
+
start: <K extends string>(key: DottedKey<K>) => void;
|
|
23
|
+
stop: <K extends string>(key: DottedKey<K>) => void;
|
|
24
|
+
};
|
|
25
|
+
errorFields: (error: unknown, options?: ErrorFieldsOptions) => void;
|
|
26
|
+
flush: () => void;
|
|
27
|
+
};
|
|
15
28
|
export declare const widelogger: (options: WideloggerOptions) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
append: <K extends string>(key: DottedKey<K>, value: FieldValue) => void;
|
|
20
|
-
max: <K extends string>(key: DottedKey<K>, value: number) => void;
|
|
21
|
-
min: <K extends string>(key: DottedKey<K>, value: number) => void;
|
|
22
|
-
time: {
|
|
23
|
-
start: <K extends string>(key: DottedKey<K>) => void;
|
|
24
|
-
stop: <K extends string>(key: DottedKey<K>) => void;
|
|
25
|
-
};
|
|
26
|
-
errorFields: (error: unknown, options?: ErrorFieldsOptions) => void;
|
|
27
|
-
flush: () => void;
|
|
28
|
-
context: {
|
|
29
|
-
<T>(callback: () => Promise<T>): Promise<T>;
|
|
30
|
-
<T>(callback: () => T): T;
|
|
31
|
-
};
|
|
29
|
+
context: {
|
|
30
|
+
<T>(callback: () => Promise<T>): Promise<T>;
|
|
31
|
+
<T>(callback: () => T): T;
|
|
32
32
|
};
|
|
33
33
|
destroy: () => Promise<void>;
|
|
34
34
|
};
|
|
35
|
-
export type Widelog =
|
|
35
|
+
export type Widelog = typeof widelog;
|
package/dist/index.js
CHANGED
|
@@ -134,6 +134,69 @@ function getErrorFields(error, includeStack = true) {
|
|
|
134
134
|
error_message: "Unknown error"
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
+
var storage = new AsyncLocalStorage;
|
|
138
|
+
var widelog = {
|
|
139
|
+
set: (key, value) => {
|
|
140
|
+
storage.getStore()?.operations.push({ operation: "set", key, value });
|
|
141
|
+
},
|
|
142
|
+
count: (key, amount = 1) => {
|
|
143
|
+
storage.getStore()?.operations.push({ operation: "count", key, amount });
|
|
144
|
+
},
|
|
145
|
+
append: (key, value) => {
|
|
146
|
+
storage.getStore()?.operations.push({ operation: "append", key, value });
|
|
147
|
+
},
|
|
148
|
+
max: (key, value) => {
|
|
149
|
+
storage.getStore()?.operations.push({ operation: "max", key, value });
|
|
150
|
+
},
|
|
151
|
+
min: (key, value) => {
|
|
152
|
+
storage.getStore()?.operations.push({ operation: "min", key, value });
|
|
153
|
+
},
|
|
154
|
+
time: {
|
|
155
|
+
start: (key) => {
|
|
156
|
+
storage.getStore()?.operations.push({
|
|
157
|
+
operation: "time.start",
|
|
158
|
+
key,
|
|
159
|
+
time: performance.now()
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
stop: (key) => {
|
|
163
|
+
storage.getStore()?.operations.push({
|
|
164
|
+
operation: "time.stop",
|
|
165
|
+
key,
|
|
166
|
+
time: performance.now()
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
errorFields: (error, options = {}) => {
|
|
171
|
+
const context = storage.getStore();
|
|
172
|
+
if (!context) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const prefix = options.prefix ?? "error";
|
|
176
|
+
const fields = getErrorFields(error, options.includeStack ?? true);
|
|
177
|
+
const nameKey = `${prefix}.error_name`;
|
|
178
|
+
const messageKey = `${prefix}.error_message`;
|
|
179
|
+
context.operations.push({ operation: "set", key: nameKey, value: fields.error_name }, { operation: "set", key: messageKey, value: fields.error_message });
|
|
180
|
+
if (fields.error_stack !== undefined) {
|
|
181
|
+
context.operations.push({
|
|
182
|
+
operation: "set",
|
|
183
|
+
key: `${prefix}.error_stack`,
|
|
184
|
+
value: fields.error_stack
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
flush: () => {
|
|
189
|
+
const store = storage.getStore();
|
|
190
|
+
if (!store) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const event = flush(store);
|
|
194
|
+
if (Object.keys(event).length === 0) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
store.transport(event);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
137
200
|
var widelogger = (options) => {
|
|
138
201
|
const environment = options.environment ?? "development" ?? "development";
|
|
139
202
|
const isDevelopment = environment !== "production";
|
|
@@ -157,11 +220,7 @@ var widelogger = (options) => {
|
|
|
157
220
|
environment
|
|
158
221
|
}
|
|
159
222
|
}, pinoTransport);
|
|
160
|
-
const storage = new AsyncLocalStorage;
|
|
161
223
|
const transport = (event) => {
|
|
162
|
-
if (Object.keys(event).length === 0) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
224
|
const statusCode = typeof event.status_code === "number" ? event.status_code : undefined;
|
|
166
225
|
const isError = statusCode !== undefined ? statusCode >= 500 : event.outcome === "error";
|
|
167
226
|
const payload = { event_name: options.defaultEventName, ...event };
|
|
@@ -172,13 +231,13 @@ var widelogger = (options) => {
|
|
|
172
231
|
logger.info(payload);
|
|
173
232
|
};
|
|
174
233
|
const clearContext = () => {
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
|
|
234
|
+
const context2 = storage.getStore();
|
|
235
|
+
if (context2 && context2.operations.length > 0) {
|
|
236
|
+
context2.operations = [];
|
|
178
237
|
}
|
|
179
238
|
};
|
|
180
|
-
function
|
|
181
|
-
return storage.run({ operations: [] }, () => {
|
|
239
|
+
function context(callback) {
|
|
240
|
+
return storage.run({ operations: [], transport }, () => {
|
|
182
241
|
let result;
|
|
183
242
|
try {
|
|
184
243
|
result = callback();
|
|
@@ -193,62 +252,6 @@ var widelogger = (options) => {
|
|
|
193
252
|
return result;
|
|
194
253
|
});
|
|
195
254
|
}
|
|
196
|
-
const widelog = {
|
|
197
|
-
set: (key, value) => {
|
|
198
|
-
storage.getStore()?.operations.push({ operation: "set", key, value });
|
|
199
|
-
},
|
|
200
|
-
count: (key, amount = 1) => {
|
|
201
|
-
storage.getStore()?.operations.push({ operation: "count", key, amount });
|
|
202
|
-
},
|
|
203
|
-
append: (key, value) => {
|
|
204
|
-
storage.getStore()?.operations.push({ operation: "append", key, value });
|
|
205
|
-
},
|
|
206
|
-
max: (key, value) => {
|
|
207
|
-
storage.getStore()?.operations.push({ operation: "max", key, value });
|
|
208
|
-
},
|
|
209
|
-
min: (key, value) => {
|
|
210
|
-
storage.getStore()?.operations.push({ operation: "min", key, value });
|
|
211
|
-
},
|
|
212
|
-
time: {
|
|
213
|
-
start: (key) => {
|
|
214
|
-
storage.getStore()?.operations.push({
|
|
215
|
-
operation: "time.start",
|
|
216
|
-
key,
|
|
217
|
-
time: performance.now()
|
|
218
|
-
});
|
|
219
|
-
},
|
|
220
|
-
stop: (key) => {
|
|
221
|
-
storage.getStore()?.operations.push({
|
|
222
|
-
operation: "time.stop",
|
|
223
|
-
key,
|
|
224
|
-
time: performance.now()
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
errorFields: (error, options2 = {}) => {
|
|
229
|
-
const context = storage.getStore();
|
|
230
|
-
if (!context) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
const prefix = options2.prefix ?? "error";
|
|
234
|
-
const fields = getErrorFields(error, options2.includeStack ?? true);
|
|
235
|
-
const nameKey = `${prefix}.error_name`;
|
|
236
|
-
const messageKey = `${prefix}.error_message`;
|
|
237
|
-
context.operations.push({ operation: "set", key: nameKey, value: fields.error_name }, { operation: "set", key: messageKey, value: fields.error_message });
|
|
238
|
-
if (fields.error_stack !== undefined) {
|
|
239
|
-
context.operations.push({
|
|
240
|
-
operation: "set",
|
|
241
|
-
key: `${prefix}.error_stack`,
|
|
242
|
-
value: fields.error_stack
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
flush: () => {
|
|
247
|
-
const event = flush(storage.getStore());
|
|
248
|
-
transport(event);
|
|
249
|
-
},
|
|
250
|
-
context: runContext
|
|
251
|
-
};
|
|
252
255
|
const destroy = async () => {
|
|
253
256
|
await new Promise((resolve) => {
|
|
254
257
|
logger.flush(() => resolve());
|
|
@@ -257,8 +260,9 @@ var widelogger = (options) => {
|
|
|
257
260
|
pinoTransport.end();
|
|
258
261
|
}
|
|
259
262
|
};
|
|
260
|
-
return {
|
|
263
|
+
return { context, destroy };
|
|
261
264
|
};
|
|
262
265
|
export {
|
|
263
|
-
widelogger
|
|
266
|
+
widelogger,
|
|
267
|
+
widelog
|
|
264
268
|
};
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "widelogger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js"
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
13
14
|
}
|
|
14
15
|
},
|
|
15
16
|
"repository": {
|