@kangc/skywalking-backend-js
Version:
The NodeJS agent for Apache SkyWalking
193 lines • 8.48 kB
JavaScript
"use strict";
/*!
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var AgentConfig_1 = tslib_1.__importDefault(require("../../config/AgentConfig"));
var DummySpan_1 = tslib_1.__importDefault(require("../../trace/span/DummySpan"));
var Segment_1 = tslib_1.__importDefault(require("../../trace/context/Segment"));
var EntrySpan_1 = tslib_1.__importDefault(require("../../trace/span/EntrySpan"));
var ExitSpan_1 = tslib_1.__importDefault(require("../../trace/span/ExitSpan"));
var LocalSpan_1 = tslib_1.__importDefault(require("../../trace/span/LocalSpan"));
var SegmentRef_1 = tslib_1.__importDefault(require("./SegmentRef"));
var ContextManager_1 = tslib_1.__importDefault(require("./ContextManager"));
var Tag_1 = tslib_1.__importDefault(require("../../Tag"));
var Component_1 = require("../Component");
var logging_1 = require("../../logging");
var ContextCarrier_1 = require("./ContextCarrier");
var Tracing_pb_1 = require("../../proto/language-agent/Tracing_pb");
var EventEmitter_1 = require("../../lib/EventEmitter");
var logger = logging_1.createLogger(__filename);
EventEmitter_1.emitter.on('segments-sent', function () {
SpanContext.nActiveSegments = 0; // reset limiter
});
var SpanContext = /** @class */ (function () {
function SpanContext() {
this.spanId = 0;
this.nSpans = 0;
this.finished = false;
this.segment = new Segment_1.default();
}
SpanContext.prototype.ignoreCheck = function (operation, type, carrier) {
if (operation.match(AgentConfig_1.default.reIgnoreOperation) || (carrier && !carrier.isValid()))
return DummySpan_1.default.create();
return undefined;
};
SpanContext.prototype.spanCheck = function (spanType, operation, carrier) {
var span = this.ignoreCheck(operation, Tracing_pb_1.SpanType.ENTRY, carrier);
if (span)
return [span];
var spans = ContextManager_1.default.spans;
var parent = spans[spans.length - 1];
if (parent instanceof DummySpan_1.default)
return [parent];
return [null, parent];
};
SpanContext.prototype.newSpan = function (spanClass, parent, operation) {
var _a;
var context = !this.finished ? this : new SpanContext();
var span = new spanClass({
id: context.spanId++,
parentId: this.finished ? -1 : (_a = parent === null || parent === void 0 ? void 0 : parent.id) !== null && _a !== void 0 ? _a : -1,
context: context,
operation: operation,
});
if (this.finished && parent) {
// segment has already been closed and sent to server, if there is a parent span then need new segment to reference
var carrier = new ContextCarrier_1.ContextCarrier(parent.context.segment.relatedTraces[0], parent.context.segment.segmentId, parent.id, AgentConfig_1.default.serviceName, AgentConfig_1.default.serviceInstance, parent.operation, parent.peer, []);
var ref = SegmentRef_1.default.fromCarrier(carrier);
context.segment.relate(carrier.traceId);
span.refer(ref);
}
return span;
};
SpanContext.prototype.newEntrySpan = function (operation, carrier, inherit) {
// tslint:disable-next-line:prefer-const
var _a = this.spanCheck(Tracing_pb_1.SpanType.ENTRY, operation, carrier), span = _a[0], parent = _a[1];
if (span)
return span;
if (logger._isDebugEnabled) {
logger.debug('Creating entry span', {
parent: parent,
});
}
if (!this.finished &&
(parent === null || parent === void 0 ? void 0 : parent.type) === Tracing_pb_1.SpanType.ENTRY &&
inherit &&
(inherit instanceof Component_1.Component ? inherit === parent.component : inherit.indexOf(parent.component) != -1)) {
span = parent;
parent.operation = operation;
}
else {
span = this.newSpan(EntrySpan_1.default, parent, operation);
if (carrier && carrier.isValid())
span.extract(carrier);
}
return span;
};
SpanContext.prototype.newExitSpan = function (operation, component, inherit) {
// tslint:disable-next-line:prefer-const
var _a = this.spanCheck(Tracing_pb_1.SpanType.EXIT, operation), span = _a[0], parent = _a[1];
if (span)
return span;
if (logger._isDebugEnabled) {
logger.debug('Creating exit span', {
operation: operation,
parent: parent,
});
}
if (!this.finished && (parent === null || parent === void 0 ? void 0 : parent.type) === Tracing_pb_1.SpanType.EXIT && component === parent.inherit)
span = parent;
else
span = this.newSpan(ExitSpan_1.default, parent, operation);
if (inherit)
span.inherit = inherit;
return span;
};
SpanContext.prototype.newLocalSpan = function (operation) {
var _a;
var _b = this.spanCheck(Tracing_pb_1.SpanType.LOCAL, operation), span = _b[0], parent = _b[1];
if (span)
return span;
if (logger._isDebugEnabled) {
logger.debug('Creating local span', {
parentId: (_a = parent === null || parent === void 0 ? void 0 : parent.id) !== null && _a !== void 0 ? _a : -1,
});
}
return this.newSpan(LocalSpan_1.default, parent, operation);
};
SpanContext.prototype.start = function (span) {
var spans = ContextManager_1.default.spansDup();
logger.debug("Starting span " + span.operation, {
span: span,
spans: spans,
nSpans: this.nSpans,
});
if (!this.nSpans++) {
SpanContext.nActiveSegments += 1;
span.isCold = ContextManager_1.default.checkCold();
if (span.isCold)
span.tag(Tag_1.default.coldStart(), true);
}
if (spans.indexOf(span) === -1)
spans.push(span);
return this;
};
SpanContext.prototype.stop = function (span) {
logger.debug("Stopping span " + span.operation, {
span: span,
spans: ContextManager_1.default.spans,
nSpans: this.nSpans,
});
span.finish(this.segment);
ContextManager_1.default.clear(span);
if (--this.nSpans === 0) {
this.finished = true;
EventEmitter_1.emitter.emit('segment-finished', this.segment);
return true;
}
return false;
};
SpanContext.prototype.async = function (span) {
logger.debug("Async span " + span.operation, {
span: span,
spans: ContextManager_1.default.spans,
nSpans: this.nSpans,
});
ContextManager_1.default.clear(span);
};
SpanContext.prototype.resync = function (span) {
logger.debug("Resync span " + span.operation, {
span: span,
spans: ContextManager_1.default.spans,
nSpans: this.nSpans,
});
ContextManager_1.default.restore(span);
};
SpanContext.prototype.traceId = function () {
if (!this.segment.relatedTraces) {
return 'N/A';
}
return this.segment.relatedTraces[0].toString();
};
SpanContext.nActiveSegments = 0; // counter to allow only config.maxBufferSize active (non-dummy) segments per reporting frame
return SpanContext;
}());
exports.default = SpanContext;
//# sourceMappingURL=SpanContext.js.map