server.use(function startTracing(req, res, next) { var extractedCtx; var fields = {}; var span; var spanName = (req.route ? req.route.name : 'http_request'); extractedCtx = Tracer.globalTracer().extract(TritonConstants.RESTIFY_REQ_CARRIER, req); if (extractedCtx) { fields.childOf = extractedCtx; } // start/join a span span = Tracer.globalTracer().startSpan(spanName, fields); span.addTags({ component: 'restify', 'http.method': req.method, 'http.url': req.url, 'peer.addr': req.connection.remoteAddress, 'peer.port': req.connection.remotePort }); span.log({event: 'server-request'}); // attach the span to the req object so we can use it elsewhere. req.tritonTraceSpan = span; next(); });
dispatcher.onGet(`${CONTEXT_PATH}/hello`, function(req, res) { const serverSpan = opentracing.globalTracer().startSpan('hello', { childOf: extractSpanContext(opentracing.globalTracer(), req.headers), tags: { 'http.method': 'GET', 'http.url': extractUrl(req), } }); res.writeHead(200); res.end('Hello from Node.js!'); serverSpan.setTag('http.status_code', 200); serverSpan.finish(); });
let p2 = new TracedPromise(parent, 'p2', (resolve, reject, span) => { let childSpan = opentracing.globalTracer() .startSpan('p2Child', { childOf : span }); setTimeout((arg) => { childSpan.finish(); resolve(arg); }, 200, 'two'); });
/** * Create a new client object. * @param {Object} options - Options for constructing a client object. * @param {string} [options.address] - URL where the server is located. Must provide * this or the discovery argument * @param {bool} [options.discovery] - Use clever-discovery to locate the server. Must provide * this or the address argument * @param {number} [options.timeout] - The timeout to use for all client requests, * in milliseconds. This can be overridden on a per-request basis. Default is 5000ms. * @param {bool} [options.keepalive] - Set keepalive to true for client requests. This sets the * forever: true attribute in request. Defaults to false * @param {module:swagger-test.RetryPolicies} [options.retryPolicy=RetryPolicies.Single] - The logic to * determine which requests to retry, as well as how many times to retry. * @param {module:kayvee.Logger} [options.logger=logger.New("swagger-test-wagclient")] - The Kayvee * logger to use in the client. * @param {Object} [options.circuit] - Options for constructing the client's circuit breaker. * @param {bool} [options.circuit.forceClosed] - When set to true the circuit will always be closed. Default: true. * @param {number} [options.circuit.maxConcurrentRequests] - the maximum number of concurrent requests * the client can make at the same time. Default: 100. * @param {number} [options.circuit.requestVolumeThreshold] - The minimum number of requests needed * before a circuit can be tripped due to health. Default: 20. * @param {number} [options.circuit.sleepWindow] - how long, in milliseconds, to wait after a circuit opens * before testing for recovery. Default: 5000. * @param {number} [options.circuit.errorPercentThreshold] - the threshold to place on the rolling error * rate. Once the error rate exceeds this percentage, the circuit opens. * Default: 90. */ constructor(options) { options = options || {}; if (options.discovery) { try { this.address = discovery("swagger-test", "http").url(); } catch (e) { this.address = discovery("swagger-test", "default").url(); } } else if (options.address) { this.address = options.address; } else { throw new Error("Cannot initialize swagger-test without discovery or address"); } if (options.keepalive) { this.keepalive = options.keepalive; } else { this.keepalive = false; } if (options.timeout) { this.timeout = options.timeout; } else { this.timeout = 5000; } if (options.retryPolicy) { this.retryPolicy = options.retryPolicy; } if (options.logger) { this.logger = options.logger; } else { this.logger = new kayvee.logger("swagger-test-wagclient"); } if (options.tracer) { this.tracer = options.tracer; } else { this.tracer = opentracing.globalTracer(); } const circuitOptions = Object.assign({}, defaultCircuitOptions, options.circuit); this._hystrixCommand = commandFactory.getOrCreate("swagger-test"). errorHandler(this._hystrixCommandErrorHandler). circuitBreakerForceClosed(circuitOptions.forceClosed). requestVolumeRejectionThreshold(circuitOptions.maxConcurrentRequests). circuitBreakerRequestVolumeThreshold(circuitOptions.requestVolumeThreshold). circuitBreakerSleepWindowInMilliseconds(circuitOptions.sleepWindow). circuitBreakerErrorThresholdPercentage(circuitOptions.errorPercentThreshold). timeout(0). statisticalWindowLength(10000). statisticalWindowNumberOfBuckets(10). run(this._hystrixCommandRun). context(this). build(); setInterval(() => this._logCircuitState(), circuitOptions.logIntervalMs); }
function getRequest(parentSpan, httpOptions, name, callback) { const clientSpan = opentracing.globalTracer().startSpan(name, { childOf: parentSpan, tags: { 'http.method': 'POST', 'http.url': `http://${httpOptions.host}:${httpOptions.port}${httpOptions.path}`, } }); http.get({ host: httpOptions.host, port: httpOptions.port, path: httpOptions.path, headers: createCarrier(opentracing.globalTracer(), clientSpan), }, function (response) { clientSpan.setTag('http.status_code', response.statusCode); clientSpan.finish(); callback(response); }); }
dispatcher.onGet(`${CONTEXT_PATH}/user`, function(req, res) { function getRequest(parentSpan, httpOptions, name, callback) { const clientSpan = opentracing.globalTracer().startSpan(name, { childOf: parentSpan, tags: { 'http.method': 'POST', 'http.url': `http://${httpOptions.host}:${httpOptions.port}${httpOptions.path}`, } }); http.get({ host: httpOptions.host, port: httpOptions.port, path: httpOptions.path, headers: createCarrier(opentracing.globalTracer(), clientSpan), }, function (response) { clientSpan.setTag('http.status_code', response.statusCode); clientSpan.finish(); callback(response); }); } const serverSpan = opentracing.globalTracer().startSpan('get_user', { childOf: extractSpanContext(opentracing.globalTracer(), req.headers), tags: { 'http.method': 'GET', 'http.url': extractUrl(req), } }); getRequest(serverSpan, { host: 'wildfly-swarm', port: 3000, path: '/wildfly-swarm/user' }, 'get_user[wildfly-swarm]', function (response) { serverSpan.setTag('http.status_code', 200); serverSpan.finish(); res.writeHead(200); res.end(JSON.stringify({name: "admin"})); }); });
function startChildSpan(req, operation) { var fields = {}; var newSpan; assert.object(req, 'req'); assert.string(operation, 'operation'); fields.childOf = req.tritonTraceSpan.context(); // start then new child newSpan = Tracer.globalTracer().startSpan(operation, fields); return (newSpan); }
express.use((req, res, next) => { // do not trace health endpoint if (req.url.indexOf('health') === -1) { const serverSpan = opentracing.globalTracer().startSpan(req.method, { childOf: opentracing.globalTracer().extract(opentracing.FORMAT_HTTP_HEADERS, req.headers) }); serverSpan.setTag(opentracing.Tags.COMPONENT, 'node-js'); serverSpan.setTag(opentracing.Tags.SPAN_KIND, opentracing.Tags.SPAN_KIND_RPC_SERVER); serverSpan.setTag(opentracing.Tags.HTTP_URL, 'http://' + req.headers.host + req.url); serverSpan.setTag(opentracing.Tags.HTTP_METHOD, req.method); res.on('finish', () => { serverSpan.setTag(opentracing.Tags.HTTP_STATUS_CODE, res.statusCode); if (res.statusCode >= 500) { serverSpan.setTag(opentracing.Tags.ERROR, true); } serverSpan.finish(); }); } next(); });
import lightstep from 'lightstep-tracer'; import TracedPromise from '../..'; // Ensure the Node line numbers are accurate in stack traces require('source-map-support'); // Initialize the tracing implementation, in this case LightStep is used. // Replace '{your_access_token}' with your LightStep access token to send the // tracing data to your project. opentracing.initGlobalTracer(new lightstep.Tracer({ access_token : '{your_access_token}', component_name : 'TracedPromise', })); // Set up an initial span to track all the subsequent work let parent = opentracing.globalTracer().startSpan('Promises.all'); // Set up the child promises that run in parallel. // Simply timeouts are being used here. In a real world application, these might // be any asynchronous operation: file i/o, database transactions, network // requests, etc. let p1 = new TracedPromise(parent, 'p1', (resolve, reject) => { setTimeout(resolve, 100, 'one'); }); let p2 = new TracedPromise(parent, 'p2', (resolve, reject, span) => { let childSpan = opentracing.globalTracer() .startSpan('p2Child', { childOf : span }); setTimeout((arg) => { childSpan.finish(); resolve(arg); }, 200, 'two');