@powerhousedao/reactor-api 5.1.0-dev.25 → 5.1.0-dev.27

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.
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Datadog APM Tracing Module
3
+ *
4
+ * This module provides Datadog tracing, profiling, and logging integration.
5
+ * Tracing is enabled when DD_TRACE_ENABLED=true or DD_ENV is set.
6
+ *
7
+ * Environment Variables (aligned with vetra-cloud ECS configuration):
8
+ * - DD_TRACE_ENABLED: Enable tracing (default: "false"). Set to "true" to enable.
9
+ * - DD_ENV: Environment name (e.g., "production", "staging"). Also enables tracing if set.
10
+ * - DD_SERVICE: Service name (default: "reactor-api")
11
+ * - DD_VERSION: Service version (default: "1.0.0" or reads from package.json)
12
+ * - DD_AGENT_HOST: Datadog agent host (default: "localhost")
13
+ * - DD_TRACE_AGENT_PORT: Datadog trace agent port (default: 8126)
14
+ * - DD_DOGSTATSD_PORT: DogStatsD port for metrics (default: 8125)
15
+ * - DD_SITE: Datadog site (default: "datadoghq.com")
16
+ * - DD_PROFILING_ENABLED: Enable continuous profiling (default: "true" when tracing enabled)
17
+ * - DD_LOGS_INJECTION: Enable log correlation (default: "true" when tracing enabled)
18
+ * - DD_RUNTIME_METRICS_ENABLED: Enable runtime metrics (default: "true")
19
+ */
20
+ let tracer = null;
21
+ let isInitialized = false;
22
+ /**
23
+ * Check if Datadog tracing should be enabled based on environment variables.
24
+ * Tracing is enabled when DD_TRACE_ENABLED=true or DD_ENV is set.
25
+ */
26
+ export function isTracingEnabled() {
27
+ return process.env.DD_TRACE_ENABLED === "true" || !!process.env.DD_ENV;
28
+ }
29
+ /**
30
+ * Initialize Datadog tracing.
31
+ * This should be called as early as possible in the application lifecycle,
32
+ * ideally before any other imports.
33
+ *
34
+ * @returns The initialized tracer instance, or null if tracing is disabled.
35
+ */
36
+ export async function initTracing() {
37
+ if (isInitialized) {
38
+ return tracer;
39
+ }
40
+ isInitialized = true;
41
+ if (!isTracingEnabled()) {
42
+ return null;
43
+ }
44
+ const ddTrace = await import("dd-trace");
45
+ // Get version - default to "1.0.0" per vetra-cloud config, or read from package.json
46
+ let version = process.env.DD_VERSION;
47
+ if (!version) {
48
+ try {
49
+ const { readPackage } = await import("read-pkg");
50
+ const pkg = await readPackage();
51
+ version = pkg.version || "1.0.0";
52
+ }
53
+ catch {
54
+ version = "1.0.0";
55
+ }
56
+ }
57
+ const serviceName = process.env.DD_SERVICE ?? "reactor-api";
58
+ const env = process.env.DD_ENV ?? "development";
59
+ const hostname = process.env.DD_AGENT_HOST ?? "localhost";
60
+ const port = parseInt(process.env.DD_TRACE_AGENT_PORT ?? "8126", 10);
61
+ const dogstatsdPort = parseInt(process.env.DD_DOGSTATSD_PORT ?? "8125", 10);
62
+ // Initialize the tracer with vetra-cloud aligned configuration
63
+ tracer = ddTrace.default.init({
64
+ service: serviceName,
65
+ env,
66
+ version,
67
+ hostname,
68
+ port,
69
+ dogstatsd: {
70
+ hostname,
71
+ port: dogstatsdPort,
72
+ },
73
+ logInjection: process.env.DD_LOGS_INJECTION !== "false",
74
+ runtimeMetrics: process.env.DD_RUNTIME_METRICS_ENABLED !== "false",
75
+ profiling: process.env.DD_PROFILING_ENABLED !== "false",
76
+ // Enable common integrations
77
+ plugins: true,
78
+ // Tags for better categorization
79
+ tags: {
80
+ "dd.source": "nodejs",
81
+ },
82
+ });
83
+ // Enable profiling if not explicitly disabled
84
+ if (process.env.DD_PROFILING_ENABLED !== "false") {
85
+ try {
86
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
87
+ // @ts-expect-error - dd-trace/profiling doesn't have type declarations
88
+ const { profiler } = await import("dd-trace/profiling");
89
+ profiler.start();
90
+ /* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
91
+ }
92
+ catch (err) {
93
+ console.warn("[tracing] Failed to start profiler:", err);
94
+ }
95
+ }
96
+ console.info(`[tracing] Datadog tracing initialized: service=${serviceName}, env=${env}, version=${version}, agent=${hostname}:${port}`);
97
+ return tracer;
98
+ }
99
+ /**
100
+ * Get the current tracer instance.
101
+ * Returns null if tracing is not initialized or disabled.
102
+ */
103
+ export function getTracer() {
104
+ return tracer;
105
+ }
106
+ /**
107
+ * Create a new span for tracing a specific operation.
108
+ * If tracing is disabled, this returns a no-op wrapper.
109
+ *
110
+ * @param name - The name of the operation
111
+ * @param options - Optional span options
112
+ * @param fn - The function to trace
113
+ * @returns The result of the function
114
+ */
115
+ export async function trace(name, options, fn) {
116
+ if (!tracer) {
117
+ return fn(undefined);
118
+ }
119
+ return tracer.trace(name, options, fn);
120
+ }
121
+ /**
122
+ * Synchronous version of trace.
123
+ */
124
+ export function traceSync(name, options, fn) {
125
+ if (!tracer) {
126
+ return fn(undefined);
127
+ }
128
+ return tracer.trace(name, options, fn);
129
+ }
130
+ /**
131
+ * Add tags to the current active span.
132
+ */
133
+ export function addTags(tags) {
134
+ if (!tracer) {
135
+ return;
136
+ }
137
+ const span = tracer.scope().active();
138
+ if (span) {
139
+ span.addTags(tags);
140
+ }
141
+ }
142
+ /**
143
+ * Set an error on the current active span.
144
+ */
145
+ export function setError(error) {
146
+ if (!tracer) {
147
+ return;
148
+ }
149
+ const span = tracer.scope().active();
150
+ if (span) {
151
+ span.setTag("error", true);
152
+ span.setTag("error.message", error.message);
153
+ span.setTag("error.stack", error.stack ?? "");
154
+ }
155
+ }
156
+ /**
157
+ * Get trace context for log correlation.
158
+ * Returns trace_id and span_id for the current active span.
159
+ */
160
+ export function getTraceContext() {
161
+ if (!tracer) {
162
+ return {};
163
+ }
164
+ const span = tracer.scope().active();
165
+ if (!span) {
166
+ return {
167
+ service: process.env.DD_SERVICE ?? "reactor-api",
168
+ env: process.env.DD_ENV,
169
+ };
170
+ }
171
+ const context = span.context();
172
+ return {
173
+ trace_id: context.toTraceId(),
174
+ span_id: context.toSpanId(),
175
+ service: process.env.DD_SERVICE ?? "reactor-api",
176
+ env: process.env.DD_ENV,
177
+ };
178
+ }
179
+ /**
180
+ * Create a structured log entry with trace correlation.
181
+ * This format is compatible with Datadog log ingestion via FireLens.
182
+ */
183
+ export function createStructuredLog(level, message, data) {
184
+ const traceContext = getTraceContext();
185
+ const service = process.env.DD_SERVICE ?? "reactor-api";
186
+ const env = process.env.DD_ENV ?? "development";
187
+ const version = process.env.DD_VERSION ?? "1.0.0";
188
+ const projectName = process.env.PH_PROJECT_NAME ?? "powerhouse";
189
+ const log = {
190
+ timestamp: new Date().toISOString(),
191
+ level,
192
+ message,
193
+ // Datadog standard fields for log processing
194
+ ddsource: "nodejs",
195
+ ddtags: `env:${env},project:${projectName},version:${version}`,
196
+ service,
197
+ env,
198
+ version,
199
+ ...data,
200
+ };
201
+ // Add trace correlation if available
202
+ if (traceContext.trace_id || traceContext.span_id) {
203
+ log.dd = {
204
+ trace_id: traceContext.trace_id,
205
+ span_id: traceContext.span_id,
206
+ };
207
+ }
208
+ return log;
209
+ }
210
+ /**
211
+ * Logger that outputs structured JSON logs compatible with Datadog.
212
+ * When tracing is disabled, falls back to simple console logging.
213
+ */
214
+ export const structuredLogger = {
215
+ debug(message, data) {
216
+ if (isTracingEnabled()) {
217
+ console.log(JSON.stringify(createStructuredLog("debug", message, data)));
218
+ }
219
+ else {
220
+ console.debug(message, data ?? "");
221
+ }
222
+ },
223
+ info(message, data) {
224
+ if (isTracingEnabled()) {
225
+ console.log(JSON.stringify(createStructuredLog("info", message, data)));
226
+ }
227
+ else {
228
+ console.info(message, data ?? "");
229
+ }
230
+ },
231
+ warn(message, data) {
232
+ if (isTracingEnabled()) {
233
+ console.log(JSON.stringify(createStructuredLog("warn", message, data)));
234
+ }
235
+ else {
236
+ console.warn(message, data ?? "");
237
+ }
238
+ },
239
+ error(message, error, data) {
240
+ const errorData = { ...data };
241
+ if (error instanceof Error) {
242
+ errorData.error = {
243
+ name: error.name,
244
+ message: error.message,
245
+ stack: error.stack,
246
+ };
247
+ }
248
+ else if (error !== undefined) {
249
+ errorData.error = error;
250
+ }
251
+ if (isTracingEnabled()) {
252
+ console.log(JSON.stringify(createStructuredLog("error", message, errorData)));
253
+ }
254
+ else {
255
+ console.error(message, error ?? "", data ?? "");
256
+ }
257
+ },
258
+ };
259
+ //# sourceMappingURL=tracing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing.js","sourceRoot":"","sources":["../../src/tracing.ts"],"names":[],"mappings":"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"}