@forklaunch/core 0.5.3 → 0.5.4

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.
@@ -136,7 +136,7 @@ async function checkAuthorizationToken(authorizationMethod, authorizationToken,
136
136
  }
137
137
  resourceId = decodedJwt.payload.sub;
138
138
  } catch (error) {
139
- console.error(error);
139
+ req.openTelemetryCollector.error(error);
140
140
  return invalidAuthorizationToken;
141
141
  }
142
142
  break;
@@ -217,14 +217,271 @@ async function parseRequestAuth(req, res, next) {
217
217
  next?.();
218
218
  }
219
219
 
220
+ // src/services/getEnvVar.ts
221
+ function getEnvVar(name) {
222
+ const value = process.env[name];
223
+ return value;
224
+ }
225
+
226
+ // src/http/telemetry/openTelemetryCollector.ts
227
+ import { HyperExpressInstrumentation } from "@forklaunch/opentelemetry-instrumentation-hyper-express";
228
+ import {
229
+ metrics
230
+ } from "@opentelemetry/api";
231
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
232
+ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
233
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
234
+ import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
235
+ import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
236
+ import { Resource } from "@opentelemetry/resources";
237
+ import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
238
+ import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
239
+ import { NodeSDK } from "@opentelemetry/sdk-node";
240
+ import {
241
+ ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2
242
+ } from "@opentelemetry/semantic-conventions";
243
+ import dotenv from "dotenv";
244
+
245
+ // src/http/guards/isForklaunchRequest.ts
246
+ function isForklaunchRequest(request) {
247
+ return request != null && typeof request === "object" && "contractDetails" in request;
248
+ }
249
+
250
+ // src/http/telemetry/pinoLogger.ts
251
+ import { isNever } from "@forklaunch/common";
252
+ import { trace as trace2 } from "@opentelemetry/api";
253
+ import { logs } from "@opentelemetry/api-logs";
254
+ import pino from "pino";
255
+
256
+ // src/http/guards/isLoggerMeta.ts
257
+ function isLoggerMeta(arg) {
258
+ return typeof arg === "object" && arg !== null && "_meta" in arg;
259
+ }
260
+
261
+ // src/http/telemetry/pinoLogger.ts
262
+ import PinoPretty from "pino-pretty";
263
+ function meta(meta2) {
264
+ return meta2;
265
+ }
266
+ function mapSeverity(level) {
267
+ switch (level) {
268
+ case "silent":
269
+ return 0;
270
+ case "trace":
271
+ return 1;
272
+ case "debug":
273
+ return 5;
274
+ case "info":
275
+ return 9;
276
+ case "warn":
277
+ return 13;
278
+ case "error":
279
+ return 17;
280
+ case "fatal":
281
+ return 21;
282
+ default:
283
+ isNever(level);
284
+ return 0;
285
+ }
286
+ }
287
+ var PinoLogger = class _PinoLogger {
288
+ pinoLogger;
289
+ meta;
290
+ prettyPrinter = PinoPretty.prettyFactory({
291
+ colorize: true
292
+ });
293
+ constructor(level, meta2 = {}) {
294
+ this.pinoLogger = pino({
295
+ level: level || "info",
296
+ formatters: {
297
+ level(label) {
298
+ return { level: label };
299
+ }
300
+ },
301
+ timestamp: pino.stdTimeFunctions.isoTime,
302
+ transport: {
303
+ target: "pino-pretty",
304
+ options: { colorize: true }
305
+ }
306
+ });
307
+ this.meta = meta2;
308
+ }
309
+ log(level, ...args) {
310
+ let meta2 = {};
311
+ const filteredArgs = args.filter((arg) => {
312
+ if (isLoggerMeta(arg)) {
313
+ Object.assign(meta2, arg);
314
+ return false;
315
+ }
316
+ return true;
317
+ });
318
+ const activeSpan = trace2.getActiveSpan();
319
+ if (activeSpan) {
320
+ const activeSpanContext = activeSpan.spanContext();
321
+ meta2.trace_id = activeSpanContext.traceId;
322
+ meta2.span_id = activeSpanContext.spanId;
323
+ meta2.trace_flags = activeSpanContext.traceFlags;
324
+ meta2 = {
325
+ // @ts-expect-error accessing private property
326
+ ...activeSpan.attributes,
327
+ ...meta2
328
+ };
329
+ }
330
+ meta2 = {
331
+ "api.name": "none",
332
+ "correlation.id": "none",
333
+ ...meta2
334
+ };
335
+ this.pinoLogger[level](...filteredArgs);
336
+ logs.getLogger(process.env.OTEL_SERVICE_NAME ?? "unknown").emit({
337
+ severityText: level,
338
+ severityNumber: mapSeverity(level),
339
+ body: this.prettyPrinter(filteredArgs),
340
+ attributes: { ...this.meta, ...meta2 }
341
+ });
342
+ }
343
+ error = (msg, ...args) => this.log("error", msg, ...args);
344
+ info = (msg, ...args) => this.log("info", msg, ...args);
345
+ debug = (msg, ...args) => this.log("debug", msg, ...args);
346
+ warn = (msg, ...args) => this.log("warn", msg, ...args);
347
+ trace = (msg, ...args) => this.log("trace", msg, ...args);
348
+ child(meta2 = {}) {
349
+ return new _PinoLogger(this.pinoLogger.level, { ...this.meta, ...meta2 });
350
+ }
351
+ getBaseLogger() {
352
+ return this.pinoLogger;
353
+ }
354
+ };
355
+ function logger(level, meta2 = {}) {
356
+ return new PinoLogger(level, meta2);
357
+ }
358
+
359
+ // src/http/telemetry/openTelemetryCollector.ts
360
+ var OpenTelemetryCollector = class {
361
+ // scoped creation and create this in middleware when api execute. Also add correlation id
362
+ constructor(serviceName, level, metricDefinitions) {
363
+ this.serviceName = serviceName;
364
+ this.logger = logger(level || "info");
365
+ this.metrics = {};
366
+ for (const [metricId, metricType] of Object.entries(
367
+ metricDefinitions ?? {}
368
+ )) {
369
+ switch (metricType) {
370
+ case "counter":
371
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createCounter(metricId);
372
+ break;
373
+ case "gauge":
374
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createGauge(metricId);
375
+ break;
376
+ case "histogram":
377
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createHistogram(metricId);
378
+ break;
379
+ case "upDownCounter":
380
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createUpDownCounter(metricId);
381
+ break;
382
+ case "observableCounter":
383
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableCounter(metricId);
384
+ break;
385
+ case "observableGauge":
386
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableGauge(metricId);
387
+ break;
388
+ case "observableUpDownCounter":
389
+ this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableUpDownCounter(metricId);
390
+ break;
391
+ }
392
+ }
393
+ this.log("info", "OpenTelemetry (Traces + Logs + Metrics) started");
394
+ }
395
+ logger;
396
+ metrics;
397
+ log(level, ...args) {
398
+ this.logger.log(level, ...args);
399
+ }
400
+ info = (msg, ...args) => {
401
+ this.logger.log("info", msg, ...args);
402
+ };
403
+ error = (msg, ...args) => {
404
+ this.logger.log("error", msg, ...args);
405
+ };
406
+ warn = (msg, ...args) => {
407
+ this.logger.log("warn", msg, ...args);
408
+ };
409
+ debug = (msg, ...args) => {
410
+ this.logger.log("debug", msg, ...args);
411
+ };
412
+ trace = (msg, ...args) => {
413
+ this.logger.log("trace", msg, ...args);
414
+ };
415
+ getMetric(metricId) {
416
+ return this.metrics[metricId];
417
+ }
418
+ };
419
+ dotenv.config({ path: getEnvVar("ENV_FILE_PATH") });
420
+ new NodeSDK({
421
+ resource: new Resource({
422
+ [ATTR_SERVICE_NAME2]: getEnvVar("OTEL_SERVICE_NAME")
423
+ }),
424
+ traceExporter: new OTLPTraceExporter({
425
+ url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
426
+ }),
427
+ metricReader: new PeriodicExportingMetricReader({
428
+ exporter: new OTLPMetricExporter({
429
+ url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
430
+ }),
431
+ exportIntervalMillis: 5e3
432
+ }),
433
+ logRecordProcessors: [
434
+ new BatchLogRecordProcessor(
435
+ new OTLPLogExporter({
436
+ url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
437
+ })
438
+ )
439
+ ],
440
+ instrumentations: [
441
+ new HttpInstrumentation({
442
+ applyCustomAttributesOnSpan: (span, request) => {
443
+ span.setAttribute(
444
+ "service.name",
445
+ getEnvVar("OTEL_SERVICE_NAME") ?? "unknown"
446
+ );
447
+ if (isForklaunchRequest(request)) {
448
+ span.setAttribute("api.name", request.contractDetails?.name);
449
+ }
450
+ }
451
+ }),
452
+ new ExpressInstrumentation(),
453
+ new HyperExpressInstrumentation()
454
+ ]
455
+ }).start();
456
+ var httpRequestsTotalCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
457
+ description: "Number of HTTP requests"
458
+ });
459
+ var httpServerDurationHistogram = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
460
+ description: "Duration of HTTP server requests",
461
+ unit: "s"
462
+ });
463
+
220
464
  // src/http/middleware/request/enrichDetails.middleware.ts
221
- function enrichDetails(path, contractDetails, requestSchema, responseSchemas) {
465
+ function enrichDetails(path, contractDetails, requestSchema, responseSchemas, openTelemetryCollector) {
222
466
  return (req, res, next) => {
223
467
  req.originalPath = path;
224
468
  req.contractDetails = contractDetails;
225
469
  req.requestSchema = requestSchema;
226
470
  res.responseSchemas = responseSchemas;
471
+ req.openTelemetryCollector = openTelemetryCollector;
227
472
  req.context.span?.setAttribute(ATTR_API_NAME, req.contractDetails?.name);
473
+ const startTime = process.hrtime();
474
+ res.on("finish", () => {
475
+ const [seconds, nanoseconds] = process.hrtime(startTime);
476
+ const durationMs = seconds + nanoseconds / 1e9;
477
+ httpServerDurationHistogram.record(durationMs, {
478
+ [ATTR_SERVICE_NAME]: getEnvVar("OTEL_SERVICE_NAME") || "unknown",
479
+ [ATTR_API_NAME]: req.contractDetails?.name || "unknown",
480
+ [ATTR_HTTP_REQUEST_METHOD]: req.method,
481
+ [ATTR_HTTP_ROUTE]: req.originalPath || "unknown",
482
+ [ATTR_HTTP_RESPONSE_STATUS_CODE]: res.statusCode
483
+ });
484
+ });
228
485
  next?.();
229
486
  };
230
487
  }
@@ -266,7 +523,9 @@ function parse(req, _res, next) {
266
523
  );
267
524
  break;
268
525
  case "warning":
269
- console.warn(prettyPrintParseErrors(parsedRequest.errors, "Request"));
526
+ req.openTelemetryCollector.warn(
527
+ prettyPrintParseErrors(parsedRequest.errors, "Request")
528
+ );
270
529
  break;
271
530
  case "none":
272
531
  break;
@@ -277,9 +536,10 @@ function parse(req, _res, next) {
277
536
 
278
537
  // src/http/router/expressLikeRouter.ts
279
538
  var ForklaunchExpressLikeRouter = class {
280
- constructor(basePath, schemaValidator, internal) {
539
+ constructor(basePath, schemaValidator, internal, openTelemetryCollector) {
281
540
  this.schemaValidator = schemaValidator;
282
541
  this.internal = internal;
542
+ this.openTelemetryCollector = openTelemetryCollector;
283
543
  this.basePath = basePath;
284
544
  }
285
545
  requestHandler;
@@ -298,7 +558,8 @@ var ForklaunchExpressLikeRouter = class {
298
558
  `${this.basePath}${path}`,
299
559
  contractDetails,
300
560
  requestSchema,
301
- responseSchemas
561
+ responseSchemas,
562
+ this.openTelemetryCollector
302
563
  ),
303
564
  parse,
304
565
  parseRequestAuth
@@ -859,20 +1120,16 @@ var ForklaunchExpressLikeApplication = class extends ForklaunchExpressLikeRouter
859
1120
  *
860
1121
  * @param {SV} schemaValidator - The schema validator.
861
1122
  */
862
- constructor(schemaValidator, internal) {
863
- super("/", schemaValidator, internal);
1123
+ constructor(schemaValidator, internal, openTelemetryCollector) {
1124
+ super("/", schemaValidator, internal, openTelemetryCollector);
864
1125
  this.schemaValidator = schemaValidator;
865
1126
  this.internal = internal;
1127
+ this.openTelemetryCollector = openTelemetryCollector;
866
1128
  this.internal.use(createContext(this.schemaValidator));
867
1129
  this.internal.use(cors);
868
1130
  }
869
1131
  };
870
1132
 
871
- // src/http/guards/isForklaunchRequest.ts
872
- function isForklaunchRequest(request) {
873
- return request != null && typeof request === "object" && "contractDetails" in request;
874
- }
875
-
876
1133
  // src/http/guards/isPath.ts
877
1134
  function isPath(path) {
878
1135
  return path.startsWith("/");
@@ -946,7 +1203,7 @@ var put = (_schemaValidator, path, contractDetails, ...handlers) => {
946
1203
  };
947
1204
 
948
1205
  // src/http/handlers/trace.ts
949
- var trace2 = (_schemaValidator, path, contractDetails, ...handlers) => {
1206
+ var trace3 = (_schemaValidator, path, contractDetails, ...handlers) => {
950
1207
  return typedHandler(_schemaValidator, path, "trace", contractDetails, ...handlers);
951
1208
  };
952
1209
 
@@ -1971,8 +2228,10 @@ function parse2(req, res, next) {
1971
2228
  ${parseErrors.join("\n\n")}`));
1972
2229
  break;
1973
2230
  case "warning":
1974
- console.warn(`Invalid response:
1975
- ${parseErrors.join("\n\n")}`);
2231
+ req.openTelemetryCollector.warn(
2232
+ `Invalid response:
2233
+ ${parseErrors.join("\n\n")}`
2234
+ );
1976
2235
  break;
1977
2236
  case "none":
1978
2237
  break;
@@ -1981,96 +2240,6 @@ ${parseErrors.join("\n\n")}`);
1981
2240
  next?.();
1982
2241
  }
1983
2242
 
1984
- // src/http/telemetry/pinoLogger.ts
1985
- import { isNever } from "@forklaunch/common";
1986
- import { trace as trace3 } from "@opentelemetry/api";
1987
- import { logs } from "@opentelemetry/api-logs";
1988
- import pino from "pino";
1989
- function mapSeverity(level) {
1990
- switch (level) {
1991
- case "silent":
1992
- return 0;
1993
- case "trace":
1994
- return 1;
1995
- case "debug":
1996
- return 5;
1997
- case "info":
1998
- return 9;
1999
- case "warn":
2000
- return 13;
2001
- case "error":
2002
- return 17;
2003
- case "fatal":
2004
- return 21;
2005
- default:
2006
- isNever(level);
2007
- return 0;
2008
- }
2009
- }
2010
- var PinoLogger = class _PinoLogger {
2011
- pinoLogger;
2012
- meta;
2013
- constructor(level, meta = {}) {
2014
- this.pinoLogger = pino({
2015
- level: level || "info",
2016
- formatters: {
2017
- level(label) {
2018
- return { level: label };
2019
- }
2020
- },
2021
- timestamp: pino.stdTimeFunctions.isoTime,
2022
- transport: {
2023
- target: "pino-pretty",
2024
- options: { colorize: true }
2025
- }
2026
- });
2027
- this.meta = meta;
2028
- }
2029
- log(level, msg, meta = {}) {
2030
- const activeSpan = trace3.getActiveSpan();
2031
- if (activeSpan) {
2032
- const activeSpanContext = activeSpan.spanContext();
2033
- meta.trace_id = activeSpanContext.traceId;
2034
- meta.span_id = activeSpanContext.spanId;
2035
- meta.trace_flags = activeSpanContext.traceFlags;
2036
- if (!meta.api_name) {
2037
- meta = { ...meta, ...activeSpan?.attributes };
2038
- }
2039
- }
2040
- this.pinoLogger[level](msg);
2041
- logs.getLogger(process.env.OTEL_SERVICE_NAME ?? "unknown").emit({
2042
- severityText: level,
2043
- severityNumber: mapSeverity(level),
2044
- body: msg,
2045
- attributes: { ...this.meta, ...meta }
2046
- });
2047
- }
2048
- error(msg, meta = {}) {
2049
- this.log("error", msg, meta);
2050
- }
2051
- info(msg, meta = {}) {
2052
- this.log("info", msg, meta);
2053
- }
2054
- debug(msg, meta = {}) {
2055
- this.log("debug", msg, meta);
2056
- }
2057
- warn(msg, meta = {}) {
2058
- this.log("warn", msg, meta);
2059
- }
2060
- trace(msg, meta = {}) {
2061
- this.log("trace", msg, meta);
2062
- }
2063
- child(meta = {}) {
2064
- return new _PinoLogger(this.pinoLogger.level, { ...this.meta, ...meta });
2065
- }
2066
- getBaseLogger() {
2067
- return this.pinoLogger;
2068
- }
2069
- };
2070
- function logger(level, meta = {}) {
2071
- return new PinoLogger(level, meta);
2072
- }
2073
-
2074
2243
  // src/http/telemetry/recordMetric.ts
2075
2244
  import {
2076
2245
  ATTR_HTTP_REQUEST_METHOD as ATTR_HTTP_REQUEST_METHOD3,
@@ -2085,130 +2254,6 @@ import {
2085
2254
  prettyPrintParseErrors as prettyPrintParseErrors3
2086
2255
  } from "@forklaunch/validator";
2087
2256
 
2088
- // src/services/getEnvVar.ts
2089
- function getEnvVar(name) {
2090
- const value = process.env[name];
2091
- return value;
2092
- }
2093
-
2094
- // src/http/telemetry/openTelemetryCollector.ts
2095
- import { HyperExpressInstrumentation } from "@forklaunch/opentelemetry-instrumentation-hyper-express";
2096
- import {
2097
- metrics
2098
- } from "@opentelemetry/api";
2099
- import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
2100
- import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
2101
- import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
2102
- import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
2103
- import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
2104
- import { Resource } from "@opentelemetry/resources";
2105
- import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
2106
- import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
2107
- import { NodeSDK } from "@opentelemetry/sdk-node";
2108
- import {
2109
- ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2
2110
- } from "@opentelemetry/semantic-conventions";
2111
- import dotenv from "dotenv";
2112
- var OpenTelemetryCollector = class {
2113
- // scoped creation and create this in middleware when api execute. Also add correlation id
2114
- constructor(serviceName, level, metricDefinitions) {
2115
- this.serviceName = serviceName;
2116
- this.logger = logger(level ?? "info");
2117
- this.metrics = {};
2118
- for (const [metricId, metricType] of Object.entries(
2119
- metricDefinitions ?? {}
2120
- )) {
2121
- switch (metricType) {
2122
- case "counter":
2123
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createCounter(metricId);
2124
- break;
2125
- case "gauge":
2126
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createGauge(metricId);
2127
- break;
2128
- case "histogram":
2129
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createHistogram(metricId);
2130
- break;
2131
- case "upDownCounter":
2132
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createUpDownCounter(metricId);
2133
- break;
2134
- case "observableCounter":
2135
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableCounter(metricId);
2136
- break;
2137
- case "observableGauge":
2138
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableGauge(metricId);
2139
- break;
2140
- case "observableUpDownCounter":
2141
- this.metrics[metricId] = metrics.getMeter(this.serviceName).createObservableUpDownCounter(metricId);
2142
- break;
2143
- }
2144
- }
2145
- this.log("info", "OpenTelemetry (Traces + Logs + Metrics) started");
2146
- }
2147
- logger;
2148
- metrics;
2149
- log(level, msg, meta = {}) {
2150
- this.logger.log(level, msg, meta);
2151
- }
2152
- info(msg, meta = {}) {
2153
- this.logger.info(msg, meta);
2154
- }
2155
- error(msg, meta = {}) {
2156
- this.logger.error(msg, meta);
2157
- }
2158
- warn(msg, meta = {}) {
2159
- this.logger.warn(msg, meta);
2160
- }
2161
- debug(msg, meta = {}) {
2162
- this.logger.debug(msg, meta);
2163
- }
2164
- trace(msg, meta = {}) {
2165
- this.logger.trace(msg, meta);
2166
- }
2167
- getMetric(metricId) {
2168
- return this.metrics[metricId];
2169
- }
2170
- };
2171
- dotenv.config({ path: getEnvVar("ENV_FILE_PATH") });
2172
- new NodeSDK({
2173
- resource: new Resource({
2174
- [ATTR_SERVICE_NAME2]: getEnvVar("OTEL_SERVICE_NAME")
2175
- }),
2176
- traceExporter: new OTLPTraceExporter({
2177
- url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
2178
- }),
2179
- metricReader: new PeriodicExportingMetricReader({
2180
- exporter: new OTLPMetricExporter({
2181
- url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
2182
- }),
2183
- exportIntervalMillis: 5e3
2184
- }),
2185
- logRecordProcessors: [
2186
- new BatchLogRecordProcessor(
2187
- new OTLPLogExporter({
2188
- url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
2189
- })
2190
- )
2191
- ],
2192
- instrumentations: [
2193
- new HttpInstrumentation({
2194
- applyCustomAttributesOnSpan: (span, request) => {
2195
- span.setAttribute(
2196
- "service.name",
2197
- getEnvVar("OTEL_SERVICE_NAME") ?? "unknown"
2198
- );
2199
- if (isForklaunchRequest(request)) {
2200
- span.setAttribute("api.name", request.contractDetails?.name);
2201
- }
2202
- }
2203
- }),
2204
- new ExpressInstrumentation(),
2205
- new HyperExpressInstrumentation()
2206
- ]
2207
- }).start();
2208
- var httpRequestsTotalCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
2209
- description: "Number of HTTP requests"
2210
- });
2211
-
2212
2257
  // src/http/telemetry/recordMetric.ts
2213
2258
  function recordMetric(req, res) {
2214
2259
  httpRequestsTotalCounter.add(1, {
@@ -2227,6 +2272,7 @@ function enrichExpressLikeSend(instance, req, res, originalSend, data, shouldEnr
2227
2272
  if (shouldEnrich) {
2228
2273
  recordMetric(req, res);
2229
2274
  if (res.statusCode === 404) {
2275
+ res.type("text/plain");
2230
2276
  res.status(404);
2231
2277
  logger("error").error("Not Found");
2232
2278
  originalSend.call(instance, "Not Found");
@@ -2240,6 +2286,7 @@ function enrichExpressLikeSend(instance, req, res, originalSend, data, shouldEnr
2240
2286
  ${res.locals.errorMessage}`;
2241
2287
  }
2242
2288
  logger("error").error(errorString);
2289
+ res.type("text/plain");
2243
2290
  res.status(500);
2244
2291
  originalSend.call(instance, errorString);
2245
2292
  parseErrorSent = true;
@@ -2416,6 +2463,7 @@ export {
2416
2463
  getCodeForStatus,
2417
2464
  head,
2418
2465
  httpRequestsTotalCounter,
2466
+ httpServerDurationHistogram,
2419
2467
  isClientError,
2420
2468
  isForklaunchRequest,
2421
2469
  isForklaunchRouter,
@@ -2425,6 +2473,7 @@ export {
2425
2473
  isSuccessful,
2426
2474
  isValidStatusCode,
2427
2475
  logger,
2476
+ meta,
2428
2477
  metricsDefinitions,
2429
2478
  middleware,
2430
2479
  options,
@@ -2432,7 +2481,7 @@ export {
2432
2481
  post,
2433
2482
  put,
2434
2483
  recordMetric,
2435
- trace2 as trace,
2484
+ trace3 as trace,
2436
2485
  typedHandler
2437
2486
  };
2438
2487
  //# sourceMappingURL=index.mjs.map