@sentienguard/apm 1.0.5 → 1.0.6

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/src/index.js CHANGED
@@ -1,209 +1,209 @@
1
- /**
2
- * SentienGuard APM SDK
3
- *
4
- * Minimal, production-safe APM that runs inside client applications
5
- * and sends aggregated metrics to the SentienGuard backend.
6
- *
7
- * Usage:
8
- * import "@sentienguard/apm";
9
- *
10
- * That's it. No function calls, no setup code, no decorators.
11
- *
12
- * Configuration via environment variables:
13
- * SENTIENGUARD_APM_KEY=xxxx (required)
14
- * SENTIENGUARD_SERVICE=my-api (required)
15
- * SENTIENGUARD_ENV=production (optional, default: production)
16
- * SENTIENGUARD_ENDPOINT=https://... (optional)
17
- * SENTIENGUARD_FLUSH_INTERVAL=10 (optional, seconds)
18
- *
19
- * No config → SDK disables itself silently.
20
- */
21
-
22
- import config, { isEnabled, debug, warn, getConfig } from './config.js';
23
- import { instrumentHttp, expressMiddleware, fastifyPlugin } from './instrumentation.js';
24
- import { instrumentDependencies } from './dependencies.js';
25
- import { startErrorCapture, expressErrorMiddleware, fastifyErrorHandler } from './errors.js';
26
- import { startFlushing, stopFlushing, finalFlush, flush } from './transport.js';
27
- import { getAggregator } from './aggregator.js';
28
- import { normalizeRoute, extractRoute, RouteRegistry } from './normalizer.js';
29
- import { instrumentMongoDB, autoInstrumentMongoDB, stopMongoDBInstrumentation } from './mongodb.js';
30
- import { instrumentOpenAI, stopOpenAIInstrumentation } from './openai.js';
31
- import { createBreaker, wrapMongoOperation, getBreakerStats, shutdownBreakers } from './circuitBreaker.js';
32
-
33
- let isInitialized = false;
34
-
35
- /**
36
- * Initialize the SDK
37
- * Called automatically on import
38
- */
39
- function initialize() {
40
- if (isInitialized) {
41
- debug('SDK already initialized');
42
- return;
43
- }
44
-
45
- // Check if SDK should be enabled
46
- if (!isEnabled()) {
47
- // Silently disable - this is expected behavior
48
- debug('SDK disabled (missing API key or service name)');
49
- return;
50
- }
51
-
52
- // Warn if this import is not first (other modules may have created servers already)
53
- // We can't reliably detect this, so just log for debugging
54
- debug(`Initializing SDK for service: ${config.service}`);
55
- debug(`Environment: ${config.environment}`);
56
- debug(`Endpoint: ${config.endpoint}`);
57
- debug(`Flush interval: ${config.flushInterval}s`);
58
-
59
- // Instrument HTTP (incoming requests)
60
- instrumentHttp();
61
-
62
- // Instrument dependencies (outgoing requests)
63
- instrumentDependencies();
64
-
65
- // Auto-instrument MongoDB if available
66
- autoInstrumentMongoDB();
67
-
68
- // Start error capture
69
- startErrorCapture();
70
-
71
- // Start periodic flush
72
- startFlushing();
73
-
74
- // Handle graceful shutdown
75
- setupGracefulShutdown();
76
-
77
- isInitialized = true;
78
- debug('SDK initialized successfully');
79
- }
80
-
81
- /**
82
- * Setup graceful shutdown handlers
83
- */
84
- function setupGracefulShutdown() {
85
- const shutdown = async (signal) => {
86
- debug(`Received ${signal}, performing graceful shutdown`);
87
-
88
- // Stop accepting new data
89
- stopFlushing();
90
-
91
- // Final flush
92
- await finalFlush();
93
-
94
- debug('Shutdown complete');
95
- };
96
-
97
- // Handle common shutdown signals
98
- process.once('SIGTERM', () => shutdown('SIGTERM'));
99
- process.once('SIGINT', () => shutdown('SIGINT'));
100
-
101
- // Handle process exit
102
- process.once('beforeExit', () => shutdown('beforeExit'));
103
- }
104
-
105
- /**
106
- * Shutdown the SDK
107
- * Call this before process exit for clean shutdown
108
- */
109
- async function shutdown() {
110
- if (!isInitialized) return;
111
-
112
- debug('Shutting down SDK');
113
-
114
- // Stop MongoDB instrumentation
115
- stopMongoDBInstrumentation();
116
-
117
- // Stop OpenAI instrumentation
118
- stopOpenAIInstrumentation();
119
-
120
- // Shutdown circuit breakers
121
- shutdownBreakers();
122
-
123
- stopFlushing();
124
- await finalFlush();
125
-
126
- isInitialized = false;
127
- debug('SDK shutdown complete');
128
- }
129
-
130
- /**
131
- * Get current SDK status
132
- */
133
- function getStatus() {
134
- const aggregator = getAggregator();
135
- const stats = aggregator.getStats();
136
-
137
- return {
138
- enabled: isEnabled(),
139
- initialized: isInitialized,
140
- config: {
141
- service: config.service,
142
- environment: config.environment,
143
- flushInterval: config.flushInterval
144
- },
145
- stats
146
- };
147
- }
148
-
149
- // Auto-initialize on import
150
- initialize();
151
-
152
- // Export for advanced usage
153
- export {
154
- // Core functions
155
- initialize,
156
- shutdown,
157
- getStatus,
158
- flush,
159
-
160
- // Config
161
- getConfig,
162
- isEnabled,
163
-
164
- // Middleware for frameworks (optional, for better route extraction)
165
- expressMiddleware,
166
- expressErrorMiddleware,
167
- fastifyPlugin,
168
- fastifyErrorHandler,
169
-
170
- // Utilities (for custom instrumentation)
171
- normalizeRoute,
172
- extractRoute,
173
- RouteRegistry,
174
- getAggregator,
175
-
176
- // MongoDB instrumentation
177
- instrumentMongoDB,
178
-
179
- // OpenAI instrumentation
180
- instrumentOpenAI,
181
-
182
- // Circuit breaker
183
- createBreaker,
184
- wrapMongoOperation,
185
- getBreakerStats
186
- };
187
-
188
- // Default export
189
- export default {
190
- initialize,
191
- shutdown,
192
- getStatus,
193
- flush,
194
- expressMiddleware,
195
- expressErrorMiddleware,
196
- fastifyPlugin,
197
- fastifyErrorHandler,
198
- normalizeRoute,
199
- extractRoute,
200
- getAggregator,
201
- // MongoDB
202
- instrumentMongoDB,
203
- // OpenAI
204
- instrumentOpenAI,
205
- // Circuit breaker
206
- createBreaker,
207
- wrapMongoOperation,
208
- getBreakerStats
209
- };
1
+ /**
2
+ * SentienGuard APM SDK
3
+ *
4
+ * Minimal, production-safe APM that runs inside client applications
5
+ * and sends aggregated metrics to the SentienGuard backend.
6
+ *
7
+ * Usage:
8
+ * import "@sentienguard/apm";
9
+ *
10
+ * That's it. No function calls, no setup code, no decorators.
11
+ *
12
+ * Configuration via environment variables:
13
+ * SENTIENGUARD_APM_KEY=xxxx (required)
14
+ * SENTIENGUARD_SERVICE=my-api (required)
15
+ * SENTIENGUARD_ENV=production (optional, default: production)
16
+ * SENTIENGUARD_ENDPOINT=https://... (optional)
17
+ * SENTIENGUARD_FLUSH_INTERVAL=10 (optional, seconds)
18
+ *
19
+ * No config → SDK disables itself silently.
20
+ */
21
+
22
+ import config, { isEnabled, debug, getConfig } from './config.js';
23
+ import { instrumentHttp, expressMiddleware, fastifyPlugin } from './instrumentation.js';
24
+ import { instrumentDependencies } from './dependencies.js';
25
+ import { startErrorCapture, expressErrorMiddleware, fastifyErrorHandler } from './errors.js';
26
+ import { startFlushing, stopFlushing, finalFlush, flush } from './transport.js';
27
+ import { getAggregator } from './aggregator.js';
28
+ import { normalizeRoute, extractRoute, RouteRegistry } from './normalizer.js';
29
+ import { instrumentMongoDB, autoInstrumentMongoDB, stopMongoDBInstrumentation } from './mongodb.js';
30
+ import { instrumentOpenAI, stopOpenAIInstrumentation } from './openai.js';
31
+ import { createBreaker, wrapMongoOperation, getBreakerStats, shutdownBreakers } from './circuitBreaker.js';
32
+
33
+ let isInitialized = false;
34
+
35
+ /**
36
+ * Initialize the SDK
37
+ * Called automatically on import
38
+ */
39
+ function initialize() {
40
+ if (isInitialized) {
41
+ debug('SDK already initialized');
42
+ return;
43
+ }
44
+
45
+ // Check if SDK should be enabled
46
+ if (!isEnabled()) {
47
+ // Silently disable - this is expected behavior
48
+ debug('SDK disabled (missing API key or service name)');
49
+ return;
50
+ }
51
+
52
+ // Warn if this import is not first (other modules may have created servers already)
53
+ // We can't reliably detect this, so just log for debugging
54
+ debug(`Initializing SDK for service: ${config.service}`);
55
+ debug(`Environment: ${config.environment}`);
56
+ debug(`Endpoint: ${config.endpoint}`);
57
+ debug(`Flush interval: ${config.flushInterval}s`);
58
+
59
+ // Instrument HTTP (incoming requests)
60
+ instrumentHttp();
61
+
62
+ // Instrument dependencies (outgoing requests)
63
+ instrumentDependencies();
64
+
65
+ // Auto-instrument MongoDB if available
66
+ autoInstrumentMongoDB();
67
+
68
+ // Start error capture
69
+ startErrorCapture();
70
+
71
+ // Start periodic flush
72
+ startFlushing();
73
+
74
+ // Handle graceful shutdown
75
+ setupGracefulShutdown();
76
+
77
+ isInitialized = true;
78
+ debug('SDK initialized successfully');
79
+ }
80
+
81
+ /**
82
+ * Setup graceful shutdown handlers
83
+ */
84
+ function setupGracefulShutdown() {
85
+ const shutdown = async (signal) => {
86
+ debug(`Received ${signal}, performing graceful shutdown`);
87
+
88
+ // Stop accepting new data
89
+ stopFlushing();
90
+
91
+ // Final flush
92
+ await finalFlush();
93
+
94
+ debug('Shutdown complete');
95
+ };
96
+
97
+ // Handle common shutdown signals
98
+ process.once('SIGTERM', () => shutdown('SIGTERM'));
99
+ process.once('SIGINT', () => shutdown('SIGINT'));
100
+
101
+ // Handle process exit
102
+ process.once('beforeExit', () => shutdown('beforeExit'));
103
+ }
104
+
105
+ /**
106
+ * Shutdown the SDK
107
+ * Call this before process exit for clean shutdown
108
+ */
109
+ async function shutdown() {
110
+ if (!isInitialized) return;
111
+
112
+ debug('Shutting down SDK');
113
+
114
+ // Stop MongoDB instrumentation
115
+ stopMongoDBInstrumentation();
116
+
117
+ // Stop OpenAI instrumentation
118
+ stopOpenAIInstrumentation();
119
+
120
+ // Shutdown circuit breakers
121
+ shutdownBreakers();
122
+
123
+ stopFlushing();
124
+ await finalFlush();
125
+
126
+ isInitialized = false;
127
+ debug('SDK shutdown complete');
128
+ }
129
+
130
+ /**
131
+ * Get current SDK status
132
+ */
133
+ function getStatus() {
134
+ const aggregator = getAggregator();
135
+ const stats = aggregator.getStats();
136
+
137
+ return {
138
+ enabled: isEnabled(),
139
+ initialized: isInitialized,
140
+ config: {
141
+ service: config.service,
142
+ environment: config.environment,
143
+ flushInterval: config.flushInterval
144
+ },
145
+ stats
146
+ };
147
+ }
148
+
149
+ // Auto-initialize on import
150
+ initialize();
151
+
152
+ // Export for advanced usage
153
+ export {
154
+ // Core functions
155
+ initialize,
156
+ shutdown,
157
+ getStatus,
158
+ flush,
159
+
160
+ // Config
161
+ getConfig,
162
+ isEnabled,
163
+
164
+ // Middleware for frameworks (optional, for better route extraction)
165
+ expressMiddleware,
166
+ expressErrorMiddleware,
167
+ fastifyPlugin,
168
+ fastifyErrorHandler,
169
+
170
+ // Utilities (for custom instrumentation)
171
+ normalizeRoute,
172
+ extractRoute,
173
+ RouteRegistry,
174
+ getAggregator,
175
+
176
+ // MongoDB instrumentation
177
+ instrumentMongoDB,
178
+
179
+ // OpenAI instrumentation
180
+ instrumentOpenAI,
181
+
182
+ // Circuit breaker
183
+ createBreaker,
184
+ wrapMongoOperation,
185
+ getBreakerStats
186
+ };
187
+
188
+ // Default export
189
+ export default {
190
+ initialize,
191
+ shutdown,
192
+ getStatus,
193
+ flush,
194
+ expressMiddleware,
195
+ expressErrorMiddleware,
196
+ fastifyPlugin,
197
+ fastifyErrorHandler,
198
+ normalizeRoute,
199
+ extractRoute,
200
+ getAggregator,
201
+ // MongoDB
202
+ instrumentMongoDB,
203
+ // OpenAI
204
+ instrumentOpenAI,
205
+ // Circuit breaker
206
+ createBreaker,
207
+ wrapMongoOperation,
208
+ getBreakerStats
209
+ };