evlog 2.3.0 → 2.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.
- package/README.md +105 -25
- package/dist/elysia/index.d.mts +7 -24
- package/dist/elysia/index.d.mts.map +1 -1
- package/dist/elysia/index.mjs +14 -4
- package/dist/elysia/index.mjs.map +1 -1
- package/dist/express/index.d.mts +4 -39
- package/dist/express/index.d.mts.map +1 -1
- package/dist/express/index.mjs +2 -21
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +37 -0
- package/dist/fastify/index.d.mts.map +1 -0
- package/dist/fastify/index.mjs +73 -0
- package/dist/fastify/index.mjs.map +1 -0
- package/dist/headers-CXOd5EyZ.mjs.map +1 -1
- package/dist/hono/index.d.mts +3 -24
- package/dist/hono/index.d.mts.map +1 -1
- package/dist/hono/index.mjs.map +1 -1
- package/dist/middleware-BoVCgsfQ.d.mts +36 -0
- package/dist/middleware-BoVCgsfQ.d.mts.map +1 -0
- package/dist/nestjs/index.d.mts +83 -0
- package/dist/nestjs/index.d.mts.map +1 -0
- package/dist/nestjs/index.mjs +109 -0
- package/dist/nestjs/index.mjs.map +1 -0
- package/dist/next/index.d.mts +3 -34
- package/dist/next/index.d.mts.map +1 -1
- package/dist/nitro/module.d.mts +1 -1
- package/dist/nitro/v3/module.d.mts +1 -1
- package/dist/{nitro-Nxg6qcXd.d.mts → nitro-BRisWfGy.d.mts} +1 -1
- package/dist/{nitro-Nxg6qcXd.d.mts.map → nitro-BRisWfGy.d.mts.map} +1 -1
- package/dist/nuxt/module.mjs +1 -1
- package/dist/storage-Dd3PHiMh.mjs +29 -0
- package/dist/storage-Dd3PHiMh.mjs.map +1 -0
- package/dist/sveltekit/index.d.mts +128 -0
- package/dist/sveltekit/index.d.mts.map +1 -0
- package/dist/sveltekit/index.mjs +163 -0
- package/dist/sveltekit/index.mjs.map +1 -0
- package/package.json +39 -2
package/dist/hono/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: c.req.method,\n path: c.req.path,\n requestId: c.req.header('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(c.req.raw.headers),\n ...options,\n })\n\n if (skipped) {\n await next()\n return\n }\n\n c.set('log', logger)\n\n try {\n await next()\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ,WAAW,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,YAAY;GAC9D,SAAS,mBAAmB,EAAE,IAAI,IAAI,QAAQ;GAC9C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAGF,IAAE,IAAI,OAAO,OAAO;AAEpB,MAAI;AACF,SAAM,MAAM;AACZ,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { DrainContext, EnrichContext, RouteConfig, TailSamplingContext } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/middleware.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base options shared by all framework integrations.
|
|
6
|
+
*
|
|
7
|
+
* Every framework-specific options interface (e.g. `EvlogExpressOptions`)
|
|
8
|
+
* extends this type. If a framework needs extra fields it can add them
|
|
9
|
+
* on top; otherwise the base is used as-is.
|
|
10
|
+
*/
|
|
11
|
+
interface BaseEvlogOptions {
|
|
12
|
+
/** Route patterns to include in logging (glob). If not set, all routes are logged */
|
|
13
|
+
include?: string[];
|
|
14
|
+
/** Route patterns to exclude from logging. Exclusions take precedence over inclusions */
|
|
15
|
+
exclude?: string[];
|
|
16
|
+
/** Route-specific service configuration */
|
|
17
|
+
routes?: Record<string, RouteConfig>;
|
|
18
|
+
/**
|
|
19
|
+
* Drain callback called with every emitted event.
|
|
20
|
+
* Use with drain adapters (Axiom, OTLP, Sentry, etc.) or custom endpoints.
|
|
21
|
+
*/
|
|
22
|
+
drain?: (ctx: DrainContext) => void | Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Enrich callback called after emit, before drain.
|
|
25
|
+
* Use to add derived context (geo, deployment info, user agent, etc.).
|
|
26
|
+
*/
|
|
27
|
+
enrich?: (ctx: EnrichContext) => void | Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Custom tail sampling callback.
|
|
30
|
+
* Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.
|
|
31
|
+
*/
|
|
32
|
+
keep?: (ctx: TailSamplingContext) => void | Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { BaseEvlogOptions as t };
|
|
36
|
+
//# sourceMappingURL=middleware-BoVCgsfQ.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-BoVCgsfQ.d.mts","names":[],"sources":["../src/shared/middleware.ts"],"mappings":";;;;;AAYA;;;;;UAAiB,gBAAA;EAWuB;EATtC,OAAA;EAcwC;EAZxC,OAAA;EAiB4C;EAf5C,MAAA,GAAS,MAAA,SAAe,WAAA;EAe2B;;;;EAVnD,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EALd;;;;EAUxB,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAAxC;;;;EAKA,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;AAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { RequestLogger } from "../types.mjs";
|
|
2
|
+
import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
|
|
3
|
+
import { DynamicModule, MiddlewareConsumer, NestModule } from "@nestjs/common";
|
|
4
|
+
|
|
5
|
+
//#region src/nestjs/index.d.ts
|
|
6
|
+
declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
|
|
7
|
+
type EvlogNestJSOptions = BaseEvlogOptions;
|
|
8
|
+
interface EvlogModuleAsyncOptions {
|
|
9
|
+
/** Modules to import (for dependency injection into the factory) */
|
|
10
|
+
imports?: any[];
|
|
11
|
+
/** Factory function that returns evlog options. Can be async. */
|
|
12
|
+
useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>;
|
|
13
|
+
/** Injection tokens to resolve and pass to the factory */
|
|
14
|
+
inject?: any[];
|
|
15
|
+
}
|
|
16
|
+
declare module 'http' {
|
|
17
|
+
interface IncomingMessage {
|
|
18
|
+
log?: RequestLogger;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
declare module 'express-serve-static-core' {
|
|
22
|
+
interface Request {
|
|
23
|
+
log?: RequestLogger;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* NestJS module for evlog wide event logging.
|
|
28
|
+
*
|
|
29
|
+
* Registers a global middleware that creates a request-scoped logger
|
|
30
|
+
* for every incoming request. Use `useLogger()` to access it anywhere
|
|
31
|
+
* in the call stack, or `req.log` directly in controllers.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { Module } from '@nestjs/common'
|
|
36
|
+
* import { EvlogModule } from 'evlog/nestjs'
|
|
37
|
+
* import { createAxiomDrain } from 'evlog/axiom'
|
|
38
|
+
*
|
|
39
|
+
* @Module({
|
|
40
|
+
* imports: [
|
|
41
|
+
* EvlogModule.forRoot({
|
|
42
|
+
* drain: createAxiomDrain(),
|
|
43
|
+
* exclude: ['/health'],
|
|
44
|
+
* }),
|
|
45
|
+
* ],
|
|
46
|
+
* })
|
|
47
|
+
* export class AppModule {}
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare class EvlogModule implements NestModule {
|
|
51
|
+
private static options;
|
|
52
|
+
/**
|
|
53
|
+
* Register evlog with static configuration.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* EvlogModule.forRoot({
|
|
58
|
+
* drain: createAxiomDrain(),
|
|
59
|
+
* enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },
|
|
60
|
+
* })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
static forRoot(options?: EvlogNestJSOptions): DynamicModule;
|
|
64
|
+
/**
|
|
65
|
+
* Register evlog with async configuration (e.g. from `ConfigService`).
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* EvlogModule.forRootAsync({
|
|
70
|
+
* imports: [ConfigModule],
|
|
71
|
+
* inject: [ConfigService],
|
|
72
|
+
* useFactory: (config: ConfigService) => ({
|
|
73
|
+
* drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),
|
|
74
|
+
* }),
|
|
75
|
+
* })
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule;
|
|
79
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { EvlogModule, EvlogModuleAsyncOptions, EvlogNestJSOptions, useLogger };
|
|
83
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/nestjs/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,kBAAA,GAAqB,gBAAA;AAAA,UAIhB,uBAAA;EANhB;EAQC,OAAA;EAVwB;EAYxB,UAAA,MAAgB,IAAA,YAAgB,kBAAA,GAAqB,OAAA,CAAQ,kBAAA;EAZrC;EAcxB,MAAA;AAAA;AAAA;EAAA,UAIU,eAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAAA;EAAA,UAKE,OAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAjBV;;;;;;;;;;;;;;;;;AAOC;;;;;;;AAPD,cA0Ea,WAAA,YAAuB,UAAA;EAAA,eAEnB,OAAA;EAjEM;AAAA;;;;;;;;;;EAAA,OA8Ed,OAAA,CAAQ,OAAA,GAAS,kBAAA,GAA0B,aAAA;EAf3B;;;;;;;;;;;;;;EAAA,OAqChB,YAAA,CAAa,YAAA,EAAc,uBAAA,GAA0B,aAAA;EAkB5D,SAAA,CAAU,QAAA,EAAU,kBAAA;AAAA"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { n as extractSafeNodeHeaders, r as createMiddlewareLogger } from "../headers-CXOd5EyZ.mjs";
|
|
2
|
+
import { t as createLoggerStorage } from "../storage-Dd3PHiMh.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/nestjs/index.ts
|
|
5
|
+
const { storage, useLogger } = createLoggerStorage("middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.");
|
|
6
|
+
function createEvlogMiddleware(getOptions) {
|
|
7
|
+
return (req, res, next) => {
|
|
8
|
+
const options = getOptions();
|
|
9
|
+
const headers = extractSafeNodeHeaders(req.headers);
|
|
10
|
+
const url = new URL(req.url || "/", "http://localhost");
|
|
11
|
+
const { logger, finish, skipped } = createMiddlewareLogger({
|
|
12
|
+
method: req.method || "GET",
|
|
13
|
+
path: url.pathname,
|
|
14
|
+
requestId: headers["x-request-id"] || crypto.randomUUID(),
|
|
15
|
+
headers,
|
|
16
|
+
...options
|
|
17
|
+
});
|
|
18
|
+
if (skipped) {
|
|
19
|
+
next();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
req.log = logger;
|
|
23
|
+
res.on("finish", () => {
|
|
24
|
+
finish({ status: res.statusCode }).catch(() => {});
|
|
25
|
+
});
|
|
26
|
+
storage.run(logger, () => next());
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* NestJS module for evlog wide event logging.
|
|
31
|
+
*
|
|
32
|
+
* Registers a global middleware that creates a request-scoped logger
|
|
33
|
+
* for every incoming request. Use `useLogger()` to access it anywhere
|
|
34
|
+
* in the call stack, or `req.log` directly in controllers.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { Module } from '@nestjs/common'
|
|
39
|
+
* import { EvlogModule } from 'evlog/nestjs'
|
|
40
|
+
* import { createAxiomDrain } from 'evlog/axiom'
|
|
41
|
+
*
|
|
42
|
+
* @Module({
|
|
43
|
+
* imports: [
|
|
44
|
+
* EvlogModule.forRoot({
|
|
45
|
+
* drain: createAxiomDrain(),
|
|
46
|
+
* exclude: ['/health'],
|
|
47
|
+
* }),
|
|
48
|
+
* ],
|
|
49
|
+
* })
|
|
50
|
+
* export class AppModule {}
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
var EvlogModule = class EvlogModule {
|
|
54
|
+
static options = {};
|
|
55
|
+
/**
|
|
56
|
+
* Register evlog with static configuration.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* EvlogModule.forRoot({
|
|
61
|
+
* drain: createAxiomDrain(),
|
|
62
|
+
* enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },
|
|
63
|
+
* })
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
static forRoot(options = {}) {
|
|
67
|
+
EvlogModule.options = options;
|
|
68
|
+
return {
|
|
69
|
+
module: EvlogModule,
|
|
70
|
+
global: true
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Register evlog with async configuration (e.g. from `ConfigService`).
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* EvlogModule.forRootAsync({
|
|
79
|
+
* imports: [ConfigModule],
|
|
80
|
+
* inject: [ConfigService],
|
|
81
|
+
* useFactory: (config: ConfigService) => ({
|
|
82
|
+
* drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),
|
|
83
|
+
* }),
|
|
84
|
+
* })
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
static forRootAsync(asyncOptions) {
|
|
88
|
+
return {
|
|
89
|
+
module: EvlogModule,
|
|
90
|
+
imports: asyncOptions.imports || [],
|
|
91
|
+
providers: [{
|
|
92
|
+
provide: "EVLOG_OPTIONS",
|
|
93
|
+
useFactory: async (...args) => {
|
|
94
|
+
EvlogModule.options = await asyncOptions.useFactory(...args);
|
|
95
|
+
return EvlogModule.options;
|
|
96
|
+
},
|
|
97
|
+
inject: asyncOptions.inject || []
|
|
98
|
+
}],
|
|
99
|
+
global: true
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
configure(consumer) {
|
|
103
|
+
consumer.apply(createEvlogMiddleware(() => EvlogModule.options)).forRoutes("*");
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { EvlogModule, useLogger };
|
|
109
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.',\n)\n\nexport type EvlogNestJSOptions = BaseEvlogOptions\n\nexport { useLogger }\n\nexport interface EvlogModuleAsyncOptions {\n /** Modules to import (for dependency injection into the factory) */\n imports?: any[]\n /** Factory function that returns evlog options. Can be async. */\n useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>\n /** Injection tokens to resolve and pass to the factory */\n inject?: any[]\n}\n\ndeclare module 'http' {\n interface IncomingMessage {\n log?: RequestLogger\n }\n}\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: RequestLogger\n }\n}\n\nfunction createEvlogMiddleware(getOptions: () => EvlogNestJSOptions) {\n return (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n const options = getOptions()\n const headers = extractSafeNodeHeaders(req.headers)\n const url = new URL(req.url || '/', 'http://localhost')\n\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: req.method || 'GET',\n path: url.pathname,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n })\n\n if (skipped) {\n next()\n return\n }\n\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n\n/**\n * NestJS module for evlog wide event logging.\n *\n * Registers a global middleware that creates a request-scoped logger\n * for every incoming request. Use `useLogger()` to access it anywhere\n * in the call stack, or `req.log` directly in controllers.\n *\n * @example\n * ```ts\n * import { Module } from '@nestjs/common'\n * import { EvlogModule } from 'evlog/nestjs'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * @Module({\n * imports: [\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * exclude: ['/health'],\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\nexport class EvlogModule implements NestModule {\n\n private static options: EvlogNestJSOptions = {}\n\n /**\n * Register evlog with static configuration.\n *\n * @example\n * ```ts\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },\n * })\n * ```\n */\n static forRoot(options: EvlogNestJSOptions = {}): DynamicModule {\n EvlogModule.options = options\n return {\n module: EvlogModule,\n global: true,\n }\n }\n\n /**\n * Register evlog with async configuration (e.g. from `ConfigService`).\n *\n * @example\n * ```ts\n * EvlogModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),\n * }),\n * })\n * ```\n */\n static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule {\n return {\n module: EvlogModule,\n imports: asyncOptions.imports || [],\n providers: [\n {\n provide: 'EVLOG_OPTIONS',\n useFactory: async (...args: any[]) => {\n EvlogModule.options = await asyncOptions.useFactory(...args)\n return EvlogModule.options\n },\n inject: asyncOptions.inject || [],\n },\n ],\n global: true,\n }\n }\n\n configure(consumer: MiddlewareConsumer): void {\n consumer\n .apply(createEvlogMiddleware(() => EvlogModule.options))\n .forRoutes('*')\n }\n\n}\n"],"mappings":";;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,qFACD;AA2BD,SAAS,sBAAsB,YAAsC;AACnE,SAAQ,KAAsB,KAAqB,SAAqB;EACtE,MAAM,UAAU,YAAY;EAC5B,MAAM,UAAU,uBAAuB,IAAI,QAAQ;EACnD,MAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,mBAAmB;EAEvD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI;GACV,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BrC,IAAa,cAAb,MAAa,YAAkC;CAE7C,OAAe,UAA8B,EAAE;;;;;;;;;;;;CAa/C,OAAO,QAAQ,UAA8B,EAAE,EAAiB;AAC9D,cAAY,UAAU;AACtB,SAAO;GACL,QAAQ;GACR,QAAQ;GACT;;;;;;;;;;;;;;;;CAiBH,OAAO,aAAa,cAAsD;AACxE,SAAO;GACL,QAAQ;GACR,SAAS,aAAa,WAAW,EAAE;GACnC,WAAW,CACT;IACE,SAAS;IACT,YAAY,OAAO,GAAG,SAAgB;AACpC,iBAAY,UAAU,MAAM,aAAa,WAAW,GAAG,KAAK;AAC5D,YAAO,YAAY;;IAErB,QAAQ,aAAa,UAAU,EAAE;IAClC,CACF;GACD,QAAQ;GACT;;CAGH,UAAU,UAAoC;AAC5C,WACG,MAAM,4BAA4B,YAAY,QAAQ,CAAC,CACvD,UAAU,IAAI"}
|
package/dist/next/index.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EnvironmentContext, Log, RequestLogger, SamplingConfig } from "../types.mjs";
|
|
2
2
|
import { createError } from "../error.mjs";
|
|
3
3
|
import { log as _log } from "../logger.mjs";
|
|
4
|
+
import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
|
|
4
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
6
|
|
|
6
7
|
//#region src/next/types.d.ts
|
|
7
|
-
interface NextEvlogOptions {
|
|
8
|
+
interface NextEvlogOptions extends BaseEvlogOptions {
|
|
8
9
|
/**
|
|
9
10
|
* Service name for all logged events.
|
|
10
11
|
* @default auto-detected from SERVICE_NAME env or 'app'
|
|
@@ -28,38 +29,6 @@ interface NextEvlogOptions {
|
|
|
28
29
|
* Sampling configuration for filtering logs.
|
|
29
30
|
*/
|
|
30
31
|
sampling?: SamplingConfig;
|
|
31
|
-
/**
|
|
32
|
-
* Route patterns to include in logging.
|
|
33
|
-
* Supports glob patterns like '/api/**'.
|
|
34
|
-
* If not set, all routes are logged.
|
|
35
|
-
*/
|
|
36
|
-
include?: string[];
|
|
37
|
-
/**
|
|
38
|
-
* Route patterns to exclude from logging.
|
|
39
|
-
* Supports glob patterns like '/_next/**'.
|
|
40
|
-
* Exclusions take precedence over inclusions.
|
|
41
|
-
*/
|
|
42
|
-
exclude?: string[];
|
|
43
|
-
/**
|
|
44
|
-
* Route-specific service configuration.
|
|
45
|
-
*/
|
|
46
|
-
routes?: Record<string, RouteConfig>;
|
|
47
|
-
/**
|
|
48
|
-
* Drain callback called with every emitted event (fire-and-forget).
|
|
49
|
-
* Compatible with drain adapters and pipeline-wrapped drains.
|
|
50
|
-
*/
|
|
51
|
-
drain?: (ctx: DrainContext) => void | Promise<void>;
|
|
52
|
-
/**
|
|
53
|
-
* Enrich callback called after emit, before drain.
|
|
54
|
-
* Use this to add derived context (e.g. geo, deployment info).
|
|
55
|
-
*/
|
|
56
|
-
enrich?: (ctx: EnrichContext) => void | Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Custom tail sampling callback called before emit.
|
|
59
|
-
* Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.
|
|
60
|
-
* Equivalent to Nuxt's `evlog:emit:keep` hook.
|
|
61
|
-
*/
|
|
62
|
-
keep?: (ctx: TailSamplingContext) => void | Promise<void>;
|
|
63
32
|
/**
|
|
64
33
|
* When pretty is disabled, emit JSON strings (default) or raw objects.
|
|
65
34
|
* @default true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":";;;;;;;UAGiB,gBAAA,SAAyB,gBAAA;;;;;EAKxC,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAhBwC;;;;EAsBxC,OAAA;EANA;;;EAWA,QAAA,GAAW,cAAA;EAMX;;;AAGF;EAHE,SAAA;AAAA;AAAA,UAGe,qBAAA;EAWR;;;;EANP,OAAA;ECxBuB;;;;ED8BvB,OAAA;AAAA;;;;;;;;AA/CF;;;;;;;;;;iBCiBgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;;;KCjBlF,WAAA;EACH,OAAA;IAAW,QAAA;EAAA;EACX,OAAA;IAAW,GAAA,CAAI,IAAA;EAAA;AAAA;AAAA,KAGZ,YAAA;EACH,OAAA;IAAW,GAAA,CAAI,IAAA,UAAc,KAAA;EAAA;AAAA;;;;;;;;;;;;;;iBAoBf,eAAA,CAAgB,MAAA,GAAS,qBAAA,IACzB,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;;;AF3BpC;;;;;;;;;;;;;;;;;;;;;AAoCA;;;;;;;;AApCA,iBGuCgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWg8D,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
|
package/dist/nitro/module.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nitro-
|
|
1
|
+
{"version":3,"file":"nitro-BRisWfGy.d.mts","names":[],"sources":["../src/nitro.ts"],"mappings":";;;UAIiB,kBAAA;EAAA;;;;EAKf,OAAA;EA8BwB;;;EAzBxB,GAAA,GAAM,OAAA,CAAQ,kBAAA;EA8BW;;;;EAxBzB,MAAA;EAAA;;;;;EAOA,OAAA;EAiBA;;;;;EAVA,OAAA;;;;EAKA,MAAA,GAAS,MAAA,SAAe,WAAA;;;;EAKxB,QAAA,GAAW,cAAA;AAAA"}
|
package/dist/nuxt/module.mjs
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/storage.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.
|
|
6
|
+
*
|
|
7
|
+
* Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)
|
|
8
|
+
* calls this once at module level to get its own isolated storage + accessor pair.
|
|
9
|
+
*
|
|
10
|
+
* @param contextHint - Human-readable hint appended to the error message when
|
|
11
|
+
* `useLogger()` is called outside of a request (e.g.
|
|
12
|
+
* `"middleware context. Make sure app.use(evlog()) is registered before your routes."`).
|
|
13
|
+
*/
|
|
14
|
+
function createLoggerStorage(contextHint) {
|
|
15
|
+
const storage = new AsyncLocalStorage();
|
|
16
|
+
function useLogger() {
|
|
17
|
+
const logger = storage.getStore();
|
|
18
|
+
if (!logger) throw new Error(`[evlog] useLogger() was called outside of an evlog ${contextHint}`);
|
|
19
|
+
return logger;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
storage,
|
|
23
|
+
useLogger
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { createLoggerStorage as t };
|
|
29
|
+
//# sourceMappingURL=storage-Dd3PHiMh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-Dd3PHiMh.mjs","names":[],"sources":["../src/shared/storage.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\n\n/**\n * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.\n *\n * Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)\n * calls this once at module level to get its own isolated storage + accessor pair.\n *\n * @param contextHint - Human-readable hint appended to the error message when\n * `useLogger()` is called outside of a request (e.g.\n * `\"middleware context. Make sure app.use(evlog()) is registered before your routes.\"`).\n */\nexport function createLoggerStorage(contextHint: string) {\n const storage = new AsyncLocalStorage<RequestLogger>()\n\n function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger) {\n throw new Error(\n `[evlog] useLogger() was called outside of an evlog ${contextHint}`,\n )\n }\n return logger as RequestLogger<T>\n }\n\n return { storage, useLogger }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,oBAAoB,aAAqB;CACvD,MAAM,UAAU,IAAI,mBAAkC;CAEtD,SAAS,YAA0E;EACjF,MAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,OACH,OAAM,IAAI,MACR,sDAAsD,cACvD;AAEH,SAAO;;AAGT,QAAO;EAAE;EAAS;EAAW"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { RequestLogger } from "../types.mjs";
|
|
2
|
+
import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/sveltekit/index.d.ts
|
|
5
|
+
declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
|
|
6
|
+
type EvlogSvelteKitOptions = BaseEvlogOptions;
|
|
7
|
+
/**
|
|
8
|
+
* SvelteKit `Handle` function signature — avoids a hard dependency on `@sveltejs/kit`.
|
|
9
|
+
*/
|
|
10
|
+
type SvelteKitHandle = (input: {
|
|
11
|
+
event: {
|
|
12
|
+
request: Request;
|
|
13
|
+
url: URL;
|
|
14
|
+
locals: Record<string, any>;
|
|
15
|
+
};
|
|
16
|
+
resolve: (event: any) => Promise<Response>;
|
|
17
|
+
}) => Promise<Response>;
|
|
18
|
+
/**
|
|
19
|
+
* SvelteKit `HandleServerError` signature — avoids a hard dependency on `@sveltejs/kit`.
|
|
20
|
+
*/
|
|
21
|
+
type SvelteKitHandleServerError = (input: {
|
|
22
|
+
error: unknown;
|
|
23
|
+
event: {
|
|
24
|
+
request: Request;
|
|
25
|
+
url: URL;
|
|
26
|
+
locals: Record<string, any>;
|
|
27
|
+
};
|
|
28
|
+
status: number;
|
|
29
|
+
message: string;
|
|
30
|
+
}) => MaybePromise<void | AppError>;
|
|
31
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
32
|
+
/** Minimal SvelteKit `App.Error` shape */
|
|
33
|
+
interface AppError {
|
|
34
|
+
message: string;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create an evlog handle hook for SvelteKit.
|
|
39
|
+
*
|
|
40
|
+
* Add it to your `src/hooks.server.ts` using SvelteKit's `sequence` helper
|
|
41
|
+
* or as the sole handle export.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* // src/hooks.server.ts
|
|
46
|
+
* import { initLogger } from 'evlog'
|
|
47
|
+
* import { evlog } from 'evlog/sveltekit'
|
|
48
|
+
* import { createAxiomDrain } from 'evlog/axiom'
|
|
49
|
+
*
|
|
50
|
+
* initLogger({ env: { service: 'my-sveltekit-app' } })
|
|
51
|
+
*
|
|
52
|
+
* export const handle = evlog({
|
|
53
|
+
* drain: createAxiomDrain(),
|
|
54
|
+
* enrich: (ctx) => {
|
|
55
|
+
* ctx.event.region = process.env.FLY_REGION
|
|
56
|
+
* },
|
|
57
|
+
* })
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* // Compose with other hooks using sequence
|
|
63
|
+
* import { sequence } from '@sveltejs/kit/hooks'
|
|
64
|
+
* import { evlog } from 'evlog/sveltekit'
|
|
65
|
+
*
|
|
66
|
+
* export const handle = sequence(evlog(), yourOtherHook)
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare function evlog(options?: EvlogSvelteKitOptions): SvelteKitHandle;
|
|
70
|
+
/**
|
|
71
|
+
* Create an evlog error handler for SvelteKit.
|
|
72
|
+
*
|
|
73
|
+
* Logs unhandled errors via `event.locals.log` (if available) and returns
|
|
74
|
+
* structured error responses for `EvlogError` instances. For non-evlog errors,
|
|
75
|
+
* returns a generic error response with sanitized messages in production.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // src/hooks.server.ts
|
|
80
|
+
* import { evlog, evlogHandleError } from 'evlog/sveltekit'
|
|
81
|
+
*
|
|
82
|
+
* export const handle = evlog()
|
|
83
|
+
* export const handleError = evlogHandleError()
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
declare function evlogHandleError(): SvelteKitHandleServerError;
|
|
87
|
+
/**
|
|
88
|
+
* Create both `handle` and `handleError` hooks in a single call.
|
|
89
|
+
*
|
|
90
|
+
* This is the recommended setup for SvelteKit — it returns both hooks
|
|
91
|
+
* pre-configured and ready to export from `hooks.server.ts`.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* // src/hooks.server.ts
|
|
96
|
+
* import { initLogger } from 'evlog'
|
|
97
|
+
* import { createEvlogHooks } from 'evlog/sveltekit'
|
|
98
|
+
* import { createAxiomDrain } from 'evlog/axiom'
|
|
99
|
+
*
|
|
100
|
+
* initLogger({ env: { service: 'my-app' } })
|
|
101
|
+
*
|
|
102
|
+
* export const { handle, handleError } = createEvlogHooks({
|
|
103
|
+
* drain: createAxiomDrain(),
|
|
104
|
+
* enrich: (ctx) => {
|
|
105
|
+
* ctx.event.region = process.env.FLY_REGION
|
|
106
|
+
* },
|
|
107
|
+
* })
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* // Compose with other hooks using sequence
|
|
113
|
+
* import { sequence } from '@sveltejs/kit/hooks'
|
|
114
|
+
* import { createEvlogHooks } from 'evlog/sveltekit'
|
|
115
|
+
*
|
|
116
|
+
* const evlogHooks = createEvlogHooks()
|
|
117
|
+
*
|
|
118
|
+
* export const handle = sequence(evlogHooks.handle, yourOtherHook)
|
|
119
|
+
* export const handleError = evlogHooks.handleError
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function createEvlogHooks(options?: EvlogSvelteKitOptions): {
|
|
123
|
+
handle: SvelteKitHandle;
|
|
124
|
+
handleError: SvelteKitHandleServerError;
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
export { EvlogSvelteKitOptions, createEvlogHooks, evlog, evlogHandleError, useLogger };
|
|
128
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/sveltekit/index.ts"],"mappings":";;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,qBAAA,GAAwB,gBAAA;;;;KAO/B,eAAA,IAAmB,KAAA;EACtB,KAAA;IAAS,OAAA,EAAS,OAAA;IAAS,GAAA,EAAK,GAAA;IAAK,MAAA,EAAQ,MAAA;EAAA;EAC7C,OAAA,GAAU,KAAA,UAAe,OAAA,CAAQ,QAAA;AAAA,MAC7B,OAAA,CAAQ,QAAA;;;AAVd;KAeK,0BAAA,IAA8B,KAAA;EACjC,KAAA;EACA,KAAA;IAAS,OAAA,EAAS,OAAA;IAAS,GAAA,EAAK,GAAA;IAAK,MAAA,EAAQ,MAAA;EAAA;EAC7C,MAAA;EACA,OAAA;AAAA,MACI,YAAA,QAAoB,QAAA;AAAA,KAErB,YAAA,MAAkB,CAAA,GAAI,OAAA,CAAQ,CAAA;;UAGzB,QAAA;EACR,OAAA;EAAA,CACC,GAAA;AAAA;;;;;;;;;;;;;;;;;AAjBmB;;;;;;;;;;;;;;;;iBAoDN,KAAA,CAAM,OAAA,GAAS,qBAAA,GAA6B,eAAA;;;;;;;;;AA1C1B;;;;;;;;iBAkHlB,gBAAA,CAAA,GAAoB,0BAAA;;;;;;AAhHA;;;;;AAwCpC;;;;;;;;;AAwEA;;;;;AA6DA;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,OAAA,GAAS,qBAAA"}
|