-
Notifications
You must be signed in to change notification settings - Fork 1k
feat(sdk-node): wire up metric producers from declarative config #6712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
2549aaa
1e473e4
cce2e63
3a8eea9
76f26f3
9f88a33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,7 @@ import type { | |
| LoggerProviderOptions, | ||
| LogRecordProcessor, | ||
| } from '@opentelemetry/sdk-logs'; | ||
| import type { MetricProducer } from '@opentelemetry/sdk-metrics'; | ||
| import { | ||
| BatchLogRecordProcessor, | ||
| ConsoleLogRecordExporter, | ||
|
|
@@ -509,6 +510,33 @@ export function getOtlpMetricExporterFromEnv(): PushMetricExporter { | |
| return new OTLPProtoMetricExporter(); | ||
| } | ||
|
|
||
| function getMetricProducersFromConfiguration( | ||
| producers: PeriodicMetricReaderConfigModel['producers'] | ||
| ): MetricProducer[] | undefined { | ||
| if (!producers || producers.length === 0) { | ||
| return undefined; | ||
| } | ||
| const result: MetricProducer[] = []; | ||
| for (const producer of producers) { | ||
| if (producer.opencensus) { | ||
| try { | ||
| const { | ||
| OpenCensusMetricProducer, | ||
| // eslint-disable-next-line @typescript-eslint/no-require-imports | ||
| } = require('@opentelemetry/shim-opencensus'); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will be one of the very few conditional imports that we have in OTel JS. FWIW, we currently do this for:
I think having a dynamic import here is a better option than having a dep on shim-opencensus and always importing it. Aside: I'm kinda curious if, given https://opentelemetry.io/blog/2023/sunsetting-opencensus/, we could eventually/soon/now remove opencensus support. https://opentelemetry.io/blog/2023/sunsetting-opencensus/#fn:3 mentions supporting the OpenCensus shims for a year. It has been more than a year since the @maryliag Do you happen to know? Whereever we have Node.js-specific usage docs for declarative config, I think we should add a note that using
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't have any extra info on top of what you shared, but that is a good point! Since this is a new feature, I think make sense to don't support opencensus, so we don't have to worry about maintenance of a package that is already unmaintained
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Declarative config needs to follow the spec, but the spec says opencensus is stable. So to make this optional/not implemented at all in declarative config, it needs to be updated in the spec first. |
||
| result.push(new OpenCensusMetricProducer()); | ||
| } catch { | ||
| diag.warn( | ||
| 'OpenCensus metric producer configured but @opentelemetry/shim-opencensus is not installed.' | ||
| ); | ||
| } | ||
| } else { | ||
| diag.warn('Unsupported metric producer configured.'); | ||
| } | ||
| } | ||
| return result.length > 0 ? result : undefined; | ||
| } | ||
|
|
||
| export function getPeriodicMetricReaderFromConfiguration( | ||
| periodic: PeriodicMetricReaderConfigModel | ||
| ): IMetricReader | undefined { | ||
|
|
@@ -543,17 +571,23 @@ export function getPeriodicMetricReaderFromConfiguration( | |
| }); | ||
| } | ||
|
|
||
| const metricProducers = getMetricProducersFromConfiguration( | ||
| periodic.producers | ||
| ); | ||
|
|
||
| if (exporter) { | ||
| // TODO(6425): add cardinality_limits | ||
| return new PeriodicExportingMetricReader({ | ||
| exportIntervalMillis: periodic.interval ?? 60_000, | ||
| exportTimeoutMillis: periodic.timeout ?? 30_000, | ||
| exporter, | ||
| metricProducers, | ||
| }); | ||
| } | ||
| if (periodic.exporter.console) { | ||
| return new PeriodicExportingMetricReader({ | ||
| exporter: new ConsoleMetricExporter(), | ||
| metricProducers, | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,7 +55,11 @@ import { | |
| ATTR_SERVICE_INSTANCE_ID, | ||
| } from '../src/semconv'; | ||
| import { ATTR_OS_TYPE } from '@opentelemetry/resources/src/semconv'; | ||
| import { getLogRecordExporter, setupContextManager } from '../src/utils'; | ||
| import { | ||
| getLogRecordExporter, | ||
| getPeriodicMetricReaderFromConfiguration, | ||
| setupContextManager, | ||
| } from '../src/utils'; | ||
| import { NOOP_SDK } from '../src/start'; | ||
| import { | ||
| ConsoleMetricExporter, | ||
|
|
@@ -962,6 +966,30 @@ describe('startNodeSDK', function () { | |
| assert.equal(getLogRecordExporter(exporter), undefined); | ||
| }); | ||
|
|
||
| it('should create metric reader with opencensus producer when shim is available', async () => { | ||
| const reader = getPeriodicMetricReaderFromConfiguration({ | ||
| exporter: { console: {} }, | ||
| producers: [{ opencensus: {} }], | ||
| }); | ||
| assert.ok(reader !== undefined); | ||
| await (reader as PeriodicExportingMetricReader).shutdown(); | ||
| }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test isn't actually testing that the shim producer is working. If I make this change: diff --git a/experimental/packages/opentelemetry-sdk-node/src/utils.ts b/experimental/packages/opentelemetry-sdk-node/src/utils.ts
index d80eb9a36..9495a2d01 100644
--- a/experimental/packages/opentelemetry-sdk-node/src/utils.ts
+++ b/experimental/packages/opentelemetry-sdk-node/src/utils.ts
@@ -529,7 +529,7 @@ function getMetricProducersFromConfiguration(
const {
OpenCensusMetricProducer,
// eslint-disable-next-line @typescript-eslint/no-require-imports
- } = require('@opentelemetry/shim-opencensus');
+ } = require('@opentelemetry/shim-opencensusXXX');
result.push(new OpenCensusMetricProducer());
} catch {
diag.warn(the test case still passes. I think this could cheat and look at |
||
|
|
||
| it('should warn for unsupported metric producer', async () => { | ||
| const warnSpy = Sinon.spy(diag, 'warn'); | ||
| const reader = getPeriodicMetricReaderFromConfiguration({ | ||
| exporter: { console: {} }, | ||
| producers: [{ 'unknown/producer': {} }], | ||
| }); | ||
| assert.ok(reader !== undefined); | ||
| assert.ok( | ||
| warnSpy.args.some(args => | ||
| String(args[0]).includes('Unsupported metric producer') | ||
| ) | ||
| ); | ||
| await (reader as PeriodicExportingMetricReader).shutdown(); | ||
| }); | ||
|
|
||
| it('null context manager', async () => { | ||
| setupContextManager(null); | ||
| assert.equal( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.