UNPKG

dd-trace

Version:

Datadog APM tracing client for JavaScript

135 lines (107 loc) 3.39 kB
'use strict' const opentracing = require('opentracing') const now = require('performance-now') const Span = opentracing.Span const SpanContext = require('./span_context') const id = require('../id') const tagger = require('../tagger') const log = require('../log') const { storage } = require('../../../datadog-core') const { DD_TRACE_EXPERIMENTAL_STATE_TRACKING } = process.env class DatadogSpan extends Span { constructor (tracer, processor, prioritySampler, fields, debug) { super() const operationName = fields.operationName const parent = fields.parent || null const tags = Object.assign({}, fields.tags) const hostname = fields.hostname this._parentTracer = tracer this._debug = debug this._processor = processor this._prioritySampler = prioritySampler this._store = storage.getStore() this._spanContext = this._createContext(parent) this._spanContext._name = operationName this._spanContext._tags = tags this._spanContext._hostname = hostname this._startTime = fields.startTime || this._getTime() } toString () { const spanContext = this.context() const resourceName = spanContext._tags['resource.name'] const resource = resourceName.length > 100 ? `${resourceName.substring(0, 97)}...` : resourceName const json = JSON.stringify({ traceId: spanContext._traceId, spanId: spanContext._spanId, parentId: spanContext._parentId, service: spanContext._tags['service.name'], name: spanContext._name, resource }) return `Span${json}` } _createContext (parent) { let spanContext if (parent) { spanContext = new SpanContext({ traceId: parent._traceId, spanId: id(), parentId: parent._spanId, sampling: parent._sampling, baggageItems: Object.assign({}, parent._baggageItems), trace: parent._trace }) } else { const spanId = id() spanContext = new SpanContext({ traceId: spanId, spanId }) } spanContext._trace.started.push(this) spanContext._trace.startTime = spanContext._trace.startTime || Date.now() spanContext._trace.ticks = spanContext._trace.ticks || now() return spanContext } _getTime () { const { startTime, ticks } = this._spanContext._trace return startTime + now() - ticks } _context () { return this._spanContext } _tracer () { return this._parentTracer } _setOperationName (name) { this._spanContext._name = name } _setBaggageItem (key, value) { this._spanContext._baggageItems[key] = value } _getBaggageItem (key) { return this._spanContext._baggageItems[key] } _addTags (keyValuePairs) { tagger.add(this._spanContext._tags, keyValuePairs) this._prioritySampler.sample(this, false) } _finish (finishTime) { if (this._duration !== undefined) { return } if (DD_TRACE_EXPERIMENTAL_STATE_TRACKING === 'true') { if (!this._spanContext._tags['service.name']) { log.error(`Finishing invalid span: ${this}`) } } finishTime = parseFloat(finishTime) || this._getTime() this._duration = finishTime - this._startTime this._spanContext._trace.finished.push(this) this._spanContext._isFinished = true this._processor.process(this) } } module.exports = DatadogSpan