@vtvlive/interactive-apm 0.0.2
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/LICENSE +21 -0
- package/README.md +320 -0
- package/dist/factories/tracing-provider.factory.d.ts +81 -0
- package/dist/factories/tracing-provider.factory.d.ts.map +1 -0
- package/dist/factories/tracing-provider.factory.js +93 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/init/elastic-apm-init.d.ts +51 -0
- package/dist/init/elastic-apm-init.d.ts.map +1 -0
- package/dist/init/elastic-apm-init.js +86 -0
- package/dist/init/opentelemetry-init.d.ts +51 -0
- package/dist/init/opentelemetry-init.d.ts.map +1 -0
- package/dist/init/opentelemetry-init.js +156 -0
- package/dist/interfaces/tracing-provider.interface.d.ts +43 -0
- package/dist/interfaces/tracing-provider.interface.d.ts.map +1 -0
- package/dist/interfaces/tracing-provider.interface.js +2 -0
- package/dist/modules/tracing.module.d.ts +96 -0
- package/dist/modules/tracing.module.d.ts.map +1 -0
- package/dist/modules/tracing.module.js +162 -0
- package/dist/providers/elastic-apm.tracing-provider.d.ts +57 -0
- package/dist/providers/elastic-apm.tracing-provider.d.ts.map +1 -0
- package/dist/providers/elastic-apm.tracing-provider.js +163 -0
- package/dist/providers/opentelemetry.tracing-provider.d.ts +68 -0
- package/dist/providers/opentelemetry.tracing-provider.d.ts.map +1 -0
- package/dist/providers/opentelemetry.tracing-provider.js +288 -0
- package/dist/services/tracing.service.d.ts +88 -0
- package/dist/services/tracing.service.d.ts.map +1 -0
- package/dist/services/tracing.service.js +103 -0
- package/dist/types/apm-provider.type.d.ts +47 -0
- package/dist/types/apm-provider.type.d.ts.map +1 -0
- package/dist/types/apm-provider.type.js +32 -0
- package/dist/utils/tracing.helper.d.ts +68 -0
- package/dist/utils/tracing.helper.d.ts.map +1 -0
- package/dist/utils/tracing.helper.js +115 -0
- package/package.json +105 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 VTVLive
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# @vtvlive/interactive-apm
|
|
2
|
+
|
|
3
|
+
> APM integration package supporting both Elastic APM and OpenTelemetry with NestJS integration
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Dual APM Provider Support**: Switch between Elastic APM and OpenTelemetry via environment variable
|
|
8
|
+
- **NestJS Integration**: Ready-to-use module with dependency injection
|
|
9
|
+
- **Standalone Usage**: Works without NestJS for vanilla TypeScript/JavaScript projects
|
|
10
|
+
- **Flexible Configuration**: Configure via environment variables or programmatic options
|
|
11
|
+
- **TypeScript Support**: Fully typed with TypeScript
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### For OpenTelemetry
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @vtvlive/interactive-apm @opentelemetry/api @opentelemetry/exporter-trace-otlp-http @opentelemetry/instrumentation-http @opentelemetry/sdk-node @opentelemetry/resources
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### For Elastic APM
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @vtvlive/interactive-apm elastic-apm-node
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### For NestJS Integration
|
|
28
|
+
|
|
29
|
+
Add the required NestJS dependencies:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @nestjs/common @nestjs/config
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Environment Variables
|
|
36
|
+
|
|
37
|
+
| Variable | Description | Default |
|
|
38
|
+
|----------|-------------|---------|
|
|
39
|
+
| `APM_PROVIDER` | Provider selection: `elastic-apm` or `opentelemetry` | `opentelemetry` |
|
|
40
|
+
| `ELASTIC_APM_SERVICE_NAME` | Service name for APM | Required |
|
|
41
|
+
| `ELASTIC_APM_SERVER_URL` | Elastic APM server URL | `http://localhost:8200` |
|
|
42
|
+
| `ELASTIC_APM_SECRET_TOKEN` | Secret token for authentication | Optional |
|
|
43
|
+
| `ELASTIC_APM_ENVIRONMENT` | Deployment environment | `development` |
|
|
44
|
+
| `ELASTIC_OTLP_ENDPOINT` | OTLP endpoint (OpenTelemetry only) | `http://localhost:8200/v1/traces` |
|
|
45
|
+
| `ELASTIC_OTLP_AUTH_TOKEN` | OTLP-specific auth token (takes precedence over `ELASTIC_APM_SECRET_TOKEN`) | Optional |
|
|
46
|
+
| `ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER` | Enable console exporter for debugging (default: `false`) | `false` |
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
### NestJS Integration
|
|
51
|
+
|
|
52
|
+
#### Basic Usage (reads from environment)
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// app.module.ts
|
|
56
|
+
import { TracingModule } from '@vtvlive/interactive-apm';
|
|
57
|
+
|
|
58
|
+
@Module({
|
|
59
|
+
imports: [
|
|
60
|
+
TracingModule.registerAsync(),
|
|
61
|
+
// ... other modules
|
|
62
|
+
],
|
|
63
|
+
})
|
|
64
|
+
export class AppModule {}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### With Explicit Options
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// app.module.ts
|
|
71
|
+
import { TracingModule } from '@vtvlive/interactive-apm';
|
|
72
|
+
|
|
73
|
+
@Module({
|
|
74
|
+
imports: [
|
|
75
|
+
TracingModule.register({
|
|
76
|
+
provider: 'opentelemetry',
|
|
77
|
+
serviceName: 'my-service',
|
|
78
|
+
otlpEndpoint: 'http://localhost:8200/v1/traces',
|
|
79
|
+
environment: 'production',
|
|
80
|
+
autoInit: true,
|
|
81
|
+
}),
|
|
82
|
+
// ... other modules
|
|
83
|
+
],
|
|
84
|
+
})
|
|
85
|
+
export class AppModule {}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Using ConfigService
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// app.module.ts
|
|
92
|
+
import { TracingModule } from '@vtvlive/interactive-apm';
|
|
93
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
94
|
+
|
|
95
|
+
@Module({
|
|
96
|
+
imports: [
|
|
97
|
+
TracingModule.registerAsync({
|
|
98
|
+
imports: [ConfigModule],
|
|
99
|
+
useFactory: (configService: ConfigService) => ({
|
|
100
|
+
provider: configService.get('APM_PROVIDER'),
|
|
101
|
+
serviceName: configService.get('ELASTIC_APM_SERVICE_NAME'),
|
|
102
|
+
environment: configService.get('ELASTIC_APM_ENVIRONMENT'),
|
|
103
|
+
}),
|
|
104
|
+
inject: [ConfigService],
|
|
105
|
+
}),
|
|
106
|
+
// ... other modules
|
|
107
|
+
],
|
|
108
|
+
})
|
|
109
|
+
export class AppModule {}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### In Controllers/Services
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { Injectable } from '@nestjs/common';
|
|
116
|
+
import { TracingService } from '@vtvlive/interactive-apm';
|
|
117
|
+
|
|
118
|
+
@Injectable()
|
|
119
|
+
export class UserService {
|
|
120
|
+
constructor(private readonly tracingService: TracingService) {}
|
|
121
|
+
|
|
122
|
+
async findById(id: string) {
|
|
123
|
+
const span = this.tracingService.startSpan('user.findById', { userId: id }, 'SERVER');
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
const user = await this.userRepository.findById(id);
|
|
127
|
+
return user;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
this.tracingService.captureError(error);
|
|
130
|
+
throw error;
|
|
131
|
+
} finally {
|
|
132
|
+
span.end();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async create(data: CreateUserDto) {
|
|
137
|
+
return this.tracingService.startSpanWithParent(
|
|
138
|
+
'user.create',
|
|
139
|
+
async (span) => {
|
|
140
|
+
span.setAttribute('user.email', data.email);
|
|
141
|
+
const user = await this.userRepository.create(data);
|
|
142
|
+
return user;
|
|
143
|
+
},
|
|
144
|
+
{ userType: 'premium' }
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Standalone Usage (without NestJS)
|
|
151
|
+
|
|
152
|
+
#### OpenTelemetry
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { initOpenTelemetry, TracingHelper } from '@vtvlive/interactive-apm';
|
|
156
|
+
import { SpanKind } from '@opentelemetry/api';
|
|
157
|
+
|
|
158
|
+
// Initialize at the top of your application
|
|
159
|
+
await initOpenTelemetry({
|
|
160
|
+
serviceName: 'my-service',
|
|
161
|
+
otlpEndpoint: 'http://localhost:8200/v1/traces',
|
|
162
|
+
environment: 'production',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Use TracingHelper for manual tracing
|
|
166
|
+
const span = TracingHelper.startSpan('operation', { key: 'value' }, SpanKind.SERVER);
|
|
167
|
+
try {
|
|
168
|
+
// Your code here
|
|
169
|
+
TracingHelper.setAttribute('result', 'success');
|
|
170
|
+
} catch (error) {
|
|
171
|
+
TracingHelper.captureError(error);
|
|
172
|
+
throw error;
|
|
173
|
+
} finally {
|
|
174
|
+
TracingHelper.endSpan(span);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### Elastic APM
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { initElasticApm, createTracingProvider, TracingService } from '@vtvlive/interactive-apm';
|
|
182
|
+
|
|
183
|
+
// Initialize at the top of your application
|
|
184
|
+
initElasticApm({
|
|
185
|
+
serviceName: 'my-service',
|
|
186
|
+
serverUrl: 'http://localhost:8200',
|
|
187
|
+
environment: 'production',
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Use TracingService
|
|
191
|
+
const provider = createTracingProvider({ provider: 'elastic-apm' });
|
|
192
|
+
const tracingService = new TracingService(provider);
|
|
193
|
+
|
|
194
|
+
const span = tracingService.startSpan('operation', { key: 'value' });
|
|
195
|
+
try {
|
|
196
|
+
// Your code here
|
|
197
|
+
} catch (error) {
|
|
198
|
+
tracingService.captureError(error);
|
|
199
|
+
throw error;
|
|
200
|
+
} finally {
|
|
201
|
+
span.end();
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## API Reference
|
|
206
|
+
|
|
207
|
+
### TracingModule
|
|
208
|
+
|
|
209
|
+
NestJS module for APM integration.
|
|
210
|
+
|
|
211
|
+
| Method | Description |
|
|
212
|
+
|--------|-------------|
|
|
213
|
+
| `register(options)` | Register module with synchronous options |
|
|
214
|
+
| `registerAsync(options)` | Register module with asynchronous options |
|
|
215
|
+
|
|
216
|
+
### TracingService
|
|
217
|
+
|
|
218
|
+
Service for tracing operations.
|
|
219
|
+
|
|
220
|
+
| Method | Description |
|
|
221
|
+
|--------|-------------|
|
|
222
|
+
| `startSpan(name, attributes?, spanKind?)` | Start a new span |
|
|
223
|
+
| `startSpanWithParent(name, fn, attributes?)` | Execute function with tracing context |
|
|
224
|
+
| `captureError(error)` | Capture error to active span |
|
|
225
|
+
| `setAttribute(key, value)` | Set attribute on active span |
|
|
226
|
+
| `endSpan(span?)` | End a span |
|
|
227
|
+
| `shutdown()` | Flush and shutdown provider |
|
|
228
|
+
|
|
229
|
+
### TracingHelper
|
|
230
|
+
|
|
231
|
+
Static utility class for OpenTelemetry.
|
|
232
|
+
|
|
233
|
+
| Method | Description |
|
|
234
|
+
|--------|-------------|
|
|
235
|
+
| `startSpan(name, attributes?, spanKind?)` | Start a new span |
|
|
236
|
+
| `startSpanWithParent(name, fn, attributes?)` | Execute function with tracing context |
|
|
237
|
+
| `captureError(error)` | Capture error to active span |
|
|
238
|
+
| `setAttribute(key, value)` | Set attribute on active span |
|
|
239
|
+
| `endSpan(span?)` | End a span |
|
|
240
|
+
| `getActiveSpan()` | Get the active span |
|
|
241
|
+
| `getTraceId()` | Get the current trace ID |
|
|
242
|
+
|
|
243
|
+
### SpanKind
|
|
244
|
+
|
|
245
|
+
Types of spans:
|
|
246
|
+
|
|
247
|
+
- `INTERNAL`: Internal operation
|
|
248
|
+
- `SERVER`: Server-side request handler (API endpoints)
|
|
249
|
+
- `CLIENT`: Client-side call (outgoing HTTP, database)
|
|
250
|
+
- `PRODUCER`: Message producer
|
|
251
|
+
- `CONSUMER`: Message consumer
|
|
252
|
+
|
|
253
|
+
## Provider Selection
|
|
254
|
+
|
|
255
|
+
The package supports two APM providers:
|
|
256
|
+
|
|
257
|
+
### OpenTelemetry (default)
|
|
258
|
+
|
|
259
|
+
Uses OpenTelemetry SDK with OTLP exporter to send traces to Elastic APM.
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
APM_PROVIDER=opentelemetry
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Elastic APM
|
|
266
|
+
|
|
267
|
+
Uses the native Elastic APM Node.js agent.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
APM_PROVIDER=elastic-apm
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Testing
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Run all tests
|
|
277
|
+
npm test
|
|
278
|
+
|
|
279
|
+
# Run tests in watch mode
|
|
280
|
+
npm run test:watch
|
|
281
|
+
|
|
282
|
+
# Run tests with coverage
|
|
283
|
+
npm run test:coverage
|
|
284
|
+
|
|
285
|
+
# Run only unit tests
|
|
286
|
+
npm run test:unit
|
|
287
|
+
|
|
288
|
+
# Run only integration tests
|
|
289
|
+
npm run test:integration
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Development
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# Build the package
|
|
296
|
+
npm run build
|
|
297
|
+
|
|
298
|
+
# Build in watch mode
|
|
299
|
+
npm run build:watch
|
|
300
|
+
|
|
301
|
+
# Run tests
|
|
302
|
+
npm test
|
|
303
|
+
|
|
304
|
+
# Clean build artifacts
|
|
305
|
+
npm run clean
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**For detailed deployment instructions (build, publish, install from private registry), see [DEPLOYMENT.md](DEPLOYMENT.md)**
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT
|
|
313
|
+
|
|
314
|
+
## Author
|
|
315
|
+
|
|
316
|
+
VTVLive
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
For more information, visit the [Elastic APM documentation](https://www.elastic.co/guide/en/apm/get-started/current/index.html) or [OpenTelemetry documentation](https://opentelemetry.io/docs/instrumentation/js/).
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ITracingProvider } from '../interfaces/tracing-provider.interface';
|
|
2
|
+
import { ApmProvider } from '../types/apm-provider.type';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for creating a tracing provider
|
|
5
|
+
*/
|
|
6
|
+
export interface TracingProviderConfig {
|
|
7
|
+
/** Provider type: 'elastic-apm' or 'opentelemetry' (default: 'opentelemetry') */
|
|
8
|
+
provider?: ApmProvider | string;
|
|
9
|
+
/** Service name for APM */
|
|
10
|
+
serviceName?: string;
|
|
11
|
+
/** Deployment environment */
|
|
12
|
+
environment?: string;
|
|
13
|
+
/** Elastic APM server URL (for elastic-apm provider) */
|
|
14
|
+
serverUrl?: string;
|
|
15
|
+
/** Secret token for authentication */
|
|
16
|
+
secretToken?: string;
|
|
17
|
+
/** OTLP endpoint URL (for opentelemetry provider) */
|
|
18
|
+
otlpEndpoint?: string;
|
|
19
|
+
/** OTLP auth token (takes precedence over secretToken for OTLP) */
|
|
20
|
+
otlpAuthToken?: string;
|
|
21
|
+
/** OTLP headers as a record (key-value pairs). If provided, merges with Authorization header when token is set. */
|
|
22
|
+
otlpHeaders?: Record<string, string>;
|
|
23
|
+
/** Enable console exporter for debugging (default: false) */
|
|
24
|
+
enableConsoleExporter?: boolean;
|
|
25
|
+
/** Service version */
|
|
26
|
+
serviceVersion?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Factory function để tạo APM Provider phù hợp dựa trên cấu hình
|
|
30
|
+
*
|
|
31
|
+
* @param config Configuration options
|
|
32
|
+
* @returns ITracingProvider instance
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Tạo provider với config cụ thể
|
|
36
|
+
* const provider = createTracingProvider({
|
|
37
|
+
* provider: ApmProvider.OPENTELEMETRY,
|
|
38
|
+
* serviceName: 'my-service',
|
|
39
|
+
* otlpEndpoint: 'http://localhost:8200/v1/traces'
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Tạo provider từ environment variables
|
|
44
|
+
* const provider = createTracingProvider();
|
|
45
|
+
*/
|
|
46
|
+
export declare function createTracingProvider(config?: TracingProviderConfig): ITracingProvider;
|
|
47
|
+
/**
|
|
48
|
+
* NestJS Provider token for dependency injection
|
|
49
|
+
* Use this when integrating with NestJS
|
|
50
|
+
*/
|
|
51
|
+
export declare const TRACING_PROVIDER_TOKEN = "ITracingProvider";
|
|
52
|
+
/**
|
|
53
|
+
* NestJS factory provider for use with NestJS dependency injection
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // Trong NestJS module
|
|
57
|
+
* import { TracingProviderFactory, TRACING_PROVIDER_TOKEN } from '@vtvlive/interactive-apm';
|
|
58
|
+
*
|
|
59
|
+
* @Module({
|
|
60
|
+
* providers: [
|
|
61
|
+
* {
|
|
62
|
+
* provide: TRACING_PROVIDER_TOKEN,
|
|
63
|
+
* useFactory: (configService: ConfigService) => {
|
|
64
|
+
* return createTracingProvider({
|
|
65
|
+
* provider: configService.get('APM_PROVIDER'),
|
|
66
|
+
* serviceName: configService.get('ELASTIC_APM_SERVICE_NAME'),
|
|
67
|
+
* });
|
|
68
|
+
* },
|
|
69
|
+
* inject: [ConfigService],
|
|
70
|
+
* },
|
|
71
|
+
* ],
|
|
72
|
+
* exports: [TRACING_PROVIDER_TOKEN],
|
|
73
|
+
* })
|
|
74
|
+
* export class TracingModule {}
|
|
75
|
+
*/
|
|
76
|
+
export declare const TracingProviderFactory: {
|
|
77
|
+
provide: string;
|
|
78
|
+
useFactory: (configService?: any) => ITracingProvider;
|
|
79
|
+
inject: string[];
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=tracing-provider.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing-provider.factory.d.ts","sourceRoot":"","sources":["../../src/factories/tracing-provider.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAChC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,qBAA0B,GAAG,gBAAgB,CAQ1F;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,sBAAsB;;iCAEJ,GAAG;;CAgCjC,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TracingProviderFactory = exports.TRACING_PROVIDER_TOKEN = void 0;
|
|
4
|
+
exports.createTracingProvider = createTracingProvider;
|
|
5
|
+
const opentelemetry_tracing_provider_1 = require("../providers/opentelemetry.tracing-provider");
|
|
6
|
+
const elastic_apm_tracing_provider_1 = require("../providers/elastic-apm.tracing-provider");
|
|
7
|
+
const apm_provider_type_1 = require("../types/apm-provider.type");
|
|
8
|
+
/**
|
|
9
|
+
* Factory function để tạo APM Provider phù hợp dựa trên cấu hình
|
|
10
|
+
*
|
|
11
|
+
* @param config Configuration options
|
|
12
|
+
* @returns ITracingProvider instance
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Tạo provider với config cụ thể
|
|
16
|
+
* const provider = createTracingProvider({
|
|
17
|
+
* provider: ApmProvider.OPENTELEMETRY,
|
|
18
|
+
* serviceName: 'my-service',
|
|
19
|
+
* otlpEndpoint: 'http://localhost:8200/v1/traces'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Tạo provider từ environment variables
|
|
24
|
+
* const provider = createTracingProvider();
|
|
25
|
+
*/
|
|
26
|
+
function createTracingProvider(config = {}) {
|
|
27
|
+
const provider = config.provider || process.env.APM_PROVIDER || apm_provider_type_1.ApmProvider.OPENTELEMETRY;
|
|
28
|
+
if (provider === apm_provider_type_1.ApmProvider.ELASTIC_APM || provider === 'elastic-apm') {
|
|
29
|
+
return new elastic_apm_tracing_provider_1.ElasticApmTracingProvider(config);
|
|
30
|
+
}
|
|
31
|
+
return new opentelemetry_tracing_provider_1.OpenTelemetryTracingProvider(config);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* NestJS Provider token for dependency injection
|
|
35
|
+
* Use this when integrating with NestJS
|
|
36
|
+
*/
|
|
37
|
+
exports.TRACING_PROVIDER_TOKEN = 'ITracingProvider';
|
|
38
|
+
/**
|
|
39
|
+
* NestJS factory provider for use with NestJS dependency injection
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* // Trong NestJS module
|
|
43
|
+
* import { TracingProviderFactory, TRACING_PROVIDER_TOKEN } from '@vtvlive/interactive-apm';
|
|
44
|
+
*
|
|
45
|
+
* @Module({
|
|
46
|
+
* providers: [
|
|
47
|
+
* {
|
|
48
|
+
* provide: TRACING_PROVIDER_TOKEN,
|
|
49
|
+
* useFactory: (configService: ConfigService) => {
|
|
50
|
+
* return createTracingProvider({
|
|
51
|
+
* provider: configService.get('APM_PROVIDER'),
|
|
52
|
+
* serviceName: configService.get('ELASTIC_APM_SERVICE_NAME'),
|
|
53
|
+
* });
|
|
54
|
+
* },
|
|
55
|
+
* inject: [ConfigService],
|
|
56
|
+
* },
|
|
57
|
+
* ],
|
|
58
|
+
* exports: [TRACING_PROVIDER_TOKEN],
|
|
59
|
+
* })
|
|
60
|
+
* export class TracingModule {}
|
|
61
|
+
*/
|
|
62
|
+
exports.TracingProviderFactory = {
|
|
63
|
+
provide: exports.TRACING_PROVIDER_TOKEN,
|
|
64
|
+
useFactory: (configService) => {
|
|
65
|
+
// Support both standalone and NestJS usage
|
|
66
|
+
const get = (key, defaultValue) => {
|
|
67
|
+
if (configService && typeof configService.get === 'function') {
|
|
68
|
+
return configService.get(key, defaultValue);
|
|
69
|
+
}
|
|
70
|
+
return process.env[key] || defaultValue;
|
|
71
|
+
};
|
|
72
|
+
const otlpAuthToken = get('ELASTIC_OTLP_AUTH_TOKEN', '');
|
|
73
|
+
const secretToken = get('ELASTIC_APM_SECRET_TOKEN', '');
|
|
74
|
+
// Build Authorization header if token is provided
|
|
75
|
+
const headers = {};
|
|
76
|
+
const token = otlpAuthToken || secretToken;
|
|
77
|
+
if (token) {
|
|
78
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
79
|
+
}
|
|
80
|
+
return createTracingProvider({
|
|
81
|
+
provider: get('APM_PROVIDER', 'opentelemetry'),
|
|
82
|
+
serviceName: get('ELASTIC_APM_SERVICE_NAME', 'interactive-backend'),
|
|
83
|
+
environment: get('ELASTIC_APM_ENVIRONMENT', 'development'),
|
|
84
|
+
serverUrl: get('ELASTIC_APM_SERVER_URL', 'http://localhost:8200'),
|
|
85
|
+
secretToken,
|
|
86
|
+
otlpEndpoint: get('ELASTIC_OTLP_ENDPOINT', 'http://localhost:8200/v1/traces'),
|
|
87
|
+
otlpAuthToken,
|
|
88
|
+
otlpHeaders: Object.keys(headers).length > 0 ? headers : undefined,
|
|
89
|
+
enableConsoleExporter: get('ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER', 'false') === 'true',
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
inject: ['CONFIG_SERVICE'], // Optional injection token
|
|
93
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { TracingModule, TracingModuleOptions, TracingModuleAsyncOptions } from './modules/tracing.module';
|
|
2
|
+
export { TracingService } from './services/tracing.service';
|
|
3
|
+
export { TracingHelper } from './utils/tracing.helper';
|
|
4
|
+
export { ITracingProvider } from './interfaces/tracing-provider.interface';
|
|
5
|
+
export { ApmProvider, SpanKind } from './types/apm-provider.type';
|
|
6
|
+
export { ElasticApmTracingProvider } from './providers/elastic-apm.tracing-provider';
|
|
7
|
+
export { OpenTelemetryTracingProvider } from './providers/opentelemetry.tracing-provider';
|
|
8
|
+
export { createTracingProvider, TracingProviderFactory, TRACING_PROVIDER_TOKEN, TracingProviderConfig } from './factories/tracing-provider.factory';
|
|
9
|
+
export { initElasticApm, isElasticApmStarted, getElasticApmAgent, shouldUseElasticApm, ElasticApmInitOptions } from './init/elastic-apm-init';
|
|
10
|
+
export { initOpenTelemetry, shouldUseOpenTelemetry, OpenTelemetryInitOptions } from './init/opentelemetry-init';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAG1G,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAG1F,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAGpJ,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldUseOpenTelemetry = exports.initOpenTelemetry = exports.shouldUseElasticApm = exports.getElasticApmAgent = exports.isElasticApmStarted = exports.initElasticApm = exports.TRACING_PROVIDER_TOKEN = exports.TracingProviderFactory = exports.createTracingProvider = exports.OpenTelemetryTracingProvider = exports.ElasticApmTracingProvider = exports.SpanKind = exports.ApmProvider = exports.TracingHelper = exports.TracingService = exports.TracingModule = void 0;
|
|
4
|
+
// Core exports - NestJS integration
|
|
5
|
+
var tracing_module_1 = require("./modules/tracing.module");
|
|
6
|
+
Object.defineProperty(exports, "TracingModule", { enumerable: true, get: function () { return tracing_module_1.TracingModule; } });
|
|
7
|
+
// Services
|
|
8
|
+
var tracing_service_1 = require("./services/tracing.service");
|
|
9
|
+
Object.defineProperty(exports, "TracingService", { enumerable: true, get: function () { return tracing_service_1.TracingService; } });
|
|
10
|
+
// Utils - Standalone usage
|
|
11
|
+
var tracing_helper_1 = require("./utils/tracing.helper");
|
|
12
|
+
Object.defineProperty(exports, "TracingHelper", { enumerable: true, get: function () { return tracing_helper_1.TracingHelper; } });
|
|
13
|
+
// Types
|
|
14
|
+
var apm_provider_type_1 = require("./types/apm-provider.type");
|
|
15
|
+
Object.defineProperty(exports, "ApmProvider", { enumerable: true, get: function () { return apm_provider_type_1.ApmProvider; } });
|
|
16
|
+
Object.defineProperty(exports, "SpanKind", { enumerable: true, get: function () { return apm_provider_type_1.SpanKind; } });
|
|
17
|
+
// Providers - for direct usage
|
|
18
|
+
var elastic_apm_tracing_provider_1 = require("./providers/elastic-apm.tracing-provider");
|
|
19
|
+
Object.defineProperty(exports, "ElasticApmTracingProvider", { enumerable: true, get: function () { return elastic_apm_tracing_provider_1.ElasticApmTracingProvider; } });
|
|
20
|
+
var opentelemetry_tracing_provider_1 = require("./providers/opentelemetry.tracing-provider");
|
|
21
|
+
Object.defineProperty(exports, "OpenTelemetryTracingProvider", { enumerable: true, get: function () { return opentelemetry_tracing_provider_1.OpenTelemetryTracingProvider; } });
|
|
22
|
+
// Factory
|
|
23
|
+
var tracing_provider_factory_1 = require("./factories/tracing-provider.factory");
|
|
24
|
+
Object.defineProperty(exports, "createTracingProvider", { enumerable: true, get: function () { return tracing_provider_factory_1.createTracingProvider; } });
|
|
25
|
+
Object.defineProperty(exports, "TracingProviderFactory", { enumerable: true, get: function () { return tracing_provider_factory_1.TracingProviderFactory; } });
|
|
26
|
+
Object.defineProperty(exports, "TRACING_PROVIDER_TOKEN", { enumerable: true, get: function () { return tracing_provider_factory_1.TRACING_PROVIDER_TOKEN; } });
|
|
27
|
+
// Init functions - for standalone/non-NestJS usage
|
|
28
|
+
var elastic_apm_init_1 = require("./init/elastic-apm-init");
|
|
29
|
+
Object.defineProperty(exports, "initElasticApm", { enumerable: true, get: function () { return elastic_apm_init_1.initElasticApm; } });
|
|
30
|
+
Object.defineProperty(exports, "isElasticApmStarted", { enumerable: true, get: function () { return elastic_apm_init_1.isElasticApmStarted; } });
|
|
31
|
+
Object.defineProperty(exports, "getElasticApmAgent", { enumerable: true, get: function () { return elastic_apm_init_1.getElasticApmAgent; } });
|
|
32
|
+
Object.defineProperty(exports, "shouldUseElasticApm", { enumerable: true, get: function () { return elastic_apm_init_1.shouldUseElasticApm; } });
|
|
33
|
+
var opentelemetry_init_1 = require("./init/opentelemetry-init");
|
|
34
|
+
Object.defineProperty(exports, "initOpenTelemetry", { enumerable: true, get: function () { return opentelemetry_init_1.initOpenTelemetry; } });
|
|
35
|
+
Object.defineProperty(exports, "shouldUseOpenTelemetry", { enumerable: true, get: function () { return opentelemetry_init_1.shouldUseOpenTelemetry; } });
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elastic APM Initialization (Standalone)
|
|
3
|
+
*
|
|
4
|
+
* Use this to initialize Elastic APM agent before your application starts.
|
|
5
|
+
* This is useful for non-NestJS applications or when you need manual control.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { initElasticApm } from '@vtvlive/interactive-apm';
|
|
9
|
+
*
|
|
10
|
+
* // Initialize at the top of your application
|
|
11
|
+
* initElasticApm({
|
|
12
|
+
* serviceName: 'my-service',
|
|
13
|
+
* serverUrl: 'http://localhost:8200',
|
|
14
|
+
* environment: 'production',
|
|
15
|
+
* });
|
|
16
|
+
*/
|
|
17
|
+
export interface ElasticApmInitOptions {
|
|
18
|
+
/** Service name for APM */
|
|
19
|
+
serviceName?: string;
|
|
20
|
+
/** Elastic APM server URL */
|
|
21
|
+
serverUrl?: string;
|
|
22
|
+
/** Secret token for authentication */
|
|
23
|
+
secretToken?: string;
|
|
24
|
+
/** Service version */
|
|
25
|
+
serviceVersion?: string;
|
|
26
|
+
/** Deployment environment */
|
|
27
|
+
environment?: string;
|
|
28
|
+
/** APM log level */
|
|
29
|
+
logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if APM should use Elastic APM provider based on configuration
|
|
33
|
+
* @returns true if Elastic APM should be used
|
|
34
|
+
*/
|
|
35
|
+
export declare function shouldUseElasticApm(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Initialize Elastic APM agent for standalone usage
|
|
38
|
+
*
|
|
39
|
+
* @param options Configuration options
|
|
40
|
+
* @returns The APM agent instance
|
|
41
|
+
*/
|
|
42
|
+
export declare function initElasticApm(options?: ElasticApmInitOptions): any;
|
|
43
|
+
/**
|
|
44
|
+
* Check if Elastic APM agent is started
|
|
45
|
+
*/
|
|
46
|
+
export declare function isElasticApmStarted(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Get the Elastic APM agent instance
|
|
49
|
+
*/
|
|
50
|
+
export declare function getElasticApmAgent(): any;
|
|
51
|
+
//# sourceMappingURL=elastic-apm-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elastic-apm-init.d.ts","sourceRoot":"","sources":["../../src/init/elastic-apm-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAG7C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,GAAG,CAuBvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAWxC"}
|