-
Notifications
You must be signed in to change notification settings - Fork 928
Docs/clarify ignore outgoing request hook #5792
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 all commits
f6dcb75
2752130
b78004f
4442f12
45d0986
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 |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Multiple Metric Readers Example | ||
|
||
This example demonstrates how to use the new `metricReaders` (plural) option in the NodeSDK configuration to register multiple metric readers simultaneously. | ||
|
||
## Features | ||
|
||
- **Multiple Metric Readers**: Configure multiple metric readers in a single SDK instance | ||
- **Console Export**: Metrics are exported to the console for easy debugging | ||
- **Prometheus Export**: Metrics are also exported to a Prometheus endpoint | ||
- **Auto-instrumentation**: Automatic instrumentation of Node.js applications | ||
|
||
## Usage | ||
|
||
### Running the Example | ||
|
||
```bash | ||
node multiple-metric-readers.js | ||
``` | ||
|
||
### What Happens | ||
|
||
1. The SDK is configured with two metric readers: | ||
- A `ConsoleMetricExporter` that prints metrics to the console | ||
- A `PrometheusExporter` that exposes metrics on `http://localhost:9464/metrics` | ||
|
||
2. A counter metric is created and incremented every second | ||
|
||
3. Metrics are automatically exported to both destinations | ||
|
||
### API Changes | ||
|
||
This example demonstrates the new API that supports multiple metric readers: | ||
|
||
```javascript | ||
// OLD (deprecated) - single metric reader | ||
const sdk = new opentelemetry.NodeSDK({ | ||
metricReader: singleMetricReader, // deprecated | ||
}); | ||
|
||
// NEW - multiple metric readers | ||
const sdk = new opentelemetry.NodeSDK({ | ||
metricReaders: [consoleMetricReader, prometheusMetricReader], // new | ||
}); | ||
``` | ||
|
||
### Benefits | ||
|
||
- **Flexibility**: Export metrics to multiple destinations simultaneously | ||
- **Debugging**: Console export for development and debugging | ||
- **Production**: Prometheus export for production monitoring | ||
- **Backward Compatibility**: The old `metricReader` option still works but shows a deprecation warning | ||
|
||
### Checking the Results | ||
|
||
1. **Console Output**: Watch the console for metric exports every second | ||
2. **Prometheus Endpoint**: Visit `http://localhost:9464/metrics` to see the Prometheus-formatted metrics | ||
|
||
## Migration Guide | ||
|
||
If you're currently using the single `metricReader` option, you can migrate to the new `metricReaders` option: | ||
|
||
```javascript | ||
// Before | ||
const sdk = new opentelemetry.NodeSDK({ | ||
metricReader: myMetricReader, | ||
}); | ||
|
||
// After | ||
const sdk = new opentelemetry.NodeSDK({ | ||
metricReaders: [myMetricReader], | ||
}); | ||
``` | ||
|
||
The old `metricReader` option will continue to work but will show a deprecation warning. It's recommended to migrate to the new `metricReaders` option for future compatibility. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const process = require('process'); | ||
const opentelemetry = require('@opentelemetry/sdk-node'); | ||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); | ||
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base'); | ||
const { resourceFromAttributes } = require('@opentelemetry/resources'); | ||
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions'); | ||
const { | ||
ConsoleMetricExporter, | ||
PeriodicExportingMetricReader | ||
} = require('@opentelemetry/sdk-metrics'); | ||
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); | ||
|
||
// Create multiple metric readers | ||
const consoleMetricReader = new PeriodicExportingMetricReader({ | ||
exporter: new ConsoleMetricExporter(), | ||
exportIntervalMillis: 1000, | ||
exportTimeoutMillis: 500, | ||
}); | ||
|
||
const prometheusMetricReader = new PrometheusExporter({ | ||
port: 9464, | ||
endpoint: '/metrics', | ||
}); | ||
|
||
// Configure the SDK with multiple metric readers | ||
const sdk = new opentelemetry.NodeSDK({ | ||
resource: resourceFromAttributes({ | ||
[ATTR_SERVICE_NAME]: 'multiple-metric-readers-example', | ||
}), | ||
traceExporter: new ConsoleSpanExporter(), | ||
// Use the new metricReaders option (plural) instead of the deprecated metricReader (singular) | ||
metricReaders: [consoleMetricReader, prometheusMetricReader], | ||
instrumentations: [getNodeAutoInstrumentations()] | ||
}); | ||
|
||
// Initialize the SDK and register with the OpenTelemetry API | ||
sdk.start(); | ||
|
||
// Create a meter and some metrics | ||
const meter = opentelemetry.metrics.getMeter('example-meter'); | ||
const counter = meter.createCounter('example_counter', { | ||
description: 'An example counter', | ||
}); | ||
|
||
// Increment the counter every second | ||
setInterval(() => { | ||
counter.add(1, { 'example.label': 'value' }); | ||
console.log('Counter incremented'); | ||
}, 1000); | ||
|
||
// Gracefully shut down the SDK on process exit | ||
process.on('SIGTERM', () => { | ||
sdk.shutdown() | ||
.then(() => console.log('Tracing terminated')) | ||
.catch((error) => console.log('Error terminating tracing', error)) | ||
.finally(() => process.exit(0)); | ||
}); | ||
|
||
console.log('Multiple metric readers example started'); | ||
console.log('Metrics will be exported to console and Prometheus endpoint at http://localhost:9464/metrics'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -322,6 +322,123 @@ | |
delete env.OTEL_TRACES_EXPORTER; | ||
}); | ||
|
||
it('should register a meter provider if multiple readers are provided', async () => { | ||
// need to set OTEL_TRACES_EXPORTER to none since default value is otlp | ||
// which sets up an exporter and affects the context manager | ||
env.OTEL_TRACES_EXPORTER = 'none'; | ||
const consoleExporter = new ConsoleMetricExporter(); | ||
const inMemoryExporter = new InMemoryMetricExporter( | ||
AggregationTemporality.CUMULATIVE | ||
); | ||
const metricReader1 = new PeriodicExportingMetricReader({ | ||
exporter: consoleExporter, | ||
exportIntervalMillis: 100, | ||
exportTimeoutMillis: 100, | ||
}); | ||
const metricReader2 = new PeriodicExportingMetricReader({ | ||
exporter: inMemoryExporter, | ||
exportIntervalMillis: 100, | ||
exportTimeoutMillis: 100, | ||
}); | ||
|
||
const sdk = new NodeSDK({ | ||
metricReaders: [metricReader1, metricReader2], | ||
autoDetectResources: false, | ||
}); | ||
|
||
sdk.start(); | ||
|
||
assert.strictEqual( | ||
context['_getContextManager'](), | ||
ctxManager, | ||
'context manager should not change' | ||
); | ||
assert.strictEqual( | ||
propagation['_getGlobalPropagator'](), | ||
propagator, | ||
'propagator should not change' | ||
); | ||
assert.strictEqual( | ||
(trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), | ||
delegate, | ||
'tracer provider should not have changed' | ||
); | ||
|
||
const meterProvider = metrics.getMeterProvider() as MeterProvider; | ||
assert.ok(meterProvider instanceof MeterProvider); | ||
|
||
// Verify that both metric readers are registered | ||
const sharedState = (meterProvider as any)['_sharedState']; | ||
assert.strictEqual(sharedState.metricCollectors.length, 2); | ||
|
||
await sdk.shutdown(); | ||
delete env.OTEL_TRACES_EXPORTER; | ||
}); | ||
|
||
it('should show deprecation warning when using metricReader option', async () => { | ||
// need to set OTEL_TRACES_EXPORTER to none since default value is otlp | ||
// which sets up an exporter and affects the context manager | ||
env.OTEL_TRACES_EXPORTER = 'none'; | ||
const exporter = new ConsoleMetricExporter(); | ||
const metricReader = new PeriodicExportingMetricReader({ | ||
exporter: exporter, | ||
exportIntervalMillis: 100, | ||
exportTimeoutMillis: 100, | ||
}); | ||
|
||
const warnSpy = Sinon.spy(diag, 'warn'); | ||
|
||
const sdk = new NodeSDK({ | ||
metricReader: metricReader, | ||
autoDetectResources: false, | ||
}); | ||
|
||
sdk.start(); | ||
|
||
// Verify deprecation warning was shown | ||
sinon.assert.calledWith( | ||
Check failure on line 399 in experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
|
||
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. Please add an import for sinon |
||
warnSpy, | ||
"The 'metricReader' option is deprecated. Please use 'metricReaders' instead." | ||
); | ||
|
||
assert.ok(metrics.getMeterProvider() instanceof MeterProvider); | ||
|
||
await sdk.shutdown(); | ||
delete env.OTEL_TRACES_EXPORTER; | ||
}); | ||
|
||
it('should not show deprecation warning when using metricReaders option', async () => { | ||
// need to set OTEL_TRACES_EXPORTER to none since default value is otlp | ||
// which sets up an exporter and affects the context manager | ||
env.OTEL_TRACES_EXPORTER = 'none'; | ||
const exporter = new ConsoleMetricExporter(); | ||
const metricReader = new PeriodicExportingMetricReader({ | ||
exporter: exporter, | ||
exportIntervalMillis: 100, | ||
exportTimeoutMillis: 100, | ||
}); | ||
|
||
const warnSpy = Sinon.spy(diag, 'warn'); | ||
|
||
const sdk = new NodeSDK({ | ||
metricReaders: [metricReader], | ||
autoDetectResources: false, | ||
}); | ||
|
||
sdk.start(); | ||
|
||
// Verify no metricReader deprecation warning was shown | ||
sinon.assert.neverCalledWith( | ||
Check failure on line 431 in experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
|
||
warnSpy, | ||
"The 'metricReader' option is deprecated. Please use 'metricReaders' instead." | ||
); | ||
|
||
assert.ok(metrics.getMeterProvider() instanceof MeterProvider); | ||
|
||
await sdk.shutdown(); | ||
delete env.OTEL_TRACES_EXPORTER; | ||
}); | ||
|
||
it('should register a logger provider if a log record processor is provided', async () => { | ||
env.OTEL_TRACES_EXPORTER = 'none'; | ||
const logRecordExporter = new InMemoryLogRecordExporter(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change. Fine because this package is experimental but make sure it is noted in the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to have anything to do with documenting or clarifying...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like #5777