diff --git a/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/src/detectors/ContainerDetector.ts b/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/src/detectors/ContainerDetector.ts
index e318c8bd4..fcbbcc6e1 100644
--- a/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/src/detectors/ContainerDetector.ts
+++ b/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/src/detectors/ContainerDetector.ts
@@ -57,9 +57,29 @@ export class ContainerDetector implements Detector {
this.UTF8_UNICODE
);
const splitData = rawData.trim().split('\n');
- for (const str of splitData) {
- if (str.length >= this.CONTAINER_ID_LENGTH) {
- return str.substring(str.length - this.CONTAINER_ID_LENGTH);
+ for (const line of splitData) {
+ const lastSlashIdx = line.lastIndexOf('/');
+ if (lastSlashIdx === -1) {
+ continue;
+ }
+ const lastSection = line.substring(lastSlashIdx + 1);
+ const colonIdx = lastSection.lastIndexOf(':');
+ if (colonIdx !== -1) {
+ // since containerd v1.5.0+, containerId is divided by the last colon when the cgroupDriver is systemd:
+ // https://github.com/containerd/containerd/blob/release/1.5/pkg/cri/server/helpers_linux.go#L64
+ return lastSection.substring(colonIdx + 1);
+ } else {
+ let startIdx = lastSection.lastIndexOf('-');
+ let endIdx = lastSection.lastIndexOf('.');
+
+ startIdx = startIdx === -1 ? 0 : startIdx + 1;
+ if (endIdx === -1) {
+ endIdx = lastSection.length;
+ }
+ if (startIdx > endIdx) {
+ continue;
+ }
+ return lastSection.substring(startIdx, endIdx);
}
}
return undefined;
diff --git a/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/test/ContainerDetector.test.ts b/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/test/ContainerDetector.test.ts
index e9c5c3aaf..8ee03d1f3 100644
--- a/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/test/ContainerDetector.test.ts
+++ b/auto-merge/contrib/detectors/node/opentelemetry-resource-detector-container/test/ContainerDetector.test.ts
@@ -28,7 +28,7 @@ import { ContainerDetector } from '../src';
describe('ContainerDetector', () => {
let readStub;
const correctCgroupV1Data =
- 'bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm';
+ '12:pids:/kubepods.slice/bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm';
const correctCgroupV2Data = `tmhdefghijklmnopqrstuvwxyzafgrefghiugkmnopqrstuvwxyzabcdefghijkl/hostname
fhkjdshgfhsdfjhdsfkjhfkdshkjhfd/host
sahfhfjkhjhfhjdhfjkdhfkjdhfjkhhdsjfhdfhjdhfkj/somethingelse`;
diff --git a/auto-merge/js/CHANGELOG.md b/auto-merge/js/CHANGELOG.md
index 4c48f21a6..53987c416 100644
--- a/auto-merge/js/CHANGELOG.md
+++ b/auto-merge/js/CHANGELOG.md
@@ -17,6 +17,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/
### :house: (Internal)
+* test: added a performance benchmark test for span creation [#4105](https://github.com/open-telemetry/opentelemetry-js/pull/4105)
+
## 1.17.0
### :bug: (Bug Fix)
diff --git a/auto-merge/js/experimental/examples/opencensus-shim/README.md b/auto-merge/js/experimental/examples/opencensus-shim/README.md
index 0738d67d8..6d95a9135 100644
--- a/auto-merge/js/experimental/examples/opencensus-shim/README.md
+++ b/auto-merge/js/experimental/examples/opencensus-shim/README.md
@@ -9,6 +9,8 @@ The example has:
- Root Spans (on client), instrumented with OpenCensus's HTTP instrumentation
- Child Span from a remote parent (on server), instrumented with OpenCensus's HTTP instrumentation
- Another Child Span created in the server representing some work being done, instrumented manually with OpenTelemetry.
+- Server metrics coming from OpenCensus's HTTP instrumentation, available through the
+OpenTelemetry's Prometheus exporter.
## Installation
@@ -64,6 +66,14 @@ Go to Jaeger with your browser and click on the "Servi
+## Check the Prometheus metrics
+
+Load the Prometheus metrics endpoint of the server at in your
+browser. You should see the `opencensus_io_http_server_*` related metrics in
+the output.
+
+
+
## Useful links
- For more information on OpenTelemetry, visit:
diff --git a/auto-merge/js/experimental/examples/opencensus-shim/images/prom-metrics.png b/auto-merge/js/experimental/examples/opencensus-shim/images/prom-metrics.png
new file mode 100644
index 000000000..953e12253
Binary files /dev/null and b/auto-merge/js/experimental/examples/opencensus-shim/images/prom-metrics.png differ
diff --git a/auto-merge/js/experimental/examples/opencensus-shim/package.json b/auto-merge/js/experimental/examples/opencensus-shim/package.json
index d8615a6b7..bd97c726c 100644
--- a/auto-merge/js/experimental/examples/opencensus-shim/package.json
+++ b/auto-merge/js/experimental/examples/opencensus-shim/package.json
@@ -28,10 +28,13 @@
},
"dependencies": {
"@opencensus/core": "0.1.0",
+ "@opencensus/instrumentation-http": "0.1.0",
"@opencensus/nodejs-base": "0.1.0",
"@opentelemetry/api": "1.6.0",
+ "@opentelemetry/exporter-prometheus": "0.43.0",
"@opentelemetry/exporter-trace-otlp-grpc": "0.43.0",
"@opentelemetry/resources": "1.17.0",
+ "@opentelemetry/sdk-metrics": "1.17.0",
"@opentelemetry/sdk-trace-node": "1.17.0",
"@opentelemetry/semantic-conventions": "1.17.0",
"@opentelemetry/shim-opencensus": "0.43.0"
diff --git a/auto-merge/js/experimental/examples/opencensus-shim/server.js b/auto-merge/js/experimental/examples/opencensus-shim/server.js
index 98ddcf5b6..00893bafe 100644
--- a/auto-merge/js/experimental/examples/opencensus-shim/server.js
+++ b/auto-merge/js/experimental/examples/opencensus-shim/server.js
@@ -5,6 +5,8 @@ const setup = require('./setup');
const utils = require('./utils');
const { trace } = require('@opentelemetry/api');
+const oc = require('@opencensus/core');
+
setup('opencensus-shim-example-server');
const http = require('http');
diff --git a/auto-merge/js/experimental/examples/opencensus-shim/setup.js b/auto-merge/js/experimental/examples/opencensus-shim/setup.js
index 37206971e..99bf8bf8b 100644
--- a/auto-merge/js/experimental/examples/opencensus-shim/setup.js
+++ b/auto-merge/js/experimental/examples/opencensus-shim/setup.js
@@ -15,37 +15,64 @@
*/
'use strict';
-const { DiagConsoleLogger, diag, DiagLogLevel } = require('@opentelemetry/api');
+const { diag, metrics } = require('@opentelemetry/api');
const {
NodeTracerProvider,
BatchSpanProcessor,
} = require('@opentelemetry/sdk-trace-node');
+const { MeterProvider } = require('@opentelemetry/sdk-metrics');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-grpc');
+const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const { Resource } = require('@opentelemetry/resources');
const {
SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
+const { OpenCensusMetricProducer } = require('@opentelemetry/shim-opencensus');
+const instrumentationHttp = require('@opencensus/instrumentation-http');
+const { TracingBase } = require('@opencensus/nodejs-base');
+const oc = require('@opencensus/core');
module.exports = function setup(serviceName) {
- const tracing = require('@opencensus/nodejs-base');
+ /**
+ * You can alternatively just use the @opentelemetry/nodejs package directly:
+ *
+ * ```js
+ * const tracing = require('@opencensus/nodejs');
+ * ```
+ */
+ const tracing = new TracingBase(['http']);
+ tracing.tracer = new oc.CoreTracer();
- diag.setLogger(new DiagConsoleLogger(), { logLevel: DiagLogLevel.ALL });
- const provider = new NodeTracerProvider({
- resource: new Resource({
- [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
- }),
+ const resource = new Resource({
+ [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
});
- provider.addSpanProcessor(
+ const tracerProvider = new NodeTracerProvider({ resource });
+ tracerProvider.addSpanProcessor(
new BatchSpanProcessor(new OTLPTraceExporter(), {
scheduledDelayMillis: 5000,
})
);
- provider.register();
+ tracerProvider.register();
+
+ const meterProvider = new MeterProvider({ resource });
+ meterProvider.addMetricReader(
+ new PrometheusExporter({
+ metricProducers: [
+ new OpenCensusMetricProducer({
+ openCensusMetricProducerManager:
+ oc.Metrics.getMetricProducerManager(),
+ }),
+ ],
+ })
+ );
+ metrics.setGlobalMeterProvider(meterProvider);
// Start OpenCensus tracing
- tracing.start({ samplingRate: 1, logger: diag });
+ tracing.start({ samplingRate: 1, logger: diag, stats: oc.globalStats });
+ // Register OpenCensus HTTP stats views
+ instrumentationHttp.registerAllViews(oc.globalStats);
- return provider;
+ return tracerProvider;
};
diff --git a/auto-merge/js/experimental/packages/shim-opencensus/README.md b/auto-merge/js/experimental/packages/shim-opencensus/README.md
index e79cfc0f4..66e4d6e3d 100644
--- a/auto-merge/js/experimental/packages/shim-opencensus/README.md
+++ b/auto-merge/js/experimental/packages/shim-opencensus/README.md
@@ -13,11 +13,11 @@ More details are available in the [OpenCensus Compatibility Specification](https
npm install --save @opentelemetry/shim-opencensus
```
-## Usage
+## Tracing usage
### Installing the shim's require-in-the-middle hook
-This is the recommended way to use the shim.
+This is the recommended way to use the shim for tracing.
This package provides a `require-in-the-middle` hook which replaces OpenCensus's `CoreTracer`
class with a shim implementation that writes to the OpenTelemetry API. This will cause all
@@ -72,6 +72,25 @@ tracer.startRootSpan({name: 'main'}, rootSpan => {
});
```
+## Metrics usage
+
+OpenCensus metrics can be collected and sent to an OpenTelemetry exporter by providing the
+`OpenCensusMetricProducer` to your `MetricReader`. For example, to export OpenCensus metrics
+through the OpenTelemetry Prometheus exporter:
+
+```js
+meterProvider.addMetricReader(
+ new PrometheusExporter({
+ metricProducers: [
+ new OpenCensusMetricProducer({
+ openCensusMetricProducerManager:
+ oc.Metrics.getMetricProducerManager(),
+ }),
+ ],
+ })
+);
+```
+
## Example
See [examples/opencensus-shim](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/examples/opencensus-shim) for a short example.
diff --git a/auto-merge/js/package.json b/auto-merge/js/package.json
index fb734e564..6d5460207 100644
--- a/auto-merge/js/package.json
+++ b/auto-merge/js/package.json
@@ -15,6 +15,7 @@
"test:browser": "lerna run test:browser",
"test:webworker": "lerna run test:webworker",
"test:backcompat": "lerna run test:backcompat",
+ "test:bench": "lerna run test:bench",
"bootstrap": "lerna bootstrap --hoist --nohoist='zone.js'",
"changelog": "lerna-changelog",
"codecov": "lerna run codecov",
@@ -65,6 +66,7 @@
"devDependencies": {
"@typescript-eslint/eslint-plugin": "5.59.11",
"@typescript-eslint/parser": "5.59.11",
+ "benchmark": "2.1.4",
"eslint": "8.44.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-header": "3.1.1",
diff --git a/common/config/rush/npm-shrinkwrap.json b/common/config/rush/npm-shrinkwrap.json
index 0dab8ad1a..7ba3f0d68 100644
--- a/common/config/rush/npm-shrinkwrap.json
+++ b/common/config/rush/npm-shrinkwrap.json
@@ -4982,9 +4982,9 @@
"integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q=="
},
"node_modules/@types/node": {
- "version": "18.17.17",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.17.tgz",
- "integrity": "sha512-cOxcXsQ2sxiwkykdJqvyFS+MLQPLvIdwh5l6gNg8qF6s+C7XSkEWOZjK+XhUZd+mYvHV/180g2cnCcIl4l06Pw=="
+ "version": "18.17.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.18.tgz",
+ "integrity": "sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw=="
},
"node_modules/@types/qs": {
"version": "6.9.8",
@@ -7390,9 +7390,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001535",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001535.tgz",
- "integrity": "sha512-48jLyUkiWFfhm/afF7cQPqPjaUmSraEhK4j+FCTJpgnGGEZHqyLe3hmWH7lIooZdSzXL0ReMvHz0vKDoTBsrwg==",
+ "version": "1.0.30001538",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz",
+ "integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==",
"funding": [
{
"type": "opencollective",
@@ -8645,9 +8645,9 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
- "version": "1.4.523",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.523.tgz",
- "integrity": "sha512-9AreocSUWnzNtvLcbpng6N+GkXnCcBR80IQkxRC9Dfdyg4gaWNUPBujAHUpKkiUkoSoR9UlhA4zD/IgBklmhzg=="
+ "version": "1.4.525",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.525.tgz",
+ "integrity": "sha512-GIZ620hDK4YmIqAWkscG4W6RwY6gOx1y5J6f4JUQwctiJrqH2oxZYU4mXHi35oV32tr630UcepBzSBGJ/WYcZA=="
},
"node_modules/elliptic": {
"version": "6.5.4",
@@ -10239,9 +10239,9 @@
}
},
"node_modules/follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "version": "1.15.3",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
+ "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"funding": [
{
"type": "individual",
@@ -19264,9 +19264,9 @@
}
},
"node_modules/webpack-dev-server/node_modules/ws": {
- "version": "8.14.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz",
- "integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==",
+ "version": "8.14.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
+ "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"engines": {
"node": ">=10.0.0"
},
diff --git a/pkgs/sdk/trace/base/package.json b/pkgs/sdk/trace/base/package.json
index 61872ce3c..0970b15cb 100644
--- a/pkgs/sdk/trace/base/package.json
+++ b/pkgs/sdk/trace/base/package.json
@@ -30,6 +30,7 @@
"tdd:browser": "karma start",
"tdd:node": "npm run test -- --watch-extensions ts --watch",
"test": "npm run test:node && npm run test:browser && npm run test:webworker",
+ "test:bench": "node test/performance/benchmark/index.js",
"test:browser": "nyc karma start ./karma.conf.js --single-run",
"test:debug": "nyc karma start ./karma.debug.conf.js --wait",
"test:node": "",
diff --git a/pkgs/sdk/trace/base/test/performance/benchmark/index.js b/pkgs/sdk/trace/base/test/performance/benchmark/index.js
new file mode 100644
index 000000000..83558ea01
--- /dev/null
+++ b/pkgs/sdk/trace/base/test/performance/benchmark/index.js
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+require('./span');
diff --git a/pkgs/sdk/trace/base/test/performance/benchmark/span.js b/pkgs/sdk/trace/base/test/performance/benchmark/span.js
new file mode 100644
index 000000000..ac978a614
--- /dev/null
+++ b/pkgs/sdk/trace/base/test/performance/benchmark/span.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+const Benchmark = require('benchmark');
+const { BasicTracerProvider } = require('../../../build/src');
+
+const tracerProvider = new BasicTracerProvider();
+const tracer = tracerProvider.getTracer('test')
+
+const suite = new Benchmark.Suite();
+
+suite.on('cycle', event => {
+ console.log(String(event.target));
+});
+
+suite.add('create spans (10 attributes)', function() {
+ const span = tracer.startSpan('span');
+ span.setAttribute('aaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('bbbbbbbbbbbbbbbbbbbb', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('cccccccccccccccccccc', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('dddddddddddddddddddd', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('eeeeeeeeeeeeeeeeeeee', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('ffffffffffffffffffff', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('gggggggggggggggggggg', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('hhhhhhhhhhhhhhhhhhhh', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('iiiiiiiiiiiiiiiiiiii', 'aaaaaaaaaaaaaaaaaaaa');
+ span.setAttribute('jjjjjjjjjjjjjjjjjjjj', 'aaaaaaaaaaaaaaaaaaaa');
+});
+
+suite.run();