@tracekit/node-apm 1.0.2 → 1.1.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/README.md +93 -0
- package/dist/client.d.ts +6 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/express.d.ts +3 -1
- package/dist/middleware/express.d.ts.map +1 -1
- package/dist/middleware/express.js +49 -22
- package/dist/middleware/express.js.map +1 -1
- package/dist/nestjs/tracekit.module.d.ts +3 -2
- package/dist/nestjs/tracekit.module.d.ts.map +1 -1
- package/dist/nestjs/tracekit.module.js +22 -7
- package/dist/nestjs/tracekit.module.js.map +1 -1
- package/dist/snapshot-client.d.ts +48 -0
- package/dist/snapshot-client.d.ts.map +1 -0
- package/dist/snapshot-client.js +184 -0
- package/dist/snapshot-client.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Zero-config distributed tracing and performance monitoring for Express and NestJ
|
|
|
15
15
|
- **TypeScript First** - Full type definitions included
|
|
16
16
|
- **HTTP Request Tracing** - Track every request, route, and handler
|
|
17
17
|
- **Error Tracking** - Capture exceptions with full context
|
|
18
|
+
- **Code Monitoring** - Live debugging with breakpoints and variable inspection
|
|
18
19
|
- **Low Overhead** - < 5% performance impact
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
@@ -95,6 +96,94 @@ export class AppModule {}
|
|
|
95
96
|
|
|
96
97
|
That's it! Your app is now automatically traced.
|
|
97
98
|
|
|
99
|
+
## Code Monitoring (Live Debugging)
|
|
100
|
+
|
|
101
|
+
TraceKit includes production-safe code monitoring for live debugging without redeployment.
|
|
102
|
+
|
|
103
|
+
### Enable Code Monitoring
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import * as tracekit from '@tracekit/node-apm';
|
|
107
|
+
|
|
108
|
+
// Enable code monitoring
|
|
109
|
+
const client = tracekit.init({
|
|
110
|
+
apiKey: process.env.TRACEKIT_API_KEY!,
|
|
111
|
+
serviceName: 'my-app',
|
|
112
|
+
enableCodeMonitoring: true, // Enable live debugging
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Add Debug Points
|
|
117
|
+
|
|
118
|
+
Add checkpoints anywhere in your code to capture variable state and stack traces:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// In any service or controller
|
|
122
|
+
app.post('/checkout', async (req, res) => {
|
|
123
|
+
const cart = req.body.cart;
|
|
124
|
+
const userId = req.body.userId;
|
|
125
|
+
|
|
126
|
+
// Capture snapshot at this point
|
|
127
|
+
await client.captureSnapshot('checkout-validation', {
|
|
128
|
+
userId,
|
|
129
|
+
cartItems: cart.items.length,
|
|
130
|
+
totalAmount: cart.total,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Process payment...
|
|
134
|
+
const result = await processPayment(cart);
|
|
135
|
+
|
|
136
|
+
// Another checkpoint
|
|
137
|
+
await client.captureSnapshot('payment-complete', {
|
|
138
|
+
userId,
|
|
139
|
+
paymentId: result.paymentId,
|
|
140
|
+
success: result.success,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
res.json(result);
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Automatic Breakpoint Management
|
|
148
|
+
|
|
149
|
+
- **Auto-Registration**: First call to `captureSnapshot()` automatically creates breakpoints in TraceKit
|
|
150
|
+
- **Smart Matching**: Breakpoints match by function name + label (stable across code changes)
|
|
151
|
+
- **Background Sync**: SDK polls for active breakpoints every 30 seconds
|
|
152
|
+
- **Production Safe**: No performance impact when breakpoints are inactive
|
|
153
|
+
|
|
154
|
+
### View Captured Data
|
|
155
|
+
|
|
156
|
+
Snapshots include:
|
|
157
|
+
- **Variables**: Local variables at capture point
|
|
158
|
+
- **Stack Trace**: Full call stack with file/line numbers
|
|
159
|
+
- **Request Context**: HTTP method, URL, headers, query params
|
|
160
|
+
- **Execution Time**: When the snapshot was captured
|
|
161
|
+
|
|
162
|
+
### NestJS Usage
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
166
|
+
import { SnapshotClient } from '@tracekit/node-apm';
|
|
167
|
+
|
|
168
|
+
@Injectable()
|
|
169
|
+
export class PaymentService {
|
|
170
|
+
constructor(
|
|
171
|
+
@Inject('TRACEKIT_SNAPSHOT_CLIENT')
|
|
172
|
+
private snapshotClient?: SnapshotClient
|
|
173
|
+
) {}
|
|
174
|
+
|
|
175
|
+
async processPayment(order: Order) {
|
|
176
|
+
// Automatic snapshot capture
|
|
177
|
+
await this.snapshotClient?.checkAndCaptureWithContext('payment-processing', {
|
|
178
|
+
orderId: order.id,
|
|
179
|
+
amount: order.amount,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// ... payment logic
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
98
187
|
Get your API key at [https://app.tracekit.dev](https://app.tracekit.dev)
|
|
99
188
|
|
|
100
189
|
## Configuration
|
|
@@ -119,6 +208,9 @@ tracekit.init({
|
|
|
119
208
|
|
|
120
209
|
// Optional: Sample rate 0.0-1.0 (default: 1.0 = 100%)
|
|
121
210
|
sampleRate: 0.5, // Trace 50% of requests
|
|
211
|
+
|
|
212
|
+
// Optional: Enable live code debugging (default: false)
|
|
213
|
+
enableCodeMonitoring: true, // Enable breakpoints and snapshots
|
|
122
214
|
});
|
|
123
215
|
```
|
|
124
216
|
|
|
@@ -138,6 +230,7 @@ import { TracekitModule } from '@tracekit/node-apm/nestjs';
|
|
|
138
230
|
apiKey: config.get('TRACEKIT_API_KEY')!,
|
|
139
231
|
serviceName: config.get('APP_NAME', 'my-app'),
|
|
140
232
|
enabled: config.get('NODE_ENV') !== 'development',
|
|
233
|
+
enableCodeMonitoring: config.get('TRACEKIT_CODE_MONITORING_ENABLED', false),
|
|
141
234
|
}),
|
|
142
235
|
}),
|
|
143
236
|
],
|
package/dist/client.d.ts
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
import * as api from '@opentelemetry/api';
|
|
2
|
+
import { SnapshotClient } from './snapshot-client';
|
|
2
3
|
export interface TracekitConfig {
|
|
3
4
|
apiKey: string;
|
|
4
5
|
endpoint?: string;
|
|
5
6
|
serviceName?: string;
|
|
6
7
|
enabled?: boolean;
|
|
7
8
|
sampleRate?: number;
|
|
9
|
+
enableCodeMonitoring?: boolean;
|
|
8
10
|
}
|
|
9
11
|
export declare class TracekitClient {
|
|
10
12
|
private provider;
|
|
11
13
|
private tracer;
|
|
12
14
|
private config;
|
|
15
|
+
private snapshotClient?;
|
|
13
16
|
constructor(config: TracekitConfig);
|
|
14
17
|
startTrace(operationName: string, attributes?: Record<string, any>): api.Span;
|
|
15
18
|
startSpan(operationName: string, parentSpan?: api.Span | null, attributes?: Record<string, any>): api.Span;
|
|
16
19
|
endSpan(span: api.Span, finalAttributes?: Record<string, any>, status?: string): void;
|
|
17
20
|
addEvent(span: api.Span, name: string, attributes?: Record<string, any>): void;
|
|
18
21
|
recordException(span: api.Span, error: Error): void;
|
|
22
|
+
private formatStackTrace;
|
|
19
23
|
flush(): Promise<void>;
|
|
20
24
|
shutdown(): Promise<void>;
|
|
21
25
|
isEnabled(): boolean;
|
|
22
26
|
shouldSample(): boolean;
|
|
23
27
|
getTracer(): api.Tracer;
|
|
28
|
+
getSnapshotClient(): SnapshotClient | undefined;
|
|
29
|
+
captureSnapshot(label: string, variables?: Record<string, any>): Promise<void>;
|
|
24
30
|
private normalizeAttributes;
|
|
25
31
|
}
|
|
26
32
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAE5B,MAAM,EAAE,cAAc;IAiDlC,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,GAAG,CAAC,IAAI;IAOjF,SAAS,CACP,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,EAC5B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACnC,GAAG,CAAC,IAAI;IAcX,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAgBzF,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI;IAIlF,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAwBnD,OAAO,CAAC,gBAAgB;IAgClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,OAAO;IAIvB,SAAS,IAAI,GAAG,CAAC,MAAM;IAKvB,iBAAiB,IAAI,cAAc,GAAG,SAAS;IAKzC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxF,OAAO,CAAC,mBAAmB;CAiB5B"}
|
package/dist/client.js
CHANGED
|
@@ -40,6 +40,7 @@ const resources_1 = require("@opentelemetry/resources");
|
|
|
40
40
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
41
41
|
const sdk_trace_node_2 = require("@opentelemetry/sdk-trace-node");
|
|
42
42
|
const api = __importStar(require("@opentelemetry/api"));
|
|
43
|
+
const snapshot_client_1 = require("./snapshot-client");
|
|
43
44
|
class TracekitClient {
|
|
44
45
|
constructor(config) {
|
|
45
46
|
this.config = {
|
|
@@ -47,6 +48,7 @@ class TracekitClient {
|
|
|
47
48
|
serviceName: config.serviceName || 'node-app',
|
|
48
49
|
enabled: config.enabled ?? true,
|
|
49
50
|
sampleRate: config.sampleRate ?? 1.0,
|
|
51
|
+
enableCodeMonitoring: config.enableCodeMonitoring ?? false,
|
|
50
52
|
apiKey: config.apiKey,
|
|
51
53
|
};
|
|
52
54
|
const resource = new resources_1.Resource({
|
|
@@ -66,6 +68,10 @@ class TracekitClient {
|
|
|
66
68
|
this.provider.register();
|
|
67
69
|
}
|
|
68
70
|
this.tracer = api.trace.getTracer('@tracekit/node-apm', '1.0.0');
|
|
71
|
+
if (this.config.enableCodeMonitoring) {
|
|
72
|
+
this.snapshotClient = new snapshot_client_1.SnapshotClient(this.config.apiKey, this.config.endpoint.replace('/v1/traces', ''), this.config.serviceName);
|
|
73
|
+
this.snapshotClient.start();
|
|
74
|
+
}
|
|
69
75
|
}
|
|
70
76
|
startTrace(operationName, attributes = {}) {
|
|
71
77
|
return this.tracer.startSpan(operationName, {
|
|
@@ -100,16 +106,51 @@ class TracekitClient {
|
|
|
100
106
|
span.addEvent(name, this.normalizeAttributes(attributes));
|
|
101
107
|
}
|
|
102
108
|
recordException(span, error) {
|
|
109
|
+
let formattedStackTrace = '';
|
|
110
|
+
if (error.stack) {
|
|
111
|
+
formattedStackTrace = this.formatStackTrace(error.stack);
|
|
112
|
+
}
|
|
113
|
+
span.addEvent('exception', {
|
|
114
|
+
'exception.type': error.constructor.name,
|
|
115
|
+
'exception.message': error.message,
|
|
116
|
+
'exception.stacktrace': formattedStackTrace,
|
|
117
|
+
});
|
|
103
118
|
span.recordException(error);
|
|
104
119
|
span.setStatus({
|
|
105
120
|
code: api.SpanStatusCode.ERROR,
|
|
106
121
|
message: error.message,
|
|
107
122
|
});
|
|
108
123
|
}
|
|
124
|
+
formatStackTrace(stack) {
|
|
125
|
+
const lines = stack.split('\n');
|
|
126
|
+
const formatted = [];
|
|
127
|
+
for (let i = 0; i < lines.length; i++) {
|
|
128
|
+
const line = lines[i].trim();
|
|
129
|
+
if (i === 0 && !line.startsWith('at ')) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const match = line.match(/at\s+(?:([^\s]+)\s+\()?([^:]+):(\d+):\d+\)?/);
|
|
133
|
+
if (match) {
|
|
134
|
+
const functionName = match[1] || '';
|
|
135
|
+
const file = match[2];
|
|
136
|
+
const lineNumber = match[3];
|
|
137
|
+
if (functionName && functionName !== 'anonymous') {
|
|
138
|
+
formatted.push(`${functionName} at ${file}:${lineNumber}`);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
formatted.push(`${file}:${lineNumber}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return formatted.join('\n');
|
|
146
|
+
}
|
|
109
147
|
async flush() {
|
|
110
148
|
await this.provider.forceFlush();
|
|
111
149
|
}
|
|
112
150
|
async shutdown() {
|
|
151
|
+
if (this.snapshotClient) {
|
|
152
|
+
this.snapshotClient.stop();
|
|
153
|
+
}
|
|
113
154
|
await this.provider.shutdown();
|
|
114
155
|
}
|
|
115
156
|
isEnabled() {
|
|
@@ -121,6 +162,14 @@ class TracekitClient {
|
|
|
121
162
|
getTracer() {
|
|
122
163
|
return this.tracer;
|
|
123
164
|
}
|
|
165
|
+
getSnapshotClient() {
|
|
166
|
+
return this.snapshotClient;
|
|
167
|
+
}
|
|
168
|
+
async captureSnapshot(label, variables = {}) {
|
|
169
|
+
if (this.snapshotClient) {
|
|
170
|
+
await this.snapshotClient.checkAndCaptureWithContext(label, variables);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
124
173
|
normalizeAttributes(attributes) {
|
|
125
174
|
const normalized = {};
|
|
126
175
|
for (const [key, value] of Object.entries(attributes)) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kEAAmE;AACnE,sFAA4E;AAC5E,wDAAoD;AACpD,8EAAiF;AACjF,kEAGuC;AACvC,wDAA0C;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare function init(config: TracekitConfig): TracekitClient;
|
|
|
3
3
|
export declare function middleware(): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
|
|
4
4
|
export declare function getClient(): TracekitClient;
|
|
5
5
|
export { TracekitClient, TracekitConfig } from './client';
|
|
6
|
+
export { SnapshotClient } from './snapshot-client';
|
|
6
7
|
export { createExpressMiddleware, getCurrentSpan } from './middleware/express';
|
|
7
8
|
export { Span, Context } from '@opentelemetry/api';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAS1D,wBAAgB,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAG3D;AAKD,wBAAgB,UAAU,6HAOzB;AAKD,wBAAgB,SAAS,IAAI,cAAc,CAO1C;AAGD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG/E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCurrentSpan = exports.createExpressMiddleware = exports.TracekitClient = void 0;
|
|
3
|
+
exports.getCurrentSpan = exports.createExpressMiddleware = exports.SnapshotClient = exports.TracekitClient = void 0;
|
|
4
4
|
exports.init = init;
|
|
5
5
|
exports.middleware = middleware;
|
|
6
6
|
exports.getClient = getClient;
|
|
@@ -15,7 +15,7 @@ function middleware() {
|
|
|
15
15
|
if (!globalClient) {
|
|
16
16
|
throw new Error('TraceKit not initialized. Call tracekit.init() first.');
|
|
17
17
|
}
|
|
18
|
-
return (0, express_1.createExpressMiddleware)(globalClient);
|
|
18
|
+
return (0, express_1.createExpressMiddleware)(globalClient, globalClient.getSnapshotClient());
|
|
19
19
|
}
|
|
20
20
|
function getClient() {
|
|
21
21
|
if (!globalClient) {
|
|
@@ -25,6 +25,8 @@ function getClient() {
|
|
|
25
25
|
}
|
|
26
26
|
var client_2 = require("./client");
|
|
27
27
|
Object.defineProperty(exports, "TracekitClient", { enumerable: true, get: function () { return client_2.TracekitClient; } });
|
|
28
|
+
var snapshot_client_1 = require("./snapshot-client");
|
|
29
|
+
Object.defineProperty(exports, "SnapshotClient", { enumerable: true, get: function () { return snapshot_client_1.SnapshotClient; } });
|
|
28
30
|
var express_2 = require("./middleware/express");
|
|
29
31
|
Object.defineProperty(exports, "createExpressMiddleware", { enumerable: true, get: function () { return express_2.createExpressMiddleware; } });
|
|
30
32
|
Object.defineProperty(exports, "getCurrentSpan", { enumerable: true, get: function () { return express_2.getCurrentSpan; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AASA,oBAGC;AAKD,gCAOC;AAKD,8BAOC;AApCD,qCAA0D;AAC1D,kDAA+D;AAG/D,IAAI,YAAY,GAA0B,IAAI,CAAC;AAK/C,SAAgB,IAAI,CAAC,MAAsB;IACzC,YAAY,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,YAAY,CAAC;AACtB,CAAC;AAKD,SAAgB,UAAU;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,IAAA,iCAAuB,EAAC,YAAY,EAAE,YAAY,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACjF,CAAC;AAKD,SAAgB,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAGD,mCAA0D;AAAjD,wGAAA,cAAc,OAAA;AACvB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,gDAA+E;AAAtE,kHAAA,uBAAuB,OAAA;AAAE,yGAAA,cAAc,OAAA"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
2
|
import { TracekitClient } from '../client';
|
|
3
|
+
import { SnapshotClient } from '../snapshot-client';
|
|
3
4
|
import * as api from '@opentelemetry/api';
|
|
4
|
-
export declare function createExpressMiddleware(client: TracekitClient): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
5
|
+
export declare function createExpressMiddleware(client: TracekitClient, snapshotClient?: SnapshotClient): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
5
6
|
export declare function getCurrentSpan(req: Request): api.Span | null;
|
|
7
|
+
export declare function getRequestContext(): Record<string, any> | undefined;
|
|
6
8
|
//# sourceMappingURL=express.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAK1C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,EAAE,cAAc,IAC/E,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAsE9D;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAE5D;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAEnE"}
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createExpressMiddleware = createExpressMiddleware;
|
|
4
4
|
exports.getCurrentSpan = getCurrentSpan;
|
|
5
|
-
|
|
5
|
+
exports.getRequestContext = getRequestContext;
|
|
6
|
+
const async_hooks_1 = require("async_hooks");
|
|
7
|
+
const requestContextStorage = new async_hooks_1.AsyncLocalStorage();
|
|
8
|
+
function createExpressMiddleware(client, snapshotClient) {
|
|
6
9
|
return async (req, res, next) => {
|
|
7
10
|
if (!client.isEnabled() || !client.shouldSample()) {
|
|
8
11
|
return next();
|
|
@@ -17,34 +20,48 @@ function createExpressMiddleware(client) {
|
|
|
17
20
|
'http.client_ip': getClientIp(req),
|
|
18
21
|
});
|
|
19
22
|
req.__tracekitSpan = span;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'http.duration_ms': durationMs,
|
|
29
|
-
}, res.statusCode >= 400 ? 'ERROR' : 'OK');
|
|
30
|
-
}
|
|
31
|
-
return originalSend.call(this, body);
|
|
23
|
+
const requestContext = {
|
|
24
|
+
method: req.method,
|
|
25
|
+
path: req.path,
|
|
26
|
+
url: req.originalUrl,
|
|
27
|
+
ip: getClientIp(req),
|
|
28
|
+
user_agent: req.get('user-agent') || '',
|
|
29
|
+
query: req.query,
|
|
30
|
+
headers: filterHeaders(req.headers),
|
|
32
31
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
requestContextStorage.run(requestContext, () => {
|
|
33
|
+
const originalSend = res.send;
|
|
34
|
+
let responseSent = false;
|
|
35
|
+
res.send = function (body) {
|
|
36
|
+
if (!responseSent) {
|
|
37
|
+
responseSent = true;
|
|
38
|
+
const durationMs = Date.now() - startTime;
|
|
39
|
+
client.endSpan(span, {
|
|
40
|
+
'http.status_code': res.statusCode,
|
|
41
|
+
'http.duration_ms': durationMs,
|
|
42
|
+
}, res.statusCode >= 400 ? 'ERROR' : 'OK');
|
|
43
|
+
}
|
|
44
|
+
return originalSend.call(this, body);
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
next();
|
|
40
48
|
}
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error instanceof Error) {
|
|
51
|
+
client.recordException(span, error);
|
|
52
|
+
client.endSpan(span, {}, 'ERROR');
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
43
57
|
};
|
|
44
58
|
}
|
|
45
59
|
function getCurrentSpan(req) {
|
|
46
60
|
return req.__tracekitSpan || null;
|
|
47
61
|
}
|
|
62
|
+
function getRequestContext() {
|
|
63
|
+
return requestContextStorage.getStore();
|
|
64
|
+
}
|
|
48
65
|
function getOperationName(req) {
|
|
49
66
|
if (req.route?.path) {
|
|
50
67
|
return `${req.method} ${req.route.path}`;
|
|
@@ -57,4 +74,14 @@ function getClientIp(req) {
|
|
|
57
74
|
req.socket.remoteAddress ||
|
|
58
75
|
'');
|
|
59
76
|
}
|
|
77
|
+
function filterHeaders(headers) {
|
|
78
|
+
const filtered = {};
|
|
79
|
+
const allowlist = ['content-type', 'content-length', 'host', 'user-agent', 'referer'];
|
|
80
|
+
for (const key of allowlist) {
|
|
81
|
+
if (headers[key]) {
|
|
82
|
+
filtered[key] = headers[key];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return filtered;
|
|
86
|
+
}
|
|
60
87
|
//# sourceMappingURL=express.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { DynamicModule } from '@nestjs/common';
|
|
1
|
+
import { DynamicModule, OnModuleDestroy } from '@nestjs/common';
|
|
2
2
|
import { TracekitConfig } from '../client';
|
|
3
|
-
export declare class TracekitModule {
|
|
3
|
+
export declare class TracekitModule implements OnModuleDestroy {
|
|
4
4
|
static forRoot(config: TracekitConfig): DynamicModule;
|
|
5
5
|
static forRootAsync(options: {
|
|
6
6
|
useFactory: (...args: any[]) => Promise<TracekitConfig> | TracekitConfig;
|
|
7
7
|
inject?: any[];
|
|
8
8
|
}): DynamicModule;
|
|
9
|
+
onModuleDestroy(): Promise<void>;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=tracekit.module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracekit.module.d.ts","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAU,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"tracekit.module.d.ts","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3D,qBAEa,cAAe,YAAW,eAAe;IACpD,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa;IA0BrD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;QAC3B,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;QACzE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,GAAG,aAAa;IAgCX,eAAe;CAGtB"}
|
|
@@ -14,11 +14,15 @@ const client_1 = require("../client");
|
|
|
14
14
|
const tracekit_interceptor_1 = require("./tracekit.interceptor");
|
|
15
15
|
let TracekitModule = TracekitModule_1 = class TracekitModule {
|
|
16
16
|
static forRoot(config) {
|
|
17
|
+
const client = new client_1.TracekitClient(config);
|
|
18
|
+
const snapshotClient = client.getSnapshotClient();
|
|
17
19
|
const clientProvider = {
|
|
18
20
|
provide: 'TRACEKIT_CLIENT',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
useValue: client,
|
|
22
|
+
};
|
|
23
|
+
const snapshotClientProvider = {
|
|
24
|
+
provide: 'TRACEKIT_SNAPSHOT_CLIENT',
|
|
25
|
+
useValue: snapshotClient,
|
|
22
26
|
};
|
|
23
27
|
const interceptorProvider = {
|
|
24
28
|
provide: core_1.APP_INTERCEPTOR,
|
|
@@ -26,8 +30,8 @@ let TracekitModule = TracekitModule_1 = class TracekitModule {
|
|
|
26
30
|
};
|
|
27
31
|
return {
|
|
28
32
|
module: TracekitModule_1,
|
|
29
|
-
providers: [clientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
|
|
30
|
-
exports: ['TRACEKIT_CLIENT'],
|
|
33
|
+
providers: [clientProvider, snapshotClientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
|
|
34
|
+
exports: ['TRACEKIT_CLIENT', 'TRACEKIT_SNAPSHOT_CLIENT'],
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
static forRootAsync(options) {
|
|
@@ -39,16 +43,27 @@ let TracekitModule = TracekitModule_1 = class TracekitModule {
|
|
|
39
43
|
},
|
|
40
44
|
inject: options.inject || [],
|
|
41
45
|
};
|
|
46
|
+
const snapshotClientProvider = {
|
|
47
|
+
provide: 'TRACEKIT_SNAPSHOT_CLIENT',
|
|
48
|
+
useFactory: async (...args) => {
|
|
49
|
+
const config = await options.useFactory(...args);
|
|
50
|
+
const client = new client_1.TracekitClient(config);
|
|
51
|
+
return client.getSnapshotClient();
|
|
52
|
+
},
|
|
53
|
+
inject: options.inject || [],
|
|
54
|
+
};
|
|
42
55
|
const interceptorProvider = {
|
|
43
56
|
provide: core_1.APP_INTERCEPTOR,
|
|
44
57
|
useClass: tracekit_interceptor_1.TracekitInterceptor,
|
|
45
58
|
};
|
|
46
59
|
return {
|
|
47
60
|
module: TracekitModule_1,
|
|
48
|
-
providers: [clientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
|
|
49
|
-
exports: ['TRACEKIT_CLIENT'],
|
|
61
|
+
providers: [clientProvider, snapshotClientProvider, interceptorProvider, tracekit_interceptor_1.TracekitInterceptor],
|
|
62
|
+
exports: ['TRACEKIT_CLIENT', 'TRACEKIT_SNAPSHOT_CLIENT'],
|
|
50
63
|
};
|
|
51
64
|
}
|
|
65
|
+
async onModuleDestroy() {
|
|
66
|
+
}
|
|
52
67
|
};
|
|
53
68
|
exports.TracekitModule = TracekitModule;
|
|
54
69
|
exports.TracekitModule = TracekitModule = TracekitModule_1 = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracekit.module.js","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"tracekit.module.js","sourceRoot":"","sources":["../../src/nestjs/tracekit.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAgF;AAChF,uCAA+C;AAC/C,sCAA2D;AAC3D,iEAA6D;AAItD,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,MAAM,CAAC,OAAO,CAAC,MAAsB;QACnC,MAAM,MAAM,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAElD,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,QAAQ,EAAE,MAAM;SACjB,CAAC;QAEF,MAAM,sBAAsB,GAAG;YAC7B,OAAO,EAAE,0BAA0B;YACnC,QAAQ,EAAE,cAAc;SACzB,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YAC7F,OAAO,EAAE,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAGnB;QACC,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjD,OAAO,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,sBAAsB,GAAG;YAC7B,OAAO,EAAE,0BAA0B;YACnC,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,IAAI,uBAAc,CAAC,MAAM,CAAC,CAAC;gBAC1C,OAAO,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,sBAAe;YACxB,QAAQ,EAAE,0CAAmB;SAC9B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE,CAAC,cAAc,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,0CAAmB,CAAC;YAC7F,OAAO,EAAE,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe;IAErB,CAAC;CACF,CAAA;AAjEY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAiE1B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface BreakpointConfig {
|
|
2
|
+
id: string;
|
|
3
|
+
service_name: string;
|
|
4
|
+
file_path: string;
|
|
5
|
+
function_name: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
line_number: number;
|
|
8
|
+
condition?: string;
|
|
9
|
+
max_captures: number;
|
|
10
|
+
capture_count: number;
|
|
11
|
+
expire_at?: Date;
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface Snapshot {
|
|
15
|
+
breakpoint_id?: string;
|
|
16
|
+
service_name: string;
|
|
17
|
+
file_path: string;
|
|
18
|
+
function_name: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
line_number: number;
|
|
21
|
+
variables: Record<string, any>;
|
|
22
|
+
stack_trace: string;
|
|
23
|
+
trace_id?: string;
|
|
24
|
+
span_id?: string;
|
|
25
|
+
request_context?: Record<string, any>;
|
|
26
|
+
captured_at: Date;
|
|
27
|
+
}
|
|
28
|
+
export declare class SnapshotClient {
|
|
29
|
+
private apiKey;
|
|
30
|
+
private baseURL;
|
|
31
|
+
private serviceName;
|
|
32
|
+
private breakpointsCache;
|
|
33
|
+
private registrationCache;
|
|
34
|
+
private pollInterval?;
|
|
35
|
+
private lastFetch?;
|
|
36
|
+
constructor(apiKey: string, baseURL: string, serviceName: string);
|
|
37
|
+
start(): void;
|
|
38
|
+
stop(): void;
|
|
39
|
+
checkAndCaptureWithContext(label: string, variables?: Record<string, any>): Promise<void>;
|
|
40
|
+
private parseStackTrace;
|
|
41
|
+
private fetchActiveBreakpoints;
|
|
42
|
+
private updateBreakpointCache;
|
|
43
|
+
private autoRegisterBreakpoint;
|
|
44
|
+
private captureSnapshot;
|
|
45
|
+
private extractRequestContext;
|
|
46
|
+
private sanitizeVariables;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=snapshot-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-client.d.ts","sourceRoot":"","sources":["../src/snapshot-client.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,SAAS,CAAC,CAAO;gBAEb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAOhE,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;IASN,0BAA0B,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,OAAO,CAAC,IAAI,CAAC;IAqEhB,OAAO,CAAC,eAAe;YA+BT,sBAAsB;IAsBpC,OAAO,CAAC,qBAAqB;YAqBf,sBAAsB;YAiCtB,eAAe;IAsB7B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,iBAAiB;CAc1B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SnapshotClient = void 0;
|
|
4
|
+
const express_1 = require("./middleware/express");
|
|
5
|
+
class SnapshotClient {
|
|
6
|
+
constructor(apiKey, baseURL, serviceName) {
|
|
7
|
+
this.breakpointsCache = new Map();
|
|
8
|
+
this.registrationCache = new Set();
|
|
9
|
+
this.apiKey = apiKey;
|
|
10
|
+
this.baseURL = baseURL;
|
|
11
|
+
this.serviceName = serviceName;
|
|
12
|
+
}
|
|
13
|
+
start() {
|
|
14
|
+
this.fetchActiveBreakpoints();
|
|
15
|
+
this.pollInterval = setInterval(() => this.fetchActiveBreakpoints(), 30000);
|
|
16
|
+
console.log(`📸 TraceKit Snapshot Client started for service: ${this.serviceName}`);
|
|
17
|
+
}
|
|
18
|
+
stop() {
|
|
19
|
+
if (this.pollInterval) {
|
|
20
|
+
clearInterval(this.pollInterval);
|
|
21
|
+
this.pollInterval = undefined;
|
|
22
|
+
}
|
|
23
|
+
console.log('📸 TraceKit Snapshot Client stopped');
|
|
24
|
+
}
|
|
25
|
+
async checkAndCaptureWithContext(label, variables = {}) {
|
|
26
|
+
const stack = new Error().stack || '';
|
|
27
|
+
const caller = this.parseStackTrace(stack);
|
|
28
|
+
if (!caller) {
|
|
29
|
+
console.warn('⚠️ Could not detect caller location');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const { file, line, functionName } = caller;
|
|
33
|
+
const locationKey = `${functionName}:${label}`;
|
|
34
|
+
if (!this.registrationCache.has(locationKey)) {
|
|
35
|
+
const breakpoint = await this.autoRegisterBreakpoint({
|
|
36
|
+
file_path: file,
|
|
37
|
+
line_number: line,
|
|
38
|
+
function_name: functionName,
|
|
39
|
+
label,
|
|
40
|
+
});
|
|
41
|
+
if (breakpoint) {
|
|
42
|
+
this.registrationCache.add(locationKey);
|
|
43
|
+
this.breakpointsCache.set(locationKey, breakpoint);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const breakpoint = this.breakpointsCache.get(locationKey);
|
|
50
|
+
if (!breakpoint || !breakpoint.enabled) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (breakpoint.expire_at && new Date() > breakpoint.expire_at) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (breakpoint.max_captures > 0 && breakpoint.capture_count >= breakpoint.max_captures) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const requestContext = this.extractRequestContext();
|
|
60
|
+
const snapshot = {
|
|
61
|
+
breakpoint_id: breakpoint.id,
|
|
62
|
+
service_name: this.serviceName,
|
|
63
|
+
file_path: file,
|
|
64
|
+
function_name: functionName,
|
|
65
|
+
label,
|
|
66
|
+
line_number: line,
|
|
67
|
+
variables: this.sanitizeVariables(variables),
|
|
68
|
+
stack_trace: stack,
|
|
69
|
+
request_context: requestContext,
|
|
70
|
+
captured_at: new Date(),
|
|
71
|
+
};
|
|
72
|
+
await this.captureSnapshot(snapshot);
|
|
73
|
+
}
|
|
74
|
+
parseStackTrace(stack) {
|
|
75
|
+
const lines = stack.split('\n');
|
|
76
|
+
const callerLine = lines[3]?.trim();
|
|
77
|
+
if (!callerLine)
|
|
78
|
+
return null;
|
|
79
|
+
const match = callerLine.match(/at\s+(?:([^\s]+)\s+\()?([^:]+):(\d+):\d+\)?/);
|
|
80
|
+
if (!match)
|
|
81
|
+
return null;
|
|
82
|
+
const functionName = match[1] || 'anonymous';
|
|
83
|
+
const file = match[2];
|
|
84
|
+
const line = parseInt(match[3], 10);
|
|
85
|
+
return { file, line, functionName };
|
|
86
|
+
}
|
|
87
|
+
async fetchActiveBreakpoints() {
|
|
88
|
+
try {
|
|
89
|
+
const url = `${this.baseURL}/sdk/snapshots/active/${this.serviceName}`;
|
|
90
|
+
const response = await fetch(url, {
|
|
91
|
+
headers: {
|
|
92
|
+
'X-API-Key': this.apiKey,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error(`HTTP ${response.status}`);
|
|
97
|
+
}
|
|
98
|
+
const data = await response.json();
|
|
99
|
+
this.updateBreakpointCache(data.breakpoints || []);
|
|
100
|
+
this.lastFetch = new Date();
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error('⚠️ Failed to fetch breakpoints:', error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
updateBreakpointCache(breakpoints) {
|
|
107
|
+
this.breakpointsCache.clear();
|
|
108
|
+
for (const bp of breakpoints) {
|
|
109
|
+
if (bp.label && bp.function_name) {
|
|
110
|
+
const labelKey = `${bp.function_name}:${bp.label}`;
|
|
111
|
+
this.breakpointsCache.set(labelKey, bp);
|
|
112
|
+
}
|
|
113
|
+
const lineKey = `${bp.file_path}:${bp.line_number}`;
|
|
114
|
+
this.breakpointsCache.set(lineKey, bp);
|
|
115
|
+
}
|
|
116
|
+
if (breakpoints.length > 0) {
|
|
117
|
+
console.log(`📸 Updated breakpoint cache: ${breakpoints.length} active breakpoints`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async autoRegisterBreakpoint(data) {
|
|
121
|
+
try {
|
|
122
|
+
const response = await fetch(`${this.baseURL}/sdk/snapshots/auto-register`, {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
headers: {
|
|
125
|
+
'X-API-Key': this.apiKey,
|
|
126
|
+
'Content-Type': 'application/json',
|
|
127
|
+
},
|
|
128
|
+
body: JSON.stringify({
|
|
129
|
+
service_name: this.serviceName,
|
|
130
|
+
...data,
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
console.error('⚠️ Failed to auto-register breakpoint:', response.status);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const result = await response.json();
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error('⚠️ Failed to auto-register breakpoint:', error);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async captureSnapshot(snapshot) {
|
|
146
|
+
try {
|
|
147
|
+
const response = await fetch(`${this.baseURL}/sdk/snapshots/capture`, {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
headers: {
|
|
150
|
+
'X-API-Key': this.apiKey,
|
|
151
|
+
'Content-Type': 'application/json',
|
|
152
|
+
},
|
|
153
|
+
body: JSON.stringify(snapshot),
|
|
154
|
+
});
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
console.error('⚠️ Failed to capture snapshot:', response.status);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
console.log(`📸 Snapshot captured: ${snapshot.label || snapshot.file_path}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error('⚠️ Failed to capture snapshot:', error);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
extractRequestContext() {
|
|
167
|
+
return (0, express_1.getRequestContext)();
|
|
168
|
+
}
|
|
169
|
+
sanitizeVariables(variables) {
|
|
170
|
+
const sanitized = {};
|
|
171
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
172
|
+
try {
|
|
173
|
+
JSON.stringify(value);
|
|
174
|
+
sanitized[key] = value;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
sanitized[key] = `[${typeof value}]`;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return sanitized;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.SnapshotClient = SnapshotClient;
|
|
184
|
+
//# sourceMappingURL=snapshot-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-client.js","sourceRoot":"","sources":["../src/snapshot-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracekit/node-apm",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "TraceKit APM for Node.js - Zero-config distributed tracing for Express and NestJS",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "TraceKit APM for Node.js - Zero-config distributed tracing and code monitoring for Express and NestJS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|