Named Tracers / Tracer Registry (#582)
* feat: spike of named tracer registry * chore: mysql/mongo tracer registry support * fix: lint * chore: add getTracer back * chore: change default tracer name to empty string * fix: lint * chore: update examples for registry * chore(tracer-registry): make name required * chore: lint * chore: update examples for required tracer name * chore: remove unused tracer delegate * chore: remove references to basic tracer * chore: remove references to NodeTracer * chore: update xhr for tracer registry * chore: update tracer names to match package names * chore: add version script to all packages * chore: update plugins to use version script * chore: add jsdoc to noop tracer registry * chore: update ioredis for tracer registry * chore: update pg pool for tracer registry * fix: lint * chore: fix tests * chore: lint * chore: lint Co-authored-by: Mayur Kale <mayurkale@google.com>
This commit is contained in:
parent
059595a215
commit
18c6aa4f19
|
@ -71,6 +71,7 @@ docs
|
|||
|
||||
#lerna
|
||||
.changelog
|
||||
package.json.lerna_backup
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
|
|
|
@ -2,26 +2,26 @@
|
|||
|
||||
const benchmark = require('./benchmark');
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { BasicTracer, BatchSpanProcessor, InMemorySpanExporter, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { BasicTracerRegistry, BatchSpanProcessor, InMemorySpanExporter, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const exporter = new InMemorySpanExporter();
|
||||
const logger = new opentelemetry.NoopLogger();
|
||||
|
||||
const setups = [
|
||||
{
|
||||
name: 'BasicTracer',
|
||||
tracer: new BasicTracer({ logger })
|
||||
name: 'BasicTracerRegistry',
|
||||
registry: new BasicTracerRegistry({ logger })
|
||||
},
|
||||
{
|
||||
name: 'NodeTracer',
|
||||
tracer: new NodeTracer({ logger })
|
||||
name: 'NodeTracerRegistry',
|
||||
registry: new NodeTracerRegistry({ logger })
|
||||
}
|
||||
];
|
||||
|
||||
for (const setup of setups) {
|
||||
console.log(`Beginning ${setup.name} Benchmark...`);
|
||||
const tracer = setup.tracer;
|
||||
const tracer = setup.registry.getTracer("benchmark");
|
||||
const suite = benchmark()
|
||||
.add('#startSpan', function () {
|
||||
const span = tracer.startSpan('op');
|
||||
|
@ -55,7 +55,7 @@ for (const setup of setups) {
|
|||
.add('#startSpan with SimpleSpanProcessor', function () {
|
||||
const simpleSpanProcessor = new SimpleSpanProcessor(exporter);
|
||||
|
||||
tracer.addSpanProcessor(simpleSpanProcessor);
|
||||
registry.addSpanProcessor(simpleSpanProcessor);
|
||||
const span = tracer.startSpan('op');
|
||||
span.end();
|
||||
|
||||
|
@ -64,7 +64,7 @@ for (const setup of setups) {
|
|||
.add('#startSpan with BatchSpanProcessor', function () {
|
||||
const batchSpanProcessor = new BatchSpanProcessor(exporter);
|
||||
|
||||
tracer.addSpanProcessor(batchSpanProcessor);
|
||||
registry.addSpanProcessor(batchSpanProcessor);
|
||||
const span = tracer.startSpan('op');
|
||||
span.end();
|
||||
batchSpanProcessor.shutdown();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { BasicTracer, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { BasicTracerRegistry, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const { CollectorExporter } = require('@opentelemetry/exporter-collector');
|
||||
|
@ -20,16 +20,17 @@ if (EXPORTER.toLowerCase().startsWith('z')) {
|
|||
exporter = new CollectorExporter(options);
|
||||
}
|
||||
|
||||
const tracer = new BasicTracer();
|
||||
const registry = new BasicTracerRegistry();
|
||||
|
||||
// Configure span processor to send spans to the provided exporter
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
const tracer = opentelemetry.getTracer('example-basic-tracer-node')
|
||||
|
||||
// Create a span. A span must be closed.
|
||||
const span = opentelemetry.getTracer().startSpan('main');
|
||||
const span = tracer.startSpan('main');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
doWork(span);
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ exporter.shutdown();
|
|||
function doWork(parent) {
|
||||
// Start another span. In this example, the main method already started a
|
||||
// span, so that'll be the parent span, and this will be a child span.
|
||||
const span = opentelemetry.getTracer().startSpan('doWork', {
|
||||
const span = tracer.startSpan('doWork', {
|
||||
parent: parent
|
||||
});
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { BasicTracer, BatchSpanProcessor, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { BasicTracerRegistry, BatchSpanProcessor, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const { CollectorExporter } = require('@opentelemetry/exporter-collector');
|
||||
|
||||
const tracer = new BasicTracer();
|
||||
const registry = new BasicTracerRegistry();
|
||||
|
||||
const zipkinExporter = new ZipkinExporter({serviceName: 'basic-service'});
|
||||
const jaegerExporter = new JaegerExporter({
|
||||
|
@ -14,21 +14,22 @@ const collectorExporter = new CollectorExporter({serviceName: 'basic-service'});
|
|||
|
||||
// It is recommended to use this BatchSpanProcessor for better performance
|
||||
// and optimization, especially in production.
|
||||
tracer.addSpanProcessor(new BatchSpanProcessor(zipkinExporter, {
|
||||
registry.addSpanProcessor(new BatchSpanProcessor(zipkinExporter, {
|
||||
bufferSize: 10 // This is added for example, default size is 100.
|
||||
}));
|
||||
|
||||
// It is recommended to use SimpleSpanProcessor in case of Jaeger exporter as
|
||||
// it's internal client already handles the spans with batching logic.
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(jaegerExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(jaegerExporter));
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(collectorExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(collectorExporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
const tracer = opentelemetry.getTracer('default');
|
||||
|
||||
// Create a span. A span must be closed.
|
||||
const span = opentelemetry.getTracer().startSpan('main');
|
||||
const span = tracer.startSpan('main');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
doWork(span);
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ collectorExporter.shutdown();
|
|||
function doWork(parent) {
|
||||
// Start another span. In this example, the main method already started a
|
||||
// span, so that'll be the parent span, and this will be a child span.
|
||||
const span = opentelemetry.getTracer().startSpan('doWork', {
|
||||
const span = tracer.startSpan('doWork', {
|
||||
parent: parent
|
||||
});
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('dns-client-service');
|
||||
|
||||
const dns = require('dns').promises;
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-dns');
|
||||
|
||||
/** A function which makes a dns lookup and handles response. */
|
||||
function makeLookup() {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const EXPORTER = process.env.EXPORTER || '';
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
dns: {
|
||||
enabled: true,
|
||||
|
@ -30,10 +30,10 @@ function setupTracerAndExporters(service) {
|
|||
});
|
||||
}
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -14,7 +14,7 @@ const grpc = require('grpc');
|
|||
const messages = require('./helloworld_pb');
|
||||
const services = require('./helloworld_grpc_pb');
|
||||
const PORT = 50051;
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-grpc-client');
|
||||
|
||||
/** A function which makes requests and handles response. */
|
||||
function main() {
|
||||
|
|
|
@ -10,7 +10,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('grpc-server-service');
|
||||
|
||||
const grpc = require('grpc');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-grpc-server');
|
||||
|
||||
const messages = require('./helloworld_pb');
|
||||
const services = require('./helloworld_grpc_pb');
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const EXPORTER = process.env.EXPORTER || '';
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
grpc: {
|
||||
enabled: true,
|
||||
|
@ -29,10 +29,10 @@ function setupTracerAndExporters(service) {
|
|||
});
|
||||
}
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -13,7 +13,7 @@ const path = require('path');
|
|||
const grpc = require('grpc');
|
||||
const protoLoader = require('@grpc/proto-loader');
|
||||
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-grpc-capitalize-client');
|
||||
|
||||
const PROTO_PATH = path.join(__dirname, 'protos/defs.proto');
|
||||
const PROTO_OPTIONS = { keepCase: true, enums: String, defaults: true, oneofs: true };
|
||||
|
|
|
@ -19,7 +19,7 @@ const PROTO_OPTIONS = { keepCase: true, enums: String, defaults: true, oneofs: t
|
|||
const definition = protoLoader.loadSync(PROTO_PATH, PROTO_OPTIONS);
|
||||
const rpcProto = grpc.loadPackageDefinition(definition).rpc;
|
||||
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-grpc-capitalize-server');
|
||||
|
||||
/** Implements the Capitalize RPC method. */
|
||||
function capitalize(call, callback) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const EXPORTER = process.env.EXPORTER || '';
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
grpc: {
|
||||
enabled: true,
|
||||
|
@ -31,10 +31,10 @@ function setupTracerAndExporters(service) {
|
|||
|
||||
// It is recommended to use this `BatchSpanProcessor` for better performance
|
||||
// and optimization, especially in production.
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -10,7 +10,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('http-client-service');
|
||||
|
||||
const http = require('http');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-http-client');
|
||||
|
||||
/** A function which makes requests and handles response. */
|
||||
function makeRequest() {
|
||||
|
|
|
@ -9,7 +9,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('http-server-service');
|
||||
|
||||
const http = require('http');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-http-server');
|
||||
|
||||
/** Starts a HTTP server that receives requests on sample server port. */
|
||||
function startServer (port) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const EXPORTER = process.env.EXPORTER || '';
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
|
||||
let exporter;
|
||||
if (EXPORTER.toLowerCase().startsWith('z')) {
|
||||
|
@ -21,10 +21,10 @@ function setupTracerAndExporters(service) {
|
|||
});
|
||||
}
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -9,7 +9,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('https-client-service');
|
||||
|
||||
const https = require('https');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-https-client');
|
||||
|
||||
/** A function which makes requests and handles response. */
|
||||
function makeRequest() {
|
||||
|
@ -31,7 +31,7 @@ function makeRequest() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// The process must live for at least the interval past any traces that
|
||||
// must be exported, or some risk being lost if they are recorded after the
|
||||
// last export.
|
||||
|
|
|
@ -10,7 +10,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('https-server-service');
|
||||
|
||||
const https = require('https');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-https-server');
|
||||
|
||||
/** Starts a HTTPs server that receives requests on sample server port. */
|
||||
function startServer (port) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
|
@ -9,7 +9,7 @@ const EXPORTER = process.env.EXPORTER || '';
|
|||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
function setupTracerAndExporters(service) {
|
||||
let exporter;
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
|
||||
if (EXPORTER.toLowerCase().startsWith('z')) {
|
||||
exporter = new ZipkinExporter({
|
||||
|
@ -21,10 +21,10 @@ function setupTracerAndExporters(service) {
|
|||
});
|
||||
}
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -10,7 +10,7 @@ const config = require('./setup');
|
|||
config.setupTracerAndExporters('http-client-service');
|
||||
|
||||
const http = require('http');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-mysql-http-client');
|
||||
|
||||
/** A function which makes requests and handles response. */
|
||||
function makeRequest() {
|
||||
|
|
|
@ -11,7 +11,7 @@ config.setupTracerAndExporters('http-mysql-server-service');
|
|||
const mysql = require('mysql');
|
||||
const http = require('http');
|
||||
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-mysql-http-server');
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host : 'localhost',
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
mysql: {
|
||||
enabled: true,
|
||||
|
@ -20,15 +20,15 @@ function setupTracerAndExporters(service) {
|
|||
}
|
||||
});
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter({
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter({
|
||||
serviceName: service,
|
||||
})));
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(new JaegerExporter({
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(new JaegerExporter({
|
||||
serviceName: service,
|
||||
})));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
const { NodeTracer } = require("@opentelemetry/node");
|
||||
const { NodeTracerRegistry } = require("@opentelemetry/node");
|
||||
const { SimpleSpanProcessor } = require("@opentelemetry/tracing");
|
||||
const { JaegerExporter } = require("@opentelemetry/exporter-jaeger");
|
||||
const { ZipkinExporter } = require("@opentelemetry/exporter-zipkin");
|
||||
const { TracerShim } = require("@opentelemetry/shim-opentracing");
|
||||
|
||||
function shim(serviceName) {
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(getExporter(serviceName)));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(getExporter(serviceName)));
|
||||
|
||||
return new TracerShim(tracer);
|
||||
return new TracerShim(registry.getTracer("opentracing-shim"));
|
||||
}
|
||||
|
||||
function getExporter(serviceName) {
|
||||
|
|
|
@ -4,7 +4,7 @@ const opentelemetry = require('@opentelemetry/core');
|
|||
const types = require('@opentelemetry/types');
|
||||
const config = require('./setup');
|
||||
config.setupTracerAndExporters('redis-client-service');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-redis-client');
|
||||
const axios = require('axios').default;
|
||||
|
||||
function makeRequest() {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
const opentelemetry = require('@opentelemetry/core');
|
||||
const config = require('./setup');
|
||||
config.setupTracerAndExporters('redis-server-service');
|
||||
const tracer = opentelemetry.getTracer();
|
||||
const tracer = opentelemetry.getTracer('example-redis-server');
|
||||
|
||||
// Require in rest of modules
|
||||
const express = require('express');
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||
const EXPORTER = process.env.EXPORTER || '';
|
||||
|
||||
function setupTracerAndExporters(service) {
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
|
||||
let exporter;
|
||||
if (EXPORTER.toLowerCase().startsWith('z')) {
|
||||
|
@ -21,10 +21,10 @@ function setupTracerAndExporters(service) {
|
|||
});
|
||||
}
|
||||
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracerRegistry bindings
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
}
|
||||
|
||||
exports.setupTracerAndExporters = setupTracerAndExporters;
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing';
|
||||
import { WebTracer } from '@opentelemetry/web';
|
||||
import { WebTracerRegistry } from '@opentelemetry/web';
|
||||
import { DocumentLoad } from '@opentelemetry/plugin-document-load';
|
||||
import { ZoneScopeManager } from '@opentelemetry/scope-zone';
|
||||
import { CollectorExporter } from '@opentelemetry/exporter-collector'
|
||||
|
||||
const webTracer = new WebTracer({
|
||||
const registry = new WebTracerRegistry({
|
||||
plugins: [
|
||||
new DocumentLoad()
|
||||
]
|
||||
});
|
||||
webTracer.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
||||
|
||||
const webTracerWithZone = new WebTracer({
|
||||
const registryWithZone = new WebTracerRegistry({
|
||||
scopeManager: new ZoneScopeManager(),
|
||||
plugins: [
|
||||
new DocumentLoad()
|
||||
]
|
||||
});
|
||||
webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
||||
webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));
|
||||
registryWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
||||
registryWithZone.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));
|
||||
|
||||
console.log('Current span is window', webTracerWithZone.getCurrentSpan() === window);
|
||||
const tracerWithZone = registryWithZone.getTracer('example-tracer-web');
|
||||
console.log('Current span is window', tracerWithZone.getCurrentSpan() === window);
|
||||
|
||||
// example of keeping track of scope between async operations
|
||||
const prepareClickEvent = () => {
|
||||
|
@ -28,33 +29,33 @@ const prepareClickEvent = () => {
|
|||
const url2 = 'https://raw.githubusercontent.com/open-telemetry/opentelemetry-js/master/packages/opentelemetry-web/package.json';
|
||||
|
||||
const element = document.getElementById('button1');
|
||||
let mainSpan = webTracerWithZone.startSpan('main-span');
|
||||
webTracerWithZone.bind(element, mainSpan);
|
||||
let mainSpan = tracerWithZone.startSpan('main-span');
|
||||
tracerWithZone.bind(element, mainSpan);
|
||||
|
||||
const onClick = () => {
|
||||
const span1 = webTracerWithZone.startSpan(`files-series-info-1`, {
|
||||
parent: webTracerWithZone.getCurrentSpan()
|
||||
const span1 = tracerWithZone.startSpan(`files-series-info-1`, {
|
||||
parent: tracerWithZone.getCurrentSpan()
|
||||
});
|
||||
|
||||
const span2 = webTracerWithZone.startSpan(`files-series-info-2`, {
|
||||
parent: webTracerWithZone.getCurrentSpan()
|
||||
const span2 = tracerWithZone.startSpan(`files-series-info-2`, {
|
||||
parent: tracerWithZone.getCurrentSpan()
|
||||
});
|
||||
|
||||
webTracerWithZone.withSpan(span1, () => {
|
||||
tracerWithZone.withSpan(span1, () => {
|
||||
getData(url1).then((data) => {
|
||||
console.log('current span is span1', webTracerWithZone.getCurrentSpan() === span1);
|
||||
console.log('current span is span1', tracerWithZone.getCurrentSpan() === span1);
|
||||
console.log('info from package.json', data.description, data.version);
|
||||
webTracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
|
||||
tracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
|
||||
span1.end();
|
||||
});
|
||||
});
|
||||
|
||||
webTracerWithZone.withSpan(span2, () => {
|
||||
tracerWithZone.withSpan(span2, () => {
|
||||
getData(url2).then((data) => {
|
||||
setTimeout(() => {
|
||||
console.log('current span is span2', webTracerWithZone.getCurrentSpan() === span2);
|
||||
console.log('current span is span2', tracerWithZone.getCurrentSpan() === span2);
|
||||
console.log('info from package.json', data.description, data.version);
|
||||
webTracerWithZone.getCurrentSpan().addEvent('fetching-span2-completed');
|
||||
tracerWithZone.getCurrentSpan().addEvent('fetching-span2-completed');
|
||||
span2.end();
|
||||
}, 100);
|
||||
});
|
||||
|
|
|
@ -27,10 +27,10 @@ export * from './trace/globaltracer-utils';
|
|||
export * from './trace/instrumentation/BasePlugin';
|
||||
export * from './trace/NoopSpan';
|
||||
export * from './trace/NoopTracer';
|
||||
export * from './trace/NoopTracerRegistry';
|
||||
export * from './trace/NoRecordingSpan';
|
||||
export * from './trace/sampler/ProbabilitySampler';
|
||||
export * from './trace/spancontext-utils';
|
||||
export * from './trace/TracerDelegate';
|
||||
export * from './trace/TraceState';
|
||||
export * from './metrics/NoopMeter';
|
||||
export * from './utils/url';
|
||||
|
|
|
@ -59,3 +59,5 @@ export class NoopTracer implements Tracer {
|
|||
return NOOP_HTTP_TEXT_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
export const noopTracer = new NoopTracer();
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*!
|
||||
* Copyright 2019, 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.
|
||||
*/
|
||||
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { noopTracer } from './NoopTracer';
|
||||
|
||||
/**
|
||||
* An implementation of the {@link TracerRegistry} which returns an impotent Tracer
|
||||
* for all calls to `getTracer`
|
||||
*/
|
||||
export class NoopTracerRegistry implements types.TracerRegistry {
|
||||
getTracer(_name?: string, _version?: string): types.Tracer {
|
||||
return noopTracer;
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*!
|
||||
* Copyright 2019, 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.
|
||||
*/
|
||||
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { NoopTracer } from './NoopTracer';
|
||||
|
||||
// Acts a bridge to the global tracer that can be safely called before the
|
||||
// global tracer is initialized. The purpose of the delegation is to avoid the
|
||||
// sometimes nearly intractable initialization order problems that can arise in
|
||||
// applications with a complex set of dependencies. Also allows for the tracer
|
||||
// to be changed/disabled during runtime without needing to change reference
|
||||
// to the global tracer
|
||||
export class TracerDelegate implements types.Tracer {
|
||||
private _currentTracer: types.Tracer;
|
||||
private readonly _tracer: types.Tracer | null;
|
||||
private readonly _fallbackTracer: types.Tracer;
|
||||
|
||||
// Wrap a tracer with a TracerDelegate. Provided tracer becomes the default
|
||||
// fallback tracer for when a global tracer has not been initialized
|
||||
constructor(tracer?: types.Tracer, fallbackTracer?: types.Tracer) {
|
||||
this._tracer = tracer || null;
|
||||
this._fallbackTracer = fallbackTracer || new NoopTracer();
|
||||
this._currentTracer = this._tracer || this._fallbackTracer; // equivalent to this.start()
|
||||
}
|
||||
|
||||
// Begin using the user provided tracer. Stop always falling back to fallback tracer
|
||||
start(): void {
|
||||
this._currentTracer = this._tracer || this._fallbackTracer;
|
||||
}
|
||||
|
||||
// Stop the delegate from using the provided tracer. Begin to use the fallback tracer
|
||||
stop(): void {
|
||||
this._currentTracer = this._fallbackTracer;
|
||||
}
|
||||
|
||||
// -- Tracer interface implementation below -- //
|
||||
|
||||
getCurrentSpan(): types.Span | undefined {
|
||||
return this._currentTracer.getCurrentSpan.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
);
|
||||
}
|
||||
|
||||
bind<T>(target: T, span?: types.Span): T {
|
||||
return (this._currentTracer.bind.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
) as unknown) as T;
|
||||
}
|
||||
|
||||
startSpan(name: string, options?: types.SpanOptions): types.Span {
|
||||
return this._currentTracer.startSpan.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
);
|
||||
}
|
||||
|
||||
withSpan<T extends (...args: unknown[]) => ReturnType<T>>(
|
||||
span: types.Span,
|
||||
fn: T
|
||||
): ReturnType<T> {
|
||||
return this._currentTracer.withSpan.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
);
|
||||
}
|
||||
|
||||
getBinaryFormat(): types.BinaryFormat {
|
||||
return this._currentTracer.getBinaryFormat.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
);
|
||||
}
|
||||
|
||||
getHttpTextFormat(): types.HttpTextFormat {
|
||||
return this._currentTracer.getHttpTextFormat.apply(
|
||||
this._currentTracer,
|
||||
// tslint:disable-next-line:no-any
|
||||
arguments as any
|
||||
);
|
||||
}
|
||||
}
|
|
@ -15,21 +15,31 @@
|
|||
*/
|
||||
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { TracerDelegate } from './TracerDelegate';
|
||||
import { NoopTracerRegistry } from './NoopTracerRegistry';
|
||||
|
||||
let globalTracerDelegate = new TracerDelegate();
|
||||
let globalTracerRegistry: types.TracerRegistry = new NoopTracerRegistry();
|
||||
|
||||
/**
|
||||
* Set the current global tracer. Returns the initialized global tracer
|
||||
*/
|
||||
export function initGlobalTracer(tracer: types.Tracer): types.Tracer {
|
||||
return (globalTracerDelegate = new TracerDelegate(tracer));
|
||||
export function initGlobalTracerRegistry(
|
||||
tracerRegistry: types.TracerRegistry
|
||||
): types.TracerRegistry {
|
||||
return (globalTracerRegistry = tracerRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global tracer
|
||||
* Returns the global tracer registry.
|
||||
*/
|
||||
export function getTracer(): types.Tracer {
|
||||
// Return the global tracer delegate
|
||||
return globalTracerDelegate;
|
||||
export function getTracerRegistry(): types.TracerRegistry {
|
||||
// Return the global tracer registry
|
||||
return globalTracerRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tracer from the global tracer registry.
|
||||
*/
|
||||
export function getTracer(name: string, version?: string): types.Tracer {
|
||||
// Return the global tracer registry
|
||||
return globalTracerRegistry.getTracer(name, version);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
PluginConfig,
|
||||
PluginInternalFiles,
|
||||
PluginInternalFilesVersion,
|
||||
TracerRegistry,
|
||||
} from '@opentelemetry/types';
|
||||
import * as semver from 'semver';
|
||||
import * as path from 'path';
|
||||
|
@ -39,14 +40,22 @@ export abstract class BasePlugin<T> implements Plugin<T> {
|
|||
protected readonly _internalFilesList?: PluginInternalFiles; // required for internalFilesExports
|
||||
protected _config!: PluginConfig;
|
||||
|
||||
constructor(
|
||||
protected readonly _tracerName: string,
|
||||
protected readonly _tracerVersion?: string
|
||||
) {}
|
||||
|
||||
enable(
|
||||
moduleExports: T,
|
||||
tracer: Tracer,
|
||||
tracerRegistry: TracerRegistry,
|
||||
logger: Logger,
|
||||
config?: PluginConfig
|
||||
): T {
|
||||
this._moduleExports = moduleExports;
|
||||
this._tracer = tracer;
|
||||
this._tracer = tracerRegistry.getTracer(
|
||||
this._tracerName,
|
||||
this._tracerVersion
|
||||
);
|
||||
this._logger = logger;
|
||||
this._internalFilesExports = this._loadInternalFilesExports();
|
||||
if (config) this._config = config;
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BasePlugin, NoopTracer, NoopLogger } from '../../src';
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import { BasePlugin, NoopLogger } from '../../src';
|
||||
import { NoopTracerRegistry } from '../../src/trace/NoopTracerRegistry';
|
||||
import * as types from './fixtures/test-package/foo/bar/internal';
|
||||
|
||||
const tracer = new NoopTracer();
|
||||
const registry = new NoopTracerRegistry();
|
||||
const logger = new NoopLogger();
|
||||
|
||||
describe('BasePlugin', () => {
|
||||
|
@ -28,7 +29,7 @@ describe('BasePlugin', () => {
|
|||
const testPackage = require('./fixtures/test-package');
|
||||
const plugin = new TestPlugin();
|
||||
assert.doesNotThrow(() => {
|
||||
plugin.enable(testPackage, tracer, logger);
|
||||
plugin.enable(testPackage, registry, logger);
|
||||
});
|
||||
|
||||
// @TODO: https://github.com/open-telemetry/opentelemetry-js/issues/285
|
||||
|
@ -61,6 +62,10 @@ class TestPlugin extends BasePlugin<{ [key: string]: Function }> {
|
|||
readonly version = '0.1.0';
|
||||
readonly _basedir = basedir;
|
||||
|
||||
constructor() {
|
||||
super('test-package.opentelemetry');
|
||||
}
|
||||
|
||||
protected readonly _internalFilesList = {
|
||||
'0.1.0': {
|
||||
internal: 'foo/bar/internal.js',
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*!
|
||||
* Copyright 2019, 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.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { TracerDelegate } from '../../src/trace/TracerDelegate';
|
||||
import { NoopTracer, NoopSpan } from '../../src';
|
||||
import { TraceFlags } from '@opentelemetry/types';
|
||||
|
||||
describe('TracerDelegate', () => {
|
||||
const functions = [
|
||||
'getCurrentSpan',
|
||||
'startSpan',
|
||||
'withSpan',
|
||||
'bind',
|
||||
'getBinaryFormat',
|
||||
'getHttpTextFormat',
|
||||
];
|
||||
const spanContext = {
|
||||
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
|
||||
spanId: '6e0c63257de34c92',
|
||||
traceFlags: TraceFlags.UNSAMPLED,
|
||||
};
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should not crash with default constructor', () => {
|
||||
functions.forEach(fn => {
|
||||
const tracer = new TracerDelegate();
|
||||
try {
|
||||
((tracer as unknown) as { [fn: string]: Function })[fn](); // Try to run the function
|
||||
assert.ok(true, fn);
|
||||
} catch (err) {
|
||||
if (err.message !== 'Method not implemented.') {
|
||||
assert.ok(true, fn);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow fallback tracer to be set', () => {
|
||||
const dummyTracer = new DummyTracer();
|
||||
const tracerDelegate = new TracerDelegate(dummyTracer);
|
||||
|
||||
tracerDelegate.startSpan('foo');
|
||||
assert.deepStrictEqual(dummyTracer.spyCounter, 1);
|
||||
});
|
||||
|
||||
it('should use user provided tracer if provided', () => {
|
||||
const dummyTracer = new DummyTracer();
|
||||
const tracerDelegate = new TracerDelegate(dummyTracer);
|
||||
|
||||
tracerDelegate.startSpan('foo');
|
||||
assert.deepStrictEqual(dummyTracer.spyCounter, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.start/.stop()', () => {
|
||||
it('should use the fallback tracer when stop is called', () => {
|
||||
const dummyTracerUser = new DummyTracer();
|
||||
const dummyTracerFallback = new DummyTracer();
|
||||
const tracerDelegate = new TracerDelegate(
|
||||
dummyTracerUser,
|
||||
dummyTracerFallback
|
||||
);
|
||||
|
||||
tracerDelegate.stop();
|
||||
tracerDelegate.startSpan('fallback');
|
||||
assert.deepStrictEqual(dummyTracerUser.spyCounter, 0);
|
||||
assert.deepStrictEqual(dummyTracerFallback.spyCounter, 1);
|
||||
});
|
||||
|
||||
it('should use the user tracer when start is called', () => {
|
||||
const dummyTracerUser = new DummyTracer();
|
||||
const dummyTracerFallback = new DummyTracer();
|
||||
const tracerDelegate = new TracerDelegate(
|
||||
dummyTracerUser,
|
||||
dummyTracerFallback
|
||||
);
|
||||
|
||||
tracerDelegate.stop();
|
||||
tracerDelegate.startSpan('fallback');
|
||||
assert.deepStrictEqual(dummyTracerUser.spyCounter, 0);
|
||||
assert.deepStrictEqual(dummyTracerFallback.spyCounter, 1);
|
||||
|
||||
tracerDelegate.start();
|
||||
tracerDelegate.startSpan('user');
|
||||
assert.deepStrictEqual(dummyTracerUser.spyCounter, 1);
|
||||
assert.deepStrictEqual(
|
||||
dummyTracerFallback.spyCounter,
|
||||
1,
|
||||
'Only user tracer counter is incremented'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
class DummyTracer extends NoopTracer {
|
||||
spyCounter = 0;
|
||||
|
||||
startSpan(name: string, options?: types.SpanOptions | undefined) {
|
||||
this.spyCounter = this.spyCounter + 1;
|
||||
return new NoopSpan(spanContext);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -17,11 +17,12 @@
|
|||
import * as assert from 'assert';
|
||||
import * as types from '@opentelemetry/types';
|
||||
import {
|
||||
getTracer,
|
||||
initGlobalTracer,
|
||||
getTracerRegistry,
|
||||
initGlobalTracerRegistry,
|
||||
} from '../../src/trace/globaltracer-utils';
|
||||
import { NoopTracer, NoopSpan } from '../../src';
|
||||
import { TraceFlags } from '@opentelemetry/types';
|
||||
import { NoopTracerRegistry } from '../../src/trace/NoopTracerRegistry';
|
||||
|
||||
describe('globaltracer-utils', () => {
|
||||
const functions = [
|
||||
|
@ -32,13 +33,13 @@ describe('globaltracer-utils', () => {
|
|||
'getHttpTextFormat',
|
||||
];
|
||||
|
||||
it('should expose a tracer via getTracer', () => {
|
||||
const tracer = getTracer();
|
||||
it('should expose a tracer registry via getTracerRegistry', () => {
|
||||
const tracer = getTracerRegistry();
|
||||
assert.ok(tracer);
|
||||
assert.strictEqual(typeof tracer, 'object');
|
||||
});
|
||||
|
||||
describe('GlobalTracer', () => {
|
||||
describe('GlobalTracerRegistry', () => {
|
||||
const spanContext = {
|
||||
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
|
||||
spanId: '6e0c63257de34c92',
|
||||
|
@ -47,12 +48,12 @@ describe('globaltracer-utils', () => {
|
|||
const dummySpan = new NoopSpan(spanContext);
|
||||
|
||||
afterEach(() => {
|
||||
initGlobalTracer(new NoopTracer());
|
||||
initGlobalTracerRegistry(new NoopTracerRegistry());
|
||||
});
|
||||
|
||||
it('should not crash', () => {
|
||||
functions.forEach(fn => {
|
||||
const tracer = getTracer();
|
||||
const tracer = getTracerRegistry();
|
||||
try {
|
||||
((tracer as unknown) as { [fn: string]: Function })[fn](); // Try to run the function
|
||||
assert.ok(true, fn);
|
||||
|
@ -64,8 +65,9 @@ describe('globaltracer-utils', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should use the global tracer', () => {
|
||||
const tracer = initGlobalTracer(new TestTracer());
|
||||
it('should use the global tracer registry', () => {
|
||||
initGlobalTracerRegistry(new TestTracerRegistry());
|
||||
const tracer = getTracerRegistry().getTracer('name');
|
||||
const span = tracer.startSpan('test');
|
||||
assert.deepStrictEqual(span, dummySpan);
|
||||
});
|
||||
|
@ -78,5 +80,11 @@ describe('globaltracer-utils', () => {
|
|||
return dummySpan;
|
||||
}
|
||||
}
|
||||
|
||||
class TestTracerRegistry extends NoopTracerRegistry {
|
||||
getTracer(_name: string, version?: string) {
|
||||
return new TestTracer();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -35,18 +35,18 @@ opentelemetry.initGlobalTracer(tracer);
|
|||
## Usage in Node
|
||||
```js
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { BasicTracer, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { BasicTracerRegistry, SimpleSpanProcessor } = require('@opentelemetry/tracing');
|
||||
const { CollectorExporter } = require('@opentelemetry/exporter-collector');
|
||||
|
||||
const collectorOptions = {
|
||||
url: '<opentelemetry-collector-url>' // url is optional and can be omitted - default is http://localhost:55678/v1/trace
|
||||
};
|
||||
|
||||
const tracer = new BasicTracer();
|
||||
const registry = new BasicTracerRegistry();
|
||||
const exporter = new CollectorExporter(collectorOptions);
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
||||
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import * as assert from 'assert';
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { Span, BasicTracer } from '@opentelemetry/tracing';
|
||||
import { Span, BasicTracerRegistry } from '@opentelemetry/tracing';
|
||||
import {
|
||||
NoopLogger,
|
||||
hrTimeToMicroseconds,
|
||||
|
@ -32,9 +32,9 @@ import {
|
|||
import * as zipkinTypes from '../src/types';
|
||||
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
logger,
|
||||
});
|
||||
}).getTracer('default');
|
||||
const parentId = '5c1c63257de34c67';
|
||||
const spanContext: types.SpanContext = {
|
||||
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
|
||||
|
|
|
@ -11,14 +11,14 @@ For manual instrumentation see the
|
|||
[@opentelemetry/tracing](https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-tracing) package.
|
||||
|
||||
## How does automated instrumentation work?
|
||||
This package exposes a `NodeTracer` that will automatically hook into the module loader of Node.js.
|
||||
This package exposes a `NodeTracerRegistry` that will automatically hook into the module loader of Node.js.
|
||||
|
||||
For this to work, please make sure that `NodeTracer` is initialized before any other module of your application, (like `http` or `express`) is loaded.
|
||||
For this to work, please make sure that `NodeTracerRegistry` is initialized before any other module of your application, (like `http` or `express`) is loaded.
|
||||
|
||||
OpenTelemetry comes with a growing number of instrumentation plugins for well know modules (see [supported modules](https://github.com/open-telemetry/opentelemetry-js#plugins)) and an API to create custom plugins (see [the plugin developer guide](https://github.com/open-telemetry/opentelemetry-js/blob/master/doc/plugin-guide.md)).
|
||||
|
||||
|
||||
Whenever a module is loaded `NodeTracer` will check if a matching instrumentation plugin has been installed.
|
||||
Whenever a module is loaded `NodeTracerRegistry` will check if a matching instrumentation plugin has been installed.
|
||||
|
||||
> **Please note:** This module does *not* bundle any plugins. They need to be installed separately.
|
||||
|
||||
|
@ -34,7 +34,7 @@ This instrumentation code will automatically
|
|||
In short, this means that this module will use provided plugins to automatically instrument your application to produce spans and provide end-to-end tracing by just adding a few lines of code.
|
||||
|
||||
## Creating custom spans on top of auto-instrumentation
|
||||
Additionally to automated instrumentation, `NodeTracer` exposes the same API as [@opentelemetry/tracing](https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-tracing), allowing creating custom spans if needed.
|
||||
Additionally to automated instrumentation, `NodeTracerRegistry` exposes the same API as [@opentelemetry/tracing](https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-tracing), allowing creating custom spans if needed.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -50,14 +50,14 @@ npm install --save @opentelemetry/plugin-https
|
|||
|
||||
## Usage
|
||||
|
||||
The following code will configure the `NodeTracer` to instrument `http` using `@opentelemetry/plugin-http`.
|
||||
The following code will configure the `NodeTracerRegistry` to instrument `http` using `@opentelemetry/plugin-http`.
|
||||
|
||||
```js
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
// Create and configure NodeTracer
|
||||
const tracer = new NodeTracer({
|
||||
// Create and configure NodeTracerRegistry
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
http: {
|
||||
enabled: true,
|
||||
|
@ -68,25 +68,25 @@ const tracer = new NodeTracer({
|
|||
}
|
||||
});
|
||||
|
||||
// Initialize the tracer
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the registry
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
|
||||
// Your application code - http will automatically be instrumented if
|
||||
// @opentelemetry/plugin-http is present
|
||||
const http = require('http');
|
||||
```
|
||||
|
||||
To enable instrumentation for all [supported modules](https://github.com/open-telemetry/opentelemetry-js#plugins), create an instance of `NodeTracer` without providing any plugin configuration to the constructor.
|
||||
To enable instrumentation for all [supported modules](https://github.com/open-telemetry/opentelemetry-js#plugins), create an instance of `NodeTracerRegistry` without providing any plugin configuration to the constructor.
|
||||
|
||||
```js
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
// Create and initialize NodeTracer
|
||||
const tracer = new NodeTracer();
|
||||
// Create and initialize NodeTracerRegistry
|
||||
const registry = new NodeTracerRegistry();
|
||||
|
||||
// Initialize the tracer
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// Initialize the registry
|
||||
opentelemetry.initGlobalTracerRegistry(registry);
|
||||
|
||||
// Your application code
|
||||
// ...
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BasicTracer } from '@opentelemetry/tracing';
|
||||
import { BasicTracerRegistry } from '@opentelemetry/tracing';
|
||||
import { AsyncHooksScopeManager } from '@opentelemetry/scope-async-hooks';
|
||||
import { PluginLoader } from './instrumentation/PluginLoader';
|
||||
import { NodeTracerConfig, DEFAULT_INSTRUMENTATION_PLUGINS } from './config';
|
||||
|
@ -22,7 +22,7 @@ import { NodeTracerConfig, DEFAULT_INSTRUMENTATION_PLUGINS } from './config';
|
|||
/**
|
||||
* This class represents a node tracer with `async_hooks` module.
|
||||
*/
|
||||
export class NodeTracer extends BasicTracer {
|
||||
export class NodeTracerRegistry extends BasicTracerRegistry {
|
||||
private readonly _pluginLoader: PluginLoader;
|
||||
|
||||
/**
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
|
||||
import { Plugins } from './instrumentation/PluginLoader';
|
||||
import { BasicTracerConfig } from '@opentelemetry/tracing';
|
||||
import { TracerConfig } from '@opentelemetry/tracing';
|
||||
|
||||
/**
|
||||
* NodeTracerConfig provides an interface for configuring a Node Tracer.
|
||||
*/
|
||||
export interface NodeTracerConfig extends BasicTracerConfig {
|
||||
export interface NodeTracerConfig extends TracerConfig {
|
||||
/** Plugins options. */
|
||||
plugins?: Plugins;
|
||||
}
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './NodeTracer';
|
||||
export * from './NodeTracerRegistry';
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger, Plugin, Tracer, PluginConfig } from '@opentelemetry/types';
|
||||
import {
|
||||
Logger,
|
||||
Plugin,
|
||||
PluginConfig,
|
||||
TracerRegistry,
|
||||
} from '@opentelemetry/types';
|
||||
import * as hook from 'require-in-the-middle';
|
||||
import * as utils from './utils';
|
||||
|
||||
|
@ -55,7 +60,7 @@ export class PluginLoader {
|
|||
private _hookState = HookState.UNINITIALIZED;
|
||||
|
||||
/** Constructs a new PluginLoader instance. */
|
||||
constructor(readonly tracer: Tracer, readonly logger: Logger) {}
|
||||
constructor(readonly registry: TracerRegistry, readonly logger: Logger) {}
|
||||
|
||||
/**
|
||||
* Loads a list of plugins. Each plugin module should implement the core
|
||||
|
@ -115,7 +120,7 @@ export class PluginLoader {
|
|||
|
||||
this._plugins.push(plugin);
|
||||
// Enable each supported plugin.
|
||||
return plugin.enable(exports, this.tracer, this.logger, config);
|
||||
return plugin.enable(exports, this.registry, this.logger, config);
|
||||
} catch (e) {
|
||||
this.logger.error(
|
||||
`PluginLoader#load: could not load plugin ${modulePath} of module ${name}. Error: ${e.message}`
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
NoopLogger,
|
||||
NoRecordingSpan,
|
||||
} from '@opentelemetry/core';
|
||||
import { NodeTracer } from '../src/NodeTracer';
|
||||
import { NodeTracerRegistry } from '../src/NodeTracerRegistry';
|
||||
import { TraceFlags } from '@opentelemetry/types';
|
||||
import { Span } from '@opentelemetry/tracing';
|
||||
import * as path from 'path';
|
||||
|
@ -39,8 +39,8 @@ const INSTALLED_PLUGINS_PATH = path.join(
|
|||
'node_modules'
|
||||
);
|
||||
|
||||
describe('NodeTracer', () => {
|
||||
let tracer: NodeTracer;
|
||||
describe('NodeTracerRegistry', () => {
|
||||
let registry: NodeTracerRegistry;
|
||||
before(() => {
|
||||
module.paths.push(INSTALLED_PLUGINS_PATH);
|
||||
});
|
||||
|
@ -48,45 +48,45 @@ describe('NodeTracer', () => {
|
|||
afterEach(() => {
|
||||
// clear require cache
|
||||
Object.keys(require.cache).forEach(key => delete require.cache[key]);
|
||||
tracer.stop();
|
||||
registry.stop();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should construct an instance with required only options', () => {
|
||||
tracer = new NodeTracer();
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
registry = new NodeTracerRegistry();
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with binary format', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
binaryFormat: new BinaryTraceContext(),
|
||||
});
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with http text format', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
httpTextFormat: new HttpTraceContext(),
|
||||
});
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with logger', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with sampler', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
sampler: ALWAYS_SAMPLER,
|
||||
});
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
|
||||
it('should load user configured plugins', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
plugins: {
|
||||
'simple-module': {
|
||||
|
@ -102,7 +102,7 @@ describe('NodeTracer', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
const pluginLoader = tracer['_pluginLoader'];
|
||||
const pluginLoader = registry['_pluginLoader'];
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
require('simple-module');
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 1);
|
||||
|
@ -111,39 +111,39 @@ describe('NodeTracer', () => {
|
|||
});
|
||||
|
||||
it('should construct an instance with default attributes', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
defaultAttributes: {
|
||||
region: 'eu-west',
|
||||
asg: 'my-asg',
|
||||
},
|
||||
});
|
||||
assert.ok(tracer instanceof NodeTracer);
|
||||
assert.ok(registry instanceof NodeTracerRegistry);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.startSpan()', () => {
|
||||
it('should start a span with name only', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
const span = tracer.startSpan('my-span');
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
assert.ok(span);
|
||||
});
|
||||
|
||||
it('should start a span with name and options', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
const span = tracer.startSpan('my-span', {});
|
||||
const span = registry.getTracer('default').startSpan('my-span', {});
|
||||
assert.ok(span);
|
||||
});
|
||||
|
||||
it('should return a default span with no sampling', () => {
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
const span = tracer.startSpan('my-span');
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
assert.ok(span instanceof NoRecordingSpan);
|
||||
assert.strictEqual(span.context().traceFlags, TraceFlags.UNSAMPLED);
|
||||
assert.strictEqual(span.isRecording(), false);
|
||||
|
@ -156,11 +156,11 @@ describe('NodeTracer', () => {
|
|||
const defaultAttributes = {
|
||||
foo: 'bar',
|
||||
};
|
||||
tracer = new NodeTracer({
|
||||
registry = new NodeTracerRegistry({
|
||||
defaultAttributes,
|
||||
});
|
||||
|
||||
const span = tracer.startSpan('my-span') as Span;
|
||||
const span = registry.getTracer('default').startSpan('my-span') as Span;
|
||||
assert.ok(span instanceof Span);
|
||||
assert.deepStrictEqual(span.attributes, defaultAttributes);
|
||||
});
|
||||
|
@ -168,32 +168,48 @@ describe('NodeTracer', () => {
|
|||
|
||||
describe('.getCurrentSpan()', () => {
|
||||
it('should return undefined with AsyncHooksScopeManager when no span started', () => {
|
||||
tracer = new NodeTracer({});
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
registry = new NodeTracerRegistry({});
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.withSpan()', () => {
|
||||
it('should run scope with AsyncHooksScopeManager scope manager', done => {
|
||||
tracer = new NodeTracer({});
|
||||
const span = tracer.startSpan('my-span');
|
||||
tracer.withSpan(span, () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), span);
|
||||
registry = new NodeTracerRegistry({});
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
span
|
||||
);
|
||||
return done();
|
||||
});
|
||||
// @todo: below check is not running.
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('should run scope with AsyncHooksScopeManager scope manager with multiple spans', done => {
|
||||
tracer = new NodeTracer({});
|
||||
const span = tracer.startSpan('my-span');
|
||||
tracer.withSpan(span, () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), span);
|
||||
registry = new NodeTracerRegistry({});
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
span
|
||||
);
|
||||
|
||||
const span1 = tracer.startSpan('my-span1', { parent: span });
|
||||
tracer.withSpan(span1, () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), span1);
|
||||
const span1 = registry
|
||||
.getTracer('default')
|
||||
.startSpan('my-span1', { parent: span });
|
||||
registry.getTracer('default').withSpan(span1, () => {
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
span1
|
||||
);
|
||||
assert.deepStrictEqual(
|
||||
span1.context().traceId,
|
||||
span.context().traceId
|
||||
|
@ -203,48 +219,66 @@ describe('NodeTracer', () => {
|
|||
});
|
||||
// when span ended.
|
||||
// @todo: below check is not running.
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('should find correct scope with promises', done => {
|
||||
tracer = new NodeTracer({});
|
||||
const span = tracer.startSpan('my-span');
|
||||
tracer.withSpan(span, async () => {
|
||||
registry = new NodeTracerRegistry({});
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
registry.getTracer('default').withSpan(span, async () => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await sleep(5).then(() => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), span);
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
span
|
||||
);
|
||||
});
|
||||
}
|
||||
return done();
|
||||
});
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.bind()', () => {
|
||||
it('should bind scope with AsyncHooksScopeManager scope manager', done => {
|
||||
const tracer = new NodeTracer({});
|
||||
const span = tracer.startSpan('my-span');
|
||||
const registry = new NodeTracerRegistry({});
|
||||
const span = registry.getTracer('default').startSpan('my-span');
|
||||
const fn = () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), span);
|
||||
assert.deepStrictEqual(
|
||||
registry.getTracer('default').getCurrentSpan(),
|
||||
span
|
||||
);
|
||||
return done();
|
||||
};
|
||||
const patchedFn = tracer.bind(fn, span);
|
||||
const patchedFn = registry.getTracer('default').bind(fn, span);
|
||||
return patchedFn();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getBinaryFormat()', () => {
|
||||
it('should get default binary formatter', () => {
|
||||
tracer = new NodeTracer({});
|
||||
assert.ok(tracer.getBinaryFormat() instanceof BinaryTraceContext);
|
||||
registry = new NodeTracerRegistry({});
|
||||
assert.ok(
|
||||
registry.getTracer('default').getBinaryFormat() instanceof
|
||||
BinaryTraceContext
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getHttpTextFormat()', () => {
|
||||
it('should get default HTTP text formatter', () => {
|
||||
tracer = new NodeTracer({});
|
||||
assert.ok(tracer.getHttpTextFormat() instanceof HttpTraceContext);
|
||||
registry = new NodeTracerRegistry({});
|
||||
assert.ok(
|
||||
registry.getTracer('default').getHttpTextFormat() instanceof
|
||||
HttpTraceContext
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NoopLogger, NoopTracer } from '@opentelemetry/core';
|
||||
import { NoopLogger, NoopTracerRegistry } from '@opentelemetry/core';
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
HookState,
|
||||
PluginLoader,
|
||||
searchPathForTest,
|
||||
Plugins,
|
||||
searchPathForTest,
|
||||
} from '../../src/instrumentation/PluginLoader';
|
||||
|
||||
const INSTALLED_PLUGINS_PATH = path.join(__dirname, 'node_modules');
|
||||
|
@ -86,7 +86,7 @@ const notSupportedVersionPlugins: Plugins = {
|
|||
};
|
||||
|
||||
describe('PluginLoader', () => {
|
||||
const tracer = new NoopTracer();
|
||||
const registry = new NoopTracerRegistry();
|
||||
const logger = new NoopLogger();
|
||||
|
||||
before(() => {
|
||||
|
@ -101,19 +101,19 @@ describe('PluginLoader', () => {
|
|||
|
||||
describe('.state()', () => {
|
||||
it('returns UNINITIALIZED when first called', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_hookState'], HookState.UNINITIALIZED);
|
||||
});
|
||||
|
||||
it('transitions from UNINITIALIZED to ENABLED', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
pluginLoader.load(simplePlugins);
|
||||
assert.strictEqual(pluginLoader['_hookState'], HookState.ENABLED);
|
||||
pluginLoader.unload();
|
||||
});
|
||||
|
||||
it('transitions from ENABLED to DISABLED', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
pluginLoader.load(simplePlugins).unload();
|
||||
assert.strictEqual(pluginLoader['_hookState'], HookState.DISABLED);
|
||||
});
|
||||
|
@ -138,7 +138,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it('should load a plugin and patch the target modules', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(simplePlugins);
|
||||
// The hook is only called the first time the module is loaded.
|
||||
|
@ -150,7 +150,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it('should load a plugin and patch the core module', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(httpPlugins);
|
||||
// The hook is only called the first time the module is loaded.
|
||||
|
@ -161,7 +161,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
// @TODO: simplify this test once we can load module with custom path
|
||||
it('should not load the plugin when supported versions does not match', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(notSupportedVersionPlugins);
|
||||
// The hook is only called the first time the module is loaded.
|
||||
|
@ -171,7 +171,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
// @TODO: simplify this test once we can load module with custom path
|
||||
it('should load a plugin and patch the target modules when supported versions match', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(supportedVersionPlugins);
|
||||
// The hook is only called the first time the module is loaded.
|
||||
|
@ -183,7 +183,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it('should not load a plugin when value is false', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(disablePlugins);
|
||||
const simpleModule = require('simple-module');
|
||||
|
@ -194,7 +194,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it('should not load a plugin when value is true but path is missing', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(missingPathPlugins);
|
||||
const simpleModule = require('simple-module');
|
||||
|
@ -205,7 +205,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it('should not load a non existing plugin', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(nonexistentPlugins);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
|
@ -213,7 +213,7 @@ describe('PluginLoader', () => {
|
|||
});
|
||||
|
||||
it(`doesn't patch modules for which plugins aren't specified`, () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
pluginLoader.load({});
|
||||
assert.strictEqual(require('simple-module').value(), 0);
|
||||
pluginLoader.unload();
|
||||
|
@ -222,7 +222,7 @@ describe('PluginLoader', () => {
|
|||
|
||||
describe('.unload()', () => {
|
||||
it('should unload the plugins and unpatch the target module when unloads', () => {
|
||||
const pluginLoader = new PluginLoader(tracer, logger);
|
||||
const pluginLoader = new PluginLoader(registry, logger);
|
||||
assert.strictEqual(pluginLoader['_plugins'].length, 0);
|
||||
pluginLoader.load(simplePlugins);
|
||||
// The hook is only called the first time the module is loaded.
|
||||
|
|
|
@ -18,9 +18,9 @@ npm install --save @opentelemetry/plugin-dns
|
|||
## Usage
|
||||
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
dns: {
|
||||
enabled: true,
|
||||
|
@ -37,7 +37,7 @@ const tracer = new NodeTracer({
|
|||
If you use Zipkin, you must use `ignoreHostnames` in order to not trace those calls. If the server is local. You can set :
|
||||
|
||||
```
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
dns: {
|
||||
enabled: true,
|
||||
|
|
|
@ -14,22 +14,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as shimmer from 'shimmer';
|
||||
import * as semver from 'semver';
|
||||
import * as utils from './utils';
|
||||
import { BasePlugin } from '@opentelemetry/core';
|
||||
import { SpanOptions, SpanKind, Span } from '@opentelemetry/types';
|
||||
import { Span, SpanKind, SpanOptions } from '@opentelemetry/types';
|
||||
import { LookupAddress } from 'dns';
|
||||
import * as semver from 'semver';
|
||||
import * as shimmer from 'shimmer';
|
||||
import { AddressFamily } from './enums/AddressFamily';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import {
|
||||
Dns,
|
||||
LookupPromiseSignature,
|
||||
DnsPluginConfig,
|
||||
LookupCallbackSignature,
|
||||
LookupFunction,
|
||||
LookupFunctionSignature,
|
||||
LookupCallbackSignature,
|
||||
DnsPluginConfig,
|
||||
LookupPromiseSignature,
|
||||
} from './types';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import { AddressFamily } from './enums/AddressFamily';
|
||||
import { LookupAddress } from 'dns';
|
||||
import * as utils from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
/**
|
||||
* Dns instrumentation plugin for Opentelemetry
|
||||
|
@ -39,7 +40,7 @@ export class DnsPlugin extends BasePlugin<Dns> {
|
|||
protected _config!: DnsPluginConfig;
|
||||
|
||||
constructor(readonly moduleName: string, readonly version: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-dns', VERSION);
|
||||
// For now component is equal to moduleName but it can change in the future.
|
||||
this.component = this.moduleName;
|
||||
this._config = {};
|
||||
|
|
|
@ -20,19 +20,20 @@ import {
|
|||
} from '@opentelemetry/tracing';
|
||||
import * as assert from 'assert';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin } from '../../src/dns';
|
||||
import * as sinon from 'sinon';
|
||||
import * as dns from 'dns';
|
||||
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
const tracer = registry.getTracer('default');
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
describe('DnsPlugin', () => {
|
||||
before(() => {
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, tracer.logger);
|
||||
assert.strictEqual(dns.lookup.__wrapped, true);
|
||||
});
|
||||
|
||||
|
|
|
@ -20,18 +20,18 @@ import {
|
|||
} from '@opentelemetry/tracing';
|
||||
import * as assert from 'assert';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin, DnsPlugin } from '../../src/dns';
|
||||
import * as dns from 'dns';
|
||||
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
describe('DnsPlugin', () => {
|
||||
before(() => {
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, registry.logger);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { BasicTracerRegistry, Span } from '@opentelemetry/tracing';
|
||||
import { CanonicalCode, SpanKind } from '@opentelemetry/types';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { CanonicalCode, SpanKind } from '@opentelemetry/types';
|
||||
import { AttributeNames } from '../../src/enums/AttributeNames';
|
||||
import { IgnoreMatcher } from '../../src/types';
|
||||
import * as utils from '../../src/utils';
|
||||
import { Span, BasicTracer } from '@opentelemetry/tracing';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { AttributeNames } from '../../src/enums/AttributeNames';
|
||||
|
||||
describe('Utility', () => {
|
||||
describe('parseResponseStatus()', () => {
|
||||
|
@ -162,7 +162,7 @@ describe('Utility', () => {
|
|||
it('should have error attributes', () => {
|
||||
const errorMessage = 'test error';
|
||||
const span = new Span(
|
||||
new BasicTracer(),
|
||||
new BasicTracerRegistry().getTracer('default'),
|
||||
'test',
|
||||
{ spanId: '', traceId: '' },
|
||||
SpanKind.INTERNAL
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from '@opentelemetry/tracing';
|
||||
import * as assert from 'assert';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin } from '../../src/dns';
|
||||
import * as dns from 'dns';
|
||||
import * as utils from '../utils/utils';
|
||||
|
@ -29,14 +29,14 @@ import { CanonicalCode } from '@opentelemetry/types';
|
|||
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
describe('dns.lookup()', () => {
|
||||
before(function(done) {
|
||||
// mandatory
|
||||
if (process.env.CI) {
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, registry.logger);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ describe('dns.lookup()', () => {
|
|||
}
|
||||
done();
|
||||
});
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, registry.logger);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from '@opentelemetry/tracing';
|
||||
import * as assert from 'assert';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin } from '../../src/dns';
|
||||
import * as dns from 'dns';
|
||||
import * as utils from '../utils/utils';
|
||||
|
@ -30,8 +30,8 @@ import { CanonicalCode } from '@opentelemetry/types';
|
|||
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
describe('dns.promises.lookup()', () => {
|
||||
before(function(done) {
|
||||
|
@ -42,7 +42,7 @@ describe('dns.promises.lookup()', () => {
|
|||
|
||||
// if node version is supported, it's mandatory for CI
|
||||
if (process.env.CI) {
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, registry.logger);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ describe('dns.promises.lookup()', () => {
|
|||
}
|
||||
done();
|
||||
});
|
||||
plugin.enable(dns, tracer, tracer.logger);
|
||||
plugin.enable(dns, registry, registry.logger);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
@ -21,7 +21,6 @@ import {
|
|||
TRACE_PARENT_HEADER,
|
||||
} from '@opentelemetry/core';
|
||||
import { PluginConfig, Span, SpanOptions } from '@opentelemetry/types';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import {
|
||||
addSpanNetworkEvent,
|
||||
hasKey,
|
||||
|
@ -29,6 +28,8 @@ import {
|
|||
PerformanceLegacy,
|
||||
PerformanceTimingNames as PTN,
|
||||
} from '@opentelemetry/web';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import { VERSION } from './version';
|
||||
|
||||
/**
|
||||
* This class represents a document load plugin
|
||||
|
@ -44,7 +45,7 @@ export class DocumentLoad extends BasePlugin<unknown> {
|
|||
* @param config
|
||||
*/
|
||||
constructor(config: PluginConfig = {}) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-document-load', VERSION);
|
||||
this._onDocumentLoaded = this._onDocumentLoaded.bind(this);
|
||||
this._config = config;
|
||||
}
|
||||
|
|
|
@ -18,18 +18,16 @@
|
|||
* Can't use Sinon Fake Time here as then cannot stub the performance getEntriesByType with desired metrics
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
|
||||
import { ConsoleLogger, TRACE_PARENT_HEADER } from '@opentelemetry/core';
|
||||
import {
|
||||
BasicTracer,
|
||||
BasicTracerRegistry,
|
||||
ReadableSpan,
|
||||
SimpleSpanProcessor,
|
||||
SpanExporter,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { Logger, PluginConfig, TimedEvent } from '@opentelemetry/types';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { ExportResult } from '../../opentelemetry-base/build/src';
|
||||
import { DocumentLoad } from '../src';
|
||||
import { PerformanceTimingNames as PTN } from '@opentelemetry/web';
|
||||
|
@ -193,7 +191,7 @@ function ensureNetworkEventsExists(events: TimedEvent[]) {
|
|||
describe('DocumentLoad Plugin', () => {
|
||||
let plugin: DocumentLoad;
|
||||
let moduleExports: any;
|
||||
let tracer: BasicTracer;
|
||||
let registry: BasicTracerRegistry;
|
||||
let logger: Logger;
|
||||
let config: PluginConfig;
|
||||
let spanProcessor: SimpleSpanProcessor;
|
||||
|
@ -205,13 +203,13 @@ describe('DocumentLoad Plugin', () => {
|
|||
value: 'complete',
|
||||
});
|
||||
moduleExports = {};
|
||||
tracer = new BasicTracer();
|
||||
registry = new BasicTracerRegistry();
|
||||
logger = new ConsoleLogger();
|
||||
config = {};
|
||||
plugin = new DocumentLoad();
|
||||
dummyExporter = new DummyExporter();
|
||||
spanProcessor = new SimpleSpanProcessor(dummyExporter);
|
||||
tracer.addSpanProcessor(spanProcessor);
|
||||
registry.addSpanProcessor(spanProcessor);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -239,7 +237,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
spyEntries.restore();
|
||||
});
|
||||
it('should start collecting the performance immediately', done => {
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
assert.strictEqual(window.document.readyState, 'complete');
|
||||
assert.strictEqual(spyEntries.callCount, 2);
|
||||
|
@ -266,7 +264,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
it('should collect performance after document load event', done => {
|
||||
const spy = sinon.spy(window, 'addEventListener');
|
||||
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
const args = spy.args[0];
|
||||
const name = args[0];
|
||||
assert.strictEqual(name, 'load');
|
||||
|
@ -301,7 +299,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should export correct span with events', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
|
||||
setTimeout(() => {
|
||||
const rootSpan = spyOnEnd.args[0][0][0] as ReadableSpan;
|
||||
|
@ -358,7 +356,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should create a root span with server context traceId', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
const rootSpan = spyOnEnd.args[0][0][0] as ReadableSpan;
|
||||
const fetchSpan = spyOnEnd.args[1][0][0] as ReadableSpan;
|
||||
|
@ -394,7 +392,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should create span for each of the resource', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
const spanResource1 = spyOnEnd.args[1][0][0] as ReadableSpan;
|
||||
const spanResource2 = spyOnEnd.args[2][0][0] as ReadableSpan;
|
||||
|
@ -432,7 +430,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should create span for each of the resource', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
const spanResource1 = spyOnEnd.args[1][0][0] as ReadableSpan;
|
||||
|
||||
|
@ -473,7 +471,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should still export rootSpan and fetchSpan', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
|
||||
setTimeout(() => {
|
||||
const rootSpan = spyOnEnd.args[0][0][0] as ReadableSpan;
|
||||
|
@ -505,7 +503,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should export correct span with events', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
const rootSpan = spyOnEnd.args[0][0][0] as ReadableSpan;
|
||||
const fetchSpan = spyOnEnd.args[1][0][0] as ReadableSpan;
|
||||
|
@ -553,7 +551,7 @@ describe('DocumentLoad Plugin', () => {
|
|||
|
||||
it('should not create any span', done => {
|
||||
const spyOnEnd = sinon.spy(dummyExporter, 'export');
|
||||
plugin.enable(moduleExports, tracer, logger, config);
|
||||
plugin.enable(moduleExports, registry, logger, config);
|
||||
setTimeout(() => {
|
||||
assert.ok(spyOnEnd.callCount === 0);
|
||||
done();
|
||||
|
|
|
@ -22,9 +22,9 @@ OpenTelemetry gRPC Instrumentation allows the user to automatically collect trac
|
|||
|
||||
To load a specific plugin (**gRPC** in this case), specify it in the Node Tracer's configuration.
|
||||
```javascript
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
grpc: {
|
||||
enabled: true,
|
||||
|
@ -37,9 +37,9 @@ const tracer = new NodeTracer({
|
|||
|
||||
To load all the [supported plugins](https://github.com/open-telemetry/opentelemetry-js#plugins), use below approach. Each plugin is only loaded when the module that it patches is loaded; in other words, there is no computational overhead for listing plugins for unused modules.
|
||||
```javascript
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
```
|
||||
|
||||
See [examples/grpc](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/grpc) for a short example.
|
||||
|
|
|
@ -16,33 +16,33 @@
|
|||
|
||||
import { BasePlugin } from '@opentelemetry/core';
|
||||
import {
|
||||
CanonicalCode,
|
||||
Span,
|
||||
SpanContext,
|
||||
SpanKind,
|
||||
SpanOptions,
|
||||
Span,
|
||||
Status,
|
||||
CanonicalCode,
|
||||
SpanContext,
|
||||
} from '@opentelemetry/types';
|
||||
import * as events from 'events';
|
||||
import * as grpcTypes from 'grpc';
|
||||
import * as path from 'path';
|
||||
import * as shimmer from 'shimmer';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import {
|
||||
grpc,
|
||||
ModuleExportsMapping,
|
||||
GrpcPluginOptions,
|
||||
ServerCallWithMeta,
|
||||
SendUnaryDataCallback,
|
||||
GrpcClientFunc,
|
||||
GrpcInternalClientTypes,
|
||||
GrpcPluginOptions,
|
||||
ModuleExportsMapping,
|
||||
SendUnaryDataCallback,
|
||||
ServerCallWithMeta,
|
||||
} from './types';
|
||||
import {
|
||||
findIndex,
|
||||
_grpcStatusCodeToCanonicalCode,
|
||||
_grpcStatusCodeToSpanStatus,
|
||||
} from './utils';
|
||||
|
||||
import * as events from 'events';
|
||||
import * as grpcTypes from 'grpc';
|
||||
import * as shimmer from 'shimmer';
|
||||
import * as path from 'path';
|
||||
import { VERSION } from './version';
|
||||
|
||||
/** The metadata key under which span context is stored as a binary value. */
|
||||
export const GRPC_TRACE_KEY = 'grpc-trace-bin';
|
||||
|
@ -56,7 +56,7 @@ export class GrpcPlugin extends BasePlugin<grpc> {
|
|||
protected _config!: GrpcPluginOptions;
|
||||
|
||||
constructor(readonly moduleName: string, readonly version: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-grpc', VERSION);
|
||||
this._config = {};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,22 +14,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NoopLogger, NoopTracer } from '@opentelemetry/core';
|
||||
import { NoopLogger, NoopTracerRegistry } from '@opentelemetry/core';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { SpanKind, Tracer } from '@opentelemetry/types';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
|
||||
import { assertSpan, assertPropagation } from './utils/assertionUtils';
|
||||
import { SpanKind } from '@opentelemetry/types';
|
||||
import * as assert from 'assert';
|
||||
import * as grpc from 'grpc';
|
||||
import * as semver from 'semver';
|
||||
import * as sinon from 'sinon';
|
||||
import { GrpcPlugin, plugin } from '../src';
|
||||
import { SendUnaryDataCallback } from '../src/types';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as semver from 'semver';
|
||||
import * as grpc from 'grpc';
|
||||
import * as sinon from 'sinon';
|
||||
import { assertPropagation, assertSpan } from './utils/assertionUtils';
|
||||
|
||||
const PROTO_PATH = __dirname + '/fixtures/grpc-test.proto';
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
|
@ -318,7 +316,7 @@ describe('GrpcPlugin', () => {
|
|||
});
|
||||
|
||||
it('should patch client constructor makeClientConstructor() and makeGenericClientConstructor()', () => {
|
||||
plugin.enable(grpc, new NoopTracer(), new NoopLogger());
|
||||
plugin.enable(grpc, new NoopTracerRegistry(), new NoopLogger());
|
||||
(plugin['_moduleExports'] as any).makeGenericClientConstructor({});
|
||||
assert.strictEqual(clientPatchStub.callCount, 1);
|
||||
});
|
||||
|
@ -370,7 +368,7 @@ describe('GrpcPlugin', () => {
|
|||
|
||||
const runTest = (
|
||||
method: typeof methodList[0],
|
||||
tracer: Tracer,
|
||||
registry: NodeTracerRegistry,
|
||||
checkSpans = true
|
||||
) => {
|
||||
it(`should ${
|
||||
|
@ -410,9 +408,11 @@ describe('GrpcPlugin', () => {
|
|||
const expectEmpty = memoryExporter.getFinishedSpans();
|
||||
assert.strictEqual(expectEmpty.length, 0);
|
||||
|
||||
const span = tracer.startSpan('TestSpan', { kind: SpanKind.PRODUCER });
|
||||
return tracer.withSpan(span, async () => {
|
||||
const rootSpan = tracer.getCurrentSpan();
|
||||
const span = registry
|
||||
.getTracer('default')
|
||||
.startSpan('TestSpan', { kind: SpanKind.PRODUCER });
|
||||
return registry.getTracer('default').withSpan(span, async () => {
|
||||
const rootSpan = registry.getTracer('default').getCurrentSpan();
|
||||
if (!rootSpan) {
|
||||
assert.ok(false);
|
||||
return; // return so typechecking passes for rootSpan.end()
|
||||
|
@ -465,7 +465,7 @@ describe('GrpcPlugin', () => {
|
|||
method: typeof methodList[0],
|
||||
key: string,
|
||||
errorCode: number,
|
||||
tracer: Tracer
|
||||
registry: NodeTracerRegistry
|
||||
) => {
|
||||
it(`should raise an error for client/server rootSpans: method=${method.methodName}, status=${key}`, async () => {
|
||||
const expectEmpty = memoryExporter.getFinishedSpans();
|
||||
|
@ -503,9 +503,11 @@ describe('GrpcPlugin', () => {
|
|||
const expectEmpty = memoryExporter.getFinishedSpans();
|
||||
assert.strictEqual(expectEmpty.length, 0);
|
||||
|
||||
const span = tracer.startSpan('TestSpan', { kind: SpanKind.PRODUCER });
|
||||
return tracer.withSpan(span, async () => {
|
||||
const rootSpan = tracer.getCurrentSpan();
|
||||
const span = registry
|
||||
.getTracer('default')
|
||||
.startSpan('TestSpan', { kind: SpanKind.PRODUCER });
|
||||
return registry.getTracer('default').withSpan(span, async () => {
|
||||
const rootSpan = registry.getTracer('default').getCurrentSpan();
|
||||
if (!rootSpan) {
|
||||
assert.ok(false);
|
||||
return; // return so typechecking passes for rootSpan.end()
|
||||
|
@ -552,8 +554,8 @@ describe('GrpcPlugin', () => {
|
|||
|
||||
describe('enable()', () => {
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
@ -562,7 +564,7 @@ describe('GrpcPlugin', () => {
|
|||
const config = {
|
||||
// TODO: add plugin options here once supported
|
||||
};
|
||||
plugin.enable(grpc, tracer, logger, config);
|
||||
plugin.enable(grpc, registry, logger, config);
|
||||
|
||||
const proto = grpc.load(PROTO_PATH).pkg_test;
|
||||
server = startServer(grpc, proto);
|
||||
|
@ -579,7 +581,7 @@ describe('GrpcPlugin', () => {
|
|||
|
||||
methodList.forEach(method => {
|
||||
describe(`Test automatic tracing for grpc remote method ${method.description}`, () => {
|
||||
runTest(method, tracer);
|
||||
runTest(method, registry);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -589,7 +591,7 @@ describe('GrpcPlugin', () => {
|
|||
// tslint:disable-next-line:no-any
|
||||
const errorCode = Number(grpc.status[statusKey as any]);
|
||||
if (errorCode > grpc.status.OK) {
|
||||
runErrorTest(method, statusKey, errorCode, tracer);
|
||||
runErrorTest(method, statusKey, errorCode, registry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -598,14 +600,14 @@ describe('GrpcPlugin', () => {
|
|||
|
||||
describe('disable()', () => {
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({ logger });
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new NodeTracerRegistry({ logger });
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
||||
before(() => {
|
||||
plugin.enable(grpc, tracer, logger);
|
||||
plugin.enable(grpc, registry, logger);
|
||||
plugin.disable();
|
||||
|
||||
const proto = grpc.load(PROTO_PATH).pkg_test;
|
||||
|
@ -622,7 +624,7 @@ describe('GrpcPlugin', () => {
|
|||
|
||||
methodList.map(method => {
|
||||
describe(`Test automatic tracing for grpc remote method ${method.description}`, () => {
|
||||
runTest(method, tracer, false);
|
||||
runTest(method, registry, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,9 +22,9 @@ OpenTelemetry HTTP Instrumentation allows the user to automatically collect trac
|
|||
|
||||
To load a specific plugin (HTTP in this case), specify it in the Node Tracer's configuration.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
http: {
|
||||
enabled: true,
|
||||
|
@ -38,9 +38,9 @@ const tracer = new NodeTracer({
|
|||
|
||||
To load all the [supported plugins](https://github.com/open-telemetry/opentelemetry-js#plugins), use below approach. Each plugin is only loaded when the module that it patches is loaded; in other words, there is no computational overhead for listing plugins for unused modules.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
```
|
||||
|
||||
See [examples/http](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/http) for a short example.
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
import { BasePlugin, isValid } from '@opentelemetry/core';
|
||||
import {
|
||||
CanonicalCode,
|
||||
Span,
|
||||
SpanKind,
|
||||
SpanOptions,
|
||||
CanonicalCode,
|
||||
Status,
|
||||
} from '@opentelemetry/types';
|
||||
import {
|
||||
|
@ -29,22 +29,23 @@ import {
|
|||
RequestOptions,
|
||||
ServerResponse,
|
||||
} from 'http';
|
||||
import { Socket } from 'net';
|
||||
import * as semver from 'semver';
|
||||
import * as shimmer from 'shimmer';
|
||||
import * as url from 'url';
|
||||
import {
|
||||
HttpPluginConfig,
|
||||
Http,
|
||||
Func,
|
||||
ResponseEndArgs,
|
||||
ParsedRequestOptions,
|
||||
HttpRequestArgs,
|
||||
Err,
|
||||
} from './types';
|
||||
import { Format } from './enums/Format';
|
||||
import { AttributeNames } from './enums/AttributeNames';
|
||||
import { Format } from './enums/Format';
|
||||
import {
|
||||
Err,
|
||||
Func,
|
||||
Http,
|
||||
HttpPluginConfig,
|
||||
HttpRequestArgs,
|
||||
ParsedRequestOptions,
|
||||
ResponseEndArgs,
|
||||
} from './types';
|
||||
import * as utils from './utils';
|
||||
import { Socket } from 'net';
|
||||
import { VERSION } from './version';
|
||||
|
||||
/**
|
||||
* Http instrumentation plugin for Opentelemetry
|
||||
|
@ -56,7 +57,7 @@ export class HttpPlugin extends BasePlugin<Http> {
|
|||
private readonly _spanNotEnded: WeakSet<Span>;
|
||||
|
||||
constructor(readonly moduleName: string, readonly version: string) {
|
||||
super();
|
||||
super(`@opentelemetry/plugin-${moduleName}`, VERSION);
|
||||
// For now component is equal to moduleName but it can change in the future.
|
||||
this.component = this.moduleName;
|
||||
this._spanNotEnded = new WeakSet<Span>();
|
||||
|
|
|
@ -20,10 +20,12 @@ import * as nock from 'nock';
|
|||
import * as sinon from 'sinon';
|
||||
|
||||
import { plugin } from '../../src/http';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import {
|
||||
NoopLogger,
|
||||
NoopTracerRegistry,
|
||||
noopTracer,
|
||||
} from '@opentelemetry/core';
|
||||
import { AddressInfo } from 'net';
|
||||
import { DummyPropagation } from '../utils/DummyPropagation';
|
||||
import { httpRequest } from '../utils/httpRequest';
|
||||
|
||||
describe('HttpPlugin', () => {
|
||||
|
@ -31,17 +33,13 @@ describe('HttpPlugin', () => {
|
|||
let serverPort = 0;
|
||||
|
||||
describe('disable()', () => {
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
const registry = new NoopTracerRegistry();
|
||||
before(() => {
|
||||
nock.cleanAll();
|
||||
nock.enableNetConnect();
|
||||
|
||||
plugin.enable(http, tracer, tracer.logger);
|
||||
plugin.enable(http, registry, logger);
|
||||
// Ensure that http module is patched.
|
||||
assert.strictEqual(http.Server.prototype.emit.__wrapped, true);
|
||||
server = http.createServer((request, response) => {
|
||||
|
@ -55,8 +53,8 @@ describe('HttpPlugin', () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
tracer.startSpan = sinon.spy();
|
||||
tracer.withSpan = sinon.spy();
|
||||
noopTracer.startSpan = sinon.spy();
|
||||
noopTracer.withSpan = sinon.spy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -67,7 +65,7 @@ describe('HttpPlugin', () => {
|
|||
server.close();
|
||||
});
|
||||
describe('unpatch()', () => {
|
||||
it('should not call tracer methods for creating span', async () => {
|
||||
it('should not call registry methods for creating span', async () => {
|
||||
plugin.disable();
|
||||
const testPath = '/incoming/unpatch/';
|
||||
|
||||
|
@ -75,12 +73,15 @@ describe('HttpPlugin', () => {
|
|||
|
||||
await httpRequest.get(options).then(result => {
|
||||
assert.strictEqual(
|
||||
(tracer.startSpan as sinon.SinonSpy).called,
|
||||
(noopTracer.startSpan as sinon.SinonSpy).called,
|
||||
false
|
||||
);
|
||||
|
||||
assert.strictEqual(http.Server.prototype.emit.__wrapped, undefined);
|
||||
assert.strictEqual((tracer.withSpan as sinon.SinonSpy).called, false);
|
||||
assert.strictEqual(
|
||||
(noopTracer.withSpan as sinon.SinonSpy).called,
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { CanonicalCode, Span as ISpan, SpanKind } from '@opentelemetry/types';
|
||||
import * as assert from 'assert';
|
||||
import * as http from 'http';
|
||||
|
@ -45,11 +45,11 @@ const serverName = 'my.server.name';
|
|||
const memoryExporter = new InMemorySpanExporter();
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
function doNock(
|
||||
hostname: string,
|
||||
|
@ -109,7 +109,7 @@ describe('HttpPlugin', () => {
|
|||
plugin.component,
|
||||
process.versions.node
|
||||
);
|
||||
pluginWithBadOptions.enable(http, tracer, tracer.logger, config);
|
||||
pluginWithBadOptions.enable(http, registry, registry.logger, config);
|
||||
server = http.createServer((request, response) => {
|
||||
response.end('Test Server Response');
|
||||
});
|
||||
|
@ -187,7 +187,7 @@ describe('HttpPlugin', () => {
|
|||
applyCustomAttributesOnSpan: customAttributeFunction,
|
||||
serverName,
|
||||
};
|
||||
plugin.enable(http, tracer, tracer.logger, config);
|
||||
plugin.enable(http, registry, registry.logger, config);
|
||||
server = http.createServer((request, response) => {
|
||||
response.end('Test Server Response');
|
||||
});
|
||||
|
@ -208,7 +208,7 @@ describe('HttpPlugin', () => {
|
|||
const httpNotPatched = new HttpPlugin(
|
||||
plugin.component,
|
||||
process.versions.node
|
||||
).enable({} as Http, tracer, tracer.logger, {});
|
||||
).enable({} as Http, registry, registry.logger, {});
|
||||
assert.strictEqual(Object.keys(httpNotPatched).length, 0);
|
||||
});
|
||||
|
||||
|
@ -323,8 +323,8 @@ describe('HttpPlugin', () => {
|
|||
const testPath = '/outgoing/rootSpan/childs/1';
|
||||
doNock(hostname, testPath, 200, 'Ok');
|
||||
const name = 'TestRootSpan';
|
||||
const span = tracer.startSpan(name);
|
||||
return tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('default').startSpan(name);
|
||||
return registry.getTracer('default').withSpan(span, async () => {
|
||||
const result = await httpRequest.get(
|
||||
`${protocol}://${hostname}${testPath}`
|
||||
);
|
||||
|
@ -366,8 +366,8 @@ describe('HttpPlugin', () => {
|
|||
httpErrorCodes[i].toString()
|
||||
);
|
||||
const name = 'TestRootSpan';
|
||||
const span = tracer.startSpan(name);
|
||||
return tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('default').startSpan(name);
|
||||
return registry.getTracer('default').withSpan(span, async () => {
|
||||
const result = await httpRequest.get(
|
||||
`${protocol}://${hostname}${testPath}`
|
||||
);
|
||||
|
@ -405,8 +405,8 @@ describe('HttpPlugin', () => {
|
|||
const num = 5;
|
||||
doNock(hostname, testPath, 200, 'Ok', num);
|
||||
const name = 'TestRootSpan';
|
||||
const span = tracer.startSpan(name);
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('default').startSpan(name);
|
||||
await registry.getTracer('default').withSpan(span, async () => {
|
||||
for (let i = 0; i < num; i++) {
|
||||
await httpRequest.get(`${protocol}://${hostname}${testPath}`);
|
||||
const spans = memoryExporter.getFinishedSpans();
|
||||
|
|
|
@ -28,7 +28,7 @@ import * as superagent from 'superagent';
|
|||
import * as got from 'got';
|
||||
import * as request from 'request-promise-native';
|
||||
import * as path from 'path';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -45,11 +45,11 @@ describe('Packages', () => {
|
|||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
@ -58,7 +58,7 @@ describe('Packages', () => {
|
|||
const config: HttpPluginConfig = {
|
||||
applyCustomAttributesOnSpan: customAttributeFunction,
|
||||
};
|
||||
plugin.enable(http, tracer, tracer.logger, config);
|
||||
plugin.enable(http, registry, registry.logger, config);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -22,7 +22,7 @@ import { NoopScopeManager } from '@opentelemetry/scope-base';
|
|||
import { IgnoreMatcher } from '../../src/types';
|
||||
import * as utils from '../../src/utils';
|
||||
import * as http from 'http';
|
||||
import { Span, BasicTracer } from '@opentelemetry/tracing';
|
||||
import { Span, BasicTracerRegistry } from '@opentelemetry/tracing';
|
||||
import { AttributeNames } from '../../src';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
|
||||
|
@ -248,9 +248,9 @@ describe('Utility', () => {
|
|||
const errorMessage = 'test error';
|
||||
for (const obj of [undefined, { statusCode: 400 }]) {
|
||||
const span = new Span(
|
||||
new BasicTracer({
|
||||
new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
}),
|
||||
}).getTracer('default'),
|
||||
'test',
|
||||
{ spanId: '', traceId: '' },
|
||||
SpanKind.INTERNAL
|
||||
|
|
|
@ -24,7 +24,7 @@ import { DummyPropagation } from '../utils/DummyPropagation';
|
|||
import { httpRequest } from '../utils/httpRequest';
|
||||
import * as url from 'url';
|
||||
import * as utils from '../utils/utils';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -60,11 +60,11 @@ describe('HttpPlugin Integration tests', () => {
|
|||
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ describe('HttpPlugin Integration tests', () => {
|
|||
try {
|
||||
plugin.disable();
|
||||
} catch (e) {}
|
||||
plugin.enable(http, tracer, tracer.logger, config);
|
||||
plugin.enable(http, registry, registry.logger, config);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -22,9 +22,9 @@ OpenTelemetry HTTPS Instrumentation allows the user to automatically collect tra
|
|||
|
||||
To load a specific plugin (HTTPS in this case), specify it in the Node Tracer's configuration.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
https: {
|
||||
enabled: true,
|
||||
|
@ -38,9 +38,9 @@ const tracer = new NodeTracer({
|
|||
|
||||
To load all the [supported plugins](https://github.com/open-telemetry/opentelemetry-js#plugins), use below approach. Each plugin is only loaded when the module that it patches is loaded; in other words, there is no computational overhead for listing plugins for unused modules.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
```
|
||||
|
||||
See [examples/https](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/https) for a short example.
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { Http } from '@opentelemetry/plugin-http';
|
||||
import * as assert from 'assert';
|
||||
import * as fs from 'fs';
|
||||
import * as https from 'https';
|
||||
import { AddressInfo } from 'net';
|
||||
import * as nock from 'nock';
|
||||
import * as sinon from 'sinon';
|
||||
|
||||
import { plugin } from '../../src/https';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { Http } from '@opentelemetry/plugin-http';
|
||||
import { AddressInfo } from 'net';
|
||||
import { DummyPropagation } from '../utils/DummyPropagation';
|
||||
import { httpsRequest } from '../utils/httpsRequest';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import * as types from '@opentelemetry/types';
|
||||
|
||||
describe('HttpsPlugin', () => {
|
||||
let server: https.Server;
|
||||
|
@ -35,15 +35,18 @@ describe('HttpsPlugin', () => {
|
|||
describe('disable()', () => {
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
// const tracer = registry.getTracer('test-https')
|
||||
let tracer: types.Tracer;
|
||||
before(() => {
|
||||
nock.cleanAll();
|
||||
nock.enableNetConnect();
|
||||
|
||||
plugin.enable((https as unknown) as Http, tracer, tracer.logger);
|
||||
plugin.enable((https as unknown) as Http, registry, registry.logger);
|
||||
tracer = plugin['_tracer'];
|
||||
// Ensure that https module is patched.
|
||||
assert.strictEqual(https.Server.prototype.emit.__wrapped, true);
|
||||
server = https.createServer(
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
Http,
|
||||
HttpPluginConfig,
|
||||
|
@ -50,11 +50,12 @@ const pathname = '/test';
|
|||
const memoryExporter = new InMemorySpanExporter();
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const tracer = registry.getTracer('test-https');
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
function doNock(
|
||||
hostname: string,
|
||||
|
@ -113,7 +114,7 @@ describe('HttpsPlugin', () => {
|
|||
pluginWithBadOptions = new HttpsPlugin(process.versions.node);
|
||||
pluginWithBadOptions.enable(
|
||||
(https as unknown) as Http,
|
||||
tracer,
|
||||
registry,
|
||||
tracer.logger,
|
||||
config
|
||||
);
|
||||
|
@ -202,7 +203,7 @@ describe('HttpsPlugin', () => {
|
|||
};
|
||||
plugin.enable(
|
||||
(https as unknown) as Http,
|
||||
tracer,
|
||||
registry,
|
||||
tracer.logger,
|
||||
config
|
||||
);
|
||||
|
@ -231,7 +232,7 @@ describe('HttpsPlugin', () => {
|
|||
it(`should not patch if it's not a ${protocol} module`, () => {
|
||||
const httpsNotPatched = new HttpsPlugin(process.versions.node).enable(
|
||||
{} as Http,
|
||||
tracer,
|
||||
registry,
|
||||
tracer.logger,
|
||||
{}
|
||||
);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { SpanKind } from '@opentelemetry/types';
|
||||
import { SpanKind, Span } from '@opentelemetry/types';
|
||||
import * as assert from 'assert';
|
||||
import * as https from 'https';
|
||||
import * as http from 'http';
|
||||
|
@ -29,37 +29,35 @@ import * as superagent from 'superagent';
|
|||
import * as got from 'got';
|
||||
import * as request from 'request-promise-native';
|
||||
import * as path from 'path';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
|
||||
import { Http, HttpPluginConfig } from '@opentelemetry/plugin-http';
|
||||
import { customAttributeFunction } from './https-enable.test';
|
||||
import { Http } from '@opentelemetry/plugin-http';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const protocol = 'https';
|
||||
|
||||
export const customAttributeFunction = (span: Span): void => {
|
||||
span.setAttribute('span kind', SpanKind.CLIENT);
|
||||
};
|
||||
|
||||
describe('Packages', () => {
|
||||
describe('get', () => {
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
||||
before(() => {
|
||||
const config: HttpPluginConfig = {
|
||||
applyCustomAttributesOnSpan: customAttributeFunction,
|
||||
};
|
||||
plugin.enable((https as unknown) as Http, tracer, tracer.logger, config);
|
||||
plugin.enable((https as unknown) as Http, registry, registry.logger);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -95,8 +93,8 @@ describe('Packages', () => {
|
|||
// https://github.com/nock/nock/pull/1551
|
||||
// https://github.com/sindresorhus/got/commit/bf1aa5492ae2bc78cbbec6b7d764906fb156e6c2#diff-707a4781d57c42085155dcb27edb9ccbR258
|
||||
// TODO: check if this is still the case when new version
|
||||
`${protocol}://www.google.com`
|
||||
: `${protocol}://www.google.com/search?q=axios&oq=axios&aqs=chrome.0.69i59l2j0l3j69i60.811j0j7&sourceid=chrome&ie=UTF-8`
|
||||
'https://www.google.com'
|
||||
: `https://www.google.com/search?q=axios&oq=axios&aqs=chrome.0.69i59l2j0l3j69i60.811j0j7&sourceid=chrome&ie=UTF-8`
|
||||
);
|
||||
const result = await httpPackage.get(urlparsed.href!);
|
||||
if (!resHeaders) {
|
||||
|
|
|
@ -30,7 +30,7 @@ import { DummyPropagation } from '../utils/DummyPropagation';
|
|||
import { httpsRequest } from '../utils/httpsRequest';
|
||||
import * as url from 'url';
|
||||
import * as utils from '../utils/utils';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -65,11 +65,11 @@ describe('HttpsPlugin Integration tests', () => {
|
|||
|
||||
const httpTextFormat = new DummyPropagation();
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
logger,
|
||||
httpTextFormat,
|
||||
});
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
beforeEach(() => {
|
||||
memoryExporter.reset();
|
||||
});
|
||||
|
@ -88,7 +88,12 @@ describe('HttpsPlugin Integration tests', () => {
|
|||
try {
|
||||
plugin.disable();
|
||||
} catch (e) {}
|
||||
plugin.enable((https as unknown) as Http, tracer, tracer.logger, config);
|
||||
plugin.enable(
|
||||
(https as unknown) as Http,
|
||||
registry,
|
||||
registry.logger,
|
||||
config
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SpanKind, Status } from '@opentelemetry/types';
|
||||
import { SpanKind } from '@opentelemetry/types';
|
||||
import { hrTimeToNanoseconds } from '@opentelemetry/core';
|
||||
import * as assert from 'assert';
|
||||
import * as http from 'http';
|
||||
|
@ -36,7 +36,6 @@ export const assertSpan = (
|
|||
pathname: string;
|
||||
reqHeaders?: http.OutgoingHttpHeaders;
|
||||
path?: string | null;
|
||||
forceStatus?: Status;
|
||||
serverName?: string;
|
||||
component: string;
|
||||
}
|
||||
|
@ -68,13 +67,12 @@ export const assertSpan = (
|
|||
span.attributes[AttributeNames.HTTP_STATUS_CODE],
|
||||
validations.httpStatusCode
|
||||
);
|
||||
|
||||
assert.ok(span.endTime);
|
||||
assert.strictEqual(span.links.length, 0);
|
||||
assert.strictEqual(span.events.length, 0);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
span.status,
|
||||
validations.forceStatus || parseResponseStatus(validations.httpStatusCode)
|
||||
parseResponseStatus(validations.httpStatusCode)
|
||||
);
|
||||
|
||||
assert.ok(span.endTime, 'must be finished');
|
||||
|
|
|
@ -18,6 +18,7 @@ import { BasePlugin } from '@opentelemetry/core';
|
|||
import * as ioredisTypes from 'ioredis';
|
||||
import * as shimmer from 'shimmer';
|
||||
import { traceConnection, traceSendCommand } from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
export class IORedisPlugin extends BasePlugin<typeof ioredisTypes> {
|
||||
static readonly COMPONENT = 'ioredis';
|
||||
|
@ -25,7 +26,7 @@ export class IORedisPlugin extends BasePlugin<typeof ioredisTypes> {
|
|||
readonly supportedVersions = ['^2.0.0'];
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-ioredis', VERSION);
|
||||
}
|
||||
|
||||
protected patch(): typeof ioredisTypes {
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin, IORedisPlugin } from '../src';
|
||||
import * as ioredisTypes from 'ioredis';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
|
@ -49,7 +49,7 @@ const okStatus: Status = {
|
|||
};
|
||||
|
||||
describe('ioredis', () => {
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
let ioredis: typeof ioredisTypes;
|
||||
const shouldTestLocal = process.env.RUN_REDIS_TESTS_LOCAL;
|
||||
const shouldTest = process.env.RUN_REDIS_TESTS || shouldTestLocal;
|
||||
|
@ -68,8 +68,8 @@ describe('ioredis', () => {
|
|||
}
|
||||
|
||||
ioredis = require('ioredis');
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
plugin.enable(ioredis, tracer, new NoopLogger());
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
plugin.enable(ioredis, registry, new NoopLogger());
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -84,7 +84,7 @@ describe('ioredis', () => {
|
|||
|
||||
describe('#createClient()', () => {
|
||||
it('should propagate the current span to event handlers', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
let client: ioredisTypes.Redis;
|
||||
const attributes = {
|
||||
...DEFAULT_ATTRIBUTES,
|
||||
|
@ -93,7 +93,10 @@ describe('ioredis', () => {
|
|||
const readyHandler = () => {
|
||||
const endedSpans = memoryExporter.getFinishedSpans();
|
||||
|
||||
assert.strictEqual(tracer.getCurrentSpan(), span);
|
||||
assert.strictEqual(
|
||||
registry.getTracer('ioredis-test').getCurrentSpan(),
|
||||
span
|
||||
);
|
||||
assert.strictEqual(endedSpans.length, 2);
|
||||
assert.strictEqual(endedSpans[0].name, `connect`);
|
||||
assert.strictEqual(endedSpans[1].name, `info`);
|
||||
|
@ -119,7 +122,7 @@ describe('ioredis', () => {
|
|||
client.quit(done);
|
||||
};
|
||||
|
||||
tracer.withSpan(span, () => {
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
client = new ioredis(URL);
|
||||
client.on('ready', readyHandler);
|
||||
client.on('error', errorHandler);
|
||||
|
@ -183,8 +186,10 @@ describe('ioredis', () => {
|
|||
' '
|
||||
)}`,
|
||||
};
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry
|
||||
.getTracer('ioredis-test')
|
||||
.startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
command.method((err, _result) => {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 1);
|
||||
|
@ -211,8 +216,8 @@ describe('ioredis', () => {
|
|||
...DEFAULT_ATTRIBUTES,
|
||||
[AttributeNames.DB_STATEMENT]: 'hset hash random random',
|
||||
};
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
await registry.getTracer('ioredis-test').withSpan(span, async () => {
|
||||
try {
|
||||
await client.hset('hash', 'random', 'random');
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 1);
|
||||
|
@ -239,8 +244,8 @@ describe('ioredis', () => {
|
|||
...DEFAULT_ATTRIBUTES,
|
||||
[AttributeNames.DB_STATEMENT]: 'scan 0',
|
||||
};
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
const stream = client.scanStream();
|
||||
stream
|
||||
.on('data', resultKeys => {
|
||||
|
@ -275,8 +280,8 @@ describe('ioredis', () => {
|
|||
});
|
||||
|
||||
it('should create a child span for pubsub', async () => {
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
await registry.getTracer('ioredis-test').withSpan(span, async () => {
|
||||
try {
|
||||
const pub = new ioredis(URL);
|
||||
const sub = new ioredis(URL);
|
||||
|
@ -334,8 +339,8 @@ describe('ioredis', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'eval return {KEYS[1],ARGV[1]} 1 test',
|
||||
};
|
||||
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
// This will define a command echo:
|
||||
client.defineCommand('echo', {
|
||||
numberOfKeys: 1,
|
||||
|
@ -372,8 +377,8 @@ describe('ioredis', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'multi',
|
||||
};
|
||||
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
client
|
||||
.multi()
|
||||
.set('foo', 'bar')
|
||||
|
@ -408,8 +413,8 @@ describe('ioredis', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'set foo bar',
|
||||
};
|
||||
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
const pipeline = client.pipeline();
|
||||
pipeline.set('foo', 'bar');
|
||||
pipeline.del('cc');
|
||||
|
@ -441,8 +446,8 @@ describe('ioredis', () => {
|
|||
...DEFAULT_ATTRIBUTES,
|
||||
[AttributeNames.DB_STATEMENT]: 'get test',
|
||||
};
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
await registry.getTracer('ioredis-test').withSpan(span, async () => {
|
||||
try {
|
||||
const value = await client.get('test');
|
||||
assert.strictEqual(value, 'data');
|
||||
|
@ -470,8 +475,8 @@ describe('ioredis', () => {
|
|||
...DEFAULT_ATTRIBUTES,
|
||||
[AttributeNames.DB_STATEMENT]: 'del test',
|
||||
};
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
await registry.getTracer('ioredis-test').withSpan(span, async () => {
|
||||
try {
|
||||
const result = await client.del('test');
|
||||
assert.strictEqual(result, 1);
|
||||
|
@ -502,8 +507,10 @@ describe('ioredis', () => {
|
|||
|
||||
IOREDIS_CALLBACK_OPERATIONS.forEach(operation => {
|
||||
it(`should not create a child span for cb style ${operation.description}`, done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry
|
||||
.getTracer('ioredis-test')
|
||||
.startSpan('test span');
|
||||
registry.getTracer('ioredis-test').withSpan(span, () => {
|
||||
operation.method((err, _) => {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
|
||||
|
@ -518,8 +525,8 @@ describe('ioredis', () => {
|
|||
});
|
||||
|
||||
it('should not create a child span for hset promise upon error', async () => {
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('ioredis-test').startSpan('test span');
|
||||
await registry.getTracer('ioredis-test').withSpan(span, async () => {
|
||||
try {
|
||||
await client.hset('hash', 'random', 'random');
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
|
||||
|
|
|
@ -23,9 +23,9 @@ OpenTelemetry Mongodb Instrumentation allows the user to automatically collect t
|
|||
|
||||
To load a specific plugin (mongodb in this case), specify it in the Node Tracer's configuration.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
mongodb: {
|
||||
enabled: true,
|
||||
|
@ -38,9 +38,9 @@ const tracer = new NodeTracer({
|
|||
|
||||
To load all the [supported plugins](https://github.com/open-telemetry/opentelemetry-js#plugins), use below approach. Each plugin is only loaded when the module that it patches is loaded; in other words, there is no computational overhead for listing plugins for unused modules.
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
```
|
||||
|
||||
See [examples/mongodb](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/mongodb) for a short example.
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
/* tslint:disable:deprecation */
|
||||
|
||||
import { BasePlugin } from '@opentelemetry/core';
|
||||
import { Span, SpanKind, CanonicalCode } from '@opentelemetry/types';
|
||||
import {
|
||||
Func,
|
||||
MongoInternalCommand,
|
||||
MongoInternalTopology,
|
||||
AttributeNames,
|
||||
MongodbCommandType,
|
||||
} from './types';
|
||||
import { CanonicalCode, Span, SpanKind } from '@opentelemetry/types';
|
||||
import * as mongodb from 'mongodb';
|
||||
import * as shimmer from 'shimmer';
|
||||
import {
|
||||
AttributeNames,
|
||||
Func,
|
||||
MongodbCommandType,
|
||||
MongoInternalCommand,
|
||||
MongoInternalTopology,
|
||||
} from './types';
|
||||
import { VERSION } from './version';
|
||||
|
||||
/** MongoDBCore instrumentation plugin for OpenTelemetry */
|
||||
export class MongoDBPlugin extends BasePlugin<typeof mongodb> {
|
||||
|
@ -40,7 +41,7 @@ export class MongoDBPlugin extends BasePlugin<typeof mongodb> {
|
|||
readonly supportedVersions = ['>=2 <4'];
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-mongodb-core', VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +107,7 @@ export class MongoDBPlugin extends BasePlugin<typeof mongodb> {
|
|||
const resultHandler =
|
||||
typeof options === 'function' ? options : callback;
|
||||
if (
|
||||
currentSpan === undefined ||
|
||||
!currentSpan ||
|
||||
typeof resultHandler !== 'function' ||
|
||||
typeof commands !== 'object'
|
||||
) {
|
||||
|
@ -210,7 +211,7 @@ export class MongoDBPlugin extends BasePlugin<typeof mongodb> {
|
|||
): mongodb.Cursor {
|
||||
const currentSpan = plugin._tracer.getCurrentSpan();
|
||||
const resultHandler = args[0];
|
||||
if (currentSpan === undefined || typeof resultHandler !== 'function') {
|
||||
if (!currentSpan || typeof resultHandler !== 'function') {
|
||||
return original.apply(this, args);
|
||||
}
|
||||
const span = plugin._tracer.startSpan(`mongodb.query`, {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import * as assert from 'assert';
|
||||
import * as mongodb from 'mongodb';
|
||||
import { plugin } from '../src';
|
||||
|
@ -65,8 +65,12 @@ function accessCollection(
|
|||
function assertSpans(
|
||||
spans: ReadableSpan[],
|
||||
expectedName: string,
|
||||
expectedKind: SpanKind
|
||||
expectedKind: SpanKind,
|
||||
log = false
|
||||
) {
|
||||
if (log) {
|
||||
console.log(spans);
|
||||
}
|
||||
assert.strictEqual(spans.length, 2);
|
||||
spans.forEach(span => {
|
||||
assert(span.endTime instanceof Array);
|
||||
|
@ -75,10 +79,7 @@ function assertSpans(
|
|||
const [mongoSpan] = spans;
|
||||
assert.strictEqual(mongoSpan.name, expectedName);
|
||||
assert.strictEqual(mongoSpan.kind, expectedKind);
|
||||
assert.strictEqual(
|
||||
mongoSpan.attributes[AttributeNames.COMPONENT],
|
||||
'mongodb'
|
||||
);
|
||||
assert.strictEqual(mongoSpan.attributes[AttributeNames.COMPONENT], 'mongodb');
|
||||
assert.strictEqual(
|
||||
mongoSpan.attributes[AttributeNames.PEER_HOSTNAME],
|
||||
process.env.MONGODB_HOST || 'localhost'
|
||||
|
@ -104,12 +105,13 @@ describe('MongoDBPlugin', () => {
|
|||
let client: mongodb.MongoClient;
|
||||
let collection: mongodb.Collection;
|
||||
const logger = new NoopLogger();
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const spanProcessor = new SimpleSpanProcessor(memoryExporter);
|
||||
registry.addSpanProcessor(spanProcessor);
|
||||
|
||||
before(done => {
|
||||
plugin.enable(mongodb, tracer, logger);
|
||||
plugin.enable(mongodb, registry, logger);
|
||||
accessCollection(URL, DB_NAME, COLLECTION_NAME)
|
||||
.then(result => {
|
||||
client = result.client;
|
||||
|
@ -155,8 +157,8 @@ describe('MongoDBPlugin', () => {
|
|||
it('should create a child span for insert', done => {
|
||||
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
|
||||
|
||||
const span = tracer.startSpan(`insertRootSpan`);
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan(`insertRootSpan`);
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
collection.insertMany(insertData, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -171,8 +173,8 @@ describe('MongoDBPlugin', () => {
|
|||
});
|
||||
|
||||
it('should create a child span for update', done => {
|
||||
const span = tracer.startSpan('updateRootSpan');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('updateRootSpan');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
collection.updateOne({ a: 2 }, { $set: { b: 1 } }, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -187,8 +189,8 @@ describe('MongoDBPlugin', () => {
|
|||
});
|
||||
|
||||
it('should create a child span for remove', done => {
|
||||
const span = tracer.startSpan('removeRootSpan');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('removeRootSpan');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
collection.deleteOne({ a: 3 }, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -206,8 +208,8 @@ describe('MongoDBPlugin', () => {
|
|||
/** Should intercept cursor */
|
||||
describe('Instrumenting cursor operations', () => {
|
||||
it('should create a child span for find', done => {
|
||||
const span = tracer.startSpan('findRootSpan');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('findRootSpan');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
collection.find({}).toArray((err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -225,8 +227,8 @@ describe('MongoDBPlugin', () => {
|
|||
/** Should intercept command */
|
||||
describe('Instrumenting command operations', () => {
|
||||
it('should create a child span for create index', done => {
|
||||
const span = tracer.startSpan('indexRootSpan');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('indexRootSpan');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
collection.createIndex({ a: 1 }, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -252,7 +254,7 @@ describe('MongoDBPlugin', () => {
|
|||
it('should not create a child span for query', done => {
|
||||
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
|
||||
|
||||
const span = tracer.startSpan('insertRootSpan');
|
||||
const span = registry.getTracer('default').startSpan('insertRootSpan');
|
||||
collection.insertMany(insertData, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -262,7 +264,7 @@ describe('MongoDBPlugin', () => {
|
|||
});
|
||||
|
||||
it('should not create a child span for cursor', done => {
|
||||
const span = tracer.startSpan('findRootSpan');
|
||||
const span = registry.getTracer('default').startSpan('findRootSpan');
|
||||
collection.find({}).toArray((err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
@ -272,7 +274,7 @@ describe('MongoDBPlugin', () => {
|
|||
});
|
||||
|
||||
it('should not create a child span for command', done => {
|
||||
const span = tracer.startSpan('indexRootSpan');
|
||||
const span = registry.getTracer('default').startSpan('indexRootSpan');
|
||||
collection.createIndex({ a: 1 }, (err, result) => {
|
||||
span.end();
|
||||
assert.ifError(err);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"outDir": "build"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
"src/**/*.ts",
|
||||
"test/**/*.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ import * as mysqlTypes from 'mysql';
|
|||
import * as shimmer from 'shimmer';
|
||||
import { AttributeNames } from './enums';
|
||||
import { getConnectionAttributes, getSpanName } from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
export class MysqlPlugin extends BasePlugin<typeof mysqlTypes> {
|
||||
readonly moduleName = 'mysql';
|
||||
readonly supportedVersions = ['2.*'];
|
||||
|
||||
static readonly COMPONENT = 'mysql';
|
||||
|
@ -36,6 +36,10 @@ export class MysqlPlugin extends BasePlugin<typeof mysqlTypes> {
|
|||
|
||||
private _enabled = false;
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super('@opentelemetry/plugin-mysql', VERSION);
|
||||
}
|
||||
|
||||
protected patch(): typeof mysqlTypes {
|
||||
this._enabled = true;
|
||||
shimmer.wrap(
|
||||
|
@ -283,4 +287,4 @@ export class MysqlPlugin extends BasePlugin<typeof mysqlTypes> {
|
|||
}
|
||||
}
|
||||
|
||||
export const plugin = new MysqlPlugin();
|
||||
export const plugin = new MysqlPlugin(MysqlPlugin.COMPONENT);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -38,7 +38,7 @@ describe('mysql@2.x', () => {
|
|||
let connection: mysql.Connection;
|
||||
let pool: mysql.Pool;
|
||||
let poolCluster: mysql.PoolCluster;
|
||||
const tracer = new NodeTracer({ plugins: {} });
|
||||
const registry = new NodeTracerRegistry({ plugins: {} });
|
||||
const logger = new NoopLogger();
|
||||
const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available
|
||||
const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker
|
||||
|
@ -52,7 +52,7 @@ describe('mysql@2.x', () => {
|
|||
this.test!.parent!.pending = true;
|
||||
this.skip();
|
||||
}
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
if (testMysqlLocally) {
|
||||
testUtils.startDocker('mysql');
|
||||
// wait 15 seconds for docker container to start
|
||||
|
@ -71,7 +71,7 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
beforeEach(function() {
|
||||
plugin.enable(mysql, tracer, logger);
|
||||
plugin.enable(mysql, registry, logger);
|
||||
connection = mysql.createConnection({
|
||||
port,
|
||||
user,
|
||||
|
@ -118,8 +118,8 @@ describe('mysql@2.x', () => {
|
|||
|
||||
describe('#Connection', () => {
|
||||
it('should intercept connection.query(text: string)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
const query = connection.query(statement);
|
||||
let rows = 0;
|
||||
|
@ -140,8 +140,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept connection.query(text: string, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
connection.query(statement, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -156,8 +156,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept connection.query(text: options, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
connection.query({ sql: statement, values: [1] }, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -172,8 +172,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept connection.query(text: options, values: [], callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
// @ts-ignore this is documented https://github.com/mysqljs/mysql#performing-queries
|
||||
// but does not match the typings
|
||||
|
@ -190,8 +190,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept connection.query(text: string, values: [], callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
connection.query(statement, [1], (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -206,8 +206,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept connection.query(text: string, value: any, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
connection.query(statement, 1, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -222,8 +222,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should attach error messages to spans', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
connection.query(statement, (err, res) => {
|
||||
assert.ok(err);
|
||||
|
@ -238,8 +238,8 @@ describe('mysql@2.x', () => {
|
|||
|
||||
describe('#Pool', () => {
|
||||
it('should intercept pool.query(text: string)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
const query = pool.query(statement);
|
||||
let rows = 0;
|
||||
|
@ -260,8 +260,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.getConnection().query(text: string)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
pool.getConnection((err, conn) => {
|
||||
const query = conn.query(statement);
|
||||
|
@ -284,8 +284,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.query(text: string, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
pool.query(statement, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -300,8 +300,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.getConnection().query(text: string, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
pool.getConnection((err, conn) => {
|
||||
conn.query(statement, (err, res) => {
|
||||
|
@ -318,8 +318,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.query(text: options, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
pool.query({ sql: statement, values: [1] }, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -334,8 +334,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.query(text: options, values: [], callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
// @ts-ignore this is documented https://github.com/mysqljs/mysql#performing-queries
|
||||
// but does not match the typings
|
||||
|
@ -352,8 +352,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.query(text: string, values: [], callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
pool.query(statement, [1], (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -368,8 +368,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should intercept pool.query(text: string, value: any, callback)', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
pool.query(statement, 1, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -384,8 +384,8 @@ describe('mysql@2.x', () => {
|
|||
});
|
||||
|
||||
it('should attach error messages to spans', done => {
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
pool.query(statement, (err, res) => {
|
||||
assert.ok(err);
|
||||
|
@ -402,8 +402,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: string)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
const query = poolClusterConnection.query(statement);
|
||||
let rows = 0;
|
||||
|
@ -427,8 +427,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: string, callback)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+1 as solution';
|
||||
poolClusterConnection.query(statement, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -446,8 +446,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: options, callback)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
poolClusterConnection.query(
|
||||
{ sql: statement, values: [1] },
|
||||
|
@ -468,8 +468,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: options, values: [], callback)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1+? as solution';
|
||||
// @ts-ignore this is documented https://github.com/mysqljs/mysql#performing-queries
|
||||
// but does not match the typings
|
||||
|
@ -489,8 +489,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: string, values: [], callback)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
poolClusterConnection.query(statement, [1], (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -508,8 +508,8 @@ describe('mysql@2.x', () => {
|
|||
it('should intercept poolClusterConnection.query(text: string, value: any, callback)', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
poolClusterConnection.query(statement, 1, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
@ -527,8 +527,8 @@ describe('mysql@2.x', () => {
|
|||
it('should attach error messages to spans', done => {
|
||||
poolCluster.getConnection((err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT ? as solution';
|
||||
poolClusterConnection.query(statement, (err, res) => {
|
||||
assert.ok(err);
|
||||
|
@ -544,8 +544,8 @@ describe('mysql@2.x', () => {
|
|||
it('should get connection by name', done => {
|
||||
poolCluster.getConnection('name', (err, poolClusterConnection) => {
|
||||
assert.ifError(err);
|
||||
const span = tracer.startSpan('test span');
|
||||
tracer.withSpan(span, () => {
|
||||
const span = registry.getTracer('default').startSpan('test span');
|
||||
registry.getTracer('default').withSpan(span, () => {
|
||||
const statement = 'SELECT 1 as solution';
|
||||
poolClusterConnection.query(statement, (err, res) => {
|
||||
assert.ifError(err);
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
PgPoolExtended,
|
||||
} from './types';
|
||||
import * as utils from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
export class PostgresPoolPlugin extends BasePlugin<typeof pgPoolTypes> {
|
||||
protected _config: PostgresPoolPluginOptions;
|
||||
|
@ -35,7 +36,7 @@ export class PostgresPoolPlugin extends BasePlugin<typeof pgPoolTypes> {
|
|||
readonly supportedVersions = ['2.*'];
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-pg-pool', VERSION);
|
||||
this._config = {};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -92,7 +92,7 @@ const runCallbackTest = (
|
|||
|
||||
describe('pg-pool@2.x', () => {
|
||||
let pool: pgPool<pg.Client>;
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
const logger = new NoopLogger();
|
||||
const testPostgres = process.env.TEST_POSTGRES; // For CI: assumes local postgres db is already available
|
||||
const testPostgresLocally = process.env.TEST_POSTGRES_LOCAL; // For local: spins up local postgres db via docker
|
||||
|
@ -106,7 +106,7 @@ describe('pg-pool@2.x', () => {
|
|||
this.skip();
|
||||
}
|
||||
pool = new pgPool(CONFIG);
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
if (testPostgresLocally) {
|
||||
testUtils.startDocker('postgres');
|
||||
}
|
||||
|
@ -123,8 +123,8 @@ describe('pg-pool@2.x', () => {
|
|||
});
|
||||
|
||||
beforeEach(function() {
|
||||
plugin.enable(pgPool, tracer, logger);
|
||||
pgPlugin.enable(pg, tracer, logger);
|
||||
plugin.enable(pgPool, registry, logger);
|
||||
pgPlugin.enable(pg, registry, logger);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -152,8 +152,8 @@ describe('pg-pool@2.x', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'SELECT NOW()',
|
||||
};
|
||||
const events: TimedEvent[] = [];
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('test-pg-pool').startSpan('test span');
|
||||
await registry.getTracer('test-pg-pool').withSpan(span, async () => {
|
||||
const client = await pool.connect();
|
||||
runCallbackTest(span, pgPoolattributes, events, okStatus, 1, 0);
|
||||
assert.ok(client, 'pool.connect() returns a promise');
|
||||
|
@ -178,8 +178,10 @@ describe('pg-pool@2.x', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'SELECT NOW()',
|
||||
};
|
||||
const events: TimedEvent[] = [];
|
||||
const parentSpan = tracer.startSpan('test span');
|
||||
tracer.withSpan(parentSpan, () => {
|
||||
const parentSpan = registry
|
||||
.getTracer('test-pg-pool')
|
||||
.startSpan('test span');
|
||||
registry.getTracer('test-pg-pool').withSpan(parentSpan, () => {
|
||||
const resNoPromise = pool.connect((err, client, release) => {
|
||||
if (err) {
|
||||
return done(err);
|
||||
|
@ -212,8 +214,8 @@ describe('pg-pool@2.x', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'SELECT NOW()',
|
||||
};
|
||||
const events: TimedEvent[] = [];
|
||||
const span = tracer.startSpan('test span');
|
||||
await tracer.withSpan(span, async () => {
|
||||
const span = registry.getTracer('test-pg-pool').startSpan('test span');
|
||||
await registry.getTracer('test-pg-pool').withSpan(span, async () => {
|
||||
try {
|
||||
const result = await pool.query('SELECT NOW()');
|
||||
runCallbackTest(span, pgPoolattributes, events, okStatus, 2, 0);
|
||||
|
@ -235,8 +237,10 @@ describe('pg-pool@2.x', () => {
|
|||
[AttributeNames.DB_STATEMENT]: 'SELECT NOW()',
|
||||
};
|
||||
const events: TimedEvent[] = [];
|
||||
const parentSpan = tracer.startSpan('test span');
|
||||
tracer.withSpan(parentSpan, () => {
|
||||
const parentSpan = registry
|
||||
.getTracer('test-pg-pool')
|
||||
.startSpan('test span');
|
||||
registry.getTracer('test-pg-pool').withSpan(parentSpan, () => {
|
||||
const resNoPromise = pool.query('SELECT NOW()', (err, result) => {
|
||||
if (err) {
|
||||
return done(err);
|
||||
|
|
|
@ -16,15 +16,16 @@
|
|||
|
||||
import { BasePlugin } from '@opentelemetry/core';
|
||||
import { CanonicalCode, Span } from '@opentelemetry/types';
|
||||
import * as pgTypes from 'pg';
|
||||
import * as shimmer from 'shimmer';
|
||||
import {
|
||||
PostgresPluginOptions,
|
||||
PgClientExtended,
|
||||
PgPluginQueryConfig,
|
||||
PostgresCallback,
|
||||
PostgresPluginOptions,
|
||||
} from './types';
|
||||
import * as pgTypes from 'pg';
|
||||
import * as shimmer from 'shimmer';
|
||||
import * as utils from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
export class PostgresPlugin extends BasePlugin<typeof pgTypes> {
|
||||
protected _config: PostgresPluginOptions;
|
||||
|
@ -37,7 +38,7 @@ export class PostgresPlugin extends BasePlugin<typeof pgTypes> {
|
|||
readonly supportedVersions = ['7.*'];
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-pg', VERSION);
|
||||
this._config = {};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
|
@ -81,7 +81,8 @@ const runCallbackTest = (
|
|||
|
||||
describe('pg@7.x', () => {
|
||||
let client: pg.Client;
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
const tracer = registry.getTracer('external');
|
||||
const logger = new NoopLogger();
|
||||
const testPostgres = process.env.RUN_POSTGRES_TESTS; // For CI: assumes local postgres db is already available
|
||||
const testPostgresLocally = process.env.RUN_POSTGRES_TESTS_LOCAL; // For local: spins up local postgres db via docker
|
||||
|
@ -94,7 +95,7 @@ describe('pg@7.x', () => {
|
|||
this.test!.parent!.pending = true;
|
||||
this.skip();
|
||||
}
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
if (testPostgresLocally) {
|
||||
testUtils.startDocker('postgres');
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ describe('pg@7.x', () => {
|
|||
});
|
||||
|
||||
beforeEach(function() {
|
||||
plugin.enable(pg, tracer, logger);
|
||||
plugin.enable(pg, registry, logger);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
@ -24,9 +24,9 @@ OpenTelemetry Redis Instrumentation allows the user to automatically collect tra
|
|||
|
||||
To load a specific plugin (**redis** in this case), specify it in the Node Tracer's configuration
|
||||
```js
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer({
|
||||
const registry = new NodeTracerRegistry({
|
||||
plugins: {
|
||||
redis: {
|
||||
enabled: true,
|
||||
|
@ -39,9 +39,9 @@ const tracer = new NodeTracer({
|
|||
|
||||
To load all the [supported plugins](https://github.com/open-telemetry/opentelemetry-js#plugins), use below approach. Each plugin is only loaded when the module that it patches is loaded; in other words, there is no computational overhead for listing plugins for unused modules.
|
||||
```javascript
|
||||
const { NodeTracer } = require('@opentelemetry/node');
|
||||
const { NodeTracerRegistry } = require('@opentelemetry/node');
|
||||
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
```
|
||||
|
||||
See [examples/redis](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/redis) for a short example.
|
||||
|
|
|
@ -22,13 +22,14 @@ import {
|
|||
getTracedCreateStreamTrace,
|
||||
getTracedInternalSendCommand,
|
||||
} from './utils';
|
||||
import { VERSION } from './version';
|
||||
|
||||
export class RedisPlugin extends BasePlugin<typeof redisTypes> {
|
||||
static readonly COMPONENT = 'redis';
|
||||
readonly supportedVersions = ['^2.6.0']; // equivalent to >= 2.6.0 <3
|
||||
|
||||
constructor(readonly moduleName: string) {
|
||||
super();
|
||||
super('@opentelemetry/plugin-redis', VERSION);
|
||||
}
|
||||
|
||||
protected patch() {
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from '@opentelemetry/tracing';
|
||||
import { NodeTracer } from '@opentelemetry/node';
|
||||
import { NodeTracerRegistry } from '@opentelemetry/node';
|
||||
import { plugin, RedisPlugin } from '../src';
|
||||
import * as redisTypes from 'redis';
|
||||
import { NoopLogger } from '@opentelemetry/core';
|
||||
|
@ -48,7 +48,8 @@ const okStatus: Status = {
|
|||
};
|
||||
|
||||
describe('redis@2.x', () => {
|
||||
const tracer = new NodeTracer();
|
||||
const registry = new NodeTracerRegistry();
|
||||
const tracer = registry.getTracer('external');
|
||||
let redis: typeof redisTypes;
|
||||
const shouldTestLocal = process.env.RUN_REDIS_TESTS_LOCAL;
|
||||
const shouldTest = process.env.RUN_REDIS_TESTS || shouldTestLocal;
|
||||
|
@ -67,8 +68,8 @@ describe('redis@2.x', () => {
|
|||
}
|
||||
|
||||
redis = require('redis');
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
plugin.enable(redis, tracer, new NoopLogger());
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
plugin.enable(redis, registry, new NoopLogger());
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
@ -69,15 +69,12 @@ export class XMLHttpRequestPlugin extends BasePlugin<XMLHttpRequest> {
|
|||
readonly version: string = VERSION;
|
||||
moduleName = this.component;
|
||||
|
||||
protected _config!: XMLHttpRequestPluginConfig;
|
||||
|
||||
private _tasksCount = 0;
|
||||
private _xhrMem = new WeakMap<XMLHttpRequest, XhrMem>();
|
||||
private _usedResources = new WeakSet<PerformanceResourceTiming>();
|
||||
|
||||
constructor(config: XMLHttpRequestPluginConfig = {}) {
|
||||
super();
|
||||
this._config = config;
|
||||
constructor(protected _config: XMLHttpRequestPluginConfig = {}) {
|
||||
super('@opentelemetry/plugin-xml-http-request', VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,10 +27,14 @@ import {
|
|||
import { ZoneScopeManager } from '@opentelemetry/scope-zone';
|
||||
import * as tracing from '@opentelemetry/tracing';
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { PerformanceTimingNames as PTN, WebTracer } from '@opentelemetry/web';
|
||||
import {
|
||||
PerformanceTimingNames as PTN,
|
||||
WebTracerRegistry,
|
||||
} from '@opentelemetry/web';
|
||||
import { AttributeNames } from '../src/enums/AttributeNames';
|
||||
import { EventNames } from '../src/enums/EventNames';
|
||||
import { XMLHttpRequestPlugin } from '../src/xhr';
|
||||
import { Tracer } from '@opentelemetry/types';
|
||||
|
||||
class DummySpanExporter implements tracing.SpanExporter {
|
||||
export(spans: any) {}
|
||||
|
@ -97,7 +101,8 @@ describe('xhr', () => {
|
|||
let clearData: any;
|
||||
|
||||
describe('when request is successful', () => {
|
||||
let webTracerWithZone: WebTracer;
|
||||
let webTracerWithZone: Tracer;
|
||||
let webTracerRegistryWithZone: WebTracerRegistry;
|
||||
let dummySpanExporter: DummySpanExporter;
|
||||
let exportSpy: any;
|
||||
let rootSpan: types.Span;
|
||||
|
@ -136,7 +141,7 @@ describe('xhr', () => {
|
|||
spyEntries = sandbox.stub(performance, 'getEntriesByType');
|
||||
spyEntries.withArgs('resource').returns(resources);
|
||||
|
||||
webTracerWithZone = new WebTracer({
|
||||
webTracerRegistryWithZone = new WebTracerRegistry({
|
||||
logLevel: LogLevel.ERROR,
|
||||
httpTextFormat: new B3Format(),
|
||||
scopeManager: new ZoneScopeManager(),
|
||||
|
@ -146,9 +151,10 @@ describe('xhr', () => {
|
|||
}),
|
||||
],
|
||||
});
|
||||
webTracerWithZone = webTracerRegistryWithZone.getTracer('xhr-test');
|
||||
dummySpanExporter = new DummySpanExporter();
|
||||
exportSpy = sinon.stub(dummySpanExporter, 'export');
|
||||
webTracerWithZone.addSpanProcessor(
|
||||
webTracerRegistryWithZone.addSpanProcessor(
|
||||
new tracing.SimpleSpanProcessor(dummySpanExporter)
|
||||
);
|
||||
|
||||
|
@ -403,7 +409,8 @@ describe('xhr', () => {
|
|||
});
|
||||
|
||||
describe('when request is NOT successful', () => {
|
||||
let webTracerWithZone: WebTracer;
|
||||
let webTracerWithZoneRegistry: WebTracerRegistry;
|
||||
let webTracerWithZone: Tracer;
|
||||
let dummySpanExporter: DummySpanExporter;
|
||||
let exportSpy: any;
|
||||
let rootSpan: types.Span;
|
||||
|
@ -434,16 +441,17 @@ describe('xhr', () => {
|
|||
spyEntries = sandbox.stub(performance, 'getEntriesByType');
|
||||
spyEntries.withArgs('resource').returns(resources);
|
||||
|
||||
webTracerWithZone = new WebTracer({
|
||||
webTracerWithZoneRegistry = new WebTracerRegistry({
|
||||
logLevel: LogLevel.ERROR,
|
||||
scopeManager: new ZoneScopeManager(),
|
||||
plugins: [new XMLHttpRequestPlugin()],
|
||||
});
|
||||
dummySpanExporter = new DummySpanExporter();
|
||||
exportSpy = sinon.stub(dummySpanExporter, 'export');
|
||||
webTracerWithZone.addSpanProcessor(
|
||||
webTracerWithZoneRegistry.addSpanProcessor(
|
||||
new tracing.SimpleSpanProcessor(dummySpanExporter)
|
||||
);
|
||||
webTracerWithZone = webTracerWithZoneRegistry.getTracer('xhr-test');
|
||||
|
||||
rootSpan = webTracerWithZone.startSpan('root');
|
||||
|
||||
|
|
|
@ -16,14 +16,16 @@
|
|||
|
||||
import * as assert from 'assert';
|
||||
import * as opentracing from 'opentracing';
|
||||
import { BasicTracer, Span } from '@opentelemetry/tracing';
|
||||
import { BasicTracerRegistry, Span } from '@opentelemetry/tracing';
|
||||
import { TracerShim, SpanShim, SpanContextShim } from '../src/shim';
|
||||
import { INVALID_SPAN_CONTEXT, timeInputToHrTime } from '@opentelemetry/core';
|
||||
import { performance } from 'perf_hooks';
|
||||
|
||||
describe('OpenTracing Shim', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const shimTracer: opentracing.Tracer = new TracerShim(tracer);
|
||||
const registry = new BasicTracerRegistry();
|
||||
const shimTracer: opentracing.Tracer = new TracerShim(
|
||||
registry.getTracer('default')
|
||||
);
|
||||
opentracing.initGlobalTracer(shimTracer);
|
||||
|
||||
describe('TracerShim', () => {
|
||||
|
|
|
@ -25,22 +25,19 @@ npm install --save @opentelemetry/tracing
|
|||
|
||||
```js
|
||||
const opentelemetry = require('@opentelemetry/core');
|
||||
const { BasicTracer } = require('@opentelemetry/tracing');
|
||||
const { BasicTracerRegistry } = require('@opentelemetry/tracing');
|
||||
|
||||
// To start a trace, you first need to initialize the Tracer.
|
||||
// NOTE: the default OpenTelemetry tracer does not record any tracing information.
|
||||
const tracer = new BasicTracer();
|
||||
|
||||
// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
|
||||
opentelemetry.initGlobalTracer(tracer);
|
||||
// To start a trace, you first need to initialize the Tracer registry.
|
||||
// NOTE: the default OpenTelemetry tracer registry does not record any tracing information.
|
||||
opentelemetry.initGlobalTracer(new BasicTracerRegistry());
|
||||
|
||||
// To create a span in a trace, we used the global singleton tracer to start a new span.
|
||||
const span = opentelemetry.getTracer().startSpan('foo');
|
||||
const span = opentelemetry.getTracer('default').startSpan('foo');
|
||||
|
||||
// Create an Attributes
|
||||
// Set a span attribute
|
||||
span.setAttribute('key', 'value');
|
||||
|
||||
// We must end the spans so they becomes available for exporting.
|
||||
// We must end the spans so they become available for exporting.
|
||||
span.end();
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*!
|
||||
* Copyright 2019, 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.
|
||||
*/
|
||||
|
||||
import { ConsoleLogger } from '@opentelemetry/core';
|
||||
import * as types from '@opentelemetry/types';
|
||||
import { Logger } from '@opentelemetry/types';
|
||||
import { SpanProcessor, Tracer } from '.';
|
||||
import { DEFAULT_CONFIG } from './config';
|
||||
import { MultiSpanProcessor } from './MultiSpanProcessor';
|
||||
import { NoopSpanProcessor } from './NoopSpanProcessor';
|
||||
import { TracerConfig } from './types';
|
||||
|
||||
/**
|
||||
* This class represents a basic tracer registry which platform libraries can extend
|
||||
*/
|
||||
export class BasicTracerRegistry implements types.TracerRegistry {
|
||||
private readonly _registeredSpanProcessors: SpanProcessor[] = [];
|
||||
private readonly _tracers: Map<string, Tracer> = new Map();
|
||||
|
||||
activeSpanProcessor = new NoopSpanProcessor();
|
||||
readonly logger: Logger;
|
||||
|
||||
constructor(private _config: TracerConfig = DEFAULT_CONFIG) {
|
||||
this.logger = _config.logger || new ConsoleLogger(_config.logLevel);
|
||||
}
|
||||
|
||||
getTracer(name: string, version = '*', config?: TracerConfig): Tracer {
|
||||
const key = `${name}@${version}`;
|
||||
if (!this._tracers.has(key)) {
|
||||
this._tracers.set(key, new Tracer(config || this._config, this));
|
||||
}
|
||||
|
||||
return this._tracers.get(key)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new {@link SpanProcessor} to this tracer.
|
||||
* @param spanProcessor the new SpanProcessor to be added.
|
||||
*/
|
||||
addSpanProcessor(spanProcessor: SpanProcessor): void {
|
||||
this._registeredSpanProcessors.push(spanProcessor);
|
||||
this.activeSpanProcessor = new MultiSpanProcessor(
|
||||
this._registeredSpanProcessors
|
||||
);
|
||||
}
|
||||
|
||||
getActiveSpanProcessor(): SpanProcessor {
|
||||
return this.activeSpanProcessor;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ import {
|
|||
timeInputToHrTime,
|
||||
} from '@opentelemetry/core';
|
||||
import { ReadableSpan } from './export/ReadableSpan';
|
||||
import { BasicTracer } from './BasicTracer';
|
||||
import { Tracer } from './Tracer';
|
||||
import { SpanProcessor } from './SpanProcessor';
|
||||
import { TraceParams } from './types';
|
||||
|
||||
|
@ -52,7 +52,7 @@ export class Span implements types.Span, ReadableSpan {
|
|||
|
||||
/** Constructs a new Span instance. */
|
||||
constructor(
|
||||
parentTracer: BasicTracer,
|
||||
parentTracer: Tracer,
|
||||
spanName: string,
|
||||
spanContext: types.SpanContext,
|
||||
kind: types.SpanKind,
|
||||
|
@ -68,7 +68,7 @@ export class Span implements types.Span, ReadableSpan {
|
|||
this.startTime = timeInputToHrTime(startTime);
|
||||
this._logger = parentTracer.logger;
|
||||
this._traceParams = parentTracer.getActiveTraceParams();
|
||||
this._spanProcessor = parentTracer.activeSpanProcessor;
|
||||
this._spanProcessor = parentTracer.getActiveSpanProcessor();
|
||||
this._spanProcessor.onStart(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,19 +28,17 @@ import {
|
|||
TraceFlags,
|
||||
Logger,
|
||||
} from '@opentelemetry/types';
|
||||
import { BasicTracerConfig, TraceParams } from './types';
|
||||
import { TracerConfig, TraceParams } from './types';
|
||||
import { ScopeManager } from '@opentelemetry/scope-base';
|
||||
import { Span } from './Span';
|
||||
import { mergeConfig } from './utility';
|
||||
import { SpanProcessor } from './SpanProcessor';
|
||||
import { NoopSpanProcessor } from './NoopSpanProcessor';
|
||||
import { MultiSpanProcessor } from './MultiSpanProcessor';
|
||||
import { DEFAULT_CONFIG } from './config';
|
||||
import { BasicTracerRegistry } from './BasicTracerRegistry';
|
||||
|
||||
/**
|
||||
* This class represents a basic tracer.
|
||||
*/
|
||||
export class BasicTracer implements types.Tracer {
|
||||
export class Tracer implements types.Tracer {
|
||||
private readonly _defaultAttributes: types.Attributes;
|
||||
private readonly _binaryFormat: types.BinaryFormat;
|
||||
private readonly _httpTextFormat: types.HttpTextFormat;
|
||||
|
@ -48,13 +46,14 @@ export class BasicTracer implements types.Tracer {
|
|||
private readonly _scopeManager: ScopeManager;
|
||||
private readonly _traceParams: TraceParams;
|
||||
readonly logger: Logger;
|
||||
private readonly _registeredSpanProcessor: SpanProcessor[] = [];
|
||||
activeSpanProcessor = new NoopSpanProcessor();
|
||||
|
||||
/**
|
||||
* Constructs a new Tracer instance.
|
||||
*/
|
||||
constructor(config: BasicTracerConfig = DEFAULT_CONFIG) {
|
||||
constructor(
|
||||
config: TracerConfig = DEFAULT_CONFIG,
|
||||
private _tracerRegistry: BasicTracerRegistry
|
||||
) {
|
||||
const localConfig = mergeConfig(config);
|
||||
this._binaryFormat = localConfig.binaryFormat;
|
||||
this._defaultAttributes = localConfig.defaultAttributes;
|
||||
|
@ -162,15 +161,8 @@ export class BasicTracer implements types.Tracer {
|
|||
return this._traceParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new {@link SpanProcessor} to this tracer.
|
||||
* @param spanProcessor the new SpanProcessor to be added.
|
||||
*/
|
||||
addSpanProcessor(spanProcessor: SpanProcessor): void {
|
||||
this._registeredSpanProcessor.push(spanProcessor);
|
||||
this.activeSpanProcessor = new MultiSpanProcessor(
|
||||
this._registeredSpanProcessor
|
||||
);
|
||||
getActiveSpanProcessor() {
|
||||
return this._tracerRegistry.getActiveSpanProcessor();
|
||||
}
|
||||
|
||||
private _getParentSpanContext(
|
|
@ -14,7 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './BasicTracer';
|
||||
export * from './Tracer';
|
||||
export * from './BasicTracerRegistry';
|
||||
export * from './export/ConsoleSpanExporter';
|
||||
export * from './export/BatchSpanProcessor';
|
||||
export * from './export/InMemorySpanExporter';
|
||||
|
|
|
@ -25,9 +25,9 @@ import {
|
|||
import { LogLevel } from '@opentelemetry/core';
|
||||
|
||||
/**
|
||||
* BasicTracerConfig provides an interface for configuring a Basic Tracer.
|
||||
* TracerConfig provides an interface for configuring a Basic Tracer.
|
||||
*/
|
||||
export interface BasicTracerConfig {
|
||||
export interface TracerConfig {
|
||||
/**
|
||||
* Binary formatter which can serialize/deserialize Spans.
|
||||
*/
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BasicTracerConfig } from './types';
|
||||
import {
|
||||
DEFAULT_CONFIG,
|
||||
DEFAULT_MAX_ATTRIBUTES_PER_SPAN,
|
||||
DEFAULT_MAX_EVENTS_PER_SPAN,
|
||||
DEFAULT_MAX_LINKS_PER_SPAN,
|
||||
} from './config';
|
||||
import { DEFAULT_CONFIG } from './config';
|
||||
import { TracerConfig } from './types';
|
||||
|
||||
/**
|
||||
* Function to merge Default configuration (as specified in './config') with
|
||||
* user provided configurations.
|
||||
*/
|
||||
export function mergeConfig(userConfig: BasicTracerConfig) {
|
||||
export function mergeConfig(userConfig: TracerConfig) {
|
||||
const traceParams = userConfig.traceParams;
|
||||
const target = Object.assign({}, DEFAULT_CONFIG, userConfig);
|
||||
|
||||
|
|
|
@ -14,62 +14,62 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import {
|
||||
ALWAYS_SAMPLER,
|
||||
BinaryTraceContext,
|
||||
HttpTraceContext,
|
||||
NEVER_SAMPLER,
|
||||
NoopLogger,
|
||||
TraceState,
|
||||
NoRecordingSpan,
|
||||
TraceState,
|
||||
} from '@opentelemetry/core';
|
||||
import { TraceFlags } from '@opentelemetry/types';
|
||||
import { BasicTracer, Span } from '../src';
|
||||
import { NoopScopeManager, ScopeManager } from '@opentelemetry/scope-base';
|
||||
import { TraceFlags } from '@opentelemetry/types';
|
||||
import * as assert from 'assert';
|
||||
import { BasicTracerRegistry, Span } from '../src';
|
||||
|
||||
describe('BasicTracer', () => {
|
||||
describe('BasicTracerRegistry', () => {
|
||||
describe('constructor', () => {
|
||||
it('should construct an instance without any options', () => {
|
||||
const tracer = new BasicTracer();
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
const registry = new BasicTracerRegistry();
|
||||
assert.ok(registry instanceof BasicTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with binary format', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const registry = new BasicTracerRegistry({
|
||||
binaryFormat: new BinaryTraceContext(),
|
||||
});
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
assert.ok(registry instanceof BasicTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with http text format', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const registry = new BasicTracerRegistry({
|
||||
httpTextFormat: new HttpTraceContext(),
|
||||
scopeManager: new NoopScopeManager(),
|
||||
});
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
assert.ok(registry instanceof BasicTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with logger', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const registry = new BasicTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
scopeManager: new NoopScopeManager(),
|
||||
});
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
assert.ok(registry instanceof BasicTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with sampler', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const registry = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
sampler: ALWAYS_SAMPLER,
|
||||
});
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
assert.ok(registry instanceof BasicTracerRegistry);
|
||||
});
|
||||
|
||||
it('should construct an instance with default trace params', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
assert.deepStrictEqual(tracer.getActiveTraceParams(), {
|
||||
numberOfAttributesPerSpan: 32,
|
||||
numberOfEventsPerSpan: 128,
|
||||
|
@ -78,12 +78,12 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should construct an instance with customized numberOfAttributesPerSpan trace params', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
traceParams: {
|
||||
numberOfAttributesPerSpan: 100,
|
||||
},
|
||||
});
|
||||
}).getTracer('default');
|
||||
assert.deepStrictEqual(tracer.getActiveTraceParams(), {
|
||||
numberOfAttributesPerSpan: 100,
|
||||
numberOfEventsPerSpan: 128,
|
||||
|
@ -92,12 +92,12 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should construct an instance with customized numberOfEventsPerSpan trace params', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
traceParams: {
|
||||
numberOfEventsPerSpan: 300,
|
||||
},
|
||||
});
|
||||
}).getTracer('default');
|
||||
assert.deepStrictEqual(tracer.getActiveTraceParams(), {
|
||||
numberOfAttributesPerSpan: 32,
|
||||
numberOfEventsPerSpan: 300,
|
||||
|
@ -106,12 +106,12 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should construct an instance with customized numberOfLinksPerSpan trace params', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
traceParams: {
|
||||
numberOfLinksPerSpan: 10,
|
||||
},
|
||||
});
|
||||
}).getTracer('default');
|
||||
assert.deepStrictEqual(tracer.getActiveTraceParams(), {
|
||||
numberOfAttributesPerSpan: 32,
|
||||
numberOfEventsPerSpan: 128,
|
||||
|
@ -120,26 +120,26 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should construct an instance with default attributes', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
defaultAttributes: {
|
||||
region: 'eu-west',
|
||||
asg: 'my-asg',
|
||||
},
|
||||
});
|
||||
assert.ok(tracer instanceof BasicTracer);
|
||||
assert.ok(tracer instanceof BasicTracerRegistry);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.startSpan()', () => {
|
||||
it('should start a span with name only', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
assert.ok(span);
|
||||
assert.ok(span instanceof Span);
|
||||
});
|
||||
|
||||
it('should start a span with name and options', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {});
|
||||
assert.ok(span);
|
||||
assert.ok(span instanceof Span);
|
||||
|
@ -152,9 +152,9 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with defaultAttributes and spanoptions->attributes', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
defaultAttributes: { foo: 'bar' },
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {
|
||||
attributes: { foo: 'foo', bar: 'bar' },
|
||||
}) as Span;
|
||||
|
@ -163,16 +163,16 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with defaultAttributes and undefined spanoptions->attributes', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
defaultAttributes: { foo: 'bar' },
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {}) as Span;
|
||||
assert.deepStrictEqual(span.attributes, { foo: 'bar' });
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should start a span with spanoptions->attributes', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {
|
||||
attributes: { foo: 'foo', bar: 'bar' },
|
||||
}) as Span;
|
||||
|
@ -181,7 +181,7 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with name and parent spancontext', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const state = new TraceState('a=1,b=2');
|
||||
const span = tracer.startSpan('my-span', {
|
||||
parent: {
|
||||
|
@ -199,7 +199,7 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with name and parent span', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
const childSpan = tracer.startSpan('child-span', {
|
||||
parent: span,
|
||||
|
@ -212,7 +212,7 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with name and with invalid parent span', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {
|
||||
parent: ('invalid-parent' as unknown) as undefined,
|
||||
}) as Span;
|
||||
|
@ -220,7 +220,7 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should start a span with name and with invalid spancontext', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span', {
|
||||
parent: { traceId: '0', spanId: '0' },
|
||||
});
|
||||
|
@ -233,10 +233,10 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should return a no recording span when never sampling', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
assert.ok(span instanceof NoRecordingSpan);
|
||||
const context = span.context();
|
||||
|
@ -248,9 +248,9 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should create real span when not sampled but recording events true', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span', { isRecording: true });
|
||||
assert.ok(span instanceof Span);
|
||||
assert.strictEqual(span.context().traceFlags, TraceFlags.UNSAMPLED);
|
||||
|
@ -258,10 +258,10 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should not create real span when not sampled and recording events false', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span', { isRecording: false });
|
||||
assert.ok(span instanceof NoRecordingSpan);
|
||||
assert.strictEqual(span.context().traceFlags, TraceFlags.UNSAMPLED);
|
||||
|
@ -269,10 +269,10 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should not create real span when not sampled and no recording events configured', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
assert.ok(span instanceof NoRecordingSpan);
|
||||
assert.strictEqual(span.context().traceFlags, TraceFlags.UNSAMPLED);
|
||||
|
@ -280,10 +280,10 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
it('should create real span when sampled and recording events true', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: ALWAYS_SAMPLER,
|
||||
scopeManager: new NoopScopeManager(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan('my-span', { isRecording: true });
|
||||
assert.ok(span instanceof Span);
|
||||
assert.strictEqual(span.context().traceFlags, TraceFlags.SAMPLED);
|
||||
|
@ -294,10 +294,10 @@ describe('BasicTracer', () => {
|
|||
const defaultAttributes = {
|
||||
foo: 'bar',
|
||||
};
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: new NoopScopeManager(),
|
||||
defaultAttributes,
|
||||
});
|
||||
}).getTracer('default');
|
||||
|
||||
const span = tracer.startSpan('my-span') as Span;
|
||||
assert.ok(span instanceof Span);
|
||||
|
@ -306,25 +306,25 @@ describe('BasicTracer', () => {
|
|||
});
|
||||
|
||||
describe('.getCurrentSpan()', () => {
|
||||
it('should return undefined with NoopScopeManager', () => {
|
||||
const tracer = new BasicTracer();
|
||||
it('should return null with NoopScopeManager', () => {
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const currentSpan = tracer.getCurrentSpan();
|
||||
assert.deepStrictEqual(currentSpan, undefined);
|
||||
});
|
||||
|
||||
it('should return current span when it exists', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
scopeManager: {
|
||||
active: () => 'foo',
|
||||
} as ScopeManager,
|
||||
});
|
||||
}).getTracer('default');
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.withSpan()', () => {
|
||||
it('should run scope with NoopScopeManager scope manager', done => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
tracer.withSpan(span, () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
|
@ -335,7 +335,7 @@ describe('BasicTracer', () => {
|
|||
|
||||
describe('.bind()', () => {
|
||||
it('should bind scope with NoopScopeManager scope manager', done => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('my-span');
|
||||
const fn = () => {
|
||||
assert.deepStrictEqual(tracer.getCurrentSpan(), undefined);
|
||||
|
@ -348,14 +348,14 @@ describe('BasicTracer', () => {
|
|||
|
||||
describe('.getBinaryFormat()', () => {
|
||||
it('should get default binary formatter', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
assert.ok(tracer.getBinaryFormat() instanceof BinaryTraceContext);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getHttpTextFormat()', () => {
|
||||
it('should get default HTTP text formatter', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
assert.ok(tracer.getHttpTextFormat() instanceof HttpTraceContext);
|
||||
});
|
||||
});
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import * as assert from 'assert';
|
||||
import { MultiSpanProcessor } from '../src/MultiSpanProcessor';
|
||||
import { SpanProcessor, Span, BasicTracer } from '../src';
|
||||
import { SpanProcessor, Span, BasicTracerRegistry } from '../src';
|
||||
|
||||
class TestProcessor implements SpanProcessor {
|
||||
spans: Span[] = [];
|
||||
|
@ -30,7 +30,7 @@ class TestProcessor implements SpanProcessor {
|
|||
}
|
||||
|
||||
describe('MultiSpanProcessor', () => {
|
||||
const tracer = new BasicTracer();
|
||||
const tracer = new BasicTracerRegistry().getTracer('default');
|
||||
const span = tracer.startSpan('one');
|
||||
|
||||
it('should handle empty span processor', () => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
TraceFlags,
|
||||
SpanContext,
|
||||
} from '@opentelemetry/types';
|
||||
import { BasicTracer, Span } from '../src';
|
||||
import { BasicTracerRegistry, Span } from '../src';
|
||||
import {
|
||||
hrTime,
|
||||
hrTimeToNanoseconds,
|
||||
|
@ -33,9 +33,9 @@ import {
|
|||
const performanceTimeOrigin = hrTime();
|
||||
|
||||
describe('Span', () => {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const name = 'span1';
|
||||
const spanContext: SpanContext = {
|
||||
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
|
||||
|
|
|
@ -18,26 +18,26 @@ import * as assert from 'assert';
|
|||
import * as sinon from 'sinon';
|
||||
import {
|
||||
Span,
|
||||
BasicTracer,
|
||||
BasicTracerRegistry,
|
||||
InMemorySpanExporter,
|
||||
BatchSpanProcessor,
|
||||
} from '../../src';
|
||||
import { NEVER_SAMPLER, ALWAYS_SAMPLER, NoopLogger } from '@opentelemetry/core';
|
||||
|
||||
function createSampledSpan(spanName: string): Span {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: ALWAYS_SAMPLER,
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan(spanName);
|
||||
span.end();
|
||||
return span as Span;
|
||||
}
|
||||
|
||||
function createUnSampledSpan(spanName: string): Span {
|
||||
const tracer = new BasicTracer({
|
||||
const tracer = new BasicTracerRegistry({
|
||||
sampler: NEVER_SAMPLER,
|
||||
logger: new NoopLogger(),
|
||||
});
|
||||
}).getTracer('default');
|
||||
const span = tracer.startSpan(spanName, { isRecording: false });
|
||||
span.end();
|
||||
return span as Span;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import {
|
||||
BasicTracer,
|
||||
BasicTracerRegistry,
|
||||
ConsoleSpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from '../../src';
|
||||
|
@ -39,15 +39,17 @@ describe('ConsoleSpanExporter', () => {
|
|||
describe('.export()', () => {
|
||||
it('should export information about span', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const basicTracer = new BasicTracer();
|
||||
const basicTracerRegistry = new BasicTracerRegistry();
|
||||
consoleExporter = new ConsoleSpanExporter();
|
||||
|
||||
const spyConsole = sinon.spy(console, 'log');
|
||||
const spyExport = sinon.spy(consoleExporter, 'export');
|
||||
|
||||
basicTracer.addSpanProcessor(new SimpleSpanProcessor(consoleExporter));
|
||||
basicTracerRegistry.addSpanProcessor(
|
||||
new SimpleSpanProcessor(consoleExporter)
|
||||
);
|
||||
|
||||
const span = basicTracer.startSpan('foo');
|
||||
const span = basicTracerRegistry.getTracer('default').startSpan('foo');
|
||||
span.addEvent('foobar');
|
||||
span.end();
|
||||
|
||||
|
|
|
@ -18,14 +18,14 @@ import * as assert from 'assert';
|
|||
import {
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
BasicTracer,
|
||||
BasicTracerRegistry,
|
||||
} from '../../src';
|
||||
import { ExportResult } from '@opentelemetry/base';
|
||||
|
||||
describe('InMemorySpanExporter', () => {
|
||||
const memoryExporter = new InMemorySpanExporter();
|
||||
const tracer = new BasicTracer();
|
||||
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
const registry = new BasicTracerRegistry();
|
||||
registry.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
|
||||
|
||||
afterEach(() => {
|
||||
// reset spans in memory.
|
||||
|
@ -33,9 +33,13 @@ describe('InMemorySpanExporter', () => {
|
|||
});
|
||||
|
||||
it('should get finished spans', () => {
|
||||
const root = tracer.startSpan('root');
|
||||
const child = tracer.startSpan('child', { parent: root });
|
||||
const grandChild = tracer.startSpan('grand-child', { parent: child });
|
||||
const root = registry.getTracer('default').startSpan('root');
|
||||
const child = registry
|
||||
.getTracer('default')
|
||||
.startSpan('child', { parent: root });
|
||||
const grandChild = registry
|
||||
.getTracer('default')
|
||||
.startSpan('grand-child', { parent: child });
|
||||
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
|
||||
grandChild.end();
|
||||
|
@ -56,15 +60,21 @@ describe('InMemorySpanExporter', () => {
|
|||
});
|
||||
|
||||
it('should shutdown the exorter', () => {
|
||||
const root = tracer.startSpan('root');
|
||||
tracer.startSpan('child', { parent: root }).end();
|
||||
const root = registry.getTracer('default').startSpan('root');
|
||||
registry
|
||||
.getTracer('default')
|
||||
.startSpan('child', { parent: root })
|
||||
.end();
|
||||
root.end();
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 2);
|
||||
memoryExporter.shutdown();
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
|
||||
|
||||
// after shutdown no new spans are accepted
|
||||
tracer.startSpan('child1', { parent: root }).end();
|
||||
registry
|
||||
.getTracer('default')
|
||||
.startSpan('child1', { parent: root })
|
||||
.end();
|
||||
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
|
||||
});
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue