@prairielearn/opentelemetry 1.11.3 → 2.0.1

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/.mocharc.cjs ADDED
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ require: ['tsx'],
3
+ };
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @prairielearn/opentelemetry
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 901fce8: Upgrade all JavaScript dependencies
8
+ - b697912: Fix CommonJS preloads of packages
9
+
10
+ ## 2.0.0
11
+
12
+ ### Major Changes
13
+
14
+ - 4f30b7e: Publish as native ESM
15
+
16
+ ### Minor Changes
17
+
18
+ - c51f3aa: Upgrade all JavaScript dependencies; ensure packages loaded with ESM are instrumented
19
+
3
20
  ## 1.11.3
4
21
 
5
22
  ### Patch Changes
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import { createRequire } from 'module';
2
+ // The packages below were determined by inspecting the implementation of each
3
+ // instrumentation package and finding which packages/files they're patching.
4
+ const PRELOAD_PACKAGES = [
5
+ // @opentelemetry/instrumentation-aws-sdk
6
+ '@aws-sdk/middleware-stack/dist/cjs/MiddlewareStack.js',
7
+ '@aws-sdk/middleware-stack/dist-cjs/MiddlewareStack.js',
8
+ '@aws-sdk/middleware-stack',
9
+ '@smithy/middleware-stack',
10
+ '@aws-sdk/smithy-client',
11
+ 'aws-sdk/lib/core.js',
12
+ 'aws-sdk',
13
+ // @opentelemetry/instrumentation-connect
14
+ 'connect',
15
+ // @opentelemetry/instrumentation-dns
16
+ 'dns',
17
+ 'dns/promises',
18
+ // @opentelemetry/instrumentation-express
19
+ 'express',
20
+ // @opentelemetry/instrumentation-http
21
+ 'http',
22
+ 'https',
23
+ // @opentelemetry/instrumentation-ioredis
24
+ 'ioredis',
25
+ // @opentelemetry/instrumentation-postgres
26
+ 'pg',
27
+ 'pg-pool',
28
+ // @opentelemetry/instrumentation-redis
29
+ 'redis',
30
+ ];
31
+ const require = createRequire(import.meta.url);
32
+ for (const pkg of PRELOAD_PACKAGES) {
33
+ try {
34
+ require(pkg);
35
+ }
36
+ catch (e) {
37
+ // If the package is not found, it's fine, it just means that it wasn't
38
+ // installed. We'll throw any other errors.
39
+ if (e.code !== 'MODULE_NOT_FOUND')
40
+ throw e;
41
+ }
42
+ }
43
+ //# sourceMappingURL=commonjs-preloads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commonjs-preloads.js","sourceRoot":"","sources":["../src/commonjs-preloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,8EAA8E;AAC9E,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG;IACvB,yCAAyC;IACzC,uDAAuD;IACvD,uDAAuD;IACvD,2BAA2B;IAC3B,0BAA0B;IAC1B,wBAAwB;IACxB,qBAAqB;IACrB,SAAS;IACT,yCAAyC;IACzC,SAAS;IACT,qCAAqC;IACrC,KAAK;IACL,cAAc;IACd,yCAAyC;IACzC,SAAS;IACT,sCAAsC;IACtC,MAAM;IACN,OAAO;IACP,yCAAyC;IACzC,SAAS;IACT,0CAA0C;IAC1C,IAAI;IACJ,SAAS;IACT,uCAAuC;IACvC,OAAO;CACR,CAAC;AAEF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,uEAAuE;QACvE,2CAA2C;QAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;YAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC","sourcesContent":["import { createRequire } from 'module';\n\n// The packages below were determined by inspecting the implementation of each\n// instrumentation package and finding which packages/files they're patching.\nconst PRELOAD_PACKAGES = [\n // @opentelemetry/instrumentation-aws-sdk\n '@aws-sdk/middleware-stack/dist/cjs/MiddlewareStack.js',\n '@aws-sdk/middleware-stack/dist-cjs/MiddlewareStack.js',\n '@aws-sdk/middleware-stack',\n '@smithy/middleware-stack',\n '@aws-sdk/smithy-client',\n 'aws-sdk/lib/core.js',\n 'aws-sdk',\n // @opentelemetry/instrumentation-connect\n 'connect',\n // @opentelemetry/instrumentation-dns\n 'dns',\n 'dns/promises',\n // @opentelemetry/instrumentation-express\n 'express',\n // @opentelemetry/instrumentation-http\n 'http',\n 'https',\n // @opentelemetry/instrumentation-ioredis\n 'ioredis',\n // @opentelemetry/instrumentation-postgres\n 'pg',\n 'pg-pool',\n // @opentelemetry/instrumentation-redis\n 'redis',\n];\n\nconst require = createRequire(import.meta.url);\nfor (const pkg of PRELOAD_PACKAGES) {\n try {\n require(pkg);\n } catch (e: any) {\n // If the package is not found, it's fine, it just means that it wasn't\n // installed. We'll throw any other errors.\n if (e.code !== 'MODULE_NOT_FOUND') throw e;\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { trace, metrics, context, SpanStatusCode, ValueType, TraceFlags, Meter, Counter, Histogram, UpDownCounter, ObservableCounter, ObservableUpDownCounter, ObservableGauge, ObservableResult, } from '@opentelemetry/api';
1
+ export { trace, metrics, context, SpanStatusCode, ValueType, TraceFlags, type Meter, type Counter, type Histogram, type UpDownCounter, type ObservableCounter, type ObservableUpDownCounter, type ObservableGauge, type ObservableResult, } from '@opentelemetry/api';
2
2
  export { suppressTracing } from '@opentelemetry/core';
3
- export { init, shutdown, disableInstrumentations } from './init';
4
- export { instrumented } from './tracing';
5
- export { instrumentedWithMetrics, getCounter, getUpDownCounter, getHistogram, getObservableCounter, getObservableUpDownCounter, getObservableGauge, createObservableValueGauges, createObservableValueGaugesOptions, } from './metrics';
3
+ export { init, shutdown, disableInstrumentations } from './init.js';
4
+ export { instrumented } from './tracing.js';
5
+ export { instrumentedWithMetrics, getCounter, getUpDownCounter, getHistogram, getObservableCounter, getObservableUpDownCounter, getObservableGauge, createObservableValueGauges, type CreateObservableValueGaugesOptions, } from './metrics.js';
6
+ import './commonjs-preloads.js';
package/dist/index.js CHANGED
@@ -1,28 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createObservableValueGauges = exports.getObservableGauge = exports.getObservableUpDownCounter = exports.getObservableCounter = exports.getHistogram = exports.getUpDownCounter = exports.getCounter = exports.instrumentedWithMetrics = exports.instrumented = exports.disableInstrumentations = exports.shutdown = exports.init = exports.suppressTracing = exports.TraceFlags = exports.ValueType = exports.SpanStatusCode = exports.context = exports.metrics = exports.trace = void 0;
4
- var api_1 = require("@opentelemetry/api");
5
- Object.defineProperty(exports, "trace", { enumerable: true, get: function () { return api_1.trace; } });
6
- Object.defineProperty(exports, "metrics", { enumerable: true, get: function () { return api_1.metrics; } });
7
- Object.defineProperty(exports, "context", { enumerable: true, get: function () { return api_1.context; } });
8
- Object.defineProperty(exports, "SpanStatusCode", { enumerable: true, get: function () { return api_1.SpanStatusCode; } });
9
- Object.defineProperty(exports, "ValueType", { enumerable: true, get: function () { return api_1.ValueType; } });
10
- Object.defineProperty(exports, "TraceFlags", { enumerable: true, get: function () { return api_1.TraceFlags; } });
11
- var core_1 = require("@opentelemetry/core");
12
- Object.defineProperty(exports, "suppressTracing", { enumerable: true, get: function () { return core_1.suppressTracing; } });
13
- var init_1 = require("./init");
14
- Object.defineProperty(exports, "init", { enumerable: true, get: function () { return init_1.init; } });
15
- Object.defineProperty(exports, "shutdown", { enumerable: true, get: function () { return init_1.shutdown; } });
16
- Object.defineProperty(exports, "disableInstrumentations", { enumerable: true, get: function () { return init_1.disableInstrumentations; } });
17
- var tracing_1 = require("./tracing");
18
- Object.defineProperty(exports, "instrumented", { enumerable: true, get: function () { return tracing_1.instrumented; } });
19
- var metrics_1 = require("./metrics");
20
- Object.defineProperty(exports, "instrumentedWithMetrics", { enumerable: true, get: function () { return metrics_1.instrumentedWithMetrics; } });
21
- Object.defineProperty(exports, "getCounter", { enumerable: true, get: function () { return metrics_1.getCounter; } });
22
- Object.defineProperty(exports, "getUpDownCounter", { enumerable: true, get: function () { return metrics_1.getUpDownCounter; } });
23
- Object.defineProperty(exports, "getHistogram", { enumerable: true, get: function () { return metrics_1.getHistogram; } });
24
- Object.defineProperty(exports, "getObservableCounter", { enumerable: true, get: function () { return metrics_1.getObservableCounter; } });
25
- Object.defineProperty(exports, "getObservableUpDownCounter", { enumerable: true, get: function () { return metrics_1.getObservableUpDownCounter; } });
26
- Object.defineProperty(exports, "getObservableGauge", { enumerable: true, get: function () { return metrics_1.getObservableGauge; } });
27
- Object.defineProperty(exports, "createObservableValueGauges", { enumerable: true, get: function () { return metrics_1.createObservableValueGauges; } });
1
+ export { trace, metrics, context, SpanStatusCode, ValueType, TraceFlags, } from '@opentelemetry/api';
2
+ export { suppressTracing } from '@opentelemetry/core';
3
+ export { init, shutdown, disableInstrumentations } from './init.js';
4
+ export { instrumented } from './tracing.js';
5
+ export { instrumentedWithMetrics, getCounter, getUpDownCounter, getHistogram, getObservableCounter, getObservableUpDownCounter, getObservableGauge, createObservableValueGauges, } from './metrics.js';
6
+ // Extremely stupid workaround for the fact that the OpenTelemetry instrumentations
7
+ // don't currently have robust support for ESM. This hack ensures that instrumented
8
+ // packages are loaded for the first time via CJS, which the OpenTelemetry
9
+ // instrumentation can intercept and patch. Subsequent imports can be ESM, but that
10
+ // doesn't matter because the instrumentation has already been applied.
11
+ //
12
+ // OpenTelemetry introduced experimental support for ESM in
13
+ // https://github.com/open-telemetry/opentelemetry-js/pull/3698. This requires
14
+ // the usage of `--experimental-loader` to load the instrumentations, which
15
+ // we currently want to avoid.
16
+ import './commonjs-preloads.js';
28
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0CAe4B;AAd1B,4FAAA,KAAK,OAAA;AACL,8FAAA,OAAO,OAAA;AACP,8FAAA,OAAO,OAAA;AACP,qGAAA,cAAc,OAAA;AACd,gGAAA,SAAS,OAAA;AACT,iGAAA,UAAU,OAAA;AAUZ,4CAAsD;AAA7C,uGAAA,eAAe,OAAA;AAExB,+BAAiE;AAAxD,4FAAA,IAAI,OAAA;AAAE,gGAAA,QAAQ,OAAA;AAAE,+GAAA,uBAAuB,OAAA;AAChD,qCAAyC;AAAhC,uGAAA,YAAY,OAAA;AACrB,qCAUmB;AATjB,kHAAA,uBAAuB,OAAA;AACvB,qGAAA,UAAU,OAAA;AACV,2GAAA,gBAAgB,OAAA;AAChB,uGAAA,YAAY,OAAA;AACZ,+GAAA,oBAAoB,OAAA;AACpB,qHAAA,0BAA0B,OAAA;AAC1B,6GAAA,kBAAkB,OAAA;AAClB,sHAAA,2BAA2B,OAAA","sourcesContent":["export {\n trace,\n metrics,\n context,\n SpanStatusCode,\n ValueType,\n TraceFlags,\n Meter,\n Counter,\n Histogram,\n UpDownCounter,\n ObservableCounter,\n ObservableUpDownCounter,\n ObservableGauge,\n ObservableResult,\n} from '@opentelemetry/api';\nexport { suppressTracing } from '@opentelemetry/core';\n\nexport { init, shutdown, disableInstrumentations } from './init';\nexport { instrumented } from './tracing';\nexport {\n instrumentedWithMetrics,\n getCounter,\n getUpDownCounter,\n getHistogram,\n getObservableCounter,\n getObservableUpDownCounter,\n getObservableGauge,\n createObservableValueGauges,\n createObservableValueGaugesOptions,\n} from './metrics';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,cAAc,EACd,SAAS,EACT,UAAU,GASX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,2BAA2B,GAE5B,MAAM,cAAc,CAAC;AAEtB,mFAAmF;AACnF,mFAAmF;AACnF,0EAA0E;AAC1E,mFAAmF;AACnF,uEAAuE;AACvE,EAAE;AACF,2DAA2D;AAC3D,8EAA8E;AAC9E,2EAA2E;AAC3E,8BAA8B;AAC9B,OAAO,wBAAwB,CAAC","sourcesContent":["export {\n trace,\n metrics,\n context,\n SpanStatusCode,\n ValueType,\n TraceFlags,\n type Meter,\n type Counter,\n type Histogram,\n type UpDownCounter,\n type ObservableCounter,\n type ObservableUpDownCounter,\n type ObservableGauge,\n type ObservableResult,\n} from '@opentelemetry/api';\nexport { suppressTracing } from '@opentelemetry/core';\n\nexport { init, shutdown, disableInstrumentations } from './init.js';\nexport { instrumented } from './tracing.js';\nexport {\n instrumentedWithMetrics,\n getCounter,\n getUpDownCounter,\n getHistogram,\n getObservableCounter,\n getObservableUpDownCounter,\n getObservableGauge,\n createObservableValueGauges,\n type CreateObservableValueGaugesOptions,\n} from './metrics.js';\n\n// Extremely stupid workaround for the fact that the OpenTelemetry instrumentations\n// don't currently have robust support for ESM. This hack ensures that instrumented\n// packages are loaded for the first time via CJS, which the OpenTelemetry\n// instrumentation can intercept and patch. Subsequent imports can be ESM, but that\n// doesn't matter because the instrumentation has already been applied.\n//\n// OpenTelemetry introduced experimental support for ESM in\n// https://github.com/open-telemetry/opentelemetry-js/pull/3698. This requires\n// the usage of `--experimental-loader` to load the instrumentations, which\n// we currently want to avoid.\nimport './commonjs-preloads.js';\n"]}
package/dist/init.js CHANGED
@@ -1,33 +1,29 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.disableInstrumentations = exports.shutdown = exports.init = void 0;
4
- const grpc_js_1 = require("@grpc/grpc-js");
5
- const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
6
- const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
7
- const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
8
- const resources_1 = require("@opentelemetry/resources");
9
- const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
10
- const api_1 = require("@opentelemetry/api");
11
- const core_1 = require("@opentelemetry/core");
12
- // Exporters go here.
13
- const exporter_trace_otlp_grpc_1 = require("@opentelemetry/exporter-trace-otlp-grpc");
14
- const exporter_metrics_otlp_grpc_1 = require("@opentelemetry/exporter-metrics-otlp-grpc");
15
- // Instrumentations go here.
16
- const instrumentation_aws_sdk_1 = require("@opentelemetry/instrumentation-aws-sdk");
17
- const instrumentation_connect_1 = require("@opentelemetry/instrumentation-connect");
18
- const instrumentation_dns_1 = require("@opentelemetry/instrumentation-dns");
19
- const instrumentation_express_1 = require("@opentelemetry/instrumentation-express");
20
- const instrumentation_http_1 = require("@opentelemetry/instrumentation-http");
21
- const instrumentation_pg_1 = require("@opentelemetry/instrumentation-pg");
22
- const instrumentation_redis_1 = require("@opentelemetry/instrumentation-redis");
23
- // Resource detectors go here.
24
- const resource_detector_aws_1 = require("@opentelemetry/resource-detector-aws");
1
+ import { Metadata, credentials } from '@grpc/grpc-js';
2
+ import { metrics } from '@opentelemetry/api';
3
+ import { hrTimeToMilliseconds } from '@opentelemetry/core';
4
+ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
5
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
6
+ import { OTLPTraceExporter as OTLPTraceExporterHttp } from '@opentelemetry/exporter-trace-otlp-http';
7
+ import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';
8
+ import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';
9
+ import { DnsInstrumentation } from '@opentelemetry/instrumentation-dns';
10
+ import { ExpressLayerType, ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
11
+ import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
12
+ import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';
13
+ import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
14
+ import { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';
15
+ import { awsEc2Detector } from '@opentelemetry/resource-detector-aws';
16
+ import { detectResourcesSync, processDetector, envDetector, Resource, } from '@opentelemetry/resources';
17
+ import { PeriodicExportingMetricReader, MeterProvider, ConsoleMetricExporter, AggregationTemporality, } from '@opentelemetry/sdk-metrics';
18
+ import { SimpleSpanProcessor, BatchSpanProcessor, ParentBasedSampler, TraceIdRatioBasedSampler, AlwaysOnSampler, AlwaysOffSampler, ConsoleSpanExporter, } from '@opentelemetry/sdk-trace-base';
19
+ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
20
+ import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
25
21
  /**
26
22
  * Extends `BatchSpanProcessor` to give it the ability to filter out spans
27
23
  * before they're queued up to send. This enhances our sampling process so
28
24
  * that we can filter spans _after_ they've been emitted.
29
25
  */
30
- class FilterBatchSpanProcessor extends sdk_trace_base_1.BatchSpanProcessor {
26
+ class FilterBatchSpanProcessor extends BatchSpanProcessor {
31
27
  filter;
32
28
  constructor(exporter, filter) {
33
29
  super(exporter);
@@ -57,27 +53,31 @@ function filter(span) {
57
53
  // establishing a connection for the first time, which should happen only at
58
54
  // bootup, or if a connection errors out. Those are the cases we're
59
55
  // interested in, so we'll filter accordingly.
60
- return (0, core_1.hrTimeToMilliseconds)(span.duration) > 1;
56
+ return hrTimeToMilliseconds(span.duration) > 1;
61
57
  }
62
58
  // Always return true so that we default to including a span.
63
59
  return true;
64
60
  }
61
+ // When adding new instrumentation here, add the corresponding packages to
62
+ // `commonjs-preloads.ts` so that we can ensure that they're loaded via CJS
63
+ // before anything tries to load them via CJS. This is necessary because the
64
+ // instrumentations can't hook into the ESM loader.
65
65
  const instrumentations = [
66
- new instrumentation_aws_sdk_1.AwsInstrumentation(),
67
- new instrumentation_connect_1.ConnectInstrumentation(),
68
- new instrumentation_dns_1.DnsInstrumentation(),
69
- new instrumentation_express_1.ExpressInstrumentation({
66
+ new AwsInstrumentation(),
67
+ new ConnectInstrumentation(),
68
+ new DnsInstrumentation(),
69
+ new ExpressInstrumentation({
70
70
  // We use a lot of middleware; it makes the traces way too noisy. If we
71
71
  // want telemetry on a particular middleware, we should instrument it
72
72
  // manually.
73
- ignoreLayersType: [instrumentation_express_1.ExpressLayerType.MIDDLEWARE],
73
+ ignoreLayersType: [ExpressLayerType.MIDDLEWARE],
74
74
  ignoreLayers: [
75
75
  // These don't provide useful information to us.
76
76
  'router - /',
77
77
  'request handler - /*',
78
78
  ],
79
79
  }),
80
- new instrumentation_http_1.HttpInstrumentation({
80
+ new HttpInstrumentation({
81
81
  ignoreIncomingPaths: [
82
82
  // socket.io requests are generally just long-polling; they don't add
83
83
  // useful information for us.
@@ -87,8 +87,9 @@ const instrumentations = [
87
87
  /\/pl\/webhooks\/ping/,
88
88
  ],
89
89
  }),
90
- new instrumentation_pg_1.PgInstrumentation(),
91
- new instrumentation_redis_1.RedisInstrumentation(),
90
+ new IORedisInstrumentation(),
91
+ new PgInstrumentation(),
92
+ new RedisInstrumentation(),
92
93
  ];
93
94
  // Enable all instrumentations now, even though we haven't configured our
94
95
  // span processors or trace exporters yet. We'll set those up later.
@@ -101,7 +102,7 @@ function getHoneycombMetadata(config, datasetSuffix = '') {
101
102
  throw new Error('Missing Honeycomb API key');
102
103
  if (!config.honeycombDataset)
103
104
  throw new Error('Missing Honeycomb dataset');
104
- const metadata = new grpc_js_1.Metadata();
105
+ const metadata = new Metadata();
105
106
  metadata.set('x-honeycomb-team', config.honeycombApiKey);
106
107
  metadata.set('x-honeycomb-dataset', config.honeycombDataset + datasetSuffix);
107
108
  return metadata;
@@ -114,18 +115,16 @@ function getTraceExporter(config) {
114
115
  }
115
116
  switch (config.openTelemetryExporter) {
116
117
  case 'console':
117
- return new sdk_trace_base_1.ConsoleSpanExporter();
118
+ return new ConsoleSpanExporter();
118
119
  case 'honeycomb':
119
- return new exporter_trace_otlp_grpc_1.OTLPTraceExporter({
120
+ return new OTLPTraceExporter({
120
121
  url: 'grpc://api.honeycomb.io:443/',
121
- credentials: grpc_js_1.credentials.createSsl(),
122
+ credentials: credentials.createSsl(),
122
123
  metadata: getHoneycombMetadata(config),
123
124
  });
124
125
  break;
125
126
  case 'jaeger':
126
- return new exporter_trace_otlp_grpc_1.OTLPTraceExporter({
127
- url: process.env.OTEL_EXPORTER_JAEGER_ENDPOINT ?? 'grpc://localhost:4317/',
128
- });
127
+ return new OTLPTraceExporterHttp();
129
128
  default:
130
129
  throw new Error(`Unknown OpenTelemetry exporter: ${config.openTelemetryExporter}`);
131
130
  }
@@ -138,18 +137,18 @@ function getMetricExporter(config) {
138
137
  }
139
138
  switch (config.openTelemetryMetricExporter) {
140
139
  case 'console':
141
- return new sdk_metrics_1.ConsoleMetricExporter();
140
+ return new ConsoleMetricExporter();
142
141
  case 'honeycomb':
143
- return new exporter_metrics_otlp_grpc_1.OTLPMetricExporter({
142
+ return new OTLPMetricExporter({
144
143
  url: 'grpc://api.honeycomb.io:443/',
145
- credentials: grpc_js_1.credentials.createSsl(),
144
+ credentials: credentials.createSsl(),
146
145
  // Honeycomb recommends using a separate dataset for metrics, so we'll
147
146
  // adopt the convention of appending '-metrics' to the dataset name.
148
147
  metadata: getHoneycombMetadata(config, '-metrics'),
149
148
  // Delta temporality means that sums, histograms, etc. will reset each
150
149
  // time data is collected. This more closely matches how we want to
151
150
  // observe our metrics than the default cumulative temporality.
152
- temporalityPreference: sdk_metrics_1.AggregationTemporality.DELTA,
151
+ temporalityPreference: AggregationTemporality.DELTA,
153
152
  });
154
153
  default:
155
154
  throw new Error(`Unknown OpenTelemetry metric exporter: ${config.openTelemetryMetricExporter}`);
@@ -167,7 +166,7 @@ function getSpanProcessor(config) {
167
166
  return new FilterBatchSpanProcessor(traceExporter, filter);
168
167
  }
169
168
  case 'simple': {
170
- return new sdk_trace_base_1.SimpleSpanProcessor(traceExporter);
169
+ return new SimpleSpanProcessor(traceExporter);
171
170
  }
172
171
  default: {
173
172
  throw new Error(`Unknown OpenTelemetry span processor: ${config.openTelemetrySpanProcessor}`);
@@ -179,7 +178,7 @@ function getSpanProcessor(config) {
179
178
  * the correct metadata for the Honeycomb exporter. We don't actually have that
180
179
  * information available until we've loaded our config.
181
180
  */
182
- async function init(config) {
181
+ export async function init(config) {
183
182
  if (!config.openTelemetryEnabled) {
184
183
  // If not enabled, do nothing. We used to disable the instrumentations, but
185
184
  // per maintainers, that can actually be problematic. See the comments on
@@ -195,16 +194,16 @@ async function init(config) {
195
194
  let sampler;
196
195
  switch (config.openTelemetrySamplerType ?? 'always-on') {
197
196
  case 'always-on': {
198
- sampler = new sdk_trace_base_1.AlwaysOnSampler();
197
+ sampler = new AlwaysOnSampler();
199
198
  break;
200
199
  }
201
200
  case 'always-off': {
202
- sampler = new sdk_trace_base_1.AlwaysOffSampler();
201
+ sampler = new AlwaysOffSampler();
203
202
  break;
204
203
  }
205
204
  case 'trace-id-ratio': {
206
- sampler = new sdk_trace_base_1.ParentBasedSampler({
207
- root: new sdk_trace_base_1.TraceIdRatioBasedSampler(config.openTelemetrySampleRate),
205
+ sampler = new ParentBasedSampler({
206
+ root: new TraceIdRatioBasedSampler(config.openTelemetrySampleRate),
208
207
  });
209
208
  break;
210
209
  }
@@ -216,14 +215,14 @@ async function init(config) {
216
215
  // asynchronously. We need to initialize our instrumentations first; only
217
216
  // then can we actually start requiring all of our code that loads our config
218
217
  // and ultimately tells us how to configure OpenTelemetry.
219
- let resource = (0, resources_1.detectResourcesSync)({
220
- detectors: [resource_detector_aws_1.awsEc2Detector, resources_1.processDetector, resources_1.envDetector],
218
+ let resource = detectResourcesSync({
219
+ detectors: [awsEc2Detector, processDetector, envDetector],
221
220
  });
222
221
  if (config.serviceName) {
223
- resource = resource.merge(new resources_1.Resource({ [semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: config.serviceName }));
222
+ resource = resource.merge(new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: config.serviceName }));
224
223
  }
225
224
  // Set up tracing instrumentation.
226
- const nodeTracerProvider = new sdk_trace_node_1.NodeTracerProvider({
225
+ const nodeTracerProvider = new NodeTracerProvider({
227
226
  sampler,
228
227
  resource,
229
228
  });
@@ -236,36 +235,33 @@ async function init(config) {
236
235
  tracerProvider = nodeTracerProvider;
237
236
  // Set up metrics instrumentation if it's enabled.
238
237
  if (metricExporter) {
239
- const meterProvider = new sdk_metrics_1.MeterProvider({
238
+ const meterProvider = new MeterProvider({
240
239
  resource,
241
240
  readers: [
242
- new sdk_metrics_1.PeriodicExportingMetricReader({
241
+ new PeriodicExportingMetricReader({
243
242
  exporter: metricExporter,
244
243
  exportIntervalMillis: config.openTelemetryMetricExportIntervalMillis ?? 30_000,
245
244
  }),
246
245
  ],
247
246
  });
248
- api_1.metrics.setGlobalMeterProvider(meterProvider);
247
+ metrics.setGlobalMeterProvider(meterProvider);
249
248
  }
250
249
  }
251
- exports.init = init;
252
250
  /**
253
251
  * Gracefully shuts down the OpenTelemetry instrumentation. Should be called
254
252
  * when a `SIGTERM` signal is handled.
255
253
  */
256
- async function shutdown() {
254
+ export async function shutdown() {
257
255
  if (tracerProvider) {
258
256
  await tracerProvider.shutdown();
259
257
  tracerProvider = null;
260
258
  }
261
259
  }
262
- exports.shutdown = shutdown;
263
260
  /**
264
261
  * Disables all OpenTelemetry instrumentations. This is useful for tests that
265
262
  * need to access the unwrapped modules.
266
263
  */
267
- function disableInstrumentations() {
264
+ export function disableInstrumentations() {
268
265
  instrumentations.forEach((i) => i.disable());
269
266
  }
270
- exports.disableInstrumentations = disableInstrumentations;
271
267
  //# sourceMappingURL=init.js.map
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata, credentials } from '@grpc/grpc-js';\n\nimport { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\nimport {\n PeriodicExportingMetricReader,\n MeterProvider,\n PushMetricExporter,\n ConsoleMetricExporter,\n AggregationTemporality,\n} from '@opentelemetry/sdk-metrics';\nimport {\n SpanExporter,\n ReadableSpan,\n SpanProcessor,\n SimpleSpanProcessor,\n BatchSpanProcessor,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n AlwaysOnSampler,\n AlwaysOffSampler,\n Sampler,\n ConsoleSpanExporter,\n} from '@opentelemetry/sdk-trace-base';\nimport {\n detectResourcesSync,\n processDetector,\n envDetector,\n Resource,\n} from '@opentelemetry/resources';\nimport { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';\nimport { metrics } from '@opentelemetry/api';\nimport { hrTimeToMilliseconds } from '@opentelemetry/core';\n\n// Exporters go here.\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';\n\n// Instrumentations go here.\nimport { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';\nimport { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';\nimport { DnsInstrumentation } from '@opentelemetry/instrumentation-dns';\nimport { ExpressLayerType, ExpressInstrumentation } from '@opentelemetry/instrumentation-express';\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http';\nimport { PgInstrumentation } from '@opentelemetry/instrumentation-pg';\nimport { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';\n\n// Resource detectors go here.\nimport { awsEc2Detector } from '@opentelemetry/resource-detector-aws';\n\n/**\n * Extends `BatchSpanProcessor` to give it the ability to filter out spans\n * before they're queued up to send. This enhances our sampling process so\n * that we can filter spans _after_ they've been emitted.\n */\nclass FilterBatchSpanProcessor extends BatchSpanProcessor {\n private filter: (span: ReadableSpan) => boolean;\n\n constructor(exporter: SpanExporter, filter: (span: ReadableSpan) => boolean) {\n super(exporter);\n this.filter = filter;\n }\n\n /**\n * This is invoked after a span is \"finalized\". `super.onEnd` will queue up\n * the span to be exported, but if we don't call that, we can just drop the\n * span and the parent will be none the wiser!\n */\n onEnd(span: ReadableSpan) {\n if (!this.filter(span)) return;\n\n super.onEnd(span);\n }\n}\n\n/**\n * This will be used with our {@link FilterBatchSpanProcessor} to filter out\n * events that we're not interested in. This helps reduce our event volume\n * but still gives us fine-grained control over which events we keep.\n */\nfunction filter(span: ReadableSpan) {\n if (span.name === 'pg-pool.connect') {\n // Looking at historical data, this generally happens in under a millisecond,\n // precisely because we maintain a pool of long-lived connections. The only\n // time obtaining a client should take longer than that is if we're\n // establishing a connection for the first time, which should happen only at\n // bootup, or if a connection errors out. Those are the cases we're\n // interested in, so we'll filter accordingly.\n return hrTimeToMilliseconds(span.duration) > 1;\n }\n\n // Always return true so that we default to including a span.\n return true;\n}\n\nconst instrumentations = [\n new AwsInstrumentation(),\n new ConnectInstrumentation(),\n new DnsInstrumentation(),\n new ExpressInstrumentation({\n // We use a lot of middleware; it makes the traces way too noisy. If we\n // want telemetry on a particular middleware, we should instrument it\n // manually.\n ignoreLayersType: [ExpressLayerType.MIDDLEWARE],\n ignoreLayers: [\n // These don't provide useful information to us.\n 'router - /',\n 'request handler - /*',\n ],\n }),\n new HttpInstrumentation({\n ignoreIncomingPaths: [\n // socket.io requests are generally just long-polling; they don't add\n // useful information for us.\n /\\/socket.io\\//,\n // We get several of these per second; they just chew through our event quota.\n // They don't really do anything interesting anyways.\n /\\/pl\\/webhooks\\/ping/,\n ],\n }),\n new PgInstrumentation(),\n new RedisInstrumentation(),\n];\n\n// Enable all instrumentations now, even though we haven't configured our\n// span processors or trace exporters yet. We'll set those up later.\ninstrumentations.forEach((i) => {\n i.enable();\n});\n\nlet tracerProvider: NodeTracerProvider | null;\n\ninterface OpenTelemetryConfigEnabled {\n openTelemetryEnabled: boolean;\n openTelemetryExporter?: 'console' | 'honeycomb' | 'jaeger' | SpanExporter | null;\n openTelemetryMetricExporter?: 'console' | 'honeycomb' | PushMetricExporter | null;\n openTelemetryMetricExportIntervalMillis?: number;\n openTelemetrySamplerType: 'always-on' | 'always-off' | 'trace-id-ratio';\n openTelemetrySampleRate?: number;\n openTelemetrySpanProcessor?: 'batch' | 'simple' | SpanProcessor;\n honeycombApiKey?: string | null;\n honeycombDataset?: string | null;\n serviceName?: string;\n}\n\n// When we know for sure that OpenTelemetry is disabled, we won't require\n// any other attributes to be set.\ninterface OpenTelemetryConfigDisabled extends Partial<OpenTelemetryConfigEnabled> {\n openTelemetryEnabled: false;\n}\n\nexport type OpenTelemetryConfig = OpenTelemetryConfigEnabled | OpenTelemetryConfigDisabled;\n\nfunction getHoneycombMetadata(config: OpenTelemetryConfig, datasetSuffix = ''): Metadata {\n if (!config.honeycombApiKey) throw new Error('Missing Honeycomb API key');\n if (!config.honeycombDataset) throw new Error('Missing Honeycomb dataset');\n\n const metadata = new Metadata();\n\n metadata.set('x-honeycomb-team', config.honeycombApiKey);\n metadata.set('x-honeycomb-dataset', config.honeycombDataset + datasetSuffix);\n\n return metadata;\n}\n\nfunction getTraceExporter(config: OpenTelemetryConfig): SpanExporter | null {\n if (!config.openTelemetryExporter) return null;\n\n if (typeof config.openTelemetryExporter === 'object') {\n return config.openTelemetryExporter;\n }\n\n switch (config.openTelemetryExporter) {\n case 'console':\n return new ConsoleSpanExporter();\n case 'honeycomb':\n return new OTLPTraceExporter({\n url: 'grpc://api.honeycomb.io:443/',\n credentials: credentials.createSsl(),\n metadata: getHoneycombMetadata(config),\n });\n break;\n case 'jaeger':\n return new OTLPTraceExporter({\n url: process.env.OTEL_EXPORTER_JAEGER_ENDPOINT ?? 'grpc://localhost:4317/',\n });\n default:\n throw new Error(`Unknown OpenTelemetry exporter: ${config.openTelemetryExporter}`);\n }\n}\n\nfunction getMetricExporter(config: OpenTelemetryConfig): PushMetricExporter | null {\n if (!config.openTelemetryMetricExporter) return null;\n\n if (typeof config.openTelemetryMetricExporter === 'object') {\n return config.openTelemetryMetricExporter;\n }\n\n switch (config.openTelemetryMetricExporter) {\n case 'console':\n return new ConsoleMetricExporter();\n case 'honeycomb':\n return new OTLPMetricExporter({\n url: 'grpc://api.honeycomb.io:443/',\n credentials: credentials.createSsl(),\n // Honeycomb recommends using a separate dataset for metrics, so we'll\n // adopt the convention of appending '-metrics' to the dataset name.\n metadata: getHoneycombMetadata(config, '-metrics'),\n // Delta temporality means that sums, histograms, etc. will reset each\n // time data is collected. This more closely matches how we want to\n // observe our metrics than the default cumulative temporality.\n temporalityPreference: AggregationTemporality.DELTA,\n });\n default:\n throw new Error(\n `Unknown OpenTelemetry metric exporter: ${config.openTelemetryMetricExporter}`,\n );\n }\n}\n\nfunction getSpanProcessor(config: OpenTelemetryConfig): SpanProcessor | null {\n if (typeof config.openTelemetrySpanProcessor === 'object') {\n return config.openTelemetrySpanProcessor;\n }\n\n const traceExporter = getTraceExporter(config);\n if (!traceExporter) return null;\n\n switch (config.openTelemetrySpanProcessor ?? 'batch') {\n case 'batch': {\n return new FilterBatchSpanProcessor(traceExporter, filter);\n }\n case 'simple': {\n return new SimpleSpanProcessor(traceExporter);\n }\n default: {\n throw new Error(`Unknown OpenTelemetry span processor: ${config.openTelemetrySpanProcessor}`);\n }\n }\n}\n\n/**\n * Should be called once we've loaded our config; this will allow us to set up\n * the correct metadata for the Honeycomb exporter. We don't actually have that\n * information available until we've loaded our config.\n */\nexport async function init(config: OpenTelemetryConfig) {\n if (!config.openTelemetryEnabled) {\n // If not enabled, do nothing. We used to disable the instrumentations, but\n // per maintainers, that can actually be problematic. See the comments on\n // https://github.com/open-telemetry/opentelemetry-js-contrib/issues/970\n // The Express instrumentation also logs a benign error, which can be\n // confusing to users. There's a fix in progress if we want to switch back\n // to disabling instrumentations in the future:\n // https://github.com/open-telemetry/opentelemetry-js-contrib/pull/972\n return;\n }\n\n const metricExporter = getMetricExporter(config);\n const spanProcessor = getSpanProcessor(config);\n\n let sampler: Sampler;\n switch (config.openTelemetrySamplerType ?? 'always-on') {\n case 'always-on': {\n sampler = new AlwaysOnSampler();\n break;\n }\n case 'always-off': {\n sampler = new AlwaysOffSampler();\n break;\n }\n case 'trace-id-ratio': {\n sampler = new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(config.openTelemetrySampleRate),\n });\n break;\n }\n default:\n throw new Error(`Unknown OpenTelemetry sampler type: ${config.openTelemetrySamplerType}`);\n }\n\n // Much of this functionality is copied from `@opentelemetry/sdk-node`, but\n // we can't use the SDK directly because of the fact that we load our config\n // asynchronously. We need to initialize our instrumentations first; only\n // then can we actually start requiring all of our code that loads our config\n // and ultimately tells us how to configure OpenTelemetry.\n\n let resource = detectResourcesSync({\n detectors: [awsEc2Detector, processDetector, envDetector],\n });\n\n if (config.serviceName) {\n resource = resource.merge(\n new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: config.serviceName }),\n );\n }\n\n // Set up tracing instrumentation.\n const nodeTracerProvider = new NodeTracerProvider({\n sampler,\n resource,\n });\n if (spanProcessor) {\n nodeTracerProvider.addSpanProcessor(spanProcessor);\n }\n nodeTracerProvider.register();\n instrumentations.forEach((i) => i.setTracerProvider(nodeTracerProvider));\n\n // Save the provider so we can shut it down later.\n tracerProvider = nodeTracerProvider;\n\n // Set up metrics instrumentation if it's enabled.\n if (metricExporter) {\n const meterProvider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter: metricExporter,\n exportIntervalMillis: config.openTelemetryMetricExportIntervalMillis ?? 30_000,\n }),\n ],\n });\n metrics.setGlobalMeterProvider(meterProvider);\n }\n}\n\n/**\n * Gracefully shuts down the OpenTelemetry instrumentation. Should be called\n * when a `SIGTERM` signal is handled.\n */\nexport async function shutdown(): Promise<void> {\n if (tracerProvider) {\n await tracerProvider.shutdown();\n tracerProvider = null;\n }\n}\n\n/**\n * Disables all OpenTelemetry instrumentations. This is useful for tests that\n * need to access the unwrapped modules.\n */\nexport function disableInstrumentations() {\n instrumentations.forEach((i) => i.disable());\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata, credentials } from '@grpc/grpc-js';\nimport { metrics } from '@opentelemetry/api';\nimport { hrTimeToMilliseconds } from '@opentelemetry/core';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';\nimport { OTLPTraceExporter as OTLPTraceExporterHttp } from '@opentelemetry/exporter-trace-otlp-http';\nimport { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';\nimport { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';\nimport { DnsInstrumentation } from '@opentelemetry/instrumentation-dns';\nimport { ExpressLayerType, ExpressInstrumentation } from '@opentelemetry/instrumentation-express';\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http';\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';\nimport { PgInstrumentation } from '@opentelemetry/instrumentation-pg';\nimport { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';\nimport { awsEc2Detector } from '@opentelemetry/resource-detector-aws';\nimport {\n detectResourcesSync,\n processDetector,\n envDetector,\n Resource,\n} from '@opentelemetry/resources';\nimport {\n PeriodicExportingMetricReader,\n MeterProvider,\n PushMetricExporter,\n ConsoleMetricExporter,\n AggregationTemporality,\n} from '@opentelemetry/sdk-metrics';\nimport {\n SpanExporter,\n ReadableSpan,\n SpanProcessor,\n SimpleSpanProcessor,\n BatchSpanProcessor,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n AlwaysOnSampler,\n AlwaysOffSampler,\n Sampler,\n ConsoleSpanExporter,\n} from '@opentelemetry/sdk-trace-base';\nimport { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\nimport { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';\n\n/**\n * Extends `BatchSpanProcessor` to give it the ability to filter out spans\n * before they're queued up to send. This enhances our sampling process so\n * that we can filter spans _after_ they've been emitted.\n */\nclass FilterBatchSpanProcessor extends BatchSpanProcessor {\n private filter: (span: ReadableSpan) => boolean;\n\n constructor(exporter: SpanExporter, filter: (span: ReadableSpan) => boolean) {\n super(exporter);\n this.filter = filter;\n }\n\n /**\n * This is invoked after a span is \"finalized\". `super.onEnd` will queue up\n * the span to be exported, but if we don't call that, we can just drop the\n * span and the parent will be none the wiser!\n */\n onEnd(span: ReadableSpan) {\n if (!this.filter(span)) return;\n\n super.onEnd(span);\n }\n}\n\n/**\n * This will be used with our {@link FilterBatchSpanProcessor} to filter out\n * events that we're not interested in. This helps reduce our event volume\n * but still gives us fine-grained control over which events we keep.\n */\nfunction filter(span: ReadableSpan) {\n if (span.name === 'pg-pool.connect') {\n // Looking at historical data, this generally happens in under a millisecond,\n // precisely because we maintain a pool of long-lived connections. The only\n // time obtaining a client should take longer than that is if we're\n // establishing a connection for the first time, which should happen only at\n // bootup, or if a connection errors out. Those are the cases we're\n // interested in, so we'll filter accordingly.\n return hrTimeToMilliseconds(span.duration) > 1;\n }\n\n // Always return true so that we default to including a span.\n return true;\n}\n\n// When adding new instrumentation here, add the corresponding packages to\n// `commonjs-preloads.ts` so that we can ensure that they're loaded via CJS\n// before anything tries to load them via CJS. This is necessary because the\n// instrumentations can't hook into the ESM loader.\nconst instrumentations = [\n new AwsInstrumentation(),\n new ConnectInstrumentation(),\n new DnsInstrumentation(),\n new ExpressInstrumentation({\n // We use a lot of middleware; it makes the traces way too noisy. If we\n // want telemetry on a particular middleware, we should instrument it\n // manually.\n ignoreLayersType: [ExpressLayerType.MIDDLEWARE],\n ignoreLayers: [\n // These don't provide useful information to us.\n 'router - /',\n 'request handler - /*',\n ],\n }),\n new HttpInstrumentation({\n ignoreIncomingPaths: [\n // socket.io requests are generally just long-polling; they don't add\n // useful information for us.\n /\\/socket.io\\//,\n // We get several of these per second; they just chew through our event quota.\n // They don't really do anything interesting anyways.\n /\\/pl\\/webhooks\\/ping/,\n ],\n }),\n new IORedisInstrumentation(),\n new PgInstrumentation(),\n new RedisInstrumentation(),\n];\n\n// Enable all instrumentations now, even though we haven't configured our\n// span processors or trace exporters yet. We'll set those up later.\ninstrumentations.forEach((i) => {\n i.enable();\n});\n\nlet tracerProvider: NodeTracerProvider | null;\n\ninterface OpenTelemetryConfigEnabled {\n openTelemetryEnabled: boolean;\n openTelemetryExporter?: 'console' | 'honeycomb' | 'jaeger' | SpanExporter | null;\n openTelemetryMetricExporter?: 'console' | 'honeycomb' | PushMetricExporter | null;\n openTelemetryMetricExportIntervalMillis?: number;\n openTelemetrySamplerType: 'always-on' | 'always-off' | 'trace-id-ratio';\n openTelemetrySampleRate?: number;\n openTelemetrySpanProcessor?: 'batch' | 'simple' | SpanProcessor;\n honeycombApiKey?: string | null;\n honeycombDataset?: string | null;\n serviceName?: string;\n}\n\n// When we know for sure that OpenTelemetry is disabled, we won't require\n// any other attributes to be set.\ninterface OpenTelemetryConfigDisabled extends Partial<OpenTelemetryConfigEnabled> {\n openTelemetryEnabled: false;\n}\n\nexport type OpenTelemetryConfig = OpenTelemetryConfigEnabled | OpenTelemetryConfigDisabled;\n\nfunction getHoneycombMetadata(config: OpenTelemetryConfig, datasetSuffix = ''): Metadata {\n if (!config.honeycombApiKey) throw new Error('Missing Honeycomb API key');\n if (!config.honeycombDataset) throw new Error('Missing Honeycomb dataset');\n\n const metadata = new Metadata();\n\n metadata.set('x-honeycomb-team', config.honeycombApiKey);\n metadata.set('x-honeycomb-dataset', config.honeycombDataset + datasetSuffix);\n\n return metadata;\n}\n\nfunction getTraceExporter(config: OpenTelemetryConfig): SpanExporter | null {\n if (!config.openTelemetryExporter) return null;\n\n if (typeof config.openTelemetryExporter === 'object') {\n return config.openTelemetryExporter;\n }\n\n switch (config.openTelemetryExporter) {\n case 'console':\n return new ConsoleSpanExporter();\n case 'honeycomb':\n return new OTLPTraceExporter({\n url: 'grpc://api.honeycomb.io:443/',\n credentials: credentials.createSsl(),\n metadata: getHoneycombMetadata(config),\n });\n break;\n case 'jaeger':\n return new OTLPTraceExporterHttp();\n default:\n throw new Error(`Unknown OpenTelemetry exporter: ${config.openTelemetryExporter}`);\n }\n}\n\nfunction getMetricExporter(config: OpenTelemetryConfig): PushMetricExporter | null {\n if (!config.openTelemetryMetricExporter) return null;\n\n if (typeof config.openTelemetryMetricExporter === 'object') {\n return config.openTelemetryMetricExporter;\n }\n\n switch (config.openTelemetryMetricExporter) {\n case 'console':\n return new ConsoleMetricExporter();\n case 'honeycomb':\n return new OTLPMetricExporter({\n url: 'grpc://api.honeycomb.io:443/',\n credentials: credentials.createSsl(),\n // Honeycomb recommends using a separate dataset for metrics, so we'll\n // adopt the convention of appending '-metrics' to the dataset name.\n metadata: getHoneycombMetadata(config, '-metrics'),\n // Delta temporality means that sums, histograms, etc. will reset each\n // time data is collected. This more closely matches how we want to\n // observe our metrics than the default cumulative temporality.\n temporalityPreference: AggregationTemporality.DELTA,\n });\n default:\n throw new Error(\n `Unknown OpenTelemetry metric exporter: ${config.openTelemetryMetricExporter}`,\n );\n }\n}\n\nfunction getSpanProcessor(config: OpenTelemetryConfig): SpanProcessor | null {\n if (typeof config.openTelemetrySpanProcessor === 'object') {\n return config.openTelemetrySpanProcessor;\n }\n\n const traceExporter = getTraceExporter(config);\n if (!traceExporter) return null;\n\n switch (config.openTelemetrySpanProcessor ?? 'batch') {\n case 'batch': {\n return new FilterBatchSpanProcessor(traceExporter, filter);\n }\n case 'simple': {\n return new SimpleSpanProcessor(traceExporter);\n }\n default: {\n throw new Error(`Unknown OpenTelemetry span processor: ${config.openTelemetrySpanProcessor}`);\n }\n }\n}\n\n/**\n * Should be called once we've loaded our config; this will allow us to set up\n * the correct metadata for the Honeycomb exporter. We don't actually have that\n * information available until we've loaded our config.\n */\nexport async function init(config: OpenTelemetryConfig) {\n if (!config.openTelemetryEnabled) {\n // If not enabled, do nothing. We used to disable the instrumentations, but\n // per maintainers, that can actually be problematic. See the comments on\n // https://github.com/open-telemetry/opentelemetry-js-contrib/issues/970\n // The Express instrumentation also logs a benign error, which can be\n // confusing to users. There's a fix in progress if we want to switch back\n // to disabling instrumentations in the future:\n // https://github.com/open-telemetry/opentelemetry-js-contrib/pull/972\n return;\n }\n\n const metricExporter = getMetricExporter(config);\n const spanProcessor = getSpanProcessor(config);\n\n let sampler: Sampler;\n switch (config.openTelemetrySamplerType ?? 'always-on') {\n case 'always-on': {\n sampler = new AlwaysOnSampler();\n break;\n }\n case 'always-off': {\n sampler = new AlwaysOffSampler();\n break;\n }\n case 'trace-id-ratio': {\n sampler = new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(config.openTelemetrySampleRate),\n });\n break;\n }\n default:\n throw new Error(`Unknown OpenTelemetry sampler type: ${config.openTelemetrySamplerType}`);\n }\n\n // Much of this functionality is copied from `@opentelemetry/sdk-node`, but\n // we can't use the SDK directly because of the fact that we load our config\n // asynchronously. We need to initialize our instrumentations first; only\n // then can we actually start requiring all of our code that loads our config\n // and ultimately tells us how to configure OpenTelemetry.\n\n let resource = detectResourcesSync({\n detectors: [awsEc2Detector, processDetector, envDetector],\n });\n\n if (config.serviceName) {\n resource = resource.merge(\n new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: config.serviceName }),\n );\n }\n\n // Set up tracing instrumentation.\n const nodeTracerProvider = new NodeTracerProvider({\n sampler,\n resource,\n });\n if (spanProcessor) {\n nodeTracerProvider.addSpanProcessor(spanProcessor);\n }\n nodeTracerProvider.register();\n instrumentations.forEach((i) => i.setTracerProvider(nodeTracerProvider));\n\n // Save the provider so we can shut it down later.\n tracerProvider = nodeTracerProvider;\n\n // Set up metrics instrumentation if it's enabled.\n if (metricExporter) {\n const meterProvider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter: metricExporter,\n exportIntervalMillis: config.openTelemetryMetricExportIntervalMillis ?? 30_000,\n }),\n ],\n });\n metrics.setGlobalMeterProvider(meterProvider);\n }\n}\n\n/**\n * Gracefully shuts down the OpenTelemetry instrumentation. Should be called\n * when a `SIGTERM` signal is handled.\n */\nexport async function shutdown(): Promise<void> {\n if (tracerProvider) {\n await tracerProvider.shutdown();\n tracerProvider = null;\n }\n}\n\n/**\n * Disables all OpenTelemetry instrumentations. This is useful for tests that\n * need to access the unwrapped modules.\n */\nexport function disableInstrumentations() {\n instrumentations.forEach((i) => i.disable());\n}\n"]}
package/dist/metrics.d.ts CHANGED
@@ -6,7 +6,7 @@ export declare function getObservableCounter(meter: Meter, name: string, options
6
6
  export declare function getObservableUpDownCounter(meter: Meter, name: string, options?: MetricOptions): ObservableUpDownCounter<import("@opentelemetry/api").Attributes>;
7
7
  export declare function getObservableGauge(meter: Meter, name: string, options?: MetricOptions): ObservableGauge<import("@opentelemetry/api").Attributes>;
8
8
  export declare function instrumentedWithMetrics<T>(meter: Meter, name: string, fn: () => Promise<T> | T): Promise<T>;
9
- export interface createObservableValueGaugesOptions extends MetricOptions {
9
+ export interface CreateObservableValueGaugesOptions extends MetricOptions {
10
10
  interval: number;
11
11
  }
12
12
  /**
@@ -20,7 +20,7 @@ export interface createObservableValueGaugesOptions extends MetricOptions {
20
20
  * - `${name}.max`
21
21
  * - `${name}.avg`
22
22
  */
23
- export declare function createObservableValueGauges(meter: Meter, name: string, options: createObservableValueGaugesOptions, observe: () => number): {
23
+ export declare function createObservableValueGauges(meter: Meter, name: string, options: CreateObservableValueGaugesOptions, observe: () => number): {
24
24
  minGauge: ObservableGauge<import("@opentelemetry/api").Attributes>;
25
25
  maxGauge: ObservableGauge<import("@opentelemetry/api").Attributes>;
26
26
  averageGauge: ObservableGauge<import("@opentelemetry/api").Attributes>;
package/dist/metrics.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createObservableValueGauges = exports.instrumentedWithMetrics = exports.getObservableGauge = exports.getObservableUpDownCounter = exports.getObservableCounter = exports.getUpDownCounter = exports.getCounter = exports.getHistogram = void 0;
4
- const api_1 = require("@opentelemetry/api");
1
+ import { ValueType, } from '@opentelemetry/api';
5
2
  const histogramCache = new WeakMap();
6
3
  const counterCache = new WeakMap();
7
4
  const upDownCounterCache = new WeakMap();
@@ -21,35 +18,29 @@ function getCachedMetric(cache, meter, name, create) {
21
18
  }
22
19
  return metric;
23
20
  }
24
- function getHistogram(meter, name, options) {
21
+ export function getHistogram(meter, name, options) {
25
22
  return getCachedMetric(histogramCache, meter, name, () => meter.createHistogram(name, options));
26
23
  }
27
- exports.getHistogram = getHistogram;
28
- function getCounter(meter, name, options) {
24
+ export function getCounter(meter, name, options) {
29
25
  return getCachedMetric(counterCache, meter, name, () => meter.createCounter(name, options));
30
26
  }
31
- exports.getCounter = getCounter;
32
- function getUpDownCounter(meter, name, options) {
27
+ export function getUpDownCounter(meter, name, options) {
33
28
  return getCachedMetric(upDownCounterCache, meter, name, () => meter.createUpDownCounter(name, options));
34
29
  }
35
- exports.getUpDownCounter = getUpDownCounter;
36
- function getObservableCounter(meter, name, options) {
30
+ export function getObservableCounter(meter, name, options) {
37
31
  return getCachedMetric(observableCounterCache, meter, name, () => meter.createObservableCounter(name, options));
38
32
  }
39
- exports.getObservableCounter = getObservableCounter;
40
- function getObservableUpDownCounter(meter, name, options) {
33
+ export function getObservableUpDownCounter(meter, name, options) {
41
34
  return getCachedMetric(observableUpDownCounterCache, meter, name, () => meter.createObservableUpDownCounter(name, options));
42
35
  }
43
- exports.getObservableUpDownCounter = getObservableUpDownCounter;
44
- function getObservableGauge(meter, name, options) {
36
+ export function getObservableGauge(meter, name, options) {
45
37
  return getCachedMetric(observableGaugeCache, meter, name, () => meter.createObservableGauge(name, options));
46
38
  }
47
- exports.getObservableGauge = getObservableGauge;
48
- async function instrumentedWithMetrics(meter, name, fn) {
49
- const error = getCounter(meter, `${name}.error`, { valueType: api_1.ValueType.INT });
39
+ export async function instrumentedWithMetrics(meter, name, fn) {
40
+ const error = getCounter(meter, `${name}.error`, { valueType: ValueType.INT });
50
41
  const histogram = getHistogram(meter, `${name}.duration`, {
51
42
  unit: 'milliseconds',
52
- valueType: api_1.ValueType.DOUBLE,
43
+ valueType: ValueType.DOUBLE,
53
44
  });
54
45
  const start = performance.now();
55
46
  try {
@@ -63,7 +54,6 @@ async function instrumentedWithMetrics(meter, name, fn) {
63
54
  histogram.record(performance.now() - start);
64
55
  }
65
56
  }
66
- exports.instrumentedWithMetrics = instrumentedWithMetrics;
67
57
  /**
68
58
  * Creates a set of gauges that track the min, max, and average of a value over
69
59
  * time. The value is observed on a regular interval.
@@ -75,7 +65,7 @@ exports.instrumentedWithMetrics = instrumentedWithMetrics;
75
65
  * - `${name}.max`
76
66
  * - `${name}.avg`
77
67
  */
78
- function createObservableValueGauges(meter, name, options, observe) {
68
+ export function createObservableValueGauges(meter, name, options, observe) {
79
69
  const { interval, ...metricOptions } = options;
80
70
  let min = 0;
81
71
  let max = 0;
@@ -99,7 +89,7 @@ function createObservableValueGauges(meter, name, options, observe) {
99
89
  const averageGauge = getObservableGauge(meter, `${name}.avg`, {
100
90
  ...metricOptions,
101
91
  // Average is always a double, even if the observed value is an int.
102
- valueType: api_1.ValueType.DOUBLE,
92
+ valueType: ValueType.DOUBLE,
103
93
  });
104
94
  minGauge.addCallback((observableResult) => {
105
95
  observableResult.observe(min);
@@ -117,5 +107,4 @@ function createObservableValueGauges(meter, name, options, observe) {
117
107
  });
118
108
  return { minGauge, maxGauge, averageGauge, stop: () => clearInterval(intervalId) };
119
109
  }
120
- exports.createObservableValueGauges = createObservableValueGauges;
121
110
  //# sourceMappingURL=metrics.js.map