@senzops/apm-node 1.2.0 → 1.2.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.
@@ -1,6 +1,7 @@
1
- import { client } from '../core/client';
2
- import { getRoute } from '../core/normalizer';
3
- import { getClientIp } from '../utils/getClientIp';
1
+ import { client } from '../core/client';
2
+ import { getRoute } from '../core/normalizer';
3
+ import { invokeWithFrameworkSpan } from '../instrumentation/framework';
4
+ import { getClientIp } from '../utils/getClientIp';
4
5
 
5
6
  type EventHandler = (event: any) => any;
6
7
 
@@ -15,21 +16,44 @@ export const wrapH3 = (handler: EventHandler) => {
15
16
  ip: getClientIp(req),
16
17
  userAgent: req.headers['user-agent'],
17
18
  headers: req.headers // Pass headers
18
- }, async () => {
19
- try {
20
- const response = await handler(event);
21
- let status = 200;
22
- if (event.node.res.statusCode) status = event.node.res.statusCode;
23
- if (response && response.statusCode) status = response.statusCode;
24
-
25
- client.endTrace(status, { route: getRoute(event, path) });
26
- return response;
27
- } catch (err: any) {
28
- client.captureError(err);
29
- const status = err.statusCode || err.status || 500;
19
+ }, async () => {
20
+ try {
21
+ const route = getRoute(event, path);
22
+ const response = await invokeWithFrameworkSpan(
23
+ handler,
24
+ undefined,
25
+ [event],
26
+ {
27
+ framework: 'h3',
28
+ type: 'event_handler',
29
+ name: `h3.event_handler ${req.method || 'GET'} ${route}`,
30
+ route,
31
+ method: req.method || 'GET',
32
+ request: req,
33
+ response: event.node.res,
34
+ attributes: {
35
+ 'h3.type': 'event_handler',
36
+ 'http.route': route
37
+ }
38
+ },
39
+ undefined,
40
+ {
41
+ callbackCompletesSpan: false,
42
+ responseEndsSpan: false
43
+ }
44
+ );
45
+ let status = 200;
46
+ if (event.node.res.statusCode) status = event.node.res.statusCode;
47
+ if (response && response.statusCode) status = response.statusCode;
48
+
49
+ client.endTrace(status, { route });
50
+ return response;
51
+ } catch (err: any) {
52
+ client.captureError(err);
53
+ const status = err.statusCode || err.status || 500;
30
54
  client.endTrace(status, { route: getRoute(event, path) });
31
55
  throw err;
32
56
  }
33
57
  });
34
58
  };
35
- };
59
+ };
@@ -1,6 +1,7 @@
1
- import { client } from '../core/client';
2
- import { normalizePath } from '../core/normalizer';
3
- import { getClientIp } from '../utils/getClientIp';
1
+ import { client } from '../core/client';
2
+ import { normalizePath } from '../core/normalizer';
3
+ import { invokeWithFrameworkSpan } from '../instrumentation/framework';
4
+ import { getClientIp } from '../utils/getClientIp';
4
5
 
5
6
  // --- App Router Wrapper ---
6
7
  export const wrapNextRoute = (handler: Function) => {
@@ -37,16 +38,39 @@ export const wrapNextRoute = (handler: Function) => {
37
38
  userAgent: ua,
38
39
  ip: ip || getClientIp(req),
39
40
  headers: headers // Pass extracted headers
40
- }, async () => {
41
- try {
42
- const response = await handler(req, context);
43
- const status = response?.status || 200;
44
-
45
- client.endTrace(status, { route: normalizePath(url.pathname) });
46
- return response;
47
- } catch (err: any) {
48
- client.captureError(err);
49
- client.endTrace(500, { route: normalizePath(url.pathname) });
41
+ }, async () => {
42
+ try {
43
+ const route = normalizePath(url.pathname);
44
+ const response = await invokeWithFrameworkSpan(
45
+ handler,
46
+ undefined,
47
+ [req, context],
48
+ {
49
+ framework: 'next',
50
+ type: 'route_handler',
51
+ name: `next.app_route_handler ${method} ${route}`,
52
+ route,
53
+ method,
54
+ request: req,
55
+ attributes: {
56
+ 'next.router': 'app',
57
+ 'http.route': route,
58
+ 'url.path': url.pathname
59
+ }
60
+ },
61
+ undefined,
62
+ {
63
+ callbackCompletesSpan: false,
64
+ responseEndsSpan: false
65
+ }
66
+ );
67
+ const status = response?.status || 200;
68
+
69
+ client.endTrace(status, { route });
70
+ return response;
71
+ } catch (err: any) {
72
+ client.captureError(err);
73
+ client.endTrace(500, { route: normalizePath(url.pathname) });
50
74
  throw err;
51
75
  }
52
76
  });
@@ -71,14 +95,37 @@ export const wrapNextPages = (handler: Function) => {
71
95
  };
72
96
 
73
97
  res.once('finish', done);
74
- res.once('close', done);
75
-
76
- try {
77
- return await handler(req, res);
78
- } catch (e: any) {
79
- client.captureError(e);
80
- throw e;
98
+ res.once('close', done);
99
+
100
+ try {
101
+ const route = normalizePath(path);
102
+ return await invokeWithFrameworkSpan(
103
+ handler,
104
+ undefined,
105
+ [req, res],
106
+ {
107
+ framework: 'next',
108
+ type: 'route_handler',
109
+ name: `next.pages_api_handler ${req.method || 'GET'} ${route}`,
110
+ route,
111
+ method: req.method || 'GET',
112
+ request: req,
113
+ response: res,
114
+ attributes: {
115
+ 'next.router': 'pages',
116
+ 'http.route': route
117
+ }
118
+ },
119
+ undefined,
120
+ {
121
+ callbackCompletesSpan: false,
122
+ responseEndsSpan: true
123
+ }
124
+ );
125
+ } catch (e: any) {
126
+ client.captureError(e);
127
+ throw e;
81
128
  }
82
129
  });
83
130
  };
84
- };
131
+ };
package/wiki.md CHANGED
@@ -82,6 +82,10 @@ Senzor.init({
82
82
  maxAttributes: 64,
83
83
  captureHeaders: false,
84
84
  captureDbStatement: true,
85
+ frameworkSpans: true,
86
+ captureMiddlewareSpans: true,
87
+ captureRouterSpans: true,
88
+ captureLifecycleHookSpans: true,
85
89
  autoLogs: true,
86
90
  debug: false
87
91
  });
@@ -133,6 +137,10 @@ SENZOR_MAX_QUEUE_SIZE=10000
133
137
  SENZOR_MAX_SPANS_PER_TRACE=500
134
138
  SENZOR_CAPTURE_HEADERS=false
135
139
  SENZOR_CAPTURE_DB_STATEMENT=true
140
+ SENZOR_FRAMEWORK_SPANS=true
141
+ SENZOR_CAPTURE_MIDDLEWARE_SPANS=true
142
+ SENZOR_CAPTURE_ROUTER_SPANS=true
143
+ SENZOR_CAPTURE_LIFECYCLE_HOOK_SPANS=true
136
144
  SENZOR_AUTO_LOGS=true
137
145
  SENZOR_DEBUG=false
138
146
  ```