@loglayer/mixin-wide-events 1.0.0 → 1.1.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/dist/index.cjs +96 -20
- package/dist/index.d.cts +167 -11
- package/dist/index.d.mts +167 -11
- package/dist/index.mjs +95 -18
- package/package.json +17 -18
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Theo Gravity / [Disaresta](https://disaresta.com)
|
|
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/dist/index.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
2
|
//#region ../../core/plugin/dist/index.js
|
|
4
3
|
/**
|
|
5
4
|
* List of plugin callbacks that can be called by the plugin manager.
|
|
@@ -20,17 +19,7 @@ let PluginCallbackType = /* @__PURE__ */ function(PluginCallbackType) {
|
|
|
20
19
|
PluginCallbackType["onContextCalled"] = "onContextCalled";
|
|
21
20
|
return PluginCallbackType;
|
|
22
21
|
}({});
|
|
23
|
-
|
|
24
|
-
//#endregion
|
|
25
|
-
//#region ../../core/loglayer/dist/index.js
|
|
26
|
-
const CALLBACK_LIST = [
|
|
27
|
-
PluginCallbackType.onBeforeDataOut,
|
|
28
|
-
PluginCallbackType.onMetadataCalled,
|
|
29
|
-
PluginCallbackType.onBeforeMessageOut,
|
|
30
|
-
PluginCallbackType.transformLogLevel,
|
|
31
|
-
PluginCallbackType.shouldSendToLogger,
|
|
32
|
-
PluginCallbackType.onContextCalled
|
|
33
|
-
];
|
|
22
|
+
PluginCallbackType.onBeforeDataOut, PluginCallbackType.onMetadataCalled, PluginCallbackType.onBeforeMessageOut, PluginCallbackType.transformLogLevel, PluginCallbackType.shouldSendToLogger, PluginCallbackType.onContextCalled;
|
|
34
23
|
/**
|
|
35
24
|
* The class that the mixin extends
|
|
36
25
|
*/
|
|
@@ -45,10 +34,48 @@ let LogLayerMixinAugmentType = /* @__PURE__ */ function(LogLayerMixinAugmentType
|
|
|
45
34
|
LogLayerMixinAugmentType["LogLayer"] = "LogLayer";
|
|
46
35
|
return LogLayerMixinAugmentType;
|
|
47
36
|
}({});
|
|
48
|
-
|
|
49
37
|
//#endregion
|
|
50
38
|
//#region src/mixin.ts
|
|
51
39
|
/**
|
|
40
|
+
* Log levels that default to rate=1 (error/fatal) — can be overridden via `perLevel` or callback.
|
|
41
|
+
*/
|
|
42
|
+
const EXEMPT_LEVELS = new Set(["error", "fatal"]);
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a boolean or numeric rate to a number in [0, 1].
|
|
45
|
+
* `true` becomes 1, `false` becomes 0, numbers are clamped to [0, 1].
|
|
46
|
+
* `NaN`, `Infinity`, and `-Infinity` are treated as 0 (drop all).
|
|
47
|
+
*/
|
|
48
|
+
function toRate(value) {
|
|
49
|
+
if (value === void 0) return 1;
|
|
50
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
51
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
52
|
+
return Math.max(0, Math.min(1, value));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Run rate-based sampling (default or per_level strategy).
|
|
56
|
+
* Returns true if the rate check passes, false if dropped.
|
|
57
|
+
* Returns true for error/fatal by default, unless their rate is explicitly set in `perLevel`.
|
|
58
|
+
*/
|
|
59
|
+
function runRateSampling(level, strategy, rate, perLevel) {
|
|
60
|
+
if (EXEMPT_LEVELS.has(level) && perLevel?.[level] === void 0) return true;
|
|
61
|
+
if (strategy === "per_level" && perLevel) {
|
|
62
|
+
const perRate = toRate(perLevel[level]);
|
|
63
|
+
if (perLevel[level] === void 0) {
|
|
64
|
+
const r = toRate(rate);
|
|
65
|
+
if (r === 1) return true;
|
|
66
|
+
if (r === 0) return false;
|
|
67
|
+
return Math.random() < r;
|
|
68
|
+
}
|
|
69
|
+
if (perRate === 1) return true;
|
|
70
|
+
if (perRate === 0) return false;
|
|
71
|
+
return Math.random() < perRate;
|
|
72
|
+
}
|
|
73
|
+
const r = toRate(rate);
|
|
74
|
+
if (r === 1) return true;
|
|
75
|
+
if (r === 0) return false;
|
|
76
|
+
return Math.random() < r;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
52
79
|
* Creates a LogLayer mixin that adds wide event logging functionality.
|
|
53
80
|
*
|
|
54
81
|
* Wide events are comprehensive, self-contained log entries that capture an entire
|
|
@@ -60,7 +87,6 @@ let LogLayerMixinAugmentType = /* @__PURE__ */ function(LogLayerMixinAugmentType
|
|
|
60
87
|
* wide event data across async boundaries. For Node.js, use `new AsyncLocalStorage()`
|
|
61
88
|
* from `async_hooks`. For browser environments, provide your own compatible implementation.
|
|
62
89
|
* @param options.includeContext - Whether to include withContext() data in emitted wide events (default: true)
|
|
63
|
-
|
|
64
90
|
*
|
|
65
91
|
* @returns A LogLayer mixin registration object
|
|
66
92
|
*
|
|
@@ -95,6 +121,29 @@ function createWideEventMixin(options) {
|
|
|
95
121
|
const asyncContext = options.asyncContext;
|
|
96
122
|
const includeContext = options.includeContext ?? true;
|
|
97
123
|
const wideEventField = options.wideEventField;
|
|
124
|
+
const errorsAsArray = options.errorsAsArray ?? false;
|
|
125
|
+
const errorField = options.errorField ?? (errorsAsArray ? "errors" : "error");
|
|
126
|
+
const snapshotPerLevel = options.sampling?.perLevel ? { ...options.sampling.perLevel } : void 0;
|
|
127
|
+
const samplingConfig = options.sampling ? {
|
|
128
|
+
strategy: options.sampling.strategy ?? "default",
|
|
129
|
+
rate: options.sampling.rate,
|
|
130
|
+
perLevel: snapshotPerLevel,
|
|
131
|
+
emitLevel: options.sampling.emitLevel,
|
|
132
|
+
shouldEmit: options.sampling.shouldEmit
|
|
133
|
+
} : void 0;
|
|
134
|
+
function defaultErrorSerializer(err) {
|
|
135
|
+
if (err instanceof Error) return {
|
|
136
|
+
name: err.name,
|
|
137
|
+
message: err.message,
|
|
138
|
+
stack: err.stack
|
|
139
|
+
};
|
|
140
|
+
return { message: String(err) };
|
|
141
|
+
}
|
|
142
|
+
function getErrorSerializer(self) {
|
|
143
|
+
const config = self.getConfig?.();
|
|
144
|
+
if (config?.errorSerializer) return config.errorSerializer;
|
|
145
|
+
return defaultErrorSerializer;
|
|
146
|
+
}
|
|
98
147
|
/**
|
|
99
148
|
* Context tracker plugin - stores context in async storage
|
|
100
149
|
* for inclusion in wide events (only if includeContext is true)
|
|
@@ -160,18 +209,40 @@ function createWideEventMixin(options) {
|
|
|
160
209
|
return self;
|
|
161
210
|
}
|
|
162
211
|
/**
|
|
212
|
+
* Implementation for withWideEventError
|
|
213
|
+
*/
|
|
214
|
+
function withWideEventErrorImpl(error, self) {
|
|
215
|
+
const store = asyncContext.getStore();
|
|
216
|
+
if (store) {
|
|
217
|
+
const serializedError = getErrorSerializer(self)(error);
|
|
218
|
+
if (errorsAsArray) {
|
|
219
|
+
if (!store._llWideEvents) store._llWideEvents = {};
|
|
220
|
+
if (!store._llWideEvents[errorField]) store._llWideEvents[errorField] = [];
|
|
221
|
+
store._llWideEvents[errorField].push(serializedError);
|
|
222
|
+
} else withWideEventsImpl({ [errorField]: serializedError }, self);
|
|
223
|
+
}
|
|
224
|
+
return self;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
163
227
|
* Implementation for emitWideEvent
|
|
164
228
|
*/
|
|
165
229
|
function emitWideEventImpl(config, self) {
|
|
230
|
+
const defaultLevel = samplingConfig?.emitLevel ?? "info";
|
|
231
|
+
const level = config.level ?? defaultLevel;
|
|
232
|
+
if (samplingConfig && !samplingConfig.shouldEmit && !runRateSampling(level, samplingConfig.strategy, samplingConfig.rate, samplingConfig.perLevel)) return;
|
|
166
233
|
const store = asyncContext.getStore();
|
|
167
234
|
const wideEventData = {};
|
|
168
235
|
if (includeContext && store?._llContext) Object.assign(wideEventData, store._llContext);
|
|
169
236
|
if (store?._llWideEvents) Object.assign(wideEventData, store._llWideEvents);
|
|
170
|
-
if (
|
|
171
|
-
|
|
237
|
+
if (samplingConfig?.shouldEmit) try {
|
|
238
|
+
const callbackOk = samplingConfig.shouldEmit({
|
|
239
|
+
wideData: wideEventData,
|
|
240
|
+
level
|
|
241
|
+
});
|
|
242
|
+
if (!runRateSampling(level, samplingConfig.strategy, samplingConfig.rate, samplingConfig.perLevel) || !callbackOk) return;
|
|
243
|
+
} catch {}
|
|
172
244
|
const metadataToEmit = wideEventField ? { [wideEventField]: wideEventData } : wideEventData;
|
|
173
245
|
self.withMetadata(metadataToEmit)[level](config.message);
|
|
174
|
-
return self;
|
|
175
246
|
}
|
|
176
247
|
return {
|
|
177
248
|
mixinsToAdd: [{
|
|
@@ -189,6 +260,9 @@ function createWideEventMixin(options) {
|
|
|
189
260
|
prototype.emitWideEvent = function(config) {
|
|
190
261
|
return emitWideEventImpl(config, this);
|
|
191
262
|
};
|
|
263
|
+
prototype.withWideEventError = function(error) {
|
|
264
|
+
return withWideEventErrorImpl(error, this);
|
|
265
|
+
};
|
|
192
266
|
},
|
|
193
267
|
augmentMock: (prototype) => {
|
|
194
268
|
prototype.withWideEvents = function(data) {
|
|
@@ -203,11 +277,13 @@ function createWideEventMixin(options) {
|
|
|
203
277
|
prototype.emitWideEvent = function(config) {
|
|
204
278
|
return emitWideEventImpl(config, this);
|
|
205
279
|
};
|
|
280
|
+
prototype.withWideEventError = function(error) {
|
|
281
|
+
return withWideEventErrorImpl(error, this);
|
|
282
|
+
};
|
|
206
283
|
}
|
|
207
284
|
}],
|
|
208
285
|
pluginsToAdd: [contextTrackerPlugin]
|
|
209
286
|
};
|
|
210
287
|
}
|
|
211
|
-
|
|
212
288
|
//#endregion
|
|
213
|
-
exports.createWideEventMixin = createWideEventMixin;
|
|
289
|
+
exports.createWideEventMixin = createWideEventMixin;
|
package/dist/index.d.cts
CHANGED
|
@@ -2060,6 +2060,121 @@ declare class LogBuilder implements ILogBuilder<LogBuilder, boolean> {
|
|
|
2060
2060
|
*/
|
|
2061
2061
|
//#endregion
|
|
2062
2062
|
//#region src/types.d.ts
|
|
2063
|
+
/**
|
|
2064
|
+
* Parameters passed to a custom `shouldEmit` sampling callback.
|
|
2065
|
+
* Provides the accumulated wide event data and the log level so the
|
|
2066
|
+
* callback can make an informed keep/drop decision.
|
|
2067
|
+
*/
|
|
2068
|
+
interface WideEventSamplingParams {
|
|
2069
|
+
/**
|
|
2070
|
+
* The accumulated wide event data (wide events + optional context).
|
|
2071
|
+
* Contains the merged data that would be emitted if kept.
|
|
2072
|
+
*/
|
|
2073
|
+
wideData: Record<string, any>;
|
|
2074
|
+
/**
|
|
2075
|
+
* The log level that would be used for the emission.
|
|
2076
|
+
*/
|
|
2077
|
+
level: LogLevelType;
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* Sampling strategy for wide events.
|
|
2081
|
+
*
|
|
2082
|
+
* - `"default"` — a single `rate` applies to all non-error/fatal levels.
|
|
2083
|
+
* - `"per_level"` — per-level rates keyed by LogLevelType; levels not in the
|
|
2084
|
+
* map use `rate` as a fallback.
|
|
2085
|
+
*/
|
|
2086
|
+
type WideEventSamplingStrategy = "default" | "per_level";
|
|
2087
|
+
/**
|
|
2088
|
+
* Configuration for sampling wide event emissions.
|
|
2089
|
+
*
|
|
2090
|
+
* "error" and "fatal" levels default to a 100% keep rate, but can be
|
|
2091
|
+
* overridden by setting `perLevel` rates or via `shouldEmit`.
|
|
2092
|
+
*/
|
|
2093
|
+
interface WideEventSamplingConfig {
|
|
2094
|
+
/**
|
|
2095
|
+
* The sampling strategy.
|
|
2096
|
+
*
|
|
2097
|
+
* - `"default"` — a single `rate` applies to all non-error/fatal levels.
|
|
2098
|
+
* - `"per_level"` — per-level rates from the `perLevel` map; levels not in
|
|
2099
|
+
* the map use `rate` as a fallback.
|
|
2100
|
+
*
|
|
2101
|
+
* @default "default"
|
|
2102
|
+
*/
|
|
2103
|
+
strategy?: WideEventSamplingStrategy;
|
|
2104
|
+
/**
|
|
2105
|
+
* A rate between 0 and 1 that determines the fraction of events to keep.
|
|
2106
|
+
*
|
|
2107
|
+
* - `1` (or `true`) — keep 100% (sampling disabled)
|
|
2108
|
+
* - `0.1` — ~10% of events kept
|
|
2109
|
+
* - `0` (or `false`) — keep 0% (all dropped for sample-able levels)
|
|
2110
|
+
*
|
|
2111
|
+
* With `"default"` strategy this rate applies to all non-error/fatal levels.
|
|
2112
|
+
* With `"per_level"` strategy this field is **ignored** — unmapped levels
|
|
2113
|
+
* default to a 100% keep rate.
|
|
2114
|
+
*
|
|
2115
|
+
* @default 1
|
|
2116
|
+
*/
|
|
2117
|
+
rate?: boolean | number;
|
|
2118
|
+
/**
|
|
2119
|
+
* Per-level sampling rates when strategy is `"per_level"`.
|
|
2120
|
+
* Keys are log level strings (e.g. `"trace"`, `"info"`, `"warn"`).
|
|
2121
|
+
* Levels not listed use `rate` as a fallback.
|
|
2122
|
+
*
|
|
2123
|
+
* **Important:** "error" and "fatal" default to a 100% keep rate, but can be
|
|
2124
|
+
* explicitly overridden by setting their rate in `perLevel` or using a
|
|
2125
|
+
* `shouldEmit` callback.
|
|
2126
|
+
*
|
|
2127
|
+
* The map is snapshotted at construction time; mutating it afterward has
|
|
2128
|
+
* no effect.
|
|
2129
|
+
*
|
|
2130
|
+
* @example
|
|
2131
|
+
* ```ts
|
|
2132
|
+
* {
|
|
2133
|
+
* strategy: "per_level",
|
|
2134
|
+
* perLevel: {
|
|
2135
|
+
* trace: 0.1,
|
|
2136
|
+
* debug: 0.3,
|
|
2137
|
+
* info: 0.5,
|
|
2138
|
+
* },
|
|
2139
|
+
* }
|
|
2140
|
+
* // warn, error, fatal are all 100%
|
|
2141
|
+
* ```
|
|
2142
|
+
*/
|
|
2143
|
+
perLevel?: Partial<Record<LogLevelType, boolean | number>>;
|
|
2144
|
+
/**
|
|
2145
|
+
* A custom sampling callback that receives the wide event data and log
|
|
2146
|
+
* level, allowing you to make an informed keep/drop decision.
|
|
2147
|
+
*
|
|
2148
|
+
* When provided, this callback is invoked **in addition to** the built-in
|
|
2149
|
+
* rate-based sampling. An event is only kept when **both** the built-in
|
|
2150
|
+
* check passes (if `rate`/`perLevel` are configured) **and** the callback
|
|
2151
|
+
* returns `true`. If only `shouldEmit` is set (no `rate`), the callback
|
|
2152
|
+
* acts as the sole gate.
|
|
2153
|
+
*
|
|
2154
|
+
* **Note:** "error" and "fatal" default to a 100% keep rate, but can be
|
|
2155
|
+
* overridden by returning `false` from this callback.
|
|
2156
|
+
*
|
|
2157
|
+
* @example
|
|
2158
|
+
* ```ts
|
|
2159
|
+
* {
|
|
2160
|
+
* shouldEmit: ({ wideData, level }) => {
|
|
2161
|
+
* // Only emit wide events that have a userId
|
|
2162
|
+
* return !!wideData.userId;
|
|
2163
|
+
* },
|
|
2164
|
+
* }
|
|
2165
|
+
* ```
|
|
2166
|
+
*/
|
|
2167
|
+
shouldEmit?: (params: WideEventSamplingParams) => boolean;
|
|
2168
|
+
/**
|
|
2169
|
+
* Override the default log level when no explicit `level` is passed to
|
|
2170
|
+
* `emitWideEvent()`. When set, the resolved level uses this value instead
|
|
2171
|
+
* of `"info"`. This **does** affect sampling decisions — with `per_level`
|
|
2172
|
+
* strategy, the level from `emitLevel` determines which rate bucket applies.
|
|
2173
|
+
*
|
|
2174
|
+
* @default undefined (falls back to `"info"`)
|
|
2175
|
+
*/
|
|
2176
|
+
emitLevel?: LogLevelType;
|
|
2177
|
+
}
|
|
2063
2178
|
/**
|
|
2064
2179
|
* Configuration options for creating a wide event mixin.
|
|
2065
2180
|
*/
|
|
@@ -2089,6 +2204,34 @@ interface WideEventMixinOptions {
|
|
|
2089
2204
|
* { "userId": "123", "orderId": "456", "msg": "done" }
|
|
2090
2205
|
*/
|
|
2091
2206
|
wideEventField?: string;
|
|
2207
|
+
/**
|
|
2208
|
+
* Optional: Field name to use for error data in wide events.
|
|
2209
|
+
* @default "error" (single mode) or "errors" (array mode)
|
|
2210
|
+
*/
|
|
2211
|
+
errorField?: string;
|
|
2212
|
+
/**
|
|
2213
|
+
* Optional: When true, errors are collected as an array.
|
|
2214
|
+
* Each call to withWideEventError() appends to the array.
|
|
2215
|
+
* When false, each call replaces the previous error.
|
|
2216
|
+
* @default false
|
|
2217
|
+
*/
|
|
2218
|
+
errorsAsArray?: boolean;
|
|
2219
|
+
/**
|
|
2220
|
+
* Optional: Sampling configuration for wide events.
|
|
2221
|
+
* When provided, the mixin will randomly decide whether to emit or skip wide
|
|
2222
|
+
* events based on the configured rate(s).
|
|
2223
|
+
*
|
|
2224
|
+
* "error" and "fatal" default to a 100% keep rate, but can be overridden
|
|
2225
|
+
* via `perLevel` rates or the `shouldEmit` callback.
|
|
2226
|
+
*
|
|
2227
|
+
* @example
|
|
2228
|
+
* // Keep ~10% of wide events (excluding errors/fatals)
|
|
2229
|
+
* { sampling: { strategy: "default", rate: 0.1 } }
|
|
2230
|
+
*
|
|
2231
|
+
* // Per-level: keep all trace/debug, but sample info at 5%
|
|
2232
|
+
* { sampling: { strategy: "per_level", perLevel: { info: 0.05 } } }
|
|
2233
|
+
*/
|
|
2234
|
+
sampling?: WideEventSamplingConfig;
|
|
2092
2235
|
}
|
|
2093
2236
|
/**
|
|
2094
2237
|
* Configuration for emitting a wide event.
|
|
@@ -2102,11 +2245,6 @@ interface EmitWideEventConfig {
|
|
|
2102
2245
|
* Optional: Log level (defaults to "info").
|
|
2103
2246
|
*/
|
|
2104
2247
|
level?: LogLevelType;
|
|
2105
|
-
/**
|
|
2106
|
-
* Optional: Additional metadata to include in this specific emission.
|
|
2107
|
-
* This is merged with the accumulated wide event data.
|
|
2108
|
-
*/
|
|
2109
|
-
metadata?: Record<string, any>;
|
|
2110
2248
|
}
|
|
2111
2249
|
/**
|
|
2112
2250
|
* Interface for wide event mixin functionality.
|
|
@@ -2183,22 +2321,41 @@ interface IWideEventMixin {
|
|
|
2183
2321
|
* and logs at the specified level.
|
|
2184
2322
|
*
|
|
2185
2323
|
* @param config - Configuration for the wide event emission
|
|
2186
|
-
* @returns This logger instance for chaining
|
|
2187
2324
|
*
|
|
2188
2325
|
* @example
|
|
2189
2326
|
* ```typescript
|
|
2190
2327
|
* // Emit as info log
|
|
2191
2328
|
* logger.emitWideEvent({ message: "Order processed" });
|
|
2192
2329
|
*
|
|
2193
|
-
* // Emit as error
|
|
2330
|
+
* // Emit as error
|
|
2194
2331
|
* logger.emitWideEvent({
|
|
2195
2332
|
* message: "Order failed",
|
|
2196
2333
|
* level: "error",
|
|
2197
|
-
* metadata: { reason: "payment_declined" }
|
|
2198
2334
|
* });
|
|
2199
2335
|
* ```
|
|
2200
2336
|
*/
|
|
2201
|
-
emitWideEvent(config: EmitWideEventConfig):
|
|
2337
|
+
emitWideEvent(config: EmitWideEventConfig): void;
|
|
2338
|
+
/**
|
|
2339
|
+
* Captures an error for inclusion in the wide event.
|
|
2340
|
+
* Serializes the error using the configured errorSerializer (or default).
|
|
2341
|
+
*
|
|
2342
|
+
* @param error - The error to capture
|
|
2343
|
+
* @returns This logger instance for chaining
|
|
2344
|
+
*
|
|
2345
|
+
* @example
|
|
2346
|
+
* ```typescript
|
|
2347
|
+
* try {
|
|
2348
|
+
* await doSomething();
|
|
2349
|
+
* } catch (err) {
|
|
2350
|
+
* // For single error (replaces previous)
|
|
2351
|
+
* logger.withWideEventError(err);
|
|
2352
|
+
*
|
|
2353
|
+
* // With errorsAsArray: true - errors accumulate
|
|
2354
|
+
* logger.withWideEventError(err).withWideEventError(otherErr);
|
|
2355
|
+
* }
|
|
2356
|
+
* ```
|
|
2357
|
+
*/
|
|
2358
|
+
withWideEventError(error: any): this;
|
|
2202
2359
|
}
|
|
2203
2360
|
declare module "loglayer" {
|
|
2204
2361
|
interface LogLayer extends IWideEventMixin {}
|
|
@@ -2224,7 +2381,6 @@ declare module "@loglayer/shared" {
|
|
|
2224
2381
|
* wide event data across async boundaries. For Node.js, use `new AsyncLocalStorage()`
|
|
2225
2382
|
* from `async_hooks`. For browser environments, provide your own compatible implementation.
|
|
2226
2383
|
* @param options.includeContext - Whether to include withContext() data in emitted wide events (default: true)
|
|
2227
|
-
|
|
2228
2384
|
*
|
|
2229
2385
|
* @returns A LogLayer mixin registration object
|
|
2230
2386
|
*
|
|
@@ -2257,4 +2413,4 @@ declare module "@loglayer/shared" {
|
|
|
2257
2413
|
*/
|
|
2258
2414
|
declare function createWideEventMixin(options: WideEventMixinOptions): LogLayerMixinRegistration;
|
|
2259
2415
|
//#endregion
|
|
2260
|
-
export { type EmitWideEventConfig, type IWideEventMixin, type WideEventMixinOptions, createWideEventMixin };
|
|
2416
|
+
export { type EmitWideEventConfig, type IWideEventMixin, type WideEventMixinOptions, type WideEventSamplingConfig, type WideEventSamplingParams, type WideEventSamplingStrategy, createWideEventMixin };
|
package/dist/index.d.mts
CHANGED
|
@@ -2060,6 +2060,121 @@ declare class LogBuilder implements ILogBuilder<LogBuilder, boolean> {
|
|
|
2060
2060
|
*/
|
|
2061
2061
|
//#endregion
|
|
2062
2062
|
//#region src/types.d.ts
|
|
2063
|
+
/**
|
|
2064
|
+
* Parameters passed to a custom `shouldEmit` sampling callback.
|
|
2065
|
+
* Provides the accumulated wide event data and the log level so the
|
|
2066
|
+
* callback can make an informed keep/drop decision.
|
|
2067
|
+
*/
|
|
2068
|
+
interface WideEventSamplingParams {
|
|
2069
|
+
/**
|
|
2070
|
+
* The accumulated wide event data (wide events + optional context).
|
|
2071
|
+
* Contains the merged data that would be emitted if kept.
|
|
2072
|
+
*/
|
|
2073
|
+
wideData: Record<string, any>;
|
|
2074
|
+
/**
|
|
2075
|
+
* The log level that would be used for the emission.
|
|
2076
|
+
*/
|
|
2077
|
+
level: LogLevelType;
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* Sampling strategy for wide events.
|
|
2081
|
+
*
|
|
2082
|
+
* - `"default"` — a single `rate` applies to all non-error/fatal levels.
|
|
2083
|
+
* - `"per_level"` — per-level rates keyed by LogLevelType; levels not in the
|
|
2084
|
+
* map use `rate` as a fallback.
|
|
2085
|
+
*/
|
|
2086
|
+
type WideEventSamplingStrategy = "default" | "per_level";
|
|
2087
|
+
/**
|
|
2088
|
+
* Configuration for sampling wide event emissions.
|
|
2089
|
+
*
|
|
2090
|
+
* "error" and "fatal" levels default to a 100% keep rate, but can be
|
|
2091
|
+
* overridden by setting `perLevel` rates or via `shouldEmit`.
|
|
2092
|
+
*/
|
|
2093
|
+
interface WideEventSamplingConfig {
|
|
2094
|
+
/**
|
|
2095
|
+
* The sampling strategy.
|
|
2096
|
+
*
|
|
2097
|
+
* - `"default"` — a single `rate` applies to all non-error/fatal levels.
|
|
2098
|
+
* - `"per_level"` — per-level rates from the `perLevel` map; levels not in
|
|
2099
|
+
* the map use `rate` as a fallback.
|
|
2100
|
+
*
|
|
2101
|
+
* @default "default"
|
|
2102
|
+
*/
|
|
2103
|
+
strategy?: WideEventSamplingStrategy;
|
|
2104
|
+
/**
|
|
2105
|
+
* A rate between 0 and 1 that determines the fraction of events to keep.
|
|
2106
|
+
*
|
|
2107
|
+
* - `1` (or `true`) — keep 100% (sampling disabled)
|
|
2108
|
+
* - `0.1` — ~10% of events kept
|
|
2109
|
+
* - `0` (or `false`) — keep 0% (all dropped for sample-able levels)
|
|
2110
|
+
*
|
|
2111
|
+
* With `"default"` strategy this rate applies to all non-error/fatal levels.
|
|
2112
|
+
* With `"per_level"` strategy this field is **ignored** — unmapped levels
|
|
2113
|
+
* default to a 100% keep rate.
|
|
2114
|
+
*
|
|
2115
|
+
* @default 1
|
|
2116
|
+
*/
|
|
2117
|
+
rate?: boolean | number;
|
|
2118
|
+
/**
|
|
2119
|
+
* Per-level sampling rates when strategy is `"per_level"`.
|
|
2120
|
+
* Keys are log level strings (e.g. `"trace"`, `"info"`, `"warn"`).
|
|
2121
|
+
* Levels not listed use `rate` as a fallback.
|
|
2122
|
+
*
|
|
2123
|
+
* **Important:** "error" and "fatal" default to a 100% keep rate, but can be
|
|
2124
|
+
* explicitly overridden by setting their rate in `perLevel` or using a
|
|
2125
|
+
* `shouldEmit` callback.
|
|
2126
|
+
*
|
|
2127
|
+
* The map is snapshotted at construction time; mutating it afterward has
|
|
2128
|
+
* no effect.
|
|
2129
|
+
*
|
|
2130
|
+
* @example
|
|
2131
|
+
* ```ts
|
|
2132
|
+
* {
|
|
2133
|
+
* strategy: "per_level",
|
|
2134
|
+
* perLevel: {
|
|
2135
|
+
* trace: 0.1,
|
|
2136
|
+
* debug: 0.3,
|
|
2137
|
+
* info: 0.5,
|
|
2138
|
+
* },
|
|
2139
|
+
* }
|
|
2140
|
+
* // warn, error, fatal are all 100%
|
|
2141
|
+
* ```
|
|
2142
|
+
*/
|
|
2143
|
+
perLevel?: Partial<Record<LogLevelType, boolean | number>>;
|
|
2144
|
+
/**
|
|
2145
|
+
* A custom sampling callback that receives the wide event data and log
|
|
2146
|
+
* level, allowing you to make an informed keep/drop decision.
|
|
2147
|
+
*
|
|
2148
|
+
* When provided, this callback is invoked **in addition to** the built-in
|
|
2149
|
+
* rate-based sampling. An event is only kept when **both** the built-in
|
|
2150
|
+
* check passes (if `rate`/`perLevel` are configured) **and** the callback
|
|
2151
|
+
* returns `true`. If only `shouldEmit` is set (no `rate`), the callback
|
|
2152
|
+
* acts as the sole gate.
|
|
2153
|
+
*
|
|
2154
|
+
* **Note:** "error" and "fatal" default to a 100% keep rate, but can be
|
|
2155
|
+
* overridden by returning `false` from this callback.
|
|
2156
|
+
*
|
|
2157
|
+
* @example
|
|
2158
|
+
* ```ts
|
|
2159
|
+
* {
|
|
2160
|
+
* shouldEmit: ({ wideData, level }) => {
|
|
2161
|
+
* // Only emit wide events that have a userId
|
|
2162
|
+
* return !!wideData.userId;
|
|
2163
|
+
* },
|
|
2164
|
+
* }
|
|
2165
|
+
* ```
|
|
2166
|
+
*/
|
|
2167
|
+
shouldEmit?: (params: WideEventSamplingParams) => boolean;
|
|
2168
|
+
/**
|
|
2169
|
+
* Override the default log level when no explicit `level` is passed to
|
|
2170
|
+
* `emitWideEvent()`. When set, the resolved level uses this value instead
|
|
2171
|
+
* of `"info"`. This **does** affect sampling decisions — with `per_level`
|
|
2172
|
+
* strategy, the level from `emitLevel` determines which rate bucket applies.
|
|
2173
|
+
*
|
|
2174
|
+
* @default undefined (falls back to `"info"`)
|
|
2175
|
+
*/
|
|
2176
|
+
emitLevel?: LogLevelType;
|
|
2177
|
+
}
|
|
2063
2178
|
/**
|
|
2064
2179
|
* Configuration options for creating a wide event mixin.
|
|
2065
2180
|
*/
|
|
@@ -2089,6 +2204,34 @@ interface WideEventMixinOptions {
|
|
|
2089
2204
|
* { "userId": "123", "orderId": "456", "msg": "done" }
|
|
2090
2205
|
*/
|
|
2091
2206
|
wideEventField?: string;
|
|
2207
|
+
/**
|
|
2208
|
+
* Optional: Field name to use for error data in wide events.
|
|
2209
|
+
* @default "error" (single mode) or "errors" (array mode)
|
|
2210
|
+
*/
|
|
2211
|
+
errorField?: string;
|
|
2212
|
+
/**
|
|
2213
|
+
* Optional: When true, errors are collected as an array.
|
|
2214
|
+
* Each call to withWideEventError() appends to the array.
|
|
2215
|
+
* When false, each call replaces the previous error.
|
|
2216
|
+
* @default false
|
|
2217
|
+
*/
|
|
2218
|
+
errorsAsArray?: boolean;
|
|
2219
|
+
/**
|
|
2220
|
+
* Optional: Sampling configuration for wide events.
|
|
2221
|
+
* When provided, the mixin will randomly decide whether to emit or skip wide
|
|
2222
|
+
* events based on the configured rate(s).
|
|
2223
|
+
*
|
|
2224
|
+
* "error" and "fatal" default to a 100% keep rate, but can be overridden
|
|
2225
|
+
* via `perLevel` rates or the `shouldEmit` callback.
|
|
2226
|
+
*
|
|
2227
|
+
* @example
|
|
2228
|
+
* // Keep ~10% of wide events (excluding errors/fatals)
|
|
2229
|
+
* { sampling: { strategy: "default", rate: 0.1 } }
|
|
2230
|
+
*
|
|
2231
|
+
* // Per-level: keep all trace/debug, but sample info at 5%
|
|
2232
|
+
* { sampling: { strategy: "per_level", perLevel: { info: 0.05 } } }
|
|
2233
|
+
*/
|
|
2234
|
+
sampling?: WideEventSamplingConfig;
|
|
2092
2235
|
}
|
|
2093
2236
|
/**
|
|
2094
2237
|
* Configuration for emitting a wide event.
|
|
@@ -2102,11 +2245,6 @@ interface EmitWideEventConfig {
|
|
|
2102
2245
|
* Optional: Log level (defaults to "info").
|
|
2103
2246
|
*/
|
|
2104
2247
|
level?: LogLevelType;
|
|
2105
|
-
/**
|
|
2106
|
-
* Optional: Additional metadata to include in this specific emission.
|
|
2107
|
-
* This is merged with the accumulated wide event data.
|
|
2108
|
-
*/
|
|
2109
|
-
metadata?: Record<string, any>;
|
|
2110
2248
|
}
|
|
2111
2249
|
/**
|
|
2112
2250
|
* Interface for wide event mixin functionality.
|
|
@@ -2183,22 +2321,41 @@ interface IWideEventMixin {
|
|
|
2183
2321
|
* and logs at the specified level.
|
|
2184
2322
|
*
|
|
2185
2323
|
* @param config - Configuration for the wide event emission
|
|
2186
|
-
* @returns This logger instance for chaining
|
|
2187
2324
|
*
|
|
2188
2325
|
* @example
|
|
2189
2326
|
* ```typescript
|
|
2190
2327
|
* // Emit as info log
|
|
2191
2328
|
* logger.emitWideEvent({ message: "Order processed" });
|
|
2192
2329
|
*
|
|
2193
|
-
* // Emit as error
|
|
2330
|
+
* // Emit as error
|
|
2194
2331
|
* logger.emitWideEvent({
|
|
2195
2332
|
* message: "Order failed",
|
|
2196
2333
|
* level: "error",
|
|
2197
|
-
* metadata: { reason: "payment_declined" }
|
|
2198
2334
|
* });
|
|
2199
2335
|
* ```
|
|
2200
2336
|
*/
|
|
2201
|
-
emitWideEvent(config: EmitWideEventConfig):
|
|
2337
|
+
emitWideEvent(config: EmitWideEventConfig): void;
|
|
2338
|
+
/**
|
|
2339
|
+
* Captures an error for inclusion in the wide event.
|
|
2340
|
+
* Serializes the error using the configured errorSerializer (or default).
|
|
2341
|
+
*
|
|
2342
|
+
* @param error - The error to capture
|
|
2343
|
+
* @returns This logger instance for chaining
|
|
2344
|
+
*
|
|
2345
|
+
* @example
|
|
2346
|
+
* ```typescript
|
|
2347
|
+
* try {
|
|
2348
|
+
* await doSomething();
|
|
2349
|
+
* } catch (err) {
|
|
2350
|
+
* // For single error (replaces previous)
|
|
2351
|
+
* logger.withWideEventError(err);
|
|
2352
|
+
*
|
|
2353
|
+
* // With errorsAsArray: true - errors accumulate
|
|
2354
|
+
* logger.withWideEventError(err).withWideEventError(otherErr);
|
|
2355
|
+
* }
|
|
2356
|
+
* ```
|
|
2357
|
+
*/
|
|
2358
|
+
withWideEventError(error: any): this;
|
|
2202
2359
|
}
|
|
2203
2360
|
declare module "loglayer" {
|
|
2204
2361
|
interface LogLayer extends IWideEventMixin {}
|
|
@@ -2224,7 +2381,6 @@ declare module "@loglayer/shared" {
|
|
|
2224
2381
|
* wide event data across async boundaries. For Node.js, use `new AsyncLocalStorage()`
|
|
2225
2382
|
* from `async_hooks`. For browser environments, provide your own compatible implementation.
|
|
2226
2383
|
* @param options.includeContext - Whether to include withContext() data in emitted wide events (default: true)
|
|
2227
|
-
|
|
2228
2384
|
*
|
|
2229
2385
|
* @returns A LogLayer mixin registration object
|
|
2230
2386
|
*
|
|
@@ -2257,4 +2413,4 @@ declare module "@loglayer/shared" {
|
|
|
2257
2413
|
*/
|
|
2258
2414
|
declare function createWideEventMixin(options: WideEventMixinOptions): LogLayerMixinRegistration;
|
|
2259
2415
|
//#endregion
|
|
2260
|
-
export { type EmitWideEventConfig, type IWideEventMixin, type WideEventMixinOptions, createWideEventMixin };
|
|
2416
|
+
export { type EmitWideEventConfig, type IWideEventMixin, type WideEventMixinOptions, type WideEventSamplingConfig, type WideEventSamplingParams, type WideEventSamplingStrategy, createWideEventMixin };
|
package/dist/index.mjs
CHANGED
|
@@ -18,17 +18,7 @@ let PluginCallbackType = /* @__PURE__ */ function(PluginCallbackType) {
|
|
|
18
18
|
PluginCallbackType["onContextCalled"] = "onContextCalled";
|
|
19
19
|
return PluginCallbackType;
|
|
20
20
|
}({});
|
|
21
|
-
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region ../../core/loglayer/dist/index.js
|
|
24
|
-
const CALLBACK_LIST = [
|
|
25
|
-
PluginCallbackType.onBeforeDataOut,
|
|
26
|
-
PluginCallbackType.onMetadataCalled,
|
|
27
|
-
PluginCallbackType.onBeforeMessageOut,
|
|
28
|
-
PluginCallbackType.transformLogLevel,
|
|
29
|
-
PluginCallbackType.shouldSendToLogger,
|
|
30
|
-
PluginCallbackType.onContextCalled
|
|
31
|
-
];
|
|
21
|
+
PluginCallbackType.onBeforeDataOut, PluginCallbackType.onMetadataCalled, PluginCallbackType.onBeforeMessageOut, PluginCallbackType.transformLogLevel, PluginCallbackType.shouldSendToLogger, PluginCallbackType.onContextCalled;
|
|
32
22
|
/**
|
|
33
23
|
* The class that the mixin extends
|
|
34
24
|
*/
|
|
@@ -43,10 +33,48 @@ let LogLayerMixinAugmentType = /* @__PURE__ */ function(LogLayerMixinAugmentType
|
|
|
43
33
|
LogLayerMixinAugmentType["LogLayer"] = "LogLayer";
|
|
44
34
|
return LogLayerMixinAugmentType;
|
|
45
35
|
}({});
|
|
46
|
-
|
|
47
36
|
//#endregion
|
|
48
37
|
//#region src/mixin.ts
|
|
49
38
|
/**
|
|
39
|
+
* Log levels that default to rate=1 (error/fatal) — can be overridden via `perLevel` or callback.
|
|
40
|
+
*/
|
|
41
|
+
const EXEMPT_LEVELS = new Set(["error", "fatal"]);
|
|
42
|
+
/**
|
|
43
|
+
* Normalize a boolean or numeric rate to a number in [0, 1].
|
|
44
|
+
* `true` becomes 1, `false` becomes 0, numbers are clamped to [0, 1].
|
|
45
|
+
* `NaN`, `Infinity`, and `-Infinity` are treated as 0 (drop all).
|
|
46
|
+
*/
|
|
47
|
+
function toRate(value) {
|
|
48
|
+
if (value === void 0) return 1;
|
|
49
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
50
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
51
|
+
return Math.max(0, Math.min(1, value));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Run rate-based sampling (default or per_level strategy).
|
|
55
|
+
* Returns true if the rate check passes, false if dropped.
|
|
56
|
+
* Returns true for error/fatal by default, unless their rate is explicitly set in `perLevel`.
|
|
57
|
+
*/
|
|
58
|
+
function runRateSampling(level, strategy, rate, perLevel) {
|
|
59
|
+
if (EXEMPT_LEVELS.has(level) && perLevel?.[level] === void 0) return true;
|
|
60
|
+
if (strategy === "per_level" && perLevel) {
|
|
61
|
+
const perRate = toRate(perLevel[level]);
|
|
62
|
+
if (perLevel[level] === void 0) {
|
|
63
|
+
const r = toRate(rate);
|
|
64
|
+
if (r === 1) return true;
|
|
65
|
+
if (r === 0) return false;
|
|
66
|
+
return Math.random() < r;
|
|
67
|
+
}
|
|
68
|
+
if (perRate === 1) return true;
|
|
69
|
+
if (perRate === 0) return false;
|
|
70
|
+
return Math.random() < perRate;
|
|
71
|
+
}
|
|
72
|
+
const r = toRate(rate);
|
|
73
|
+
if (r === 1) return true;
|
|
74
|
+
if (r === 0) return false;
|
|
75
|
+
return Math.random() < r;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
50
78
|
* Creates a LogLayer mixin that adds wide event logging functionality.
|
|
51
79
|
*
|
|
52
80
|
* Wide events are comprehensive, self-contained log entries that capture an entire
|
|
@@ -58,7 +86,6 @@ let LogLayerMixinAugmentType = /* @__PURE__ */ function(LogLayerMixinAugmentType
|
|
|
58
86
|
* wide event data across async boundaries. For Node.js, use `new AsyncLocalStorage()`
|
|
59
87
|
* from `async_hooks`. For browser environments, provide your own compatible implementation.
|
|
60
88
|
* @param options.includeContext - Whether to include withContext() data in emitted wide events (default: true)
|
|
61
|
-
|
|
62
89
|
*
|
|
63
90
|
* @returns A LogLayer mixin registration object
|
|
64
91
|
*
|
|
@@ -93,6 +120,29 @@ function createWideEventMixin(options) {
|
|
|
93
120
|
const asyncContext = options.asyncContext;
|
|
94
121
|
const includeContext = options.includeContext ?? true;
|
|
95
122
|
const wideEventField = options.wideEventField;
|
|
123
|
+
const errorsAsArray = options.errorsAsArray ?? false;
|
|
124
|
+
const errorField = options.errorField ?? (errorsAsArray ? "errors" : "error");
|
|
125
|
+
const snapshotPerLevel = options.sampling?.perLevel ? { ...options.sampling.perLevel } : void 0;
|
|
126
|
+
const samplingConfig = options.sampling ? {
|
|
127
|
+
strategy: options.sampling.strategy ?? "default",
|
|
128
|
+
rate: options.sampling.rate,
|
|
129
|
+
perLevel: snapshotPerLevel,
|
|
130
|
+
emitLevel: options.sampling.emitLevel,
|
|
131
|
+
shouldEmit: options.sampling.shouldEmit
|
|
132
|
+
} : void 0;
|
|
133
|
+
function defaultErrorSerializer(err) {
|
|
134
|
+
if (err instanceof Error) return {
|
|
135
|
+
name: err.name,
|
|
136
|
+
message: err.message,
|
|
137
|
+
stack: err.stack
|
|
138
|
+
};
|
|
139
|
+
return { message: String(err) };
|
|
140
|
+
}
|
|
141
|
+
function getErrorSerializer(self) {
|
|
142
|
+
const config = self.getConfig?.();
|
|
143
|
+
if (config?.errorSerializer) return config.errorSerializer;
|
|
144
|
+
return defaultErrorSerializer;
|
|
145
|
+
}
|
|
96
146
|
/**
|
|
97
147
|
* Context tracker plugin - stores context in async storage
|
|
98
148
|
* for inclusion in wide events (only if includeContext is true)
|
|
@@ -158,18 +208,40 @@ function createWideEventMixin(options) {
|
|
|
158
208
|
return self;
|
|
159
209
|
}
|
|
160
210
|
/**
|
|
211
|
+
* Implementation for withWideEventError
|
|
212
|
+
*/
|
|
213
|
+
function withWideEventErrorImpl(error, self) {
|
|
214
|
+
const store = asyncContext.getStore();
|
|
215
|
+
if (store) {
|
|
216
|
+
const serializedError = getErrorSerializer(self)(error);
|
|
217
|
+
if (errorsAsArray) {
|
|
218
|
+
if (!store._llWideEvents) store._llWideEvents = {};
|
|
219
|
+
if (!store._llWideEvents[errorField]) store._llWideEvents[errorField] = [];
|
|
220
|
+
store._llWideEvents[errorField].push(serializedError);
|
|
221
|
+
} else withWideEventsImpl({ [errorField]: serializedError }, self);
|
|
222
|
+
}
|
|
223
|
+
return self;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
161
226
|
* Implementation for emitWideEvent
|
|
162
227
|
*/
|
|
163
228
|
function emitWideEventImpl(config, self) {
|
|
229
|
+
const defaultLevel = samplingConfig?.emitLevel ?? "info";
|
|
230
|
+
const level = config.level ?? defaultLevel;
|
|
231
|
+
if (samplingConfig && !samplingConfig.shouldEmit && !runRateSampling(level, samplingConfig.strategy, samplingConfig.rate, samplingConfig.perLevel)) return;
|
|
164
232
|
const store = asyncContext.getStore();
|
|
165
233
|
const wideEventData = {};
|
|
166
234
|
if (includeContext && store?._llContext) Object.assign(wideEventData, store._llContext);
|
|
167
235
|
if (store?._llWideEvents) Object.assign(wideEventData, store._llWideEvents);
|
|
168
|
-
if (
|
|
169
|
-
|
|
236
|
+
if (samplingConfig?.shouldEmit) try {
|
|
237
|
+
const callbackOk = samplingConfig.shouldEmit({
|
|
238
|
+
wideData: wideEventData,
|
|
239
|
+
level
|
|
240
|
+
});
|
|
241
|
+
if (!runRateSampling(level, samplingConfig.strategy, samplingConfig.rate, samplingConfig.perLevel) || !callbackOk) return;
|
|
242
|
+
} catch {}
|
|
170
243
|
const metadataToEmit = wideEventField ? { [wideEventField]: wideEventData } : wideEventData;
|
|
171
244
|
self.withMetadata(metadataToEmit)[level](config.message);
|
|
172
|
-
return self;
|
|
173
245
|
}
|
|
174
246
|
return {
|
|
175
247
|
mixinsToAdd: [{
|
|
@@ -187,6 +259,9 @@ function createWideEventMixin(options) {
|
|
|
187
259
|
prototype.emitWideEvent = function(config) {
|
|
188
260
|
return emitWideEventImpl(config, this);
|
|
189
261
|
};
|
|
262
|
+
prototype.withWideEventError = function(error) {
|
|
263
|
+
return withWideEventErrorImpl(error, this);
|
|
264
|
+
};
|
|
190
265
|
},
|
|
191
266
|
augmentMock: (prototype) => {
|
|
192
267
|
prototype.withWideEvents = function(data) {
|
|
@@ -201,11 +276,13 @@ function createWideEventMixin(options) {
|
|
|
201
276
|
prototype.emitWideEvent = function(config) {
|
|
202
277
|
return emitWideEventImpl(config, this);
|
|
203
278
|
};
|
|
279
|
+
prototype.withWideEventError = function(error) {
|
|
280
|
+
return withWideEventErrorImpl(error, this);
|
|
281
|
+
};
|
|
204
282
|
}
|
|
205
283
|
}],
|
|
206
284
|
pluginsToAdd: [contextTrackerPlugin]
|
|
207
285
|
};
|
|
208
286
|
}
|
|
209
|
-
|
|
210
287
|
//#endregion
|
|
211
|
-
export { createWideEventMixin };
|
|
288
|
+
export { createWideEventMixin };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loglayer/mixin-wide-events",
|
|
3
3
|
"description": "Adds wide event logging functionality to LogLayer for comprehensive, self-contained log entries.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -32,22 +32,14 @@
|
|
|
32
32
|
"wide-events",
|
|
33
33
|
"canonical-log-lines"
|
|
34
34
|
],
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "tsdown src/index.ts",
|
|
37
|
-
"test": "vitest --run",
|
|
38
|
-
"clean": "rm -rf .turbo node_modules dist",
|
|
39
|
-
"lint": "biome check --no-errors-on-unmatched --write --unsafe src",
|
|
40
|
-
"lint:staged": "biome check --no-errors-on-unmatched --write --unsafe --staged src",
|
|
41
|
-
"verify-types": "tsc --noEmit"
|
|
42
|
-
},
|
|
43
35
|
"devDependencies": {
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
36
|
+
"@types/node": "25.9.1",
|
|
37
|
+
"tsdown": "0.22.0",
|
|
38
|
+
"typescript": "6.0.3",
|
|
39
|
+
"vitest": "4.1.7",
|
|
40
|
+
"@loglayer/shared": "4.2.0",
|
|
41
|
+
"loglayer": "9.2.0",
|
|
42
|
+
"@internal/tsconfig": "2.1.0"
|
|
51
43
|
},
|
|
52
44
|
"peerDependencies": {},
|
|
53
45
|
"bugs": "https://github.com/loglayer/loglayer/issues",
|
|
@@ -55,5 +47,12 @@
|
|
|
55
47
|
"dist"
|
|
56
48
|
],
|
|
57
49
|
"homepage": "https://loglayer.dev",
|
|
58
|
-
"
|
|
59
|
-
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsdown src/index.ts",
|
|
52
|
+
"test": "vitest --run",
|
|
53
|
+
"clean": "rm -rf .turbo node_modules dist",
|
|
54
|
+
"lint": "biome check --no-errors-on-unmatched --write --unsafe src",
|
|
55
|
+
"lint:staged": "biome check --no-errors-on-unmatched --write --unsafe --staged src",
|
|
56
|
+
"verify-types": "tsc --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|