@vtvlive/interactive-apm 0.0.2 → 0.0.3

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 CHANGED
@@ -8,7 +8,10 @@
8
8
  - **NestJS Integration**: Ready-to-use module with dependency injection
9
9
  - **Standalone Usage**: Works without NestJS for vanilla TypeScript/JavaScript projects
10
10
  - **Flexible Configuration**: Configure via environment variables or programmatic options
11
+ - **Debug Mode**: Comprehensive logging for troubleshooting connection issues
12
+ - **OTLP Transport Options**: Support for HTTP, gRPC, and PROTO (protobuf over HTTP) transports
11
13
  - **TypeScript Support**: Fully typed with TypeScript
14
+ - **Auto Transaction Naming**: HTTP requests automatically named as "METHOD /route/path"
12
15
 
13
16
  ## Installation
14
17
 
@@ -18,6 +21,11 @@
18
21
  npm install @vtvlive/interactive-apm @opentelemetry/api @opentelemetry/exporter-trace-otlp-http @opentelemetry/instrumentation-http @opentelemetry/sdk-node @opentelemetry/resources
19
22
  ```
20
23
 
24
+ For gRPC or PROTO transport support:
25
+ ```bash
26
+ npm install @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/exporter-trace-otlp-proto
27
+ ```
28
+
21
29
  ### For Elastic APM
22
30
 
23
31
  ```bash
@@ -34,37 +42,91 @@ npm install @nestjs/common @nestjs/config
34
42
 
35
43
  ## Environment Variables
36
44
 
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` |
45
+ | Variable | Description | Default |
46
+ | -------------------------------------- | --------------------------------------------------------------------------- | --------------------------------- |
47
+ | `APM_PROVIDER` | Provider selection: `elastic-apm` or `opentelemetry` | `opentelemetry` |
48
+ | `APM_DEBUG` | Enable debug mode with detailed logging (default: `false`) | `false` |
49
+ | `ELASTIC_APM_SERVICE_NAME` | Service name for APM | Required |
50
+ | `ELASTIC_APM_SERVER_URL` | Elastic APM server URL | `http://localhost:8200` |
51
+ | `ELASTIC_APM_SECRET_TOKEN` | Secret token for authentication | Optional |
52
+ | `ELASTIC_APM_ENVIRONMENT` | Deployment environment | `development` |
53
+ | `ELASTIC_OTLP_ENDPOINT` | OTLP endpoint (OpenTelemetry only) | `http://localhost:8200/v1/traces` |
54
+ | `ELASTIC_OTLP_TRANSPORT` | OTLP transport: `http`, `grpc`, or `proto` | `http` |
55
+ | `ELASTIC_OTLP_AUTH_TOKEN` | OTLP-specific auth token (takes precedence over `ELASTIC_APM_SECRET_TOKEN`) | Optional |
56
+ | `ELASTIC_OTLP_HEADERS` | Additional OTLP headers as JSON string | Optional |
57
+ | `ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER` | Enable console exporter for debugging | `false` |
58
+
59
+ ## Debug Mode
60
+
61
+ Enable debug mode to see detailed logs about APM initialization, span creation, and export status:
62
+
63
+ ```bash
64
+ # Enable debug mode
65
+ APM_DEBUG=true
66
+
67
+ # Or in .env file
68
+ APM_DEBUG=true
69
+ ```
70
+
71
+ Debug mode provides:
72
+ - Initialization details (service name, endpoint, transport type)
73
+ - Span creation and lifecycle events
74
+ - Export success/failure status
75
+ - HTTP request/response details for troubleshooting
47
76
 
48
77
  ## Usage
49
78
 
50
79
  ### NestJS Integration
51
80
 
52
- #### Basic Usage (reads from environment)
81
+ #### Complete Example with ConfigService
53
82
 
54
83
  ```typescript
55
84
  // app.module.ts
85
+ import { Module } from '@nestjs/common';
86
+ import { ConfigModule, ConfigService } from '@nestjs/config';
56
87
  import { TracingModule } from '@vtvlive/interactive-apm';
57
88
 
58
89
  @Module({
59
90
  imports: [
60
- TracingModule.registerAsync(),
61
- // ... other modules
91
+ ConfigModule.forRoot({
92
+ isGlobal: true,
93
+ envFilePath: ['.env.local', '.env'],
94
+ }),
95
+
96
+ TracingModule.registerAsync({
97
+ imports: [ConfigModule],
98
+ useFactory: async (configService: ConfigService) => {
99
+ return {
100
+ // Provider selection
101
+ provider: configService.get<string>('APM_PROVIDER', 'opentelemetry'),
102
+
103
+ // Common configuration
104
+ serviceName: configService.get<string>('ELASTIC_APM_SERVICE_NAME', 'my-service'),
105
+ environment: configService.get<string>('ELASTIC_APM_ENVIRONMENT', 'development'),
106
+
107
+ // OpenTelemetry configuration
108
+ otlpEndpoint: configService.get<string>('ELASTIC_OTLP_ENDPOINT', 'http://localhost:8200/v1/traces'),
109
+ otlpTransport: configService.get<string>('ELASTIC_OTLP_TRANSPORT', 'http'), // 'http' | 'grpc' | 'proto'
110
+ otlpAuthToken: configService.get<string>('ELASTIC_OTLP_AUTH_TOKEN'),
111
+ otlpHeaders: configService.get('ELASTIC_OTLP_HEADERS'),
112
+ enableConsoleExporter: configService.get<string>('ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER', 'false') === 'true',
113
+
114
+ // Elastic APM configuration
115
+ serverUrl: configService.get<string>('ELASTIC_APM_SERVER_URL', 'http://localhost:8200'),
116
+ secretToken: configService.get<string>('ELASTIC_APM_SECRET_TOKEN'),
117
+
118
+ // Debug mode - parse boolean from string env var
119
+ debug: ['1', 'true', 'yes'].includes(configService.get<string>('APM_DEBUG', 'false').toLowerCase()),
120
+ };
121
+ },
122
+ inject: [ConfigService],
123
+ }),
62
124
  ],
63
125
  })
64
126
  export class AppModule {}
65
127
  ```
66
128
 
67
- #### With Explicit Options
129
+ #### Basic Usage (reads from environment)
68
130
 
69
131
  ```typescript
70
132
  // app.module.ts
@@ -72,44 +134,38 @@ import { TracingModule } from '@vtvlive/interactive-apm';
72
134
 
73
135
  @Module({
74
136
  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
- }),
137
+ TracingModule.registerAsync(),
82
138
  // ... other modules
83
139
  ],
84
140
  })
85
141
  export class AppModule {}
86
142
  ```
87
143
 
88
- #### Using ConfigService
144
+ #### In Controllers
89
145
 
90
146
  ```typescript
91
- // app.module.ts
92
- import { TracingModule } from '@vtvlive/interactive-apm';
93
- import { ConfigModule, ConfigService } from '@nestjs/config';
147
+ import { Controller, Get } from '@nestjs/common';
148
+ import { TracingService } from '@vtvlive/interactive-apm';
94
149
 
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 {}
150
+ @Controller('healthcheck')
151
+ export class HealthController {
152
+ constructor(private readonly tracingService: TracingService) {}
153
+
154
+ @Get('ping')
155
+ ping() {
156
+ return this.tracingService.startSpanWithParent(
157
+ 'healthcheck.ping',
158
+ async (span) => {
159
+ span.setAttribute('healthcheck.type', 'liveness');
160
+ return { message: 'pong' };
161
+ },
162
+ { 'http.method': 'GET', 'http.route': '/healthcheck/ping' }
163
+ );
164
+ }
165
+ }
110
166
  ```
111
167
 
112
- #### In Controllers/Services
168
+ #### In Services
113
169
 
114
170
  ```typescript
115
171
  import { Injectable } from '@nestjs/common';
@@ -117,20 +173,27 @@ import { TracingService } from '@vtvlive/interactive-apm';
117
173
 
118
174
  @Injectable()
119
175
  export class UserService {
120
- constructor(private readonly tracingService: TracingService) {}
176
+ constructor(
177
+ private readonly tracingService: TracingService,
178
+ private readonly userRepository: UserRepository
179
+ ) {}
121
180
 
122
181
  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
- }
182
+ return this.tracingService.startSpanWithParent(
183
+ 'user.findById',
184
+ async (span) => {
185
+ span.setAttribute('userId', id);
186
+
187
+ const user = await this.userRepository.findById(id);
188
+ if (!user) {
189
+ throw new NotFoundException(`User ${id} not found`);
190
+ }
191
+
192
+ span.setAttribute('user.exists', 'true');
193
+ return user;
194
+ },
195
+ { 'operation.type': 'read' }
196
+ );
134
197
  }
135
198
 
136
199
  async create(data: CreateUserDto) {
@@ -138,10 +201,23 @@ export class UserService {
138
201
  'user.create',
139
202
  async (span) => {
140
203
  span.setAttribute('user.email', data.email);
141
- const user = await this.userRepository.create(data);
204
+
205
+ // This nested call creates a child span
206
+ const hashedPassword = await this.tracingService.startSpanWithParent(
207
+ 'user.hashPassword',
208
+ async () => await bcrypt.hash(data.password, 10),
209
+ { 'operation.type': 'crypto' }
210
+ );
211
+
212
+ const user = await this.userRepository.create({
213
+ ...data,
214
+ password: hashedPassword,
215
+ });
216
+
217
+ span.setAttribute('user.created', 'true');
142
218
  return user;
143
219
  },
144
- { userType: 'premium' }
220
+ { 'operation.type': 'write' }
145
221
  );
146
222
  }
147
223
  }
@@ -152,54 +228,36 @@ export class UserService {
152
228
  #### OpenTelemetry
153
229
 
154
230
  ```typescript
155
- import { initOpenTelemetry, TracingHelper } from '@vtvlive/interactive-apm';
156
- import { SpanKind } from '@opentelemetry/api';
231
+ import { initOpenTelemetry } from '@vtvlive/interactive-apm';
157
232
 
158
- // Initialize at the top of your application
233
+ // Initialize at the top of your application (before any imports)
159
234
  await initOpenTelemetry({
160
235
  serviceName: 'my-service',
161
236
  otlpEndpoint: 'http://localhost:8200/v1/traces',
162
237
  environment: 'production',
238
+ otlpTransport: 'proto', // 'http' | 'grpc' | 'proto'
239
+ enableConsoleExporter: false,
163
240
  });
164
241
 
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
- }
242
+ // Your application code
243
+ import express from 'express';
244
+ const app = express();
176
245
  ```
177
246
 
178
247
  #### Elastic APM
179
248
 
180
249
  ```typescript
181
- import { initElasticApm, createTracingProvider, TracingService } from '@vtvlive/interactive-apm';
250
+ import { initElasticApm } from '@vtvlive/interactive-apm';
182
251
 
183
252
  // Initialize at the top of your application
184
253
  initElasticApm({
185
254
  serviceName: 'my-service',
186
255
  serverUrl: 'http://localhost:8200',
187
256
  environment: 'production',
257
+ secretToken: 'your-secret-token',
188
258
  });
189
259
 
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
- }
260
+ // Your application code
203
261
  ```
204
262
 
205
263
  ## API Reference
@@ -208,41 +266,27 @@ try {
208
266
 
209
267
  NestJS module for APM integration.
210
268
 
211
- | Method | Description |
212
- |--------|-------------|
213
- | `register(options)` | Register module with synchronous options |
214
- | `registerAsync(options)` | Register module with asynchronous options |
269
+ | Method | Description |
270
+ | ------------------------ | -------------------------------------------------------------- |
271
+ | `register(options)` | Register module with synchronous options |
272
+ | `registerAsync(options)` | Register module with asynchronous options (with ConfigService) |
215
273
 
216
274
  ### TracingService
217
275
 
218
276
  Service for tracing operations.
219
277
 
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 |
278
+ | Method | Description |
279
+ | -------------------------------------------- | ----------------------------------------------------- |
280
+ | `startSpan(name, attributes?, spanKind?)` | Start a new span (must call `span.end()` manually) |
281
+ | `startSpanWithParent(name, fn, attributes?)` | Execute function with automatic tracing (recommended) |
282
+ | `captureError(error)` | Capture error to active span |
283
+ | `setAttribute(key, value)` | Set attribute on active span |
284
+ | `endSpan(span?)` | End a span manually |
285
+ | `shutdown()` | Flush and shutdown provider |
242
286
 
243
287
  ### SpanKind
244
288
 
245
- Types of spans:
289
+ Types of spans (used with `startSpan`):
246
290
 
247
291
  - `INTERNAL`: Internal operation
248
292
  - `SERVER`: Server-side request handler (API endpoints)
@@ -250,24 +294,58 @@ Types of spans:
250
294
  - `PRODUCER`: Message producer
251
295
  - `CONSUMER`: Message consumer
252
296
 
253
- ## Provider Selection
297
+ ### OtlpTransport
254
298
 
255
- The package supports two APM providers:
299
+ Transport options for OpenTelemetry OTLP exporter:
256
300
 
257
- ### OpenTelemetry (default)
301
+ - `HTTP`: JSON over HTTP (default)
302
+ - `GRPC`: gRPC with protobuf
303
+ - `PROTO`: Protobuf over HTTP (most efficient)
258
304
 
259
- Uses OpenTelemetry SDK with OTLP exporter to send traces to Elastic APM.
305
+ ## Transaction Naming
260
306
 
261
- ```bash
262
- APM_PROVIDER=opentelemetry
263
- ```
307
+ HTTP transactions are automatically named in the format `METHOD /route/path`:
308
+
309
+ - Request to `GET /api/healthcheck/ping` → Transaction: `GET /api/healthcheck/ping`
310
+ - Request to `POST /api/users` → Transaction: `POST /api/users`
311
+
312
+ This applies to both OpenTelemetry and Elastic APM providers.
313
+
314
+ ## Provider Comparison
264
315
 
265
- ### Elastic APM
316
+ | Feature | OpenTelemetry | Elastic APM |
317
+ | -------------------- | ---------------------------- | ---------------- |
318
+ | Transport Options | HTTP, gRPC, PROTO | HTTP/HTTPS |
319
+ | Auto Instrumentation | HTTP, Express (configurable) | Built-in |
320
+ | Debug Logging | Comprehensive | Comprehensive |
321
+ | Transaction Naming | Auto + Custom | Auto + Custom |
322
+ | Standard | W3C Trace Context | Elastic APM spec |
266
323
 
267
- Uses the native Elastic APM Node.js agent.
324
+ ## Troubleshooting
325
+
326
+ ### No traces appearing in APM
327
+
328
+ 1. Check if `APM_DEBUG=true` is set to see detailed logs
329
+ 2. Verify endpoint URL is correct
330
+ 3. Check network connectivity to APM server
331
+ 4. Verify authentication token
332
+
333
+ ### Using npm link for local development
268
334
 
269
335
  ```bash
270
- APM_PROVIDER=elastic-apm
336
+ # In the package directory
337
+ cd /path/to/interactive-apm
338
+ npm link
339
+
340
+ # In your project directory
341
+ cd /path/to/your-project
342
+ npm link @vtvlive/interactive-apm
343
+ ```
344
+
345
+ Note: After making changes to the package, rebuild it:
346
+ ```bash
347
+ cd /path/to/interactive-apm
348
+ npm run build
271
349
  ```
272
350
 
273
351
  ## Testing
@@ -305,8 +383,6 @@ npm test
305
383
  npm run clean
306
384
  ```
307
385
 
308
- **For detailed deployment instructions (build, publish, install from private registry), see [DEPLOYMENT.md](DEPLOYMENT.md)**
309
-
310
386
  ## License
311
387
 
312
388
  MIT
@@ -317,4 +393,6 @@ VTVLive
317
393
 
318
394
  ---
319
395
 
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/).
396
+ For more information:
397
+ - [Elastic APM documentation](https://www.elastic.co/guide/en/apm/get-started/current/index.html)
398
+ - [OpenTelemetry documentation](https://opentelemetry.io/docs/instrumentation/js/)
@@ -1,5 +1,6 @@
1
1
  import { ITracingProvider } from '../interfaces/tracing-provider.interface';
2
2
  import { ApmProvider } from '../types/apm-provider.type';
3
+ import { OtlpTransport } from '../types/otlp-transport.type';
3
4
  /**
4
5
  * Configuration options for creating a tracing provider
5
6
  */
@@ -20,6 +21,8 @@ export interface TracingProviderConfig {
20
21
  otlpAuthToken?: string;
21
22
  /** OTLP headers as a record (key-value pairs). If provided, merges with Authorization header when token is set. */
22
23
  otlpHeaders?: Record<string, string>;
24
+ /** OTLP transport type: 'http' or 'grpc' (default: 'http') */
25
+ otlpTransport?: OtlpTransport | string;
23
26
  /** Enable console exporter for debugging (default: false) */
24
27
  enableConsoleExporter?: boolean;
25
28
  /** Service version */
@@ -1 +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"}
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;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D;;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,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;IACvC,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;;CAiCjC,CAAC"}
@@ -86,6 +86,7 @@ exports.TracingProviderFactory = {
86
86
  otlpEndpoint: get('ELASTIC_OTLP_ENDPOINT', 'http://localhost:8200/v1/traces'),
87
87
  otlpAuthToken,
88
88
  otlpHeaders: Object.keys(headers).length > 0 ? headers : undefined,
89
+ otlpTransport: get('ELASTIC_OTLP_TRANSPORT', 'http'),
89
90
  enableConsoleExporter: get('ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER', 'false') === 'true',
90
91
  });
91
92
  },
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { TracingService } from './services/tracing.service';
3
3
  export { TracingHelper } from './utils/tracing.helper';
4
4
  export { ITracingProvider } from './interfaces/tracing-provider.interface';
5
5
  export { ApmProvider, SpanKind } from './types/apm-provider.type';
6
+ export { OtlpTransport } from './types/otlp-transport.type';
6
7
  export { ElasticApmTracingProvider } from './providers/elastic-apm.tracing-provider';
7
8
  export { OpenTelemetryTracingProvider } from './providers/opentelemetry.tracing-provider';
8
9
  export { createTracingProvider, TracingProviderFactory, TRACING_PROVIDER_TOKEN, TracingProviderConfig } from './factories/tracing-provider.factory';
@@ -1 +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"}
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;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG5D,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 CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
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;
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.OtlpTransport = exports.SpanKind = exports.ApmProvider = exports.TracingHelper = exports.TracingService = exports.TracingModule = void 0;
4
4
  // Core exports - NestJS integration
5
5
  var tracing_module_1 = require("./modules/tracing.module");
6
6
  Object.defineProperty(exports, "TracingModule", { enumerable: true, get: function () { return tracing_module_1.TracingModule; } });
@@ -14,6 +14,8 @@ Object.defineProperty(exports, "TracingHelper", { enumerable: true, get: functio
14
14
  var apm_provider_type_1 = require("./types/apm-provider.type");
15
15
  Object.defineProperty(exports, "ApmProvider", { enumerable: true, get: function () { return apm_provider_type_1.ApmProvider; } });
16
16
  Object.defineProperty(exports, "SpanKind", { enumerable: true, get: function () { return apm_provider_type_1.SpanKind; } });
17
+ var otlp_transport_type_1 = require("./types/otlp-transport.type");
18
+ Object.defineProperty(exports, "OtlpTransport", { enumerable: true, get: function () { return otlp_transport_type_1.OtlpTransport; } });
17
19
  // Providers - for direct usage
18
20
  var elastic_apm_tracing_provider_1 = require("./providers/elastic-apm.tracing-provider");
19
21
  Object.defineProperty(exports, "ElasticApmTracingProvider", { enumerable: true, get: function () { return elastic_apm_tracing_provider_1.ElasticApmTracingProvider; } });
@@ -1 +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"}
1
+ {"version":3,"file":"elastic-apm-init.d.ts","sourceRoot":"","sources":["../../src/init/elastic-apm-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,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,CAyCvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAWxC"}
@@ -21,6 +21,7 @@ exports.initElasticApm = initElasticApm;
21
21
  exports.isElasticApmStarted = isElasticApmStarted;
22
22
  exports.getElasticApmAgent = getElasticApmAgent;
23
23
  const apm_provider_type_1 = require("../types/apm-provider.type");
24
+ const debug_logger_1 = require("../utils/debug-logger");
24
25
  /**
25
26
  * Check if APM should use Elastic APM provider based on configuration
26
27
  * @returns true if Elastic APM should be used
@@ -42,17 +43,33 @@ function initElasticApm(options = {}) {
42
43
  if (apm.isStarted()) {
43
44
  return apm;
44
45
  }
46
+ const serviceName = options.serviceName || process.env.ELASTIC_APM_SERVICE_NAME || 'interactive-backend';
47
+ const serverUrl = options.serverUrl || process.env.ELASTIC_APM_SERVER_URL || 'http://localhost:8200';
48
+ const secretToken = options.secretToken || process.env.ELASTIC_APM_SECRET_TOKEN;
49
+ const serviceVersion = options.serviceVersion || process.env.npm_package_version || '1.0.0';
50
+ const environment = options.environment || process.env.ELASTIC_APM_ENVIRONMENT || 'development';
51
+ // Log initialization details when debug mode is on
52
+ (0, debug_logger_1.logInitialization)('ElasticAPM', {
53
+ serviceName,
54
+ serverUrl,
55
+ hasSecretToken: !!secretToken,
56
+ serviceVersion,
57
+ environment,
58
+ logLevel: options.logLevel || 'error',
59
+ });
45
60
  // Start the agent
46
61
  const agent = apm.start({
47
- serviceName: options.serviceName || process.env.ELASTIC_APM_SERVICE_NAME || 'interactive-backend',
48
- serverUrl: options.serverUrl || process.env.ELASTIC_APM_SERVER_URL || 'http://localhost:8200',
49
- secretToken: options.secretToken || process.env.ELASTIC_APM_SECRET_TOKEN,
50
- serviceVersion: options.serviceVersion || process.env.npm_package_version || '1.0.0',
51
- environment: options.environment || process.env.ELASTIC_APM_ENVIRONMENT || 'development',
62
+ serviceName,
63
+ serverUrl,
64
+ secretToken,
65
+ serviceVersion,
66
+ environment,
52
67
  logLevel: options.logLevel || 'error',
53
68
  });
54
- console.log(`[ElasticAPM] Service: ${agent.getServiceName()}, Environment: ${agent.conf.environment}`);
55
- console.log('[ElasticAPM] Initialized');
69
+ if ((0, debug_logger_1.isDebugEnabled)()) {
70
+ (0, debug_logger_1.infoLog)(`[ElasticAPM] Service: ${agent.getServiceName()}, Environment: ${agent.conf.environment}`);
71
+ (0, debug_logger_1.infoLog)('[ElasticAPM] Initialized');
72
+ }
56
73
  return agent;
57
74
  }
58
75
  /**
@@ -14,6 +14,7 @@
14
14
  * environment: 'production',
15
15
  * });
16
16
  */
17
+ import { OtlpTransport } from '../types/otlp-transport.type';
17
18
  export interface OpenTelemetryInitOptions {
18
19
  /** Service name for APM */
19
20
  serviceName?: string;
@@ -35,6 +36,8 @@ export interface OpenTelemetryInitOptions {
35
36
  enableHttpInstrumentation?: boolean;
36
37
  /** Enable Express instrumentation */
37
38
  enableExpressInstrumentation?: boolean;
39
+ /** OTLP transport type: 'http' or 'grpc' (default: 'http') */
40
+ otlpTransport?: OtlpTransport | string;
38
41
  }
39
42
  /**
40
43
  * Check if APM should use OpenTelemetry provider based on configuration
@@ -1 +1 @@
1
- {"version":3,"file":"opentelemetry-init.d.ts","sourceRoot":"","sources":["../../src/init/opentelemetry-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kCAAkC;IAClC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,qCAAqC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,GAAG,CAAC,CAyG5F"}
1
+ {"version":3,"file":"opentelemetry-init.d.ts","sourceRoot":"","sources":["../../src/init/opentelemetry-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AA0C7D,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kCAAkC;IAClC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,qCAAqC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAwCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,GAAG,CAAC,CA2I5F"}