apitally 0.21.4 → 0.22.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/dist/common/requestLogger.cjs +23 -12
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +1 -1
- package/dist/common/requestLogger.d.ts +1 -1
- package/dist/common/requestLogger.js +23 -12
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/response.cjs +63 -88
- package/dist/common/response.cjs.map +1 -1
- package/dist/common/response.d.cts +14 -6
- package/dist/common/response.d.ts +14 -6
- package/dist/common/response.js +61 -83
- package/dist/common/response.js.map +1 -1
- package/dist/elysia/index.d.cts +6 -0
- package/dist/elysia/index.d.ts +6 -0
- package/dist/elysia/plugin.cjs +104 -76
- package/dist/elysia/plugin.cjs.map +1 -1
- package/dist/elysia/plugin.d.cts +10 -0
- package/dist/elysia/plugin.d.ts +10 -0
- package/dist/elysia/plugin.js +105 -77
- package/dist/elysia/plugin.js.map +1 -1
- package/dist/h3/plugin.cjs +59 -59
- package/dist/h3/plugin.cjs.map +1 -1
- package/dist/h3/plugin.js +60 -60
- package/dist/h3/plugin.js.map +1 -1
- package/dist/h3/utils.cjs +1 -1
- package/dist/h3/utils.cjs.map +1 -1
- package/dist/h3/utils.js +1 -1
- package/dist/h3/utils.js.map +1 -1
- package/dist/hono/middleware.cjs +63 -64
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +64 -65
- package/dist/hono/middleware.js.map +1 -1
- package/package.json +2 -2
package/dist/h3/plugin.cjs
CHANGED
|
@@ -61,77 +61,77 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
61
61
|
return response;
|
|
62
62
|
}
|
|
63
63
|
const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];
|
|
64
|
-
const responseTime = startTime ? import_node_perf_hooks.performance.now() - startTime : 0;
|
|
65
64
|
const path = (_a = event.context.matchedRoute) == null ? void 0 : _a.route;
|
|
66
|
-
const statusCode = (response == null ? void 0 : response.status) || (error == null ? void 0 : error.status) || 500;
|
|
67
|
-
const requestSize = (0, import_headers.parseContentLength)(event.req.headers.get("content-length"));
|
|
68
|
-
let responseSize = 0;
|
|
69
|
-
let newResponse = response;
|
|
70
|
-
if (response) {
|
|
71
|
-
[responseSize, newResponse] = await (0, import_response.measureResponseSize)(response);
|
|
72
|
-
}
|
|
73
65
|
const consumer = getConsumer(event);
|
|
74
66
|
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
statusCode,
|
|
81
|
-
responseTime,
|
|
82
|
-
requestSize,
|
|
83
|
-
responseSize
|
|
67
|
+
if (!response) {
|
|
68
|
+
response = new Response(null, {
|
|
69
|
+
status: (error == null ? void 0 : error.status) || 500,
|
|
70
|
+
statusText: (error == null ? void 0 : error.statusText) || "Internal Server Error",
|
|
71
|
+
headers: (error == null ? void 0 : error.headers) ? (0, import_headers.mergeHeaders)(jsonHeaders, error.headers) : jsonHeaders
|
|
84
72
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
73
|
+
}
|
|
74
|
+
const [newResponse, responsePromise] = (0, import_response.captureResponse)(response, {
|
|
75
|
+
captureBody: client.requestLogger.enabled && client.requestLogger.config.logResponseBody,
|
|
76
|
+
maxBodySize: client.requestLogger.maxBodySize
|
|
77
|
+
});
|
|
78
|
+
responsePromise.then(async (capturedResponse) => {
|
|
79
|
+
const responseTime = startTime ? import_node_perf_hooks.performance.now() - startTime : 0;
|
|
80
|
+
const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
|
|
81
|
+
const requestSize = (0, import_headers.parseContentLength)(event.req.headers.get("content-length"));
|
|
82
|
+
if (path) {
|
|
83
|
+
client.requestCounter.addRequest({
|
|
84
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
85
|
+
method: event.req.method,
|
|
86
|
+
path,
|
|
87
|
+
statusCode: response.status,
|
|
88
|
+
responseTime,
|
|
89
|
+
requestSize,
|
|
90
|
+
responseSize
|
|
96
91
|
});
|
|
97
92
|
}
|
|
98
|
-
if (
|
|
99
|
-
|
|
93
|
+
if (client.requestLogger.enabled) {
|
|
94
|
+
const logs = logsContext.getStore();
|
|
95
|
+
client.requestLogger.logRequest({
|
|
96
|
+
timestamp: (Date.now() - responseTime) / 1e3,
|
|
97
|
+
method: event.req.method,
|
|
98
|
+
path,
|
|
99
|
+
url: event.req.url,
|
|
100
|
+
headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(event.req.headers.entries())),
|
|
101
|
+
size: requestSize,
|
|
102
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
103
|
+
body: event.context[REQUEST_BODY_SYMBOL]
|
|
104
|
+
}, {
|
|
105
|
+
statusCode: response.status,
|
|
106
|
+
responseTime: responseTime / 1e3,
|
|
107
|
+
headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(response.headers.entries())),
|
|
108
|
+
size: responseSize,
|
|
109
|
+
body: capturedResponse.body
|
|
110
|
+
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
if (path && (error == null ? void 0 : error.status) === 400 && error.data && error.data.name === "ZodError") {
|
|
114
|
+
const zodError = error.data;
|
|
115
|
+
(_b = zodError.issues) == null ? void 0 : _b.forEach((issue) => {
|
|
116
|
+
client.validationErrorCounter.addValidationError({
|
|
100
117
|
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
101
118
|
method: event.req.method,
|
|
102
119
|
path,
|
|
103
|
-
|
|
104
|
-
msg:
|
|
105
|
-
|
|
120
|
+
loc: issue.path.join("."),
|
|
121
|
+
msg: issue.message,
|
|
122
|
+
type: issue.code
|
|
106
123
|
});
|
|
107
|
-
}
|
|
124
|
+
});
|
|
108
125
|
}
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
let responseBody;
|
|
113
|
-
if (newResponse && client.requestLogger.config.logResponseBody && client.requestLogger.isSupportedContentType(responseContentType)) {
|
|
114
|
-
[responseBody, newResponse] = await (0, import_response.getResponseBody)(newResponse);
|
|
115
|
-
} else if (error && client.requestLogger.config.logResponseBody) {
|
|
116
|
-
responseBody = Buffer.from(JSON.stringify(error.toJSON()));
|
|
117
|
-
}
|
|
118
|
-
const logs = logsContext.getStore();
|
|
119
|
-
client.requestLogger.logRequest({
|
|
120
|
-
timestamp: (Date.now() - responseTime) / 1e3,
|
|
126
|
+
if (path && (error == null ? void 0 : error.status) === 500 && error.cause instanceof Error) {
|
|
127
|
+
client.serverErrorCounter.addServerError({
|
|
128
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
121
129
|
method: event.req.method,
|
|
122
130
|
path,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
body: event.context[REQUEST_BODY_SYMBOL]
|
|
128
|
-
}, {
|
|
129
|
-
statusCode,
|
|
130
|
-
responseTime: responseTime / 1e3,
|
|
131
|
-
headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(responseHeaders.entries())),
|
|
132
|
-
size: responseSize,
|
|
133
|
-
body: responseBody
|
|
134
|
-
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
131
|
+
type: error.cause.name,
|
|
132
|
+
msg: error.cause.message,
|
|
133
|
+
traceback: error.cause.stack || ""
|
|
134
|
+
});
|
|
135
135
|
}
|
|
136
136
|
return newResponse;
|
|
137
137
|
}, "handleResponse");
|
|
@@ -151,7 +151,7 @@ const apitallyPlugin = (0, import_h3.definePlugin)((app, config) => {
|
|
|
151
151
|
}
|
|
152
152
|
})).use((0, import_h3.onError)((error, event) => {
|
|
153
153
|
if (client.isEnabled()) {
|
|
154
|
-
|
|
154
|
+
handleResponse(event, void 0, error);
|
|
155
155
|
}
|
|
156
156
|
}));
|
|
157
157
|
});
|
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 { getResponseBody, measureResponseSize } 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 responseTime = startTime ? performance.now() - startTime : 0;\n const path = event.context.matchedRoute?.route;\n const statusCode = response?.status || error?.status || 500;\n\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n let responseSize = 0;\n let newResponse = response;\n if (response) {\n [responseSize, newResponse] = await measureResponseSize(response);\n }\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (error?.status === 400 && (error.data as any).name === \"ZodError\") {\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 (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\n if (client.requestLogger.enabled) {\n const responseHeaders = response\n ? response.headers\n : error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders;\n const responseContentType = responseHeaders.get(\"content-type\");\n let responseBody;\n\n if (\n newResponse &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(responseContentType)\n ) {\n [responseBody, newResponse] = await getResponseBody(newResponse);\n } else if (error && client.requestLogger.config.logResponseBody) {\n responseBody = Buffer.from(JSON.stringify(error.toJSON()));\n }\n\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,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(responseHeaders.entries()),\n ),\n size: responseSize,\n body: responseBody,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\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 return 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","responseTime","performance","now","path","matchedRoute","route","statusCode","status","requestSize","parseContentLength","headers","get","responseSize","newResponse","measureResponseSize","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","cause","Error","serverErrorCounter","addServerError","traceback","stack","enabled","responseHeaders","mergeHeaders","responseContentType","responseBody","logResponseBody","isSupportedContentType","getResponseBody","Buffer","from","JSON","stringify","toJSON","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","size","body","undefined","use","onRequest","enterWith","requestContentType","logRequestBody","maxBodySize","clonedRequest","clone","requestBody","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 { 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"]}
|
package/dist/h3/plugin.js
CHANGED
|
@@ -7,7 +7,7 @@ import { ApitallyClient } from "../common/client.js";
|
|
|
7
7
|
import { consumerFromStringOrObject } from "../common/consumerRegistry.js";
|
|
8
8
|
import { mergeHeaders, parseContentLength } from "../common/headers.js";
|
|
9
9
|
import { convertHeaders } from "../common/requestLogger.js";
|
|
10
|
-
import {
|
|
10
|
+
import { captureResponse } from "../common/response.js";
|
|
11
11
|
import { patchConsole, patchWinston } from "../loggers/index.js";
|
|
12
12
|
import { getAppInfo } from "./utils.js";
|
|
13
13
|
const REQUEST_TIMESTAMP_SYMBOL = Symbol("apitally.requestTimestamp");
|
|
@@ -38,77 +38,77 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
38
38
|
return response;
|
|
39
39
|
}
|
|
40
40
|
const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];
|
|
41
|
-
const responseTime = startTime ? performance.now() - startTime : 0;
|
|
42
41
|
const path = (_a = event.context.matchedRoute) == null ? void 0 : _a.route;
|
|
43
|
-
const statusCode = (response == null ? void 0 : response.status) || (error == null ? void 0 : error.status) || 500;
|
|
44
|
-
const requestSize = parseContentLength(event.req.headers.get("content-length"));
|
|
45
|
-
let responseSize = 0;
|
|
46
|
-
let newResponse = response;
|
|
47
|
-
if (response) {
|
|
48
|
-
[responseSize, newResponse] = await measureResponseSize(response);
|
|
49
|
-
}
|
|
50
42
|
const consumer = getConsumer(event);
|
|
51
43
|
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
statusCode,
|
|
58
|
-
responseTime,
|
|
59
|
-
requestSize,
|
|
60
|
-
responseSize
|
|
44
|
+
if (!response) {
|
|
45
|
+
response = new Response(null, {
|
|
46
|
+
status: (error == null ? void 0 : error.status) || 500,
|
|
47
|
+
statusText: (error == null ? void 0 : error.statusText) || "Internal Server Error",
|
|
48
|
+
headers: (error == null ? void 0 : error.headers) ? mergeHeaders(jsonHeaders, error.headers) : jsonHeaders
|
|
61
49
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
50
|
+
}
|
|
51
|
+
const [newResponse, responsePromise] = captureResponse(response, {
|
|
52
|
+
captureBody: client.requestLogger.enabled && client.requestLogger.config.logResponseBody,
|
|
53
|
+
maxBodySize: client.requestLogger.maxBodySize
|
|
54
|
+
});
|
|
55
|
+
responsePromise.then(async (capturedResponse) => {
|
|
56
|
+
const responseTime = startTime ? performance.now() - startTime : 0;
|
|
57
|
+
const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
|
|
58
|
+
const requestSize = parseContentLength(event.req.headers.get("content-length"));
|
|
59
|
+
if (path) {
|
|
60
|
+
client.requestCounter.addRequest({
|
|
61
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
62
|
+
method: event.req.method,
|
|
63
|
+
path,
|
|
64
|
+
statusCode: response.status,
|
|
65
|
+
responseTime,
|
|
66
|
+
requestSize,
|
|
67
|
+
responseSize
|
|
73
68
|
});
|
|
74
69
|
}
|
|
75
|
-
if (
|
|
76
|
-
|
|
70
|
+
if (client.requestLogger.enabled) {
|
|
71
|
+
const logs = logsContext.getStore();
|
|
72
|
+
client.requestLogger.logRequest({
|
|
73
|
+
timestamp: (Date.now() - responseTime) / 1e3,
|
|
74
|
+
method: event.req.method,
|
|
75
|
+
path,
|
|
76
|
+
url: event.req.url,
|
|
77
|
+
headers: convertHeaders(Object.fromEntries(event.req.headers.entries())),
|
|
78
|
+
size: requestSize,
|
|
79
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
80
|
+
body: event.context[REQUEST_BODY_SYMBOL]
|
|
81
|
+
}, {
|
|
82
|
+
statusCode: response.status,
|
|
83
|
+
responseTime: responseTime / 1e3,
|
|
84
|
+
headers: convertHeaders(Object.fromEntries(response.headers.entries())),
|
|
85
|
+
size: responseSize,
|
|
86
|
+
body: capturedResponse.body
|
|
87
|
+
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
if (path && (error == null ? void 0 : error.status) === 400 && error.data && error.data.name === "ZodError") {
|
|
91
|
+
const zodError = error.data;
|
|
92
|
+
(_b = zodError.issues) == null ? void 0 : _b.forEach((issue) => {
|
|
93
|
+
client.validationErrorCounter.addValidationError({
|
|
77
94
|
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
78
95
|
method: event.req.method,
|
|
79
96
|
path,
|
|
80
|
-
|
|
81
|
-
msg:
|
|
82
|
-
|
|
97
|
+
loc: issue.path.join("."),
|
|
98
|
+
msg: issue.message,
|
|
99
|
+
type: issue.code
|
|
83
100
|
});
|
|
84
|
-
}
|
|
101
|
+
});
|
|
85
102
|
}
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
let responseBody;
|
|
90
|
-
if (newResponse && client.requestLogger.config.logResponseBody && client.requestLogger.isSupportedContentType(responseContentType)) {
|
|
91
|
-
[responseBody, newResponse] = await getResponseBody(newResponse);
|
|
92
|
-
} else if (error && client.requestLogger.config.logResponseBody) {
|
|
93
|
-
responseBody = Buffer.from(JSON.stringify(error.toJSON()));
|
|
94
|
-
}
|
|
95
|
-
const logs = logsContext.getStore();
|
|
96
|
-
client.requestLogger.logRequest({
|
|
97
|
-
timestamp: (Date.now() - responseTime) / 1e3,
|
|
103
|
+
if (path && (error == null ? void 0 : error.status) === 500 && error.cause instanceof Error) {
|
|
104
|
+
client.serverErrorCounter.addServerError({
|
|
105
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
98
106
|
method: event.req.method,
|
|
99
107
|
path,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
body: event.context[REQUEST_BODY_SYMBOL]
|
|
105
|
-
}, {
|
|
106
|
-
statusCode,
|
|
107
|
-
responseTime: responseTime / 1e3,
|
|
108
|
-
headers: convertHeaders(Object.fromEntries(responseHeaders.entries())),
|
|
109
|
-
size: responseSize,
|
|
110
|
-
body: responseBody
|
|
111
|
-
}, (error == null ? void 0 : error.cause) instanceof Error ? error.cause : void 0, logs);
|
|
108
|
+
type: error.cause.name,
|
|
109
|
+
msg: error.cause.message,
|
|
110
|
+
traceback: error.cause.stack || ""
|
|
111
|
+
});
|
|
112
112
|
}
|
|
113
113
|
return newResponse;
|
|
114
114
|
}, "handleResponse");
|
|
@@ -128,7 +128,7 @@ const apitallyPlugin = definePlugin((app, config) => {
|
|
|
128
128
|
}
|
|
129
129
|
})).use(onError((error, event) => {
|
|
130
130
|
if (client.isEnabled()) {
|
|
131
|
-
|
|
131
|
+
handleResponse(event, void 0, error);
|
|
132
132
|
}
|
|
133
133
|
}));
|
|
134
134
|
});
|
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 { getResponseBody, measureResponseSize } 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 responseTime = startTime ? performance.now() - startTime : 0;\n const path = event.context.matchedRoute?.route;\n const statusCode = response?.status || error?.status || 500;\n\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n let responseSize = 0;\n let newResponse = response;\n if (response) {\n [responseSize, newResponse] = await measureResponseSize(response);\n }\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (error?.status === 400 && (error.data as any).name === \"ZodError\") {\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 (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\n if (client.requestLogger.enabled) {\n const responseHeaders = response\n ? response.headers\n : error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders;\n const responseContentType = responseHeaders.get(\"content-type\");\n let responseBody;\n\n if (\n newResponse &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(responseContentType)\n ) {\n [responseBody, newResponse] = await getResponseBody(newResponse);\n } else if (error && client.requestLogger.config.logResponseBody) {\n responseBody = Buffer.from(JSON.stringify(error.toJSON()));\n }\n\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,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(responseHeaders.entries()),\n ),\n size: responseSize,\n body: responseBody,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\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 return 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","getResponseBody","measureResponseSize","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","responseTime","now","path","matchedRoute","route","statusCode","status","requestSize","headers","get","responseSize","newResponse","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","cause","Error","serverErrorCounter","addServerError","traceback","stack","enabled","responseHeaders","responseContentType","responseBody","logResponseBody","isSupportedContentType","Buffer","from","JSON","stringify","toJSON","logs","getStore","logRequest","timestamp","Date","url","Object","fromEntries","entries","size","body","undefined","use","enterWith","requestContentType","logRequestBody","maxBodySize","clonedRequest","clone","requestBody","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 { 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"]}
|
package/dist/h3/utils.cjs
CHANGED
package/dist/h3/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/h3/utils.ts"],"sourcesContent":["import { H3Core } from \"h3\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\n\nexport function getAppInfo(h3: H3Core, appVersion?: string) {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const h3Version = getPackageVersion(\"h3\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (h3Version) {\n versions.push([\"h3\", h3Version]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: h3
|
|
1
|
+
{"version":3,"sources":["../../src/h3/utils.ts"],"sourcesContent":["import { H3Core } from \"h3\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\n\nexport function getAppInfo(h3: H3Core, appVersion?: string) {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const h3Version = getPackageVersion(\"h3\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (h3Version) {\n versions.push([\"h3\", h3Version]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: h3[\"~routes\"]\n .map((route) => ({\n method: route.method || \"\",\n path: route.route || \"\",\n }))\n .filter(\n (route) =>\n route.method &&\n route.path &&\n ![\"HEAD\", \"OPTIONS\"].includes(route.method.toUpperCase()),\n ),\n versions: Object.fromEntries(versions),\n client: \"js:h3\",\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAEA;;;;;AAAA,6BAAkC;AAE3B,SAASA,WAAWC,IAAYC,YAAmB;AACxD,QAAMC,WAAoC,CAAA;AAC1C,MAAIC,QAAQD,SAASE,MAAM;AACzBF,aAASG,KAAK;MAAC;MAAUF,QAAQD,SAASE;KAAK;EACjD;AACA,MAAID,QAAQD,SAASI,KAAK;AACxBJ,aAASG,KAAK;MAAC;MAAOF,QAAQD,SAASI;KAAI;EAC7C;AACA,QAAMC,gBAAYC,0CAAkB,IAAA;AACpC,QAAMC,sBAAkBD,0CAAkB,OAAA;AAC1C,MAAID,WAAW;AACbL,aAASG,KAAK;MAAC;MAAME;KAAU;EACjC;AACA,MAAIE,iBAAiB;AACnBP,aAASG,KAAK;MAAC;MAAYI;KAAgB;EAC7C;AACA,MAAIR,YAAY;AACdC,aAASG,KAAK;MAAC;MAAOJ;KAAW;EACnC;AAEA,SAAO;IACLS,OAAOV,GAAG,SAAA,EACPW,IAAI,CAACC,WAAW;MACfC,QAAQD,MAAMC,UAAU;MACxBC,MAAMF,MAAMA,SAAS;IACvB,EAAA,EACCG,OACC,CAACH,UACCA,MAAMC,UACND,MAAME,QACN,CAAC;MAAC;MAAQ;MAAWE,SAASJ,MAAMC,OAAOI,YAAW,CAAA,CAAA;IAE5Df,UAAUgB,OAAOC,YAAYjB,QAAAA;IAC7BkB,QAAQ;EACV;AACF;AAnCgBrB;","names":["getAppInfo","h3","appVersion","versions","process","node","push","bun","h3Version","getPackageVersion","apitallyVersion","paths","map","route","method","path","filter","includes","toUpperCase","Object","fromEntries","client"]}
|
package/dist/h3/utils.js
CHANGED
package/dist/h3/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/h3/utils.ts"],"sourcesContent":["import { H3Core } from \"h3\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\n\nexport function getAppInfo(h3: H3Core, appVersion?: string) {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const h3Version = getPackageVersion(\"h3\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (h3Version) {\n versions.push([\"h3\", h3Version]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: h3
|
|
1
|
+
{"version":3,"sources":["../../src/h3/utils.ts"],"sourcesContent":["import { H3Core } from \"h3\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\n\nexport function getAppInfo(h3: H3Core, appVersion?: string) {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const h3Version = getPackageVersion(\"h3\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (h3Version) {\n versions.push([\"h3\", h3Version]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: h3[\"~routes\"]\n .map((route) => ({\n method: route.method || \"\",\n path: route.route || \"\",\n }))\n .filter(\n (route) =>\n route.method &&\n route.path &&\n ![\"HEAD\", \"OPTIONS\"].includes(route.method.toUpperCase()),\n ),\n versions: Object.fromEntries(versions),\n client: \"js:h3\",\n };\n}\n"],"mappings":";;AAEA,SAASA,yBAAyB;AAE3B,SAASC,WAAWC,IAAYC,YAAmB;AACxD,QAAMC,WAAoC,CAAA;AAC1C,MAAIC,QAAQD,SAASE,MAAM;AACzBF,aAASG,KAAK;MAAC;MAAUF,QAAQD,SAASE;KAAK;EACjD;AACA,MAAID,QAAQD,SAASI,KAAK;AACxBJ,aAASG,KAAK;MAAC;MAAOF,QAAQD,SAASI;KAAI;EAC7C;AACA,QAAMC,YAAYT,kBAAkB,IAAA;AACpC,QAAMU,kBAAkBV,kBAAkB,OAAA;AAC1C,MAAIS,WAAW;AACbL,aAASG,KAAK;MAAC;MAAME;KAAU;EACjC;AACA,MAAIC,iBAAiB;AACnBN,aAASG,KAAK;MAAC;MAAYG;KAAgB;EAC7C;AACA,MAAIP,YAAY;AACdC,aAASG,KAAK;MAAC;MAAOJ;KAAW;EACnC;AAEA,SAAO;IACLQ,OAAOT,GAAG,SAAA,EACPU,IAAI,CAACC,WAAW;MACfC,QAAQD,MAAMC,UAAU;MACxBC,MAAMF,MAAMA,SAAS;IACvB,EAAA,EACCG,OACC,CAACH,UACCA,MAAMC,UACND,MAAME,QACN,CAAC;MAAC;MAAQ;MAAWE,SAASJ,MAAMC,OAAOI,YAAW,CAAA,CAAA;IAE5Dd,UAAUe,OAAOC,YAAYhB,QAAAA;IAC7BiB,QAAQ;EACV;AACF;AAnCgBpB;","names":["getPackageVersion","getAppInfo","h3","appVersion","versions","process","node","push","bun","h3Version","apitallyVersion","paths","map","route","method","path","filter","includes","toUpperCase","Object","fromEntries","client"]}
|
package/dist/hono/middleware.cjs
CHANGED
|
@@ -63,77 +63,76 @@ function getMiddleware(client) {
|
|
|
63
63
|
const timestamp = Date.now() / 1e3;
|
|
64
64
|
const startTime = import_node_perf_hooks.performance.now();
|
|
65
65
|
await next();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const requestSize = (0, import_headers.parseContentLength)(c.req.header("content-length"));
|
|
70
|
-
const consumer = getConsumer(c);
|
|
71
|
-
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
72
|
-
client.requestCounter.addRequest({
|
|
73
|
-
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
74
|
-
method: c.req.method,
|
|
75
|
-
path: c.req.routePath,
|
|
76
|
-
statusCode: c.res.status,
|
|
77
|
-
responseTime,
|
|
78
|
-
requestSize,
|
|
79
|
-
responseSize
|
|
66
|
+
const [newResponse, responsePromise] = (0, import_response.captureResponse)(c.res, {
|
|
67
|
+
captureBody: client.requestLogger.enabled && client.requestLogger.config.logResponseBody && client.requestLogger.isSupportedContentType(c.res.headers.get("content-type")) || c.res.status === 400 && c.res.headers.get("content-type") === "application/json",
|
|
68
|
+
maxBodySize: client.requestLogger.maxBodySize
|
|
80
69
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
response = newResponse2;
|
|
94
|
-
}
|
|
95
|
-
if (c.error) {
|
|
96
|
-
client.serverErrorCounter.addServerError({
|
|
70
|
+
c.res = newResponse;
|
|
71
|
+
const statusCode = c.res.status;
|
|
72
|
+
const responseHeaders = c.res.headers;
|
|
73
|
+
responsePromise.then(async (capturedResponse) => {
|
|
74
|
+
const responseTime = import_node_perf_hooks.performance.now() - startTime;
|
|
75
|
+
const requestSize = (0, import_headers.parseContentLength)(c.req.header("content-length"));
|
|
76
|
+
const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
|
|
77
|
+
const consumer = getConsumer(c);
|
|
78
|
+
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
79
|
+
client.requestCounter.addRequest({
|
|
97
80
|
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
98
81
|
method: c.req.method,
|
|
99
82
|
path: c.req.routePath,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
statusCode,
|
|
84
|
+
responseTime,
|
|
85
|
+
requestSize,
|
|
86
|
+
responseSize
|
|
103
87
|
});
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
88
|
+
if (statusCode === 400 && capturedResponse.body) {
|
|
89
|
+
const responseJson = (0, import_response.getResponseJson)(capturedResponse.body);
|
|
90
|
+
const validationErrors = (0, import_utils.extractZodErrors)(responseJson);
|
|
91
|
+
validationErrors.forEach((error) => {
|
|
92
|
+
client.validationErrorCounter.addValidationError({
|
|
93
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
94
|
+
method: c.req.method,
|
|
95
|
+
path: c.req.routePath,
|
|
96
|
+
...error
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (c.error) {
|
|
101
|
+
client.serverErrorCounter.addServerError({
|
|
102
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
103
|
+
method: c.req.method,
|
|
104
|
+
path: c.req.routePath,
|
|
105
|
+
type: c.error.name,
|
|
106
|
+
msg: c.error.message,
|
|
107
|
+
traceback: c.error.stack || ""
|
|
108
|
+
});
|
|
113
109
|
}
|
|
114
|
-
if (client.requestLogger.
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
if (client.requestLogger.enabled) {
|
|
111
|
+
let requestBody;
|
|
112
|
+
const responseBody = capturedResponse.body;
|
|
113
|
+
const requestContentType = c.req.header("content-type");
|
|
114
|
+
if (client.requestLogger.config.logRequestBody && client.requestLogger.isSupportedContentType(requestContentType)) {
|
|
115
|
+
requestBody = Buffer.from(await c.req.arrayBuffer());
|
|
116
|
+
}
|
|
117
|
+
const logs = logsContext.getStore();
|
|
118
|
+
client.requestLogger.logRequest({
|
|
119
|
+
timestamp,
|
|
120
|
+
method: c.req.method,
|
|
121
|
+
path: c.req.routePath,
|
|
122
|
+
url: c.req.url,
|
|
123
|
+
headers: (0, import_requestLogger.convertHeaders)(c.req.header()),
|
|
124
|
+
size: requestSize,
|
|
125
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
126
|
+
body: requestBody
|
|
127
|
+
}, {
|
|
128
|
+
statusCode,
|
|
129
|
+
responseTime: responseTime / 1e3,
|
|
130
|
+
headers: (0, import_requestLogger.convertHeaders)(responseHeaders),
|
|
131
|
+
size: responseSize,
|
|
132
|
+
body: responseBody
|
|
133
|
+
}, c.error, logs);
|
|
117
134
|
}
|
|
118
|
-
|
|
119
|
-
client.requestLogger.logRequest({
|
|
120
|
-
timestamp,
|
|
121
|
-
method: c.req.method,
|
|
122
|
-
path: c.req.routePath,
|
|
123
|
-
url: c.req.url,
|
|
124
|
-
headers: (0, import_requestLogger.convertHeaders)(c.req.header()),
|
|
125
|
-
size: requestSize,
|
|
126
|
-
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
127
|
-
body: requestBody
|
|
128
|
-
}, {
|
|
129
|
-
statusCode: c.res.status,
|
|
130
|
-
responseTime: responseTime / 1e3,
|
|
131
|
-
headers: (0, import_requestLogger.convertHeaders)(c.res.headers),
|
|
132
|
-
size: responseSize,
|
|
133
|
-
body: responseBody
|
|
134
|
-
}, c.error, logs);
|
|
135
|
-
}
|
|
136
|
-
c.res = response;
|
|
135
|
+
});
|
|
137
136
|
});
|
|
138
137
|
};
|
|
139
138
|
}
|