apitally 0.24.0 → 0.25.1
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/dist/adonisjs/configure.cjs +1 -1
- package/dist/adonisjs/index.cjs +4 -1
- package/dist/adonisjs/index.cjs.map +1 -1
- package/dist/adonisjs/index.d.cts +2 -0
- package/dist/adonisjs/index.d.ts +2 -0
- package/dist/adonisjs/index.js +2 -0
- package/dist/adonisjs/index.js.map +1 -1
- package/dist/adonisjs/middleware.cjs +9 -5
- package/dist/adonisjs/middleware.cjs.map +1 -1
- package/dist/adonisjs/middleware.d.cts +2 -0
- package/dist/adonisjs/middleware.d.ts +2 -0
- package/dist/adonisjs/middleware.js +6 -2
- package/dist/adonisjs/middleware.js.map +1 -1
- package/dist/adonisjs/provider.cjs +3 -3
- package/dist/adonisjs/provider.d.cts +2 -0
- package/dist/adonisjs/provider.d.ts +2 -0
- package/dist/adonisjs/stubs/config/apitally.stub +1 -0
- package/dist/common/client.cjs +13 -9
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.d.cts +3 -0
- package/dist/common/client.d.ts +3 -0
- package/dist/common/client.js +4 -0
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.d.cts +2 -0
- package/dist/common/consumerRegistry.d.ts +2 -0
- package/dist/common/requestCounter.d.cts +2 -0
- package/dist/common/requestCounter.d.ts +2 -0
- package/dist/common/requestLogger.cjs +14 -5
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +6 -1
- package/dist/common/requestLogger.d.ts +6 -1
- package/dist/common/requestLogger.js +11 -2
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/serverErrorCounter.cjs +1 -1
- package/dist/common/serverErrorCounter.d.cts +2 -0
- package/dist/common/serverErrorCounter.d.ts +2 -0
- package/dist/common/spanCollector.cjs +217 -0
- package/dist/common/spanCollector.cjs.map +1 -0
- package/dist/common/spanCollector.d.cts +50 -0
- package/dist/common/spanCollector.d.ts +50 -0
- package/dist/common/spanCollector.js +194 -0
- package/dist/common/spanCollector.js.map +1 -0
- package/dist/common/types.d.cts +2 -0
- package/dist/common/types.d.ts +2 -0
- package/dist/common/validationErrorCounter.d.cts +2 -0
- package/dist/common/validationErrorCounter.d.ts +2 -0
- package/dist/elysia/index.cjs +4 -1
- package/dist/elysia/index.cjs.map +1 -1
- package/dist/elysia/index.d.cts +2 -0
- package/dist/elysia/index.d.ts +2 -0
- package/dist/elysia/index.js +2 -0
- package/dist/elysia/index.js.map +1 -1
- package/dist/elysia/plugin.cjs +16 -8
- package/dist/elysia/plugin.cjs.map +1 -1
- package/dist/elysia/plugin.d.cts +4 -0
- package/dist/elysia/plugin.d.ts +4 -0
- package/dist/elysia/plugin.js +9 -1
- package/dist/elysia/plugin.js.map +1 -1
- package/dist/elysia/utils.cjs +1 -1
- package/dist/elysia/utils.d.cts +2 -0
- package/dist/elysia/utils.d.ts +2 -0
- package/dist/express/index.cjs +4 -1
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.d.cts +2 -0
- package/dist/express/index.d.ts +2 -0
- package/dist/express/index.js +2 -0
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +92 -84
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.d.cts +2 -0
- package/dist/express/middleware.d.ts +2 -0
- package/dist/express/middleware.js +85 -77
- package/dist/express/middleware.js.map +1 -1
- package/dist/fastify/index.cjs +4 -1
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.d.cts +2 -0
- package/dist/fastify/index.d.ts +2 -0
- package/dist/fastify/index.js +2 -0
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +20 -11
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.d.cts +4 -0
- package/dist/fastify/plugin.d.ts +4 -0
- package/dist/fastify/plugin.js +14 -5
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/h3/index.cjs +4 -1
- package/dist/h3/index.cjs.map +1 -1
- package/dist/h3/index.d.cts +2 -0
- package/dist/h3/index.d.ts +2 -0
- package/dist/h3/index.js +2 -0
- package/dist/h3/index.js.map +1 -1
- package/dist/h3/plugin.cjs +20 -12
- package/dist/h3/plugin.cjs.map +1 -1
- package/dist/h3/plugin.d.cts +4 -0
- package/dist/h3/plugin.d.ts +4 -0
- package/dist/h3/plugin.js +13 -5
- package/dist/h3/plugin.js.map +1 -1
- package/dist/h3/utils.cjs +1 -1
- package/dist/hapi/index.cjs +4 -1
- package/dist/hapi/index.cjs.map +1 -1
- package/dist/hapi/index.d.cts +2 -0
- package/dist/hapi/index.d.ts +2 -0
- package/dist/hapi/index.js +2 -0
- package/dist/hapi/index.js.map +1 -1
- package/dist/hapi/plugin.cjs +15 -8
- package/dist/hapi/plugin.cjs.map +1 -1
- package/dist/hapi/plugin.d.cts +4 -0
- package/dist/hapi/plugin.d.ts +4 -0
- package/dist/hapi/plugin.js +10 -3
- package/dist/hapi/plugin.js.map +1 -1
- package/dist/hapi/utils.cjs +1 -1
- package/dist/hapi/utils.d.cts +2 -0
- package/dist/hapi/utils.d.ts +2 -0
- package/dist/hono/index.cjs +4 -1
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.d.cts +2 -0
- package/dist/hono/index.d.ts +2 -0
- package/dist/hono/index.js +2 -0
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +13 -9
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.d.cts +2 -0
- package/dist/hono/middleware.d.ts +2 -0
- package/dist/hono/middleware.js +6 -2
- package/dist/hono/middleware.js.map +1 -1
- package/dist/hono/utils.cjs +1 -1
- package/dist/hono/utils.d.cts +2 -0
- package/dist/hono/utils.d.ts +2 -0
- package/dist/koa/index.cjs +4 -1
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.d.cts +2 -0
- package/dist/koa/index.d.ts +2 -0
- package/dist/koa/index.js +2 -0
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +13 -9
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.d.cts +2 -0
- package/dist/koa/middleware.d.ts +2 -0
- package/dist/koa/middleware.js +8 -4
- package/dist/koa/middleware.js.map +1 -1
- package/dist/loggers/console.d.cts +4 -0
- package/dist/loggers/console.d.ts +4 -0
- package/dist/loggers/hapi.d.cts +4 -0
- package/dist/loggers/hapi.d.ts +4 -0
- package/dist/loggers/index.cjs +5 -5
- package/dist/loggers/index.d.cts +4 -0
- package/dist/loggers/index.d.ts +4 -0
- package/dist/loggers/nestjs.cjs +1 -1
- package/dist/loggers/nestjs.d.cts +4 -0
- package/dist/loggers/nestjs.d.ts +4 -0
- package/dist/loggers/pino.cjs +1 -1
- package/dist/loggers/pino.d.cts +4 -0
- package/dist/loggers/pino.d.ts +4 -0
- package/dist/loggers/winston.cjs +1 -1
- package/dist/loggers/winston.d.cts +4 -0
- package/dist/loggers/winston.d.ts +4 -0
- package/dist/nestjs/index.cjs +3 -0
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.d.cts +2 -0
- package/dist/nestjs/index.d.ts +2 -0
- package/dist/nestjs/index.js +2 -0
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +6 -2
package/dist/h3/plugin.cjs
CHANGED
|
@@ -26,15 +26,16 @@ module.exports = __toCommonJS(plugin_exports);
|
|
|
26
26
|
var import_h3 = require("h3");
|
|
27
27
|
var import_node_async_hooks = require("node:async_hooks");
|
|
28
28
|
var import_node_perf_hooks = require("node:perf_hooks");
|
|
29
|
-
var import_client = require(
|
|
30
|
-
var import_consumerRegistry = require(
|
|
31
|
-
var import_headers = require(
|
|
32
|
-
var import_requestLogger = require(
|
|
33
|
-
var import_response = require(
|
|
34
|
-
var import_loggers = require(
|
|
35
|
-
var import_utils = require(
|
|
29
|
+
var import_client = require('../common/client.cjs');
|
|
30
|
+
var import_consumerRegistry = require('../common/consumerRegistry.cjs');
|
|
31
|
+
var import_headers = require('../common/headers.cjs');
|
|
32
|
+
var import_requestLogger = require('../common/requestLogger.cjs');
|
|
33
|
+
var import_response = require('../common/response.cjs');
|
|
34
|
+
var import_loggers = require('../loggers/index.cjs');
|
|
35
|
+
var import_utils = require('./utils.cjs');
|
|
36
36
|
const REQUEST_TIMESTAMP_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestTimestamp");
|
|
37
37
|
const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
|
|
38
|
+
const SPAN_HANDLE_SYMBOL = /* @__PURE__ */ Symbol("apitally.spanHandle");
|
|
38
39
|
const jsonHeaders = new Headers({
|
|
39
40
|
"content-type": "application/json;charset=UTF-8"
|
|
40
41
|
});
|
|
@@ -56,7 +57,7 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
56
57
|
(0, import_loggers.patchWinston)(logsContext);
|
|
57
58
|
}
|
|
58
59
|
const handleResponse = /* @__PURE__ */ __name(async (event, response, error) => {
|
|
59
|
-
var _a
|
|
60
|
+
var _a;
|
|
60
61
|
if (event.req.method.toUpperCase() === "OPTIONS") {
|
|
61
62
|
return response;
|
|
62
63
|
}
|
|
@@ -77,6 +78,10 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
77
78
|
});
|
|
78
79
|
responsePromise.then(async (capturedResponse) => {
|
|
79
80
|
const responseTime = startTime ? import_node_perf_hooks.performance.now() - startTime : 0;
|
|
81
|
+
const spanHandle = event.context[SPAN_HANDLE_SYMBOL];
|
|
82
|
+
spanHandle == null ? void 0 : spanHandle.setName(`${event.req.method} ${path}`);
|
|
83
|
+
const spans = spanHandle == null ? void 0 : spanHandle.end();
|
|
84
|
+
const traceId = spanHandle == null ? void 0 : spanHandle.traceId;
|
|
80
85
|
const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
|
|
81
86
|
const requestSize = (0, import_headers.parseContentLength)(event.req.headers.get("content-length"));
|
|
82
87
|
if (path) {
|
|
@@ -107,12 +112,12 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
107
112
|
headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(response.headers.entries())),
|
|
108
113
|
size: responseSize,
|
|
109
114
|
body: capturedResponse.body
|
|
110
|
-
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
115
|
+
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs, spans, traceId);
|
|
111
116
|
}
|
|
112
117
|
});
|
|
113
|
-
if (path && (error == null ? void 0 : error.status) === 400 && error.data && error.data.
|
|
114
|
-
const
|
|
115
|
-
|
|
118
|
+
if (path && (error == null ? void 0 : error.status) === 400 && error.data && Array.isArray(error.data.issues)) {
|
|
119
|
+
const issues = error.data.issues;
|
|
120
|
+
issues.forEach((issue) => {
|
|
116
121
|
client.validationErrorCounter.addValidationError({
|
|
117
122
|
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
118
123
|
method: event.req.method,
|
|
@@ -138,6 +143,9 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
138
143
|
app.use((0, import_h3.onRequest)(async (event) => {
|
|
139
144
|
logsContext.enterWith([]);
|
|
140
145
|
event.context[REQUEST_TIMESTAMP_SYMBOL] = import_node_perf_hooks.performance.now();
|
|
146
|
+
const spanHandle = client.spanCollector.startSpan();
|
|
147
|
+
event.context[SPAN_HANDLE_SYMBOL] = spanHandle;
|
|
148
|
+
spanHandle.enterContext();
|
|
141
149
|
const requestContentType = event.req.headers.get("content-type");
|
|
142
150
|
const requestSize = (0, import_headers.parseContentLength)(event.req.headers.get("content-length")) ?? 0;
|
|
143
151
|
if (client.requestLogger.enabled && client.requestLogger.config.logRequestBody && client.requestLogger.isSupportedContentType(requestContentType) && requestSize <= client.requestLogger.maxBodySize) {
|
package/dist/h3/plugin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","definePlugin","app","config","client","ApitallyClient","logsContext","AsyncLocalStorage","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","patchConsole","patchWinston","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","mergeHeaders","newResponse","responsePromise","captureResponse","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","performance","now","responseSize","completed","size","undefined","requestSize","parseContentLength","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","onRequest","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","onResponse","isEnabled","onError","setConsumer","apitallyConsumer","consumerFromStringOrObject"]}
|
|
1
|
+
{"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport type { SpanHandle } from \"../common/spanCollector.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst SPAN_HANDLE_SYMBOL = Symbol(\"apitally.spanHandle\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [SPAN_HANDLE_SYMBOL]?: SpanHandle;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n\n const spanHandle = event.context[SPAN_HANDLE_SYMBOL];\n spanHandle?.setName(`${event.req.method} ${path}`);\n const spans = spanHandle?.end();\n const traceId = spanHandle?.traceId;\n\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n spans,\n traceId,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n Array.isArray((error.data as any).issues)\n ) {\n const issues = (error.data as any).issues as ZodError[\"issues\"];\n issues.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n\n const spanHandle = client.spanCollector.startSpan();\n event.context[SPAN_HANDLE_SYMBOL] = spanHandle;\n spanHandle.enterContext();\n\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","SPAN_HANDLE_SYMBOL","jsonHeaders","Headers","apitallyPlugin","definePlugin","app","config","client","ApitallyClient","logsContext","AsyncLocalStorage","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","patchConsole","patchWinston","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","mergeHeaders","newResponse","responsePromise","captureResponse","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","performance","now","spanHandle","setName","spans","end","traceId","responseSize","completed","size","undefined","requestSize","parseContentLength","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","body","cause","Error","data","Array","isArray","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","name","traceback","stack","use","onRequest","enterWith","spanCollector","startSpan","enterContext","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","onResponse","isEnabled","onError","setConsumer","apitallyConsumer","consumerFromStringOrObject"]}
|
package/dist/h3/plugin.d.cts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { SpanHandle } from '../common/spanCollector.cjs';
|
|
1
2
|
import { ApitallyConsumer, ApitallyConfig } from '../common/types.cjs';
|
|
2
3
|
import * as h3 from 'h3';
|
|
3
4
|
import { H3Event } from 'h3';
|
|
5
|
+
import '@opentelemetry/sdk-trace-base';
|
|
4
6
|
import '../common/logging.cjs';
|
|
5
7
|
import 'winston';
|
|
6
8
|
import '../common/requestLogger.cjs';
|
|
@@ -10,11 +12,13 @@ import '../common/tempGzipFile.cjs';
|
|
|
10
12
|
|
|
11
13
|
declare const REQUEST_TIMESTAMP_SYMBOL: unique symbol;
|
|
12
14
|
declare const REQUEST_BODY_SYMBOL: unique symbol;
|
|
15
|
+
declare const SPAN_HANDLE_SYMBOL: unique symbol;
|
|
13
16
|
declare module "h3" {
|
|
14
17
|
interface H3EventContext {
|
|
15
18
|
apitallyConsumer?: ApitallyConsumer | string;
|
|
16
19
|
[REQUEST_TIMESTAMP_SYMBOL]?: number;
|
|
17
20
|
[REQUEST_BODY_SYMBOL]?: Buffer;
|
|
21
|
+
[SPAN_HANDLE_SYMBOL]?: SpanHandle;
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
declare const apitallyPlugin: (options: ApitallyConfig) => h3.H3Plugin;
|
package/dist/h3/plugin.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { SpanHandle } from '../common/spanCollector.js';
|
|
1
2
|
import { ApitallyConsumer, ApitallyConfig } from '../common/types.js';
|
|
2
3
|
import * as h3 from 'h3';
|
|
3
4
|
import { H3Event } from 'h3';
|
|
5
|
+
import '@opentelemetry/sdk-trace-base';
|
|
4
6
|
import '../common/logging.js';
|
|
5
7
|
import 'winston';
|
|
6
8
|
import '../common/requestLogger.js';
|
|
@@ -10,11 +12,13 @@ import '../common/tempGzipFile.js';
|
|
|
10
12
|
|
|
11
13
|
declare const REQUEST_TIMESTAMP_SYMBOL: unique symbol;
|
|
12
14
|
declare const REQUEST_BODY_SYMBOL: unique symbol;
|
|
15
|
+
declare const SPAN_HANDLE_SYMBOL: unique symbol;
|
|
13
16
|
declare module "h3" {
|
|
14
17
|
interface H3EventContext {
|
|
15
18
|
apitallyConsumer?: ApitallyConsumer | string;
|
|
16
19
|
[REQUEST_TIMESTAMP_SYMBOL]?: number;
|
|
17
20
|
[REQUEST_BODY_SYMBOL]?: Buffer;
|
|
21
|
+
[SPAN_HANDLE_SYMBOL]?: SpanHandle;
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
declare const apitallyPlugin: (options: ApitallyConfig) => h3.H3Plugin;
|
package/dist/h3/plugin.js
CHANGED
|
@@ -12,6 +12,7 @@ import { patchConsole, patchWinston } from "../loggers/index.js";
|
|
|
12
12
|
import { getAppInfo } from "./utils.js";
|
|
13
13
|
const REQUEST_TIMESTAMP_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestTimestamp");
|
|
14
14
|
const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
|
|
15
|
+
const SPAN_HANDLE_SYMBOL = /* @__PURE__ */ Symbol("apitally.spanHandle");
|
|
15
16
|
const jsonHeaders = new Headers({
|
|
16
17
|
"content-type": "application/json;charset=UTF-8"
|
|
17
18
|
});
|
|
@@ -33,7 +34,7 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
33
34
|
patchWinston(logsContext);
|
|
34
35
|
}
|
|
35
36
|
const handleResponse = /* @__PURE__ */ __name(async (event, response, error) => {
|
|
36
|
-
var _a
|
|
37
|
+
var _a;
|
|
37
38
|
if (event.req.method.toUpperCase() === "OPTIONS") {
|
|
38
39
|
return response;
|
|
39
40
|
}
|
|
@@ -54,6 +55,10 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
54
55
|
});
|
|
55
56
|
responsePromise.then(async (capturedResponse) => {
|
|
56
57
|
const responseTime = startTime ? performance.now() - startTime : 0;
|
|
58
|
+
const spanHandle = event.context[SPAN_HANDLE_SYMBOL];
|
|
59
|
+
spanHandle == null ? void 0 : spanHandle.setName(`${event.req.method} ${path}`);
|
|
60
|
+
const spans = spanHandle == null ? void 0 : spanHandle.end();
|
|
61
|
+
const traceId = spanHandle == null ? void 0 : spanHandle.traceId;
|
|
57
62
|
const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
|
|
58
63
|
const requestSize = parseContentLength(event.req.headers.get("content-length"));
|
|
59
64
|
if (path) {
|
|
@@ -84,12 +89,12 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
84
89
|
headers: convertHeaders(Object.fromEntries(response.headers.entries())),
|
|
85
90
|
size: responseSize,
|
|
86
91
|
body: capturedResponse.body
|
|
87
|
-
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
92
|
+
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs, spans, traceId);
|
|
88
93
|
}
|
|
89
94
|
});
|
|
90
|
-
if (path && (error == null ? void 0 : error.status) === 400 && error.data && error.data.
|
|
91
|
-
const
|
|
92
|
-
|
|
95
|
+
if (path && (error == null ? void 0 : error.status) === 400 && error.data && Array.isArray(error.data.issues)) {
|
|
96
|
+
const issues = error.data.issues;
|
|
97
|
+
issues.forEach((issue) => {
|
|
93
98
|
client.validationErrorCounter.addValidationError({
|
|
94
99
|
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
95
100
|
method: event.req.method,
|
|
@@ -115,6 +120,9 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
115
120
|
app.use(onRequest(async (event) => {
|
|
116
121
|
logsContext.enterWith([]);
|
|
117
122
|
event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();
|
|
123
|
+
const spanHandle = client.spanCollector.startSpan();
|
|
124
|
+
event.context[SPAN_HANDLE_SYMBOL] = spanHandle;
|
|
125
|
+
spanHandle.enterContext();
|
|
118
126
|
const requestContentType = event.req.headers.get("content-type");
|
|
119
127
|
const requestSize = parseContentLength(event.req.headers.get("content-length")) ?? 0;
|
|
120
128
|
if (client.requestLogger.enabled && client.requestLogger.config.logRequestBody && client.requestLogger.isSupportedContentType(requestContentType) && requestSize <= client.requestLogger.maxBodySize) {
|
package/dist/h3/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["definePlugin","onError","onRequest","onResponse","AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","mergeHeaders","parseContentLength","convertHeaders","captureResponse","patchConsole","patchWinston","getAppInfo","REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","app","config","client","logsContext","setStartupData","attempt","appInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","newResponse","responsePromise","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","now","responseSize","completed","size","undefined","requestSize","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","isEnabled","setConsumer","apitallyConsumer"]}
|
|
1
|
+
{"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport type { SpanHandle } from \"../common/spanCollector.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst SPAN_HANDLE_SYMBOL = Symbol(\"apitally.spanHandle\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [SPAN_HANDLE_SYMBOL]?: SpanHandle;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n\n const spanHandle = event.context[SPAN_HANDLE_SYMBOL];\n spanHandle?.setName(`${event.req.method} ${path}`);\n const spans = spanHandle?.end();\n const traceId = spanHandle?.traceId;\n\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n spans,\n traceId,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n Array.isArray((error.data as any).issues)\n ) {\n const issues = (error.data as any).issues as ZodError[\"issues\"];\n issues.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n\n const spanHandle = client.spanCollector.startSpan();\n event.context[SPAN_HANDLE_SYMBOL] = spanHandle;\n spanHandle.enterContext();\n\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["definePlugin","onError","onRequest","onResponse","AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","mergeHeaders","parseContentLength","convertHeaders","captureResponse","patchConsole","patchWinston","getAppInfo","REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","SPAN_HANDLE_SYMBOL","jsonHeaders","Headers","apitallyPlugin","app","config","client","logsContext","setStartupData","attempt","appInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","newResponse","responsePromise","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","now","spanHandle","setName","spans","end","traceId","responseSize","completed","size","undefined","requestSize","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","Object","fromEntries","entries","body","cause","Error","data","Array","isArray","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","name","traceback","stack","use","enterWith","spanCollector","startSpan","enterContext","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","isEnabled","setConsumer","apitallyConsumer"]}
|
package/dist/h3/utils.cjs
CHANGED
|
@@ -22,7 +22,7 @@ __export(utils_exports, {
|
|
|
22
22
|
getAppInfo: () => getAppInfo
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(utils_exports);
|
|
25
|
-
var import_packageVersions = require(
|
|
25
|
+
var import_packageVersions = require('../common/packageVersions.cjs');
|
|
26
26
|
function getAppInfo(h3, appVersion) {
|
|
27
27
|
const versions = [];
|
|
28
28
|
if (process.versions.node) {
|
package/dist/hapi/index.cjs
CHANGED
|
@@ -28,13 +28,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var hapi_exports = {};
|
|
30
30
|
__export(hapi_exports, {
|
|
31
|
+
ApitallySpanProcessor: () => import_spanCollector.ApitallySpanProcessor,
|
|
31
32
|
apitallyPlugin: () => import_plugin.default,
|
|
32
33
|
setConsumer: () => import_plugin.setConsumer
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(hapi_exports);
|
|
35
|
-
var
|
|
36
|
+
var import_spanCollector = require('../common/spanCollector.cjs');
|
|
37
|
+
var import_plugin = __toESM(require('./plugin.cjs'), 1);
|
|
36
38
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
39
|
0 && (module.exports = {
|
|
40
|
+
ApitallySpanProcessor,
|
|
38
41
|
apitallyPlugin,
|
|
39
42
|
setConsumer
|
|
40
43
|
});
|
package/dist/hapi/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hapi/index.ts"],"sourcesContent":["export type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { default as apitallyPlugin, setConsumer } from \"./plugin.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../src/hapi/index.ts"],"sourcesContent":["export { ApitallySpanProcessor } from \"../common/spanCollector.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { default as apitallyPlugin, setConsumer } from \"./plugin.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;2BAAsC;AAEtC,oBAAuD;","names":[]}
|
package/dist/hapi/index.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export { ApitallySpanProcessor } from '../common/spanCollector.cjs';
|
|
1
2
|
export { ApitallyConfig, ApitallyConsumer } from '../common/types.cjs';
|
|
2
3
|
export { default as apitallyPlugin, setConsumer } from './plugin.cjs';
|
|
4
|
+
import '@opentelemetry/sdk-trace-base';
|
|
3
5
|
import '../common/logging.cjs';
|
|
4
6
|
import 'winston';
|
|
5
7
|
import '../common/requestLogger.cjs';
|
package/dist/hapi/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export { ApitallySpanProcessor } from '../common/spanCollector.js';
|
|
1
2
|
export { ApitallyConfig, ApitallyConsumer } from '../common/types.js';
|
|
2
3
|
export { default as apitallyPlugin, setConsumer } from './plugin.js';
|
|
4
|
+
import '@opentelemetry/sdk-trace-base';
|
|
3
5
|
import '../common/logging.js';
|
|
4
6
|
import 'winston';
|
|
5
7
|
import '../common/requestLogger.js';
|
package/dist/hapi/index.js
CHANGED
package/dist/hapi/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hapi/index.ts"],"sourcesContent":["export type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { default as apitallyPlugin, setConsumer } from \"./plugin.js\";\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/hapi/index.ts"],"sourcesContent":["export { ApitallySpanProcessor } from \"../common/spanCollector.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { default as apitallyPlugin, setConsumer } from \"./plugin.js\";\n"],"mappings":"AAAA,SAASA,6BAA6B;AAEtC,SAAoBC,WAAXC,UAA2BC,mBAAmB;","names":["ApitallySpanProcessor","apitallyPlugin","default","setConsumer"]}
|
package/dist/hapi/plugin.cjs
CHANGED
|
@@ -25,17 +25,18 @@ __export(plugin_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(plugin_exports);
|
|
26
26
|
var import_node_async_hooks = require("node:async_hooks");
|
|
27
27
|
var import_node_perf_hooks = require("node:perf_hooks");
|
|
28
|
-
var import_client = require(
|
|
29
|
-
var import_consumerRegistry = require(
|
|
30
|
-
var import_requestLogger = require(
|
|
31
|
-
var import_loggers = require(
|
|
32
|
-
var import_utils = require(
|
|
28
|
+
var import_client = require('../common/client.cjs');
|
|
29
|
+
var import_consumerRegistry = require('../common/consumerRegistry.cjs');
|
|
30
|
+
var import_requestLogger = require('../common/requestLogger.cjs');
|
|
31
|
+
var import_loggers = require('../loggers/index.cjs');
|
|
32
|
+
var import_utils = require('./utils.cjs');
|
|
33
33
|
const START_TIME_SYMBOL = /* @__PURE__ */ Symbol("apitally.startTime");
|
|
34
34
|
const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
|
|
35
35
|
const REQUEST_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestSize");
|
|
36
36
|
const RESPONSE_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseBody");
|
|
37
37
|
const RESPONSE_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseSize");
|
|
38
38
|
const LOGS_SYMBOL = /* @__PURE__ */ Symbol("apitally.logs");
|
|
39
|
+
const SPAN_HANDLE_SYMBOL = /* @__PURE__ */ Symbol("apitally.spanHandle");
|
|
39
40
|
function apitallyPlugin(config) {
|
|
40
41
|
const client = new import_client.ApitallyClient(config);
|
|
41
42
|
const logsContext = new import_node_async_hooks.AsyncLocalStorage();
|
|
@@ -70,10 +71,12 @@ function apitallyPlugin(config) {
|
|
|
70
71
|
return h.continue;
|
|
71
72
|
}
|
|
72
73
|
request[START_TIME_SYMBOL] = import_node_perf_hooks.performance.now();
|
|
73
|
-
const
|
|
74
|
+
const spanHandle = client.spanCollector.startSpan();
|
|
74
75
|
const logs = [];
|
|
76
|
+
request[SPAN_HANDLE_SYMBOL] = spanHandle;
|
|
75
77
|
request[LOGS_SYMBOL] = logs;
|
|
76
|
-
|
|
78
|
+
const lifecycle = request._lifecycle.bind(request);
|
|
79
|
+
request._lifecycle = () => spanHandle.runInContext(() => logsContext.run(logs, lifecycle));
|
|
77
80
|
const captureRequestBody = client.requestLogger.enabled && client.requestLogger.config.logRequestBody && client.requestLogger.isSupportedContentType(request.headers["content-type"]);
|
|
78
81
|
const chunks = [];
|
|
79
82
|
let size = 0;
|
|
@@ -120,6 +123,10 @@ function apitallyPlugin(config) {
|
|
|
120
123
|
const startTime = request[START_TIME_SYMBOL];
|
|
121
124
|
const responseTime = startTime ? import_node_perf_hooks.performance.now() - startTime : 0;
|
|
122
125
|
const timestamp = (Date.now() - responseTime) / 1e3;
|
|
126
|
+
const spanHandle = request[SPAN_HANDLE_SYMBOL];
|
|
127
|
+
spanHandle == null ? void 0 : spanHandle.setName(`${request.method.toUpperCase()} ${request.route.path}`);
|
|
128
|
+
const spans = spanHandle == null ? void 0 : spanHandle.end();
|
|
129
|
+
const traceId = spanHandle == null ? void 0 : spanHandle.traceId;
|
|
123
130
|
const requestBody = request[REQUEST_BODY_SYMBOL];
|
|
124
131
|
const requestSize = request[REQUEST_SIZE_SYMBOL];
|
|
125
132
|
const response = request.response;
|
|
@@ -184,7 +191,7 @@ function apitallyPlugin(config) {
|
|
|
184
191
|
headers: (0, import_requestLogger.convertHeaders)(responseHeaders),
|
|
185
192
|
size: responseSize,
|
|
186
193
|
body: responseBody
|
|
187
|
-
}, error, logs);
|
|
194
|
+
}, error, logs, spans, traceId);
|
|
188
195
|
}
|
|
189
196
|
return h.continue;
|
|
190
197
|
});
|
package/dist/hapi/plugin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with the logs context\n const lifecycle = (request as any)._lifecycle.bind(request);\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n (request as any)._lifecycle = () => logsContext.run(logs, lifecycle);\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","config","client","ApitallyClient","logsContext","AsyncLocalStorage","pinoLoggerPatched","requestLogger","enabled","captureLogs","patchConsole","patchWinston","name","register","server","ext","patchPinoLogger","logger","appInfo","getAppInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","handleHapiRequestEvent","request","h","isEnabled","method","toUpperCase","continue","performance","now","lifecycle","_lifecycle","bind","logs","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","isBoom","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerFromStringOrObject","consumerRegistry","addOrUpdateConsumer","route","path","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","convertHeaders","body","apitallyPlugin","setConsumer"]}
|
|
1
|
+
{"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport type { SpanHandle } from \"../common/spanCollector.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\nconst SPAN_HANDLE_SYMBOL = Symbol(\"apitally.spanHandle\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n [SPAN_HANDLE_SYMBOL]?: SpanHandle;\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with span and logs context\n const spanHandle = client.spanCollector.startSpan();\n const logs: LogRecord[] = [];\n request[SPAN_HANDLE_SYMBOL] = spanHandle;\n request[LOGS_SYMBOL] = logs;\n const lifecycle = (request as any)._lifecycle.bind(request);\n (request as any)._lifecycle = () =>\n spanHandle.runInContext(() => logsContext.run(logs, lifecycle));\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n\n const spanHandle = request[SPAN_HANDLE_SYMBOL];\n spanHandle?.setName(\n `${request.method.toUpperCase()} ${request.route.path}`,\n );\n const spans = spanHandle?.end();\n const traceId = spanHandle?.traceId;\n\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n spans,\n traceId,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","SPAN_HANDLE_SYMBOL","config","client","ApitallyClient","logsContext","AsyncLocalStorage","pinoLoggerPatched","requestLogger","enabled","captureLogs","patchConsole","patchWinston","name","register","server","ext","patchPinoLogger","logger","appInfo","getAppInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","handleHapiRequestEvent","request","h","isEnabled","method","toUpperCase","continue","performance","now","spanHandle","spanCollector","startSpan","logs","lifecycle","_lifecycle","bind","runInContext","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","isBoom","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","setName","route","path","spans","end","traceId","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerFromStringOrObject","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","convertHeaders","body","apitallyPlugin","setConsumer"]}
|
package/dist/hapi/plugin.d.cts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { SpanHandle } from '../common/spanCollector.cjs';
|
|
1
2
|
import { ApitallyConsumer, ApitallyConfig } from '../common/types.cjs';
|
|
2
3
|
import { Server, Request } from '@hapi/hapi';
|
|
3
4
|
import { LogRecord } from '../common/requestLogger.cjs';
|
|
5
|
+
import '@opentelemetry/sdk-trace-base';
|
|
4
6
|
import '../common/logging.cjs';
|
|
5
7
|
import 'winston';
|
|
6
8
|
import 'node:buffer';
|
|
@@ -13,6 +15,7 @@ declare const REQUEST_SIZE_SYMBOL: unique symbol;
|
|
|
13
15
|
declare const RESPONSE_BODY_SYMBOL: unique symbol;
|
|
14
16
|
declare const RESPONSE_SIZE_SYMBOL: unique symbol;
|
|
15
17
|
declare const LOGS_SYMBOL: unique symbol;
|
|
18
|
+
declare const SPAN_HANDLE_SYMBOL: unique symbol;
|
|
16
19
|
declare module "@hapi/hapi" {
|
|
17
20
|
interface Request {
|
|
18
21
|
[START_TIME_SYMBOL]?: number;
|
|
@@ -21,6 +24,7 @@ declare module "@hapi/hapi" {
|
|
|
21
24
|
[RESPONSE_BODY_SYMBOL]?: Buffer;
|
|
22
25
|
[RESPONSE_SIZE_SYMBOL]?: number;
|
|
23
26
|
[LOGS_SYMBOL]?: LogRecord[];
|
|
27
|
+
[SPAN_HANDLE_SYMBOL]?: SpanHandle;
|
|
24
28
|
apitallyConsumer?: ApitallyConsumer | string;
|
|
25
29
|
}
|
|
26
30
|
interface ResponseObject {
|
package/dist/hapi/plugin.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { SpanHandle } from '../common/spanCollector.js';
|
|
1
2
|
import { ApitallyConsumer, ApitallyConfig } from '../common/types.js';
|
|
2
3
|
import { Server, Request } from '@hapi/hapi';
|
|
3
4
|
import { LogRecord } from '../common/requestLogger.js';
|
|
5
|
+
import '@opentelemetry/sdk-trace-base';
|
|
4
6
|
import '../common/logging.js';
|
|
5
7
|
import 'winston';
|
|
6
8
|
import 'node:buffer';
|
|
@@ -13,6 +15,7 @@ declare const REQUEST_SIZE_SYMBOL: unique symbol;
|
|
|
13
15
|
declare const RESPONSE_BODY_SYMBOL: unique symbol;
|
|
14
16
|
declare const RESPONSE_SIZE_SYMBOL: unique symbol;
|
|
15
17
|
declare const LOGS_SYMBOL: unique symbol;
|
|
18
|
+
declare const SPAN_HANDLE_SYMBOL: unique symbol;
|
|
16
19
|
declare module "@hapi/hapi" {
|
|
17
20
|
interface Request {
|
|
18
21
|
[START_TIME_SYMBOL]?: number;
|
|
@@ -21,6 +24,7 @@ declare module "@hapi/hapi" {
|
|
|
21
24
|
[RESPONSE_BODY_SYMBOL]?: Buffer;
|
|
22
25
|
[RESPONSE_SIZE_SYMBOL]?: number;
|
|
23
26
|
[LOGS_SYMBOL]?: LogRecord[];
|
|
27
|
+
[SPAN_HANDLE_SYMBOL]?: SpanHandle;
|
|
24
28
|
apitallyConsumer?: ApitallyConsumer | string;
|
|
25
29
|
}
|
|
26
30
|
interface ResponseObject {
|