opentracing
Advanced tools
Comparing version 0.11.1 to 0.12.1
@@ -7,5 +7,5 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
else if(typeof exports === 'object') | ||
exports["Tracer"] = factory(); | ||
exports["opentracing"] = factory(); | ||
else | ||
root["Tracer"] = factory(); | ||
root["opentracing"] = factory(); | ||
})(this, function() { | ||
@@ -60,20 +60,72 @@ return /******/ (function(modules) { // webpackBootstrap | ||
module.exports = __webpack_require__(1); | ||
/***/ }, | ||
/* 1 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
'use strict'; | ||
var _global_tracer = __webpack_require__(1); | ||
var _singleton = __webpack_require__(2); | ||
var GlobalTracer = _interopRequireWildcard(_global_tracer); | ||
var _singleton2 = _interopRequireDefault(_singleton); | ||
var _constants = __webpack_require__(6); | ||
var Constants = _interopRequireWildcard(_constants); | ||
var _functions = __webpack_require__(7); | ||
var Functions = _interopRequireWildcard(_functions); | ||
var _noop = __webpack_require__(4); | ||
var Noop = _interopRequireWildcard(_noop); | ||
var _binary_carrier = __webpack_require__(9); | ||
var _binary_carrier2 = _interopRequireDefault(_binary_carrier); | ||
var _reference = __webpack_require__(8); | ||
var _reference2 = _interopRequireDefault(_reference); | ||
var _span_context = __webpack_require__(5); | ||
var _span_context2 = _interopRequireDefault(_span_context); | ||
var _span = __webpack_require__(3); | ||
var _span2 = _interopRequireDefault(_span); | ||
var _tracer = __webpack_require__(2); | ||
var _tracer2 = _interopRequireDefault(_tracer); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
module.exports = new _singleton2.default(); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
// Object.assign() is not available on Node v0.12, so implement a similar | ||
// function here (subset of a proper polyfill). | ||
function _extend(target) { | ||
for (var index = 1; index < arguments.length; index++) { | ||
var source = arguments[index]; | ||
for (var key in source) { | ||
// eslint-disable-line no-restricted-syntax | ||
if (source.hasOwnProperty(key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
} | ||
// Use `module.exports` rather than `export` to avoid the need to use `.default` | ||
// when requiring the package in ES5 code. | ||
module.exports = _extend({ | ||
BinaryCarrier: _binary_carrier2.default, | ||
Reference: _reference2.default, | ||
SpanContext: _span_context2.default, | ||
Span: _span2.default, | ||
Tracer: _tracer2.default | ||
}, Constants, Functions, GlobalTracer); | ||
// Initialize the noops last to avoid a dependecy cycle between the classes. | ||
Noop.initialize(); | ||
/***/ }, | ||
/* 2 */ | ||
/* 1 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
@@ -89,20 +141,9 @@ | ||
var _tracer = __webpack_require__(3); | ||
exports.initGlobalTracer = initGlobalTracer; | ||
exports.globalTracer = globalTracer; | ||
var _tracer = __webpack_require__(2); | ||
var _tracer2 = _interopRequireDefault(_tracer); | ||
var _constants = __webpack_require__(6); | ||
var Constants = _interopRequireWildcard(_constants); | ||
var _binary_carrier = __webpack_require__(8); | ||
var _binary_carrier2 = _interopRequireDefault(_binary_carrier); | ||
var _reference = __webpack_require__(7); | ||
var _reference2 = _interopRequireDefault(_reference); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -116,98 +157,75 @@ | ||
/** | ||
* The Singleton object is the default export of the package and extends the | ||
* standard Tracer object so that the default | ||
* exported object of the package can be conveniently be used both as the | ||
* default tracer and an interface to the library. | ||
*/ | ||
var noopTracer = new _tracer2.default(); | ||
var _globalTracer = null; | ||
var Singleton = function (_Tracer) { | ||
_inherits(Singleton, _Tracer); | ||
// Allows direct importing/requiring of the global tracer: | ||
// | ||
// let globalTracer = require('opentracing/global'); | ||
// OR | ||
// import globalTracer from 'opentracing/global'; | ||
// | ||
// 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 intractible initialization order problems that can arise in | ||
// applications with a complex set of dependencies, while also avoiding the | ||
// case where | ||
_createClass(Singleton, [{ | ||
key: 'initGlobalTracer', | ||
var GlobalTracerDelegate = function (_Tracer) { | ||
_inherits(GlobalTracerDelegate, _Tracer); | ||
function GlobalTracerDelegate() { | ||
_classCallCheck(this, GlobalTracerDelegate); | ||
// ---------------------------------------------------------------------- // | ||
// OpenTracing API methods | ||
// ---------------------------------------------------------------------- // | ||
return _possibleConstructorReturn(this, Object.getPrototypeOf(GlobalTracerDelegate).apply(this, arguments)); | ||
} | ||
/** | ||
* Set the global Tracer's underlying implementation. | ||
* | ||
* The behavior is undefined if this function is called more than once. | ||
* | ||
* @param {TracerImp} tracerImp - the Tracer implementation object | ||
*/ | ||
value: function initGlobalTracer(tracerImp) { | ||
this._imp = tracerImp; | ||
// Provide the implementation with a handle to the interface. This can | ||
// also be used a post-initialization signal. | ||
if (tracerImp) { | ||
tracerImp.setInterface(this); | ||
} | ||
_createClass(GlobalTracerDelegate, [{ | ||
key: 'startSpan', | ||
value: function startSpan() { | ||
var tracer = _globalTracer || noopTracer; | ||
return tracer.startSpan.apply(tracer, arguments); | ||
} | ||
/** | ||
* Create a new Tracer object with the given underlying implementation. | ||
* | ||
* @return {Tracer} a new Tracer object | ||
*/ | ||
}, { | ||
key: 'initNewTracer', | ||
value: function initNewTracer(tracerImp) { | ||
var tracer = new _tracer2.default(tracerImp); | ||
if (tracerImp) { | ||
tracerImp.setInterface(this); | ||
} | ||
return tracer; | ||
key: 'inject', | ||
value: function inject() { | ||
var tracer = _globalTracer || noopTracer; | ||
return tracer.inject.apply(tracer, arguments); | ||
} | ||
// ---------------------------------------------------------------------- // | ||
// Private and non-standard methods | ||
// ---------------------------------------------------------------------- // | ||
/* For internal use only: | ||
* | ||
* Creates the Singleton with no underlying implementation (i.e. defaults | ||
* to no-op behavior for all functions). | ||
* | ||
* The OpenTracing package-level object acts both at the singleton and the | ||
* package interface itself, so this Singleton is both a the Tracer and | ||
* also includes all the global library symbols. | ||
* | ||
* Note: this should never be called directly by consumers of the library. | ||
*/ | ||
}, { | ||
key: 'extract', | ||
value: function extract() { | ||
var tracer = _globalTracer || noopTracer; | ||
return tracer.extract.apply(tracer, arguments); | ||
} | ||
}]); | ||
function Singleton() { | ||
_classCallCheck(this, Singleton); | ||
return GlobalTracerDelegate; | ||
}(_tracer2.default); | ||
// Merge the constants into the singleton object so they are accessible at the | ||
// package level. | ||
var globalTracerDelegate = new GlobalTracerDelegate(); | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Singleton).call(this)); | ||
/** | ||
* Set the global Tracer. | ||
* | ||
* The behavior is undefined if this function is called more than once. | ||
* | ||
* @param {Tracer} tracer - the Tracer implementation | ||
*/ | ||
function initGlobalTracer(tracer) { | ||
_globalTracer = tracer; | ||
} | ||
for (var key in Constants) { | ||
// eslint-disable-line no-restricted-syntax | ||
_this[key] = Constants[key]; | ||
} | ||
_this.Reference = _reference2.default; | ||
// Carrier objects to be exposed at the package level | ||
_this.BinaryCarrier = _binary_carrier2.default; | ||
return _this; | ||
} | ||
return Singleton; | ||
}(_tracer2.default); | ||
exports.default = Singleton; | ||
module.exports = exports['default']; | ||
/** | ||
* Returns the global tracer. | ||
*/ | ||
function globalTracer() { | ||
// Return the delegate. Since the global tracer is largely a convenience | ||
// (the user can always create their own tracers), the delegate is used to | ||
// give the added convenience of not needing to worry about initialization | ||
// order. | ||
return globalTracerDelegate; | ||
} | ||
/***/ }, | ||
/* 3 */ | ||
/* 2 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
@@ -223,3 +241,3 @@ | ||
var _span = __webpack_require__(4); | ||
var _span = __webpack_require__(3); | ||
@@ -234,8 +252,14 @@ var _span2 = _interopRequireDefault(_span); | ||
var _constants2 = _interopRequireDefault(_constants); | ||
var Constants = _interopRequireWildcard(_constants); | ||
var _reference = __webpack_require__(7); | ||
var _functions = __webpack_require__(7); | ||
var _reference2 = _interopRequireDefault(_reference); | ||
var Functions = _interopRequireWildcard(_functions); | ||
var _noop = __webpack_require__(4); | ||
var Noop = _interopRequireWildcard(_noop); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -250,5 +274,13 @@ | ||
* The default object acts as a no-op implementation. | ||
* | ||
* Note to implementators: derived classes can choose to directly implement the | ||
* methods in the "OpenTracing API methods" section, or optionally the subset of | ||
* underscore-prefixed methods to pick up the argument checking and handling | ||
* automatically from the base class. | ||
*/ | ||
var Tracer = function () { | ||
function Tracer() { | ||
_classCallCheck(this, Tracer); | ||
} | ||
var Tracer = function () { | ||
_createClass(Tracer, [{ | ||
@@ -272,9 +304,6 @@ key: 'startSpan', | ||
* var child = Tracer.startSpan('Subroutine', { | ||
* reference: Tracer.childOf(parent.context()), | ||
* childOf: parent.context(), | ||
* }); | ||
* | ||
* @param {string|object} nameOrFields - if the given argument is a | ||
* string, it is the name of the operation and the second `fields` | ||
* argument is optional. If it is an object, it is treated as the | ||
* fields argument and a second argument should not be provided. | ||
* @param {string} name - the name of the operation. | ||
* @param {object} [fields] - the fields to set on the newly created span. | ||
@@ -300,3 +329,4 @@ * @param {string} [fields.operationName] - the name to use for the newly | ||
*/ | ||
value: function startSpan(nameOrFields, fields) { | ||
value: function startSpan(name, fields) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -306,89 +336,32 @@ if (arguments.length > 2) { | ||
} | ||
if (typeof nameOrFields !== 'string' && typeof nameOrFields !== 'object') { | ||
throw new Error('argument expected to be a string or object'); | ||
if (typeof name !== 'string') { | ||
throw new Error('argument expected to be a string'); | ||
} | ||
if (typeof nameOrFields === 'string' && nameOrFields.length === 0) { | ||
if (name.length === 0) { | ||
throw new Error('operation name cannot be length zero'); | ||
} | ||
if (typeof nameOrFields === 'object') { | ||
if (arguments.length !== 1) { | ||
throw new Error('Unexpected number of arguments'); | ||
} | ||
if (nameOrFields === null) { | ||
throw new Error('fields should not be null'); | ||
} | ||
if (!nameOrFields.operationName) { | ||
throw new Error('operationName is a required parameter'); | ||
} | ||
if (fields && fields.childOf && fields.references) { | ||
throw new Error('At most one of `childOf` and ' + '`references` may be specified'); | ||
} | ||
if (fields && fields.childOf && !(fields.childOf instanceof _span2.default || fields.childOf instanceof _span_context2.default)) { | ||
throw new Error('childOf must be a Span or SpanContext instance'); | ||
} | ||
} | ||
var spanImp = null; | ||
if (this._imp) { | ||
// Normalize the argument so the implementation is always provided | ||
// an associative array of fields. | ||
if (arguments.length === 1) { | ||
if (typeof nameOrFields === 'string') { | ||
fields = { | ||
operationName: nameOrFields | ||
}; | ||
} else { | ||
fields = nameOrFields; | ||
} | ||
// Convert fields.childOf to fields.references as needed. | ||
fields = fields || {}; | ||
if (fields.childOf) { | ||
// Convert from a Span or a SpanContext into a Reference. | ||
var childOf = Functions.childOf(fields.childOf); | ||
if (fields.references) { | ||
fields.references.push(childOf); | ||
} else { | ||
fields.operationName = nameOrFields; | ||
fields.references = [childOf]; | ||
} | ||
if (true) { | ||
if (fields.childOf && fields.references) { | ||
throw new Error('At most one of `childOf` and ' + '`references` may be specified'); | ||
} | ||
if (fields.childOf && !(fields.childOf instanceof _span2.default || fields.childOf instanceof _span_context2.default)) { | ||
throw new Error('childOf must be a Span or SpanContext instance'); | ||
} | ||
} | ||
// Convert fields.childOf to fields.references as needed. | ||
if (fields.childOf) { | ||
// Convert from a Span or a SpanContext into a Reference. | ||
var childOf = this.childOf(fields.childOf); | ||
if (fields.references) { | ||
fields.references.push(childOf); | ||
} else { | ||
fields.references = [childOf]; | ||
} | ||
delete fields.childOf; | ||
} | ||
spanImp = this._imp.startSpan(fields); | ||
delete fields.childOf; | ||
} | ||
return new _span2.default(spanImp); | ||
return this._startSpan(name, fields); | ||
} | ||
/** | ||
* Return a new REFERENCE_CHILD_OF reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_CHILD_OF reference pointing to `spanContext` | ||
*/ | ||
}, { | ||
key: 'childOf', | ||
value: function childOf(spanContext) { | ||
return new _reference2.default(_constants2.default.REFERENCE_CHILD_OF, spanContext); | ||
} | ||
/** | ||
* Return a new REFERENCE_FOLLOWS_FROM reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_FOLLOWS_FROM reference pointing to `spanContext` | ||
*/ | ||
}, { | ||
key: 'followsFrom', | ||
value: function followsFrom(spanContext) { | ||
return new _reference2.default(_constants2.default.REFERENCE_FOLLOWS_FROM, spanContext); | ||
} | ||
/** | ||
* Injects the given SpanContext instance for cross-process propagation | ||
@@ -426,2 +399,3 @@ * within `carrier`. The expected type of `carrier` depends on the value of | ||
value: function inject(spanContext, format, carrier) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -437,9 +411,9 @@ if (arguments.length !== 3) { | ||
} | ||
if (format === _constants2.default.FORMAT_TEXT_MAP && typeof carrier !== 'object') { | ||
if (format === Constants.FORMAT_TEXT_MAP && typeof carrier !== 'object') { | ||
throw new Error('Unexpected carrier object for FORMAT_TEXT_MAP'); | ||
} | ||
if (format === _constants2.default.FORMAT_HTTP_HEADERS && typeof carrier !== 'object') { | ||
if (format === Constants.FORMAT_HTTP_HEADERS && typeof carrier !== 'object') { | ||
throw new Error('Unexpected carrier object for FORMAT_HTTP_HEADERS'); | ||
} | ||
if (format === _constants2.default.FORMAT_BINARY && typeof carrier !== 'object') { | ||
if (format === Constants.FORMAT_BINARY && typeof carrier !== 'object') { | ||
throw new Error('Unexpected carrier object for FORMAT_BINARY'); | ||
@@ -449,9 +423,7 @@ } | ||
if (this._imp) { | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof _span2.default) { | ||
spanContext = spanContext.context(); | ||
} | ||
this._imp.inject(spanContext._imp, format, carrier); | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof _span2.default) { | ||
spanContext = spanContext.context(); | ||
} | ||
return this._inject(spanContext, format, carrier); | ||
} | ||
@@ -485,2 +457,3 @@ | ||
value: function extract(format, carrier) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -493,9 +466,9 @@ if (arguments.length !== 2) { | ||
} | ||
if (format === _constants2.default.FORMAT_TEXT_MAP && !(typeof carrier === 'object')) { | ||
if (format === Constants.FORMAT_TEXT_MAP && !(typeof carrier === 'object')) { | ||
throw new Error('Unexpected carrier object for FORMAT_TEXT_MAP'); | ||
} | ||
if (format === _constants2.default.FORMAT_HTTP_HEADERS && !(typeof carrier === 'object')) { | ||
if (format === Constants.FORMAT_HTTP_HEADERS && !(typeof carrier === 'object')) { | ||
throw new Error('Unexpected carrier object for FORMAT_HTTP_HEADERS'); | ||
} | ||
if (format === _constants2.default.FORMAT_BINARY) { | ||
if (format === Constants.FORMAT_BINARY) { | ||
if (carrier.buffer !== undefined && typeof carrier.buffer !== 'object') { | ||
@@ -506,72 +479,34 @@ throw new Error('Unexpected carrier object for FORMAT_BINARY'); | ||
} | ||
var spanContextImp = null; | ||
if (this._imp) { | ||
spanContextImp = this._imp.extract(format, carrier); | ||
} | ||
if (spanContextImp !== null) { | ||
return new _span_context2.default(spanContextImp); | ||
} | ||
return null; | ||
return this._extract(format, carrier); | ||
} | ||
/** | ||
* Request that any buffered or in-memory data is flushed out of the process. | ||
* | ||
* @param {function(err: objectg)} done - optional callback function with | ||
* the signature `function(err)` that will be called as soon as the | ||
* flush completes. `err` should be null or undefined if the flush | ||
* was successful. | ||
*/ | ||
}, { | ||
key: 'flush', | ||
value: function flush(done) { | ||
if (true) { | ||
if (arguments.length > 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
if (done !== undefined && typeof done !== 'function') { | ||
throw new Error('callback expected to be a function'); | ||
} | ||
} | ||
if (!this._imp) { | ||
done(null); | ||
return; | ||
} | ||
this._imp.flush(done); | ||
} | ||
// ---------------------------------------------------------------------- // | ||
// Private and non-standard methods | ||
// Derived classes can choose to implement the below | ||
// ---------------------------------------------------------------------- // | ||
/** | ||
* Note: this constructor should not be called directly by consumers of this | ||
* code. The singleton's initNewTracer() method should be invoked instead. | ||
*/ | ||
// NOTE: the input to this method is *always* an associative array. The | ||
// public-facing startSpan() method normalizes the arguments so that | ||
// all N implementations do not need to worry about variations in the call | ||
// signature. | ||
// | ||
// The default behavior returns a no-op span. | ||
}]); | ||
}, { | ||
key: '_startSpan', | ||
value: function _startSpan(name, fields) { | ||
return Noop.span; | ||
} | ||
function Tracer(imp) { | ||
_classCallCheck(this, Tracer); | ||
// The default behavior is a no-op. | ||
this._imp = imp || null; | ||
} | ||
}, { | ||
key: '_inject', | ||
value: function _inject(spanContext, format, carrier) {} | ||
/** | ||
* Handle to implementation object. | ||
* | ||
* Use of this method is discouraged as it greatly reduces the portability of | ||
* the calling code. Use only when implementation-specific functionality must | ||
* be used and cannot accessed otherwise. | ||
* | ||
* @return {object} | ||
* An implementation-dependent object. | ||
*/ | ||
// The default behavior is to return null. | ||
_createClass(Tracer, [{ | ||
key: 'imp', | ||
value: function imp() { | ||
return this._imp; | ||
}, { | ||
key: '_extract', | ||
value: function _extract(format, carrier) { | ||
return Noop.spanContext; | ||
} | ||
@@ -587,3 +522,3 @@ }]); | ||
/***/ }, | ||
/* 4 */ | ||
/* 3 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
@@ -599,12 +534,8 @@ | ||
var _tracer = __webpack_require__(3); | ||
var _noop = __webpack_require__(4); | ||
var _tracer2 = _interopRequireDefault(_tracer); | ||
var noop = _interopRequireWildcard(_noop); | ||
var _span_context = __webpack_require__(5); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
var _span_context2 = _interopRequireDefault(_span_context); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
@@ -614,4 +545,2 @@ | ||
var defaultTracer = __webpack_require__(1); | ||
/** | ||
@@ -623,4 +552,7 @@ * Span represents a logical unit of work as part of a broader Trace. Examples | ||
*/ | ||
var Span = function () { | ||
function Span() { | ||
_classCallCheck(this, Span); | ||
} | ||
var Span = function () { | ||
_createClass(Span, [{ | ||
@@ -640,2 +572,3 @@ key: 'context', | ||
value: function context() { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -646,7 +579,4 @@ if (arguments.length !== 0) { | ||
} | ||
var spanContextImp = null; | ||
if (this._imp) { | ||
spanContextImp = this._imp.context(); | ||
} | ||
return new _span_context2.default(spanContextImp); | ||
return this._context(); | ||
} | ||
@@ -663,2 +593,3 @@ | ||
value: function tracer() { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -669,6 +600,4 @@ if (arguments.length !== 0) { | ||
} | ||
if (this._imp) { | ||
return new _tracer2.default(this._imp.tracer()); | ||
} | ||
return defaultTracer; | ||
return this._tracer(); | ||
} | ||
@@ -685,2 +614,3 @@ | ||
value: function setOperationName(name) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -694,5 +624,39 @@ if (arguments.length !== 1) { | ||
} | ||
if (this._imp) { | ||
this._imp.setOperationName(name); | ||
this._setOperationName(name); | ||
return this; | ||
} | ||
/** | ||
* Sets a key:value pair on this Span that also propagates to future | ||
* children of the associated Span. | ||
* | ||
* setBaggageItem() enables powerful functionality given a full-stack | ||
* opentracing integration (e.g., arbitrary application data from a web | ||
* client can make it, transparently, all the way into the depths of a | ||
* storage system), and with it some powerful costs: use this feature with | ||
* care. | ||
* | ||
* IMPORTANT NOTE #1: setBaggageItem() will only propagate baggage items to | ||
* *future* causal descendants of the associated Span. | ||
* | ||
* IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and | ||
* value is copied into every local *and remote* child of the associated | ||
* Span, and that can add up to a lot of network and cpu overhead. | ||
* | ||
* @param {string} key | ||
* @param {string} value | ||
*/ | ||
}, { | ||
key: 'setBaggageItem', | ||
value: function setBaggageItem(key, value) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
if (arguments.length !== 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
this._setBaggageItem(key, value); | ||
return this; | ||
@@ -702,4 +666,27 @@ } | ||
/** | ||
* Adds a single tag to the span. See `AddTags()` for details. | ||
* Returns the value for a baggage item given its key. | ||
* | ||
* @param {string} key | ||
* The key for the given trace attribute. | ||
* @return {string} | ||
* String value for the given key, or undefined if the key does not | ||
* correspond to a set trace attribute. | ||
*/ | ||
}, { | ||
key: 'getBaggageItem', | ||
value: function getBaggageItem(key) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
if (arguments.length !== 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
return this._getBaggageItem(key); | ||
} | ||
/** | ||
* Adds a single tag to the span. See `addTags()` for details. | ||
* | ||
* @param {string} key | ||
@@ -712,2 +699,3 @@ * @param {any} value | ||
value: function setTag(key, value) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -721,3 +709,5 @@ if (arguments.length !== 2) { | ||
} | ||
this.addTags(_defineProperty({}, key, value)); | ||
// NOTE: the call is normalized to a call to _addTags() | ||
this._addTags(_defineProperty({}, key, value)); | ||
return this; | ||
@@ -745,3 +735,4 @@ } | ||
key: 'addTags', | ||
value: function addTags(keyValuePairs) { | ||
value: function addTags(keyValueMap) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -751,3 +742,3 @@ if (arguments.length !== 1) { | ||
} | ||
if (typeof keyValuePairs !== 'object') { | ||
if (typeof keyValueMap !== 'object') { | ||
throw new Error('Invalid argument type'); | ||
@@ -757,6 +748,3 @@ } | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.addTags(keyValuePairs); | ||
this._addTags(keyValueMap); | ||
return this; | ||
@@ -782,2 +770,3 @@ } | ||
value: function log(fields) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -791,6 +780,4 @@ if (arguments.length !== 1) { | ||
} | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.log(fields); | ||
this._log(fields); | ||
return this; | ||
@@ -810,3 +797,16 @@ } | ||
value: function logEvent(eventName, payload) { | ||
return this.log({ | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
if (arguments.length >= 1 && arguments.length <= 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
if (typeof eventName !== 'string') { | ||
throw new Error('Expected eventName to be a string'); | ||
} | ||
if (payload !== undefined && typeof payload !== 'object') { | ||
throw new Error('Expected payload to be an object'); | ||
} | ||
} | ||
return this._log({ | ||
event: eventName, | ||
@@ -834,2 +834,3 @@ payload: payload | ||
value: function finish(finishTime) { | ||
// Debug-only runtime checks on the arguments | ||
if (true) { | ||
@@ -844,36 +845,75 @@ if (arguments.length > 1) { | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.finish(finishTime); | ||
this._finish(finishTime); | ||
// Do not return `this`. The Span generally should not be used after it | ||
// is finished so chaining is not desired in this context. | ||
} | ||
// ---------------------------------------------------------------------- // | ||
// Private and non-standard methods | ||
// Derived classes can choose to implement the below | ||
// ---------------------------------------------------------------------- // | ||
/** | ||
* Constructs a new Span object, this method should not be called directly; | ||
* Tracer.startSpan() or Tracer.join() should be used instead. | ||
*/ | ||
// By default returns a no-op SpanContext. | ||
}]); | ||
}, { | ||
key: '_context', | ||
value: function _context() { | ||
return noop.spanContext; | ||
} | ||
function Span(imp) { | ||
_classCallCheck(this, Span); | ||
// By default returns a no-op tracer. | ||
// | ||
// The base class could store the tracer that created it, but it does not | ||
// in order to ensure the no-op span implementation has zero members, | ||
// which allows V8 to aggressively optimize calls to such objects. | ||
this._imp = imp; | ||
} | ||
}, { | ||
key: '_tracer', | ||
value: function _tracer() { | ||
return noop.tracer; | ||
} | ||
/** | ||
* Returns the Span implementation object. The returned object is by its | ||
* nature entirely implementation-dependent. | ||
*/ | ||
// By default does nothing | ||
}, { | ||
key: '_setOperationName', | ||
value: function _setOperationName(name) {} | ||
_createClass(Span, [{ | ||
key: 'imp', | ||
value: function imp() { | ||
return this._imp; | ||
} | ||
// By default does nothing | ||
}, { | ||
key: '_setBaggageItem', | ||
value: function _setBaggageItem(key, value) {} | ||
// By default does nothing | ||
}, { | ||
key: '_getBaggageItem', | ||
value: function _getBaggageItem(key) {} | ||
// By default does nothing | ||
// | ||
// NOTE: both setTag() and addTags() map to this function. keyValuePairs | ||
// will always be an associative array. | ||
}, { | ||
key: '_addTags', | ||
value: function _addTags(keyValuePairs) {} | ||
// By default does nothing | ||
// | ||
// NOTE: both log() and logEvent() map to this function. fields will always | ||
// be an associative array. | ||
}, { | ||
key: '_log', | ||
value: function _log(fields) {} | ||
// By default does nothing | ||
// | ||
// finishTime is expected to be either a number or undefined. | ||
}, { | ||
key: '_finish', | ||
value: function _finish(finishTime) {} | ||
}]); | ||
@@ -888,3 +928,3 @@ | ||
/***/ }, | ||
/* 5 */ | ||
/* 4 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
@@ -894,112 +934,62 @@ | ||
/** | ||
* SpanContext represents Span state that must propagate to descendant Spans | ||
* and across process boundaries. | ||
* | ||
* SpanContext is logically divided into two pieces: the user-level "Baggage" | ||
* (see setBaggageItem and getBaggageItem) that propagates across Span | ||
* boundaries and any Tracer-implementation-specific fields that are needed to | ||
* identify or otherwise contextualize the associated Span instance (e.g., a | ||
* <trace_id, span_id, sampled> tuple). | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.span = exports.spanContext = exports.tracer = undefined; | ||
exports.initialize = initialize; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _tracer = __webpack_require__(2); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _tracer2 = _interopRequireDefault(_tracer); | ||
var SpanContext = function () { | ||
_createClass(SpanContext, [{ | ||
key: 'setBaggageItem', | ||
var _span_context = __webpack_require__(5); | ||
var _span_context2 = _interopRequireDefault(_span_context); | ||
/** | ||
* Sets a key:value pair on this SpanContext that also propagates to future | ||
* children of the associated Span. | ||
* | ||
* setBaggageItem() enables powerful functionality given a full-stack | ||
* opentracing integration (e.g., arbitrary application data from a web | ||
* client can make it, transparently, all the way into the depths of a | ||
* storage system), and with it some powerful costs: use this feature with | ||
* care. | ||
* | ||
* IMPORTANT NOTE #1: setBaggageItem() will only propagate baggage items to | ||
* *future* causal descendants of the associated Span. | ||
* | ||
* IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and | ||
* value is copied into every local *and remote* child of the associated | ||
* Span, and that can add up to a lot of network and cpu overhead. | ||
* | ||
* @param {string} key | ||
* @param {string} value | ||
*/ | ||
value: function setBaggageItem(key, value) { | ||
if (true) { | ||
if (arguments.length !== 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
if (this._imp) { | ||
this._imp.setBaggageItem(key, value); | ||
} | ||
} | ||
var _span = __webpack_require__(3); | ||
/** | ||
* Returns the value for a baggage item given its key. | ||
* | ||
* @param {string} key | ||
* The key for the given trace attribute. | ||
* @return {string} | ||
* String value for the given key, or undefined if the key does not | ||
* correspond to a set trace attribute. | ||
*/ | ||
var _span2 = _interopRequireDefault(_span); | ||
}, { | ||
key: 'getBaggageItem', | ||
value: function getBaggageItem(key) { | ||
if (true) { | ||
if (arguments.length !== 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
if (this._imp) { | ||
return this._imp.getBaggageItem(key); | ||
} | ||
return undefined; | ||
} | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* Constructs a new SpanContext object. | ||
* | ||
* This method should not be called directly; Span.context() should be used | ||
* instead. | ||
*/ | ||
/* eslint-disable import/no-mutable-exports */ | ||
var tracer = exports.tracer = null; | ||
var spanContext = exports.spanContext = null; | ||
var span = exports.span = null; | ||
/* eslint-enable import/no-mutable-exports */ | ||
}]); | ||
// Deferred initialization to avoid a dependency cycle where Tracer depends on | ||
// Span which depends on the noop tracer. | ||
function initialize() { | ||
exports.tracer = tracer = new _tracer2.default(); | ||
exports.span = span = new _span2.default(); | ||
exports.spanContext = spanContext = new _span_context2.default(); | ||
} | ||
/***/ }, | ||
/* 5 */ | ||
/***/ function(module, exports) { | ||
"use strict"; | ||
function SpanContext(imp) { | ||
_classCallCheck(this, SpanContext); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
this._imp = imp; | ||
} | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/** | ||
* Returns the SpanContext implementation object. The returned object is by | ||
* its nature entirely implementation-dependent. | ||
*/ | ||
/** | ||
* SpanContext represents Span state that must propagate to descendant Spans | ||
* and across process boundaries. | ||
* | ||
* SpanContext is logically divided into two pieces: the user-level "Baggage" | ||
* (see setBaggageItem and getBaggageItem) that propagates across Span | ||
* boundaries and any Tracer-implementation-specific fields that are needed to | ||
* identify or otherwise contextualize the associated Span instance (e.g., a | ||
* <trace_id, span_id, sampled> tuple). | ||
*/ | ||
var SpanContext = function SpanContext() { | ||
_classCallCheck(this, SpanContext); | ||
}; | ||
_createClass(SpanContext, [{ | ||
key: 'imp', | ||
value: function imp() { | ||
return this._imp; | ||
} | ||
}]); | ||
return SpanContext; | ||
}(); | ||
exports.default = SpanContext; | ||
@@ -1014,68 +1004,69 @@ module.exports = exports['default']; | ||
module.exports = { | ||
/** | ||
* The FORMAT_BINARY format represents SpanContexts in an opaque binary | ||
* carrier. | ||
* | ||
* Tracer.inject() will set the buffer field to an Array-like (Array, | ||
* ArrayBuffer, or TypedBuffer) object containing the injected binary data. | ||
* Any valid Object can be used as long as the buffer field of the object | ||
* can be set. | ||
* | ||
* Tracer.extract() will look for `carrier.buffer`, and that field is | ||
* expected to be an Array-like object (Array, ArrayBuffer, or | ||
* TypedBuffer). | ||
*/ | ||
FORMAT_BINARY: 'binary', | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
/** | ||
* The FORMAT_BINARY format represents SpanContexts in an opaque binary | ||
* carrier. | ||
* | ||
* Tracer.inject() will set the buffer field to an Array-like (Array, | ||
* ArrayBuffer, or TypedBuffer) object containing the injected binary data. | ||
* Any valid Object can be used as long as the buffer field of the object | ||
* can be set. | ||
* | ||
* Tracer.extract() will look for `carrier.buffer`, and that field is | ||
* expected to be an Array-like object (Array, ArrayBuffer, or | ||
* TypedBuffer). | ||
*/ | ||
var FORMAT_BINARY = exports.FORMAT_BINARY = 'binary'; | ||
/** | ||
* The FORMAT_TEXT_MAP format represents SpanContexts using a | ||
* string->string map (backed by a Javascript Object) as a carrier. | ||
* | ||
* NOTE: Unlike FORMAT_HTTP_HEADERS, FORMAT_TEXT_MAP places no restrictions | ||
* on the characters used in either the keys or the values of the map | ||
* entries. | ||
* | ||
* The FORMAT_TEXT_MAP carrier map may contain unrelated data (e.g., | ||
* arbitrary gRPC metadata); as such, the Tracer implementation should use | ||
* a prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
FORMAT_TEXT_MAP: 'text_map', | ||
/** | ||
* The FORMAT_TEXT_MAP format represents SpanContexts using a | ||
* string->string map (backed by a Javascript Object) as a carrier. | ||
* | ||
* NOTE: Unlike FORMAT_HTTP_HEADERS, FORMAT_TEXT_MAP places no restrictions | ||
* on the characters used in either the keys or the values of the map | ||
* entries. | ||
* | ||
* The FORMAT_TEXT_MAP carrier map may contain unrelated data (e.g., | ||
* arbitrary gRPC metadata); as such, the Tracer implementation should use | ||
* a prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
var FORMAT_TEXT_MAP = exports.FORMAT_TEXT_MAP = 'text_map'; | ||
/** | ||
* The FORMAT_HTTP_HEADERS format represents SpanContexts using a | ||
* character-restricted string->string map (backed by a Javascript Object) | ||
* as a carrier. | ||
* | ||
* Keys and values in the FORMAT_HTTP_HEADERS carrier must be suitable for | ||
* use as HTTP headers (without modification or further escaping). That is, | ||
* the keys have a greatly restricted character set, casing for the keys | ||
* may not be preserved by various intermediaries, and the values should be | ||
* URL-escaped. | ||
* | ||
* The FORMAT_HTTP_HEADERS carrier map may contain unrelated data (e.g., | ||
* arbitrary HTTP headers); as such, the Tracer implementation should use a | ||
* prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
FORMAT_HTTP_HEADERS: 'http_headers', | ||
/** | ||
* The FORMAT_HTTP_HEADERS format represents SpanContexts using a | ||
* character-restricted string->string map (backed by a Javascript Object) | ||
* as a carrier. | ||
* | ||
* Keys and values in the FORMAT_HTTP_HEADERS carrier must be suitable for | ||
* use as HTTP headers (without modification or further escaping). That is, | ||
* the keys have a greatly restricted character set, casing for the keys | ||
* may not be preserved by various intermediaries, and the values should be | ||
* URL-escaped. | ||
* | ||
* The FORMAT_HTTP_HEADERS carrier map may contain unrelated data (e.g., | ||
* arbitrary HTTP headers); as such, the Tracer implementation should use a | ||
* prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
var FORMAT_HTTP_HEADERS = exports.FORMAT_HTTP_HEADERS = 'http_headers'; | ||
/** | ||
* A Span may be the "child of" a parent Span. In a “child of” reference, | ||
* the parent Span depends on the child Span in some capacity. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
REFERENCE_CHILD_OF: 'child_of', | ||
/** | ||
* A Span may be the "child of" a parent Span. In a “child of” reference, | ||
* the parent Span depends on the child Span in some capacity. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
var REFERENCE_CHILD_OF = exports.REFERENCE_CHILD_OF = 'child_of'; | ||
/** | ||
* Some parent Spans do not depend in any way on the result of their child | ||
* Spans. In these cases, we say merely that the child Span “follows from” | ||
* the parent Span in a causal sense. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
REFERENCE_FOLLOWS_FROM: 'follows_from' | ||
}; | ||
/** | ||
* Some parent Spans do not depend in any way on the result of their child | ||
* Spans. In these cases, we say merely that the child Span “follows from” | ||
* the parent Span in a causal sense. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
var REFERENCE_FOLLOWS_FROM = exports.REFERENCE_FOLLOWS_FROM = 'follows_from'; | ||
@@ -1091,6 +1082,64 @@ /***/ }, | ||
}); | ||
exports.childOf = childOf; | ||
exports.followsFrom = followsFrom; | ||
var _constants = __webpack_require__(6); | ||
var Constants = _interopRequireWildcard(_constants); | ||
var _span = __webpack_require__(3); | ||
var _span2 = _interopRequireDefault(_span); | ||
var _reference = __webpack_require__(8); | ||
var _reference2 = _interopRequireDefault(_reference); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
/** | ||
* Return a new REFERENCE_CHILD_OF reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_CHILD_OF reference pointing to `spanContext` | ||
*/ | ||
function childOf(spanContext) { | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof _span2.default) { | ||
spanContext = spanContext.context(); | ||
} | ||
return new _reference2.default(Constants.REFERENCE_CHILD_OF, spanContext); | ||
} | ||
/** | ||
* Return a new REFERENCE_FOLLOWS_FROM reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_FOLLOWS_FROM reference pointing to `spanContext` | ||
*/ | ||
function followsFrom(spanContext) { | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof _span2.default) { | ||
spanContext = spanContext.context(); | ||
} | ||
return new _reference2.default(Constants.REFERENCE_FOLLOWS_FROM, spanContext); | ||
} | ||
/***/ }, | ||
/* 8 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _span = __webpack_require__(4); | ||
var _span = __webpack_require__(3); | ||
@@ -1113,3 +1162,2 @@ var _span2 = _interopRequireDefault(_span); | ||
*/ | ||
var Reference = function () { | ||
@@ -1170,7 +1218,13 @@ _createClass(Reference, [{ | ||
/***/ }, | ||
/* 8 */ | ||
/* 9 */ | ||
/***/ function(module, exports) { | ||
'use strict'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/** | ||
@@ -1182,13 +1236,6 @@ * Convenience class to use as a binary carrier. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var BinaryCarrier = function BinaryCarrier(binaryData) { | ||
_classCallCheck(this, BinaryCarrier); | ||
this.buffer = binaryData; | ||
this._buffer = binaryData; | ||
}; | ||
@@ -1195,0 +1242,0 @@ |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Tracer=t():e.Tracer=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";e.exports=n(1)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var i=n(2),u=r(i);e.exports=new u["default"]},function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function i(e){return e&&e.__esModule?e:{"default":e}}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var f=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),l=n(3),c=i(l),s=n(6),p=r(s),d=n(8),h=i(d),_=n(7),y=i(_),v=function(e){function t(){u(this,t);var e=o(this,Object.getPrototypeOf(t).call(this));for(var n in p)e[n]=p[n];return e.Reference=y["default"],e.BinaryCarrier=h["default"],e}return a(t,e),f(t,[{key:"initGlobalTracer",value:function(e){this._imp=e,e&&e.setInterface(this)}},{key:"initNewTracer",value:function(e){var t=new c["default"](e);return e&&e.setInterface(this),t}}]),t}(c["default"]);t["default"]=v,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=n(4),a=r(o),f=n(5),l=r(f),c=n(6),s=r(c),p=n(7),d=r(p),h=function(){function e(t){i(this,e),this._imp=t||null}return u(e,[{key:"startSpan",value:function(e,t){var n=null;if(this._imp){if(1===arguments.length?t="string"==typeof e?{operationName:e}:e:t.operationName=e,t.childOf){var r=this.childOf(t.childOf);t.references?t.references.push(r):t.references=[r],delete t.childOf}n=this._imp.startSpan(t)}return new a["default"](n)}},{key:"childOf",value:function(e){return new d["default"](s["default"].REFERENCE_CHILD_OF,e)}},{key:"followsFrom",value:function(e){return new d["default"](s["default"].REFERENCE_FOLLOWS_FROM,e)}},{key:"inject",value:function(e,t,n){this._imp&&(e instanceof a["default"]&&(e=e.context()),this._imp.inject(e._imp,t,n))}},{key:"extract",value:function(e,t){var n=null;return this._imp&&(n=this._imp.extract(e,t)),null!==n?new l["default"](n):null}},{key:"flush",value:function(e){return this._imp?void this._imp.flush(e):void e(null)}}]),u(e,[{key:"imp",value:function(){return this._imp}}]),e}();t["default"]=h,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=n(3),f=r(a),l=n(5),c=r(l),s=n(1),p=function(){function e(t){u(this,e),this._imp=t}return o(e,[{key:"context",value:function(){var e=null;return this._imp&&(e=this._imp.context()),new c["default"](e)}},{key:"tracer",value:function(){return this._imp?new f["default"](this._imp.tracer()):s}},{key:"setOperationName",value:function(e){return this._imp&&this._imp.setOperationName(e),this}},{key:"setTag",value:function(e,t){return this.addTags(i({},e,t)),this}},{key:"addTags",value:function(e){if(this._imp)return this._imp.addTags(e),this}},{key:"log",value:function(e){if(this._imp)return this._imp.log(e),this}},{key:"logEvent",value:function(e,t){return this.log({event:e,payload:t})}},{key:"finish",value:function(e){this._imp&&this._imp.finish(e)}}]),o(e,[{key:"imp",value:function(){return this._imp}}]),e}();t["default"]=p,e.exports=t["default"]},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=function(){function e(t){r(this,e),this._imp=t}return i(e,[{key:"setBaggageItem",value:function(e,t){this._imp&&this._imp.setBaggageItem(e,t)}},{key:"getBaggageItem",value:function(e){if(this._imp)return this._imp.getBaggageItem(e)}}]),i(e,[{key:"imp",value:function(){return this._imp}}]),e}();t["default"]=u,e.exports=t["default"]},function(e,t){"use strict";e.exports={FORMAT_BINARY:"binary",FORMAT_TEXT_MAP:"text_map",FORMAT_HTTP_HEADERS:"http_headers",REFERENCE_CHILD_OF:"child_of",REFERENCE_FOLLOWS_FROM:"follows_from"}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=n(4),a=r(o),f=n(5),l=(r(f),function(){function e(t,n){i(this,e),this._type=t,this._referencedContext=n instanceof a["default"]?n.context():n}return u(e,[{key:"type",value:function(){return this._type}},{key:"referencedContext",value:function(){return this._referencedContext}}]),e}());t["default"]=l,e.exports=t["default"]},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function i(e){n(this,i),this.buffer=e};t["default"]=r,e.exports=t["default"]}])}); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.opentracing=t():e.opentracing=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var u=n[r]={exports:{},id:r,loaded:!1};return e[r].call(u.exports,u,u.exports,t),u.loaded=!0,u.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function o(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)n.hasOwnProperty(r)&&(e[r]=n[r])}return e}var a=n(1),i=u(a),f=n(6),c=u(f),l=n(7),s=u(l),p=n(4),d=u(p),y=n(9),_=r(y),v=n(8),h=r(v),b=n(5),O=r(b),g=n(3),x=r(g),w=n(2),k=r(w);e.exports=o({BinaryCarrier:_["default"],Reference:h["default"],SpanContext:O["default"],Span:x["default"],Tracer:k["default"]},c,s,i),d.initialize()},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function i(e){d=e}function f(){return _}Object.defineProperty(t,"__esModule",{value:!0});var c=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();t.initGlobalTracer=i,t.globalTracer=f;var l=n(2),s=r(l),p=new s["default"],d=null,y=function(e){function t(){return u(this,t),o(this,Object.getPrototypeOf(t).apply(this,arguments))}return a(t,e),c(t,[{key:"startSpan",value:function(){var e=d||p;return e.startSpan.apply(e,arguments)}},{key:"inject",value:function(){var e=d||p;return e.inject.apply(e,arguments)}},{key:"extract",value:function(){var e=d||p;return e.extract.apply(e,arguments)}}]),t}(s["default"]),_=new y},function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function u(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(3),f=u(i),c=n(5),l=(u(c),n(6)),s=(r(l),n(7)),p=r(s),d=n(4),y=r(d),_=function(){function e(){o(this,e)}return a(e,[{key:"startSpan",value:function(e,t){if(t=t||{},t.childOf){var n=p.childOf(t.childOf);t.references?t.references.push(n):t.references=[n],delete t.childOf}return this._startSpan(e,t)}},{key:"inject",value:function(e,t,n){return e instanceof f["default"]&&(e=e.context()),this._inject(e,t,n)}},{key:"extract",value:function(e,t){return this._extract(e,t)}},{key:"_startSpan",value:function(e,t){return y.span}},{key:"_inject",value:function(e,t,n){}},{key:"_extract",value:function(e,t){return y.spanContext}}]),e}();t["default"]=_,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(4),f=r(i),c=function(){function e(){o(this,e)}return a(e,[{key:"context",value:function(){return this._context()}},{key:"tracer",value:function(){return this._tracer()}},{key:"setOperationName",value:function(e){return this._setOperationName(e),this}},{key:"setBaggageItem",value:function(e,t){return this._setBaggageItem(e,t),this}},{key:"getBaggageItem",value:function(e){return this._getBaggageItem(e)}},{key:"setTag",value:function(e,t){return this._addTags(u({},e,t)),this}},{key:"addTags",value:function(e){return this._addTags(e),this}},{key:"log",value:function(e){return this._log(e),this}},{key:"logEvent",value:function(e,t){return this._log({event:e,payload:t})}},{key:"finish",value:function(e){this._finish(e)}},{key:"_context",value:function(){return f.spanContext}},{key:"_tracer",value:function(){return f.tracer}},{key:"_setOperationName",value:function(e){}},{key:"_setBaggageItem",value:function(e,t){}},{key:"_getBaggageItem",value:function(e){}},{key:"_addTags",value:function(e){}},{key:"_log",value:function(e){}},{key:"_finish",value:function(e){}}]),e}();t["default"]=c,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(){t.tracer=s=new a["default"],t.span=d=new l["default"],t.spanContext=p=new f["default"]}Object.defineProperty(t,"__esModule",{value:!0}),t.span=t.spanContext=t.tracer=void 0,t.initialize=u;var o=n(2),a=r(o),i=n(5),f=r(i),c=n(3),l=r(c),s=t.tracer=null,p=t.spanContext=null,d=t.span=null},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function u(){n(this,u)};t["default"]=r,e.exports=t["default"]},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.FORMAT_BINARY="binary",t.FORMAT_TEXT_MAP="text_map",t.FORMAT_HTTP_HEADERS="http_headers",t.REFERENCE_CHILD_OF="child_of",t.REFERENCE_FOLLOWS_FROM="follows_from"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function o(e){return e instanceof l["default"]&&(e=e.context()),new p["default"](f.REFERENCE_CHILD_OF,e)}function a(e){return e instanceof l["default"]&&(e=e.context()),new p["default"](f.REFERENCE_FOLLOWS_FROM,e)}Object.defineProperty(t,"__esModule",{value:!0}),t.childOf=o,t.followsFrom=a;var i=n(6),f=u(i),c=n(3),l=r(c),s=n(8),p=r(s)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=n(3),i=r(a),f=n(5),c=(r(f),function(){function e(t,n){u(this,e),this._type=t,this._referencedContext=n instanceof i["default"]?n.context():n}return o(e,[{key:"type",value:function(){return this._type}},{key:"referencedContext",value:function(){return this._referencedContext}}]),e}());t["default"]=c,e.exports=t["default"]},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function u(e){n(this,u),this._buffer=e};t["default"]=r,e.exports=t["default"]}])}); |
{ | ||
"name": "opentracing", | ||
"version": "0.11.1", | ||
"main": "dist/opentracing-node.js", | ||
"version": "0.12.1", | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://opensource.org/licenses/MIT" | ||
} | ||
], | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"prepublish": "npm run webpack", | ||
"test": "node node_modules/mocha/bin/mocha -c test/unittest.js --check-leaks", | ||
"webpack": "npm run webpack-node-debug && npm run webpack-node-prod && npm run webpack-browser-debug && npm run webpack-browser-prod", | ||
"webpack-node-debug": "BUILD_PLATFORM=node BUILD_CONFIG=debug webpack --display-error-details", | ||
"webpack-node-prod": "BUILD_PLATFORM=node BUILD_CONFIG=prod webpack --display-error-details", | ||
"webpack-browser-debug": "BUILD_PLATFORM=browser BUILD_CONFIG=debug webpack --display-error-details", | ||
"webpack-browser-prod": "BUILD_PLATFORM=browser BUILD_CONFIG=prod webpack --display-error-details" | ||
"test": "npm run test-cover", | ||
"cover": "npm run test-cover && istanbul check-coverage", | ||
"test-cover": "NODE_ENV=debug istanbul cover --report lcovonly --print none ./node_modules/.bin/_mocha test/unittest.js -- --check-leaks --color && istanbul report text", | ||
"cover-html": "NODE_ENV=debug istanbul cover --report html --print none ./node_modules/.bin/_mocha test/unittest.js -- --check-leaks --color && istanbul report text", | ||
"webpack": "npm run webpack-browser-debug && npm run webpack-browser-prod", | ||
"webpack-browser-debug": "BUILD_CONFIG=debug webpack --display-error-details", | ||
"webpack-browser-prod": "BUILD_CONFIG=production webpack --display-error-details" | ||
}, | ||
@@ -20,2 +27,3 @@ "repository": { | ||
"devDependencies": { | ||
"babel-cli": "^6.11.4", | ||
"babel-core": "^6.3.26", | ||
@@ -40,7 +48,9 @@ "babel-loader": "^6.2.0", | ||
"babel-plugin-transform-es2015-unicode-regex": "^6.5.0", | ||
"babel-plugin-transform-node-env-inline-and-fold": "^6.8.1", | ||
"babel-polyfill": "^6.3.14", | ||
"babel-preset-es2015": "^6.3.13", | ||
"babel-preset-es2015": "^6.13.2", | ||
"chai": "^3.4.1", | ||
"clone": "^1.0.2", | ||
"colors": "^1.1.2", | ||
"coveralls": "^2.11.12", | ||
"eslint": "2.13.1", | ||
@@ -51,2 +61,3 @@ "eslint-config-airbnb": "^9.0.1", | ||
"eslint-plugin-react": "^5.2.2", | ||
"istanbul": "^0.4.5", | ||
"json-loader": "^0.5.4", | ||
@@ -53,0 +64,0 @@ "mocha": "^2.4.5", |
122
README.md
@@ -5,2 +5,4 @@ # OpenTracing API for JavaScript | ||
[![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] | ||
## Required Reading | ||
@@ -13,3 +15,3 @@ | ||
Install the package: | ||
Install the package using `npm`: | ||
@@ -20,2 +22,24 @@ ```bash | ||
### Example | ||
The package contains a example using a naive `MockTracer` implementation. To run the example: | ||
```bash | ||
make example | ||
``` | ||
The output should look something like: | ||
``` | ||
Spans: | ||
parent_span - 1521ms | ||
tag 'custom':'tag value' | ||
tag 'alpha':'1000' | ||
child_span - 503ms | ||
tag 'alpha':'200' | ||
tag 'beta':'50' | ||
``` | ||
### Code snippet | ||
In your JavaScript code, add instrumentation to the operations to be tracked. This is composed primarily of using "spans" around operations of interest and adding log statements to capture useful data relevant to those operations. | ||
@@ -25,5 +49,9 @@ | ||
var http = require('http'); | ||
var Tracer = require('opentracing'); | ||
var opentracing = require('opentracing'); | ||
var span = Tracer.startSpan('http_request'); | ||
// NOTE: the default OpenTracing tracer does not record any tracing information. | ||
// Replace this line with the tracer implementation of your choice. | ||
var tracer = new opentracing.Tracer(); | ||
var span = tracer.startSpan('http_request'); | ||
var opts = { | ||
@@ -51,65 +79,79 @@ host : 'example.com', | ||
The default behavior of the `opentracing` package is to act as a "no-op" implementation. | ||
As noted in the source snippet, the default behavior of the `opentracing` package is to act as a "no op" implementation. To capture and make the tracing data actionable, the `tracer` object should be initialized with the OpenTracing implementation of your choice as in the pseudo-code below: | ||
To capture and make the tracing data actionable, the `Tracer` object should be initialized with the OpenTracing implementation of your choice as in the pseudo-code below: | ||
```js | ||
var Tracer = require('opentracing'); | ||
var TracingBackend = require('tracing-implementation-of-your-choice'); | ||
Tracer.initGlobalTracer(TracingBackend.create()); | ||
var CustomTracer = require('tracing-implementation-of-your-choice'); | ||
var tracer = new CustomTracer(); | ||
``` | ||
*Note: the underlying implementation object is shared between all inclusions of the `opentracing` package, so `initGlobalTracer` needs to only be called once during initialization.* | ||
### Usage in the browser | ||
## API Documentation | ||
The package contains two bundles built with webpack that can be included using a standard `<script>` tag. The library will be exposed under the global `opentracing` symbol: | ||
There is a hosted copy of the current generated [ESDoc API Documentation here](https://doc.esdoc.org/github.com/opentracing/opentracing-javascript/). | ||
* `dist/opentracing-browser.min.js` - minified, no runtime checks | ||
* `dist/opentracing-browser.js` - debug version with runtime checks | ||
## Notes on backwards-incompatible changes | ||
### Global tracer | ||
### v0.9.x to v0.10.x | ||
The library also provides a global singleton tracer for convenience. This can be set and accessed via the following: | ||
This release makes the `opentracing-javascript` package conformant with the ideas proposed in [opentracing/opentracing.github.io#99](https://github.com/opentracing/opentracing.github.io/issues/99). The API changes can be summarized as follows: | ||
```javascript | ||
opentracing.initGlobalTracer(new CustomTracer()); | ||
* Every `Span` has a `SpanContext`, available via `Span.context()`. The `SpanContext` represents the subset of `Span` state that must propagate across process boundaries in-band along with the application data. | ||
* `Span.setBaggageItem()` and `Span.getBaggageItem()` have moved to `SpanContext`. Calls can be migrated trivially: `Span.context().{set,get}BaggageItem()`. | ||
* The first parameter to `Tracer.inject()` is now a `SpanContext`. As a convenience, a `Span` may be passed instead. | ||
* There is a new concept called a `Reference`; a reference describes a relationship between a newly started `Span` and some other `Span` (via a `SpanContext`). The common case is to describe a reference to a parent `Span` that depends on the child `Span` ('REFERENCE_CHILD_OF`). | ||
* `Tracer.startSpan(operation, fields)` no longer accepts `fields.parent`; it now accepts either `fields.childOf`, a `SpanContext` or `Span` instance, or `fields.references`, an array of one or more `Reference` objects. The former is just a shorthand for the latter. | ||
* `Tracer.join(operationName, format, carrier)` has been removed from the API. In its place, use `Tracer.extract(format, carrier)` which returns a `SpanContext`, and pass that `SpanContext` as a reference in `Tracer.startSpan()`. | ||
var tracer = opentracing.globalTracer(); | ||
``` | ||
TL;DR, to start a child span, do this: | ||
Note: `globalTracer()` returns a wrapper on the actual tracer object. This is done for convenience of use as it ensures that the function will always return a non-null object. This can be helpful in cases where it is difficult or impossible to know precisely when `initGlobalTracer` is called (for example, when writing a utility library that does not control the initialization process). For more precise control, individual `Tracer` objects can be used instead of the global tracer. | ||
### Node.js debug version | ||
```javascript | ||
let parentSpan = ...; | ||
let childSpan = Tracer.startSpan('child op', { childOf : parentSpan }); | ||
var opentracing = require('opentracing/debug'); | ||
``` | ||
... and to continue a trace from the server side of an RPC, do this: | ||
Requiring `opentracing/debug` will include a version of the library with additional runtime checks that are useful for debugging but not desirable for production use. | ||
```javascript | ||
let format = ...; // same as for Tracer.join() | ||
let carrier = ...; // same as for Tracer.join() | ||
let extractedCtx = Tracer.extract(format, carrier); | ||
let serverSpan = Tracer.startSpan('...', { childOf : extractedCtx }); | ||
``` | ||
## API Documentation | ||
## Development Information | ||
There is a hosted copy of the current generated [ESDoc API Documentation here](https://doc.esdoc.org/github.com/opentracing/opentracing-javascript/). | ||
*I.e., information for developers working on this package.* | ||
## Contributing & developer information | ||
#### Building the library | ||
See the [OpenTracing website](http://opentracing.io) for general information on contributing to OpenTracing. | ||
The project is built using a `Makefile`. Run: | ||
* `make build` creates the compiled, distributable code | ||
* `make test` runs the tests | ||
## JavaScript OpenTracing Implementations | ||
## OpenTracing tracer implementations | ||
*I.e. information for developers wanting to create an OpenTracing-compatible JavaScript implementation.* | ||
*This section is intended for developers wishing to* ***implement their own tracers***. *Developers who simply wish to* ***use OpenTracing*** *can safely ignore this information.* | ||
The API layer uses a [bridge pattern](https://en.wikipedia.org/wiki/Bridge_pattern) to pass work to the specific tracing implementation. The indirection allows the API layer to enforce greater API conformance and standardization across implementations (especially in debug builds), which helps keep instrumented code more portable across OpenTracing implementations. | ||
### Custom tracer implementation | ||
The "implementation API" - i.e. the interface the API layer expects to be able to call on the implementation - is a proper subset of the API layer itself. The surface area of the implementation API has been reduced in the case where the an API layer method (usually a convenience method of some form) can be expressed in terms of another more general method. For example, `logEvent` can be expressed as a `log` call, therefore the implementation only needs to implement `log`. | ||
Implementations can subclass `opentracing.Trace`, `opentracing.Span`, and the other API classes to build a OpenTracing tracer. | ||
For truly implementation-dependent methods, the JavaScript API layer *does* expose `imp()` methods on each major type to allow the implementations to be accessed directly. Use of implementation-dependent methods is discouraged as it immediately makes instrumented code no longer portable. However, the `imp()` call does at least call attention to deviations from the standard API without making implementation-dependent calls impossible. | ||
Due to the dynamic nature of JavaScript, implementations can simply implement classes with the same signatures as the OpenTracing classes and use these directly as well (there's no need to subclass). | ||
Lastly, optionally implementations may choose to subclass `opentracing.Trace`, etc. and implement the underscore prefixed methods such as `_addTag` to pick up a bit of common code implemented in the base classes. This is entirely optional. | ||
### API compatibility testing | ||
If `mocha` is being used for unit testing, the `api_compatibility.js` file can be used to test the custom tracer. The file exports a single function that expects as an argument a function that will return a new instance of the tracer. | ||
```javascript | ||
var apiCompatibilityChecks = require('opentracing/test/api_compatibility.js'); | ||
apiCompatibilityCheck(function() { | ||
return new CustomTracer(); | ||
}); | ||
``` | ||
### MockTracer | ||
An minimal example tracer is provided in the `src/mock_tracer` directory of the source code. | ||
[ci-img]: https://travis-ci.org/opentracing/opentracing-javascript.svg?branch=master | ||
[cov-img]: https://coveralls.io/repos/github/opentracing/opentracing-javascript/badge.svg?branch=master | ||
[ci]: https://travis-ci.org/opentracing/opentracing-javascript | ||
[cov]: https://coveralls.io/github/opentracing/opentracing-javascript?branch=master |
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
/** | ||
@@ -11,4 +9,4 @@ * Convenience class to use as a binary carrier. | ||
constructor(binaryData) { | ||
this.buffer = binaryData; | ||
this._buffer = binaryData; | ||
} | ||
} |
@@ -1,68 +0,64 @@ | ||
'use strict'; | ||
/** | ||
* The FORMAT_BINARY format represents SpanContexts in an opaque binary | ||
* carrier. | ||
* | ||
* Tracer.inject() will set the buffer field to an Array-like (Array, | ||
* ArrayBuffer, or TypedBuffer) object containing the injected binary data. | ||
* Any valid Object can be used as long as the buffer field of the object | ||
* can be set. | ||
* | ||
* Tracer.extract() will look for `carrier.buffer`, and that field is | ||
* expected to be an Array-like object (Array, ArrayBuffer, or | ||
* TypedBuffer). | ||
*/ | ||
export const FORMAT_BINARY = 'binary'; | ||
module.exports = { | ||
/** | ||
* The FORMAT_BINARY format represents SpanContexts in an opaque binary | ||
* carrier. | ||
* | ||
* Tracer.inject() will set the buffer field to an Array-like (Array, | ||
* ArrayBuffer, or TypedBuffer) object containing the injected binary data. | ||
* Any valid Object can be used as long as the buffer field of the object | ||
* can be set. | ||
* | ||
* Tracer.extract() will look for `carrier.buffer`, and that field is | ||
* expected to be an Array-like object (Array, ArrayBuffer, or | ||
* TypedBuffer). | ||
*/ | ||
FORMAT_BINARY : 'binary', | ||
/** | ||
* The FORMAT_TEXT_MAP format represents SpanContexts using a | ||
* string->string map (backed by a Javascript Object) as a carrier. | ||
* | ||
* NOTE: Unlike FORMAT_HTTP_HEADERS, FORMAT_TEXT_MAP places no restrictions | ||
* on the characters used in either the keys or the values of the map | ||
* entries. | ||
* | ||
* The FORMAT_TEXT_MAP carrier map may contain unrelated data (e.g., | ||
* arbitrary gRPC metadata); as such, the Tracer implementation should use | ||
* a prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
export const FORMAT_TEXT_MAP = 'text_map'; | ||
/** | ||
* The FORMAT_TEXT_MAP format represents SpanContexts using a | ||
* string->string map (backed by a Javascript Object) as a carrier. | ||
* | ||
* NOTE: Unlike FORMAT_HTTP_HEADERS, FORMAT_TEXT_MAP places no restrictions | ||
* on the characters used in either the keys or the values of the map | ||
* entries. | ||
* | ||
* The FORMAT_TEXT_MAP carrier map may contain unrelated data (e.g., | ||
* arbitrary gRPC metadata); as such, the Tracer implementation should use | ||
* a prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
FORMAT_TEXT_MAP : 'text_map', | ||
/** | ||
* The FORMAT_HTTP_HEADERS format represents SpanContexts using a | ||
* character-restricted string->string map (backed by a Javascript Object) | ||
* as a carrier. | ||
* | ||
* Keys and values in the FORMAT_HTTP_HEADERS carrier must be suitable for | ||
* use as HTTP headers (without modification or further escaping). That is, | ||
* the keys have a greatly restricted character set, casing for the keys | ||
* may not be preserved by various intermediaries, and the values should be | ||
* URL-escaped. | ||
* | ||
* The FORMAT_HTTP_HEADERS carrier map may contain unrelated data (e.g., | ||
* arbitrary HTTP headers); as such, the Tracer implementation should use a | ||
* prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
export const FORMAT_HTTP_HEADERS = 'http_headers'; | ||
/** | ||
* The FORMAT_HTTP_HEADERS format represents SpanContexts using a | ||
* character-restricted string->string map (backed by a Javascript Object) | ||
* as a carrier. | ||
* | ||
* Keys and values in the FORMAT_HTTP_HEADERS carrier must be suitable for | ||
* use as HTTP headers (without modification or further escaping). That is, | ||
* the keys have a greatly restricted character set, casing for the keys | ||
* may not be preserved by various intermediaries, and the values should be | ||
* URL-escaped. | ||
* | ||
* The FORMAT_HTTP_HEADERS carrier map may contain unrelated data (e.g., | ||
* arbitrary HTTP headers); as such, the Tracer implementation should use a | ||
* prefix or other convention to distinguish Tracer-specific key:value | ||
* pairs. | ||
*/ | ||
FORMAT_HTTP_HEADERS : 'http_headers', | ||
/** | ||
* A Span may be the "child of" a parent Span. In a “child of” reference, | ||
* the parent Span depends on the child Span in some capacity. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
export const REFERENCE_CHILD_OF = 'child_of'; | ||
/** | ||
* A Span may be the "child of" a parent Span. In a “child of” reference, | ||
* the parent Span depends on the child Span in some capacity. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
REFERENCE_CHILD_OF : 'child_of', | ||
/** | ||
* Some parent Spans do not depend in any way on the result of their child | ||
* Spans. In these cases, we say merely that the child Span “follows from” | ||
* the parent Span in a causal sense. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
REFERENCE_FOLLOWS_FROM : 'follows_from', | ||
}; | ||
/** | ||
* Some parent Spans do not depend in any way on the result of their child | ||
* Spans. In these cases, we say merely that the child Span “follows from” | ||
* the parent Span in a causal sense. | ||
* | ||
* See more about reference types at http://opentracing.io/spec/ | ||
*/ | ||
export const REFERENCE_FOLLOWS_FROM = 'follows_from'; |
@@ -1,1 +0,42 @@ | ||
module.exports = require('./default_tracer'); | ||
import * as GlobalTracer from './global_tracer'; | ||
import * as Constants from './constants'; | ||
import * as Functions from './functions'; | ||
import * as Noop from './noop'; | ||
import BinaryCarrier from './binary_carrier'; | ||
import Reference from './reference'; | ||
import SpanContext from './span_context'; | ||
import Span from './span'; | ||
import Tracer from './tracer'; | ||
// Object.assign() is not available on Node v0.12, so implement a similar | ||
// function here (subset of a proper polyfill). | ||
function _extend(target) { | ||
for (let index = 1; index < arguments.length; index++) { | ||
const source = arguments[index]; | ||
for (let key in source) { // eslint-disable-line no-restricted-syntax | ||
if (source.hasOwnProperty(key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
} | ||
// Use `module.exports` rather than `export` to avoid the need to use `.default` | ||
// when requiring the package in ES5 code. | ||
module.exports = _extend( | ||
{ | ||
BinaryCarrier : BinaryCarrier, | ||
Reference : Reference, | ||
SpanContext : SpanContext, | ||
Span : Span, | ||
Tracer : Tracer, | ||
}, | ||
Constants, | ||
Functions, | ||
GlobalTracer | ||
); | ||
// Initialize the noops last to avoid a dependecy cycle between the classes. | ||
Noop.initialize(); |
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
import Span from './span'; | ||
@@ -40,3 +38,3 @@ import SpanContext from './span_context'; | ||
constructor(type, referencedContext) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (!(referencedContext instanceof SpanContext || referencedContext instanceof Span)) { | ||
@@ -43,0 +41,0 @@ throw new Error('referencedContext must be a Span or SpanContext instance'); |
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
/** | ||
@@ -14,72 +12,3 @@ * SpanContext represents Span state that must propagate to descendant Spans | ||
export default class SpanContext { | ||
/** | ||
* Sets a key:value pair on this SpanContext that also propagates to future | ||
* children of the associated Span. | ||
* | ||
* setBaggageItem() enables powerful functionality given a full-stack | ||
* opentracing integration (e.g., arbitrary application data from a web | ||
* client can make it, transparently, all the way into the depths of a | ||
* storage system), and with it some powerful costs: use this feature with | ||
* care. | ||
* | ||
* IMPORTANT NOTE #1: setBaggageItem() will only propagate baggage items to | ||
* *future* causal descendants of the associated Span. | ||
* | ||
* IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and | ||
* value is copied into every local *and remote* child of the associated | ||
* Span, and that can add up to a lot of network and cpu overhead. | ||
* | ||
* @param {string} key | ||
* @param {string} value | ||
*/ | ||
setBaggageItem(key, value) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
if (arguments.length !== 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
if (this._imp) { | ||
this._imp.setBaggageItem(key, value); | ||
} | ||
} | ||
/** | ||
* Returns the value for a baggage item given its key. | ||
* | ||
* @param {string} key | ||
* The key for the given trace attribute. | ||
* @return {string} | ||
* String value for the given key, or undefined if the key does not | ||
* correspond to a set trace attribute. | ||
*/ | ||
getBaggageItem(key) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
if (arguments.length !== 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
if (this._imp) { | ||
return this._imp.getBaggageItem(key); | ||
} | ||
return undefined; | ||
} | ||
/** | ||
* Constructs a new SpanContext object. | ||
* | ||
* This method should not be called directly; Span.context() should be used | ||
* instead. | ||
*/ | ||
constructor(imp) { | ||
this._imp = imp; | ||
} | ||
/** | ||
* Returns the SpanContext implementation object. The returned object is by | ||
* its nature entirely implementation-dependent. | ||
*/ | ||
imp() { | ||
return this._imp; | ||
} | ||
// The SpanContext is entirely implementation dependent | ||
} |
197
src/span.js
@@ -1,7 +0,3 @@ | ||
'use strict'; | ||
import * as noop from './noop'; | ||
import Tracer from './tracer'; | ||
import SpanContext from './span_context'; | ||
let defaultTracer = require('./default_tracer'); | ||
/** | ||
@@ -25,3 +21,4 @@ * Span represents a logical unit of work as part of a broader Trace. Examples | ||
context() { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 0) { | ||
@@ -31,9 +28,7 @@ throw new Error('Invalid number of arguments'); | ||
} | ||
let spanContextImp = null; | ||
if (this._imp) { | ||
spanContextImp = this._imp.context(); | ||
} | ||
return new SpanContext(spanContextImp); | ||
return this._context(); | ||
} | ||
/** | ||
@@ -45,3 +40,4 @@ * Returns the Tracer object used to create this Span. | ||
tracer() { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 0) { | ||
@@ -51,6 +47,4 @@ throw new Error('Invalid number of arguments'); | ||
} | ||
if (this._imp) { | ||
return new Tracer(this._imp.tracer()); | ||
} | ||
return defaultTracer; | ||
return this._tracer(); | ||
} | ||
@@ -64,3 +58,4 @@ | ||
setOperationName(name) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 1) { | ||
@@ -73,5 +68,36 @@ throw new Error('Invalid number of arguments'); | ||
} | ||
if (this._imp) { | ||
this._imp.setOperationName(name); | ||
this._setOperationName(name); | ||
return this; | ||
} | ||
/** | ||
* Sets a key:value pair on this Span that also propagates to future | ||
* children of the associated Span. | ||
* | ||
* setBaggageItem() enables powerful functionality given a full-stack | ||
* opentracing integration (e.g., arbitrary application data from a web | ||
* client can make it, transparently, all the way into the depths of a | ||
* storage system), and with it some powerful costs: use this feature with | ||
* care. | ||
* | ||
* IMPORTANT NOTE #1: setBaggageItem() will only propagate baggage items to | ||
* *future* causal descendants of the associated Span. | ||
* | ||
* IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and | ||
* value is copied into every local *and remote* child of the associated | ||
* Span, and that can add up to a lot of network and cpu overhead. | ||
* | ||
* @param {string} key | ||
* @param {string} value | ||
*/ | ||
setBaggageItem(key, value) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
this._setBaggageItem(key, value); | ||
return this; | ||
@@ -81,4 +107,24 @@ } | ||
/** | ||
* Adds a single tag to the span. See `AddTags()` for details. | ||
* Returns the value for a baggage item given its key. | ||
* | ||
* @param {string} key | ||
* The key for the given trace attribute. | ||
* @return {string} | ||
* String value for the given key, or undefined if the key does not | ||
* correspond to a set trace attribute. | ||
*/ | ||
getBaggageItem(key) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
} | ||
return this._getBaggageItem(key); | ||
} | ||
/** | ||
* Adds a single tag to the span. See `addTags()` for details. | ||
* | ||
* @param {string} key | ||
@@ -88,3 +134,4 @@ * @param {any} value | ||
setTag(key, value) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 2) { | ||
@@ -97,3 +144,5 @@ throw new Error('Invalid number of arguments'); | ||
} | ||
this.addTags({ [key] : value }); | ||
// NOTE: the call is normalized to a call to _addTags() | ||
this._addTags({ [key] : value }); | ||
return this; | ||
@@ -118,8 +167,9 @@ } | ||
*/ | ||
addTags(keyValuePairs) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
addTags(keyValueMap) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
if (typeof keyValuePairs !== 'object') { | ||
if (typeof keyValueMap !== 'object') { | ||
throw new Error('Invalid argument type'); | ||
@@ -129,6 +179,3 @@ } | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.addTags(keyValuePairs); | ||
this._addTags(keyValueMap); | ||
return this; | ||
@@ -151,3 +198,4 @@ } | ||
log(fields) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 1) { | ||
@@ -160,6 +208,4 @@ throw new Error('Invalid number of arguments'); | ||
} | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.log(fields); | ||
this._log(fields); | ||
return this; | ||
@@ -176,3 +222,16 @@ } | ||
logEvent(eventName, payload) { | ||
return this.log({ | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length >= 1 && arguments.length <= 2) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
if (typeof eventName !== 'string') { | ||
throw new Error('Expected eventName to be a string'); | ||
} | ||
if (payload !== undefined && typeof payload !== 'object') { | ||
throw new Error('Expected payload to be an object'); | ||
} | ||
} | ||
return this._log({ | ||
event : eventName, | ||
@@ -197,3 +256,4 @@ payload : payload, | ||
finish(finishTime) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length > 1) { | ||
@@ -207,27 +267,58 @@ throw new Error('Invalid arguments'); | ||
if (!this._imp) { | ||
return; | ||
} | ||
this._imp.finish(finishTime); | ||
this._finish(finishTime); | ||
// Do not return `this`. The Span generally should not be used after it | ||
// is finished so chaining is not desired in this context. | ||
} | ||
// ---------------------------------------------------------------------- // | ||
// Private and non-standard methods | ||
// Derived classes can choose to implement the below | ||
// ---------------------------------------------------------------------- // | ||
/** | ||
* Constructs a new Span object, this method should not be called directly; | ||
* Tracer.startSpan() or Tracer.join() should be used instead. | ||
*/ | ||
constructor(imp) { | ||
this._imp = imp; | ||
// By default returns a no-op SpanContext. | ||
_context() { | ||
return noop.spanContext; | ||
} | ||
/** | ||
* Returns the Span implementation object. The returned object is by its | ||
* nature entirely implementation-dependent. | ||
*/ | ||
imp() { | ||
return this._imp; | ||
// By default returns a no-op tracer. | ||
// | ||
// The base class could store the tracer that created it, but it does not | ||
// in order to ensure the no-op span implementation has zero members, | ||
// which allows V8 to aggressively optimize calls to such objects. | ||
_tracer() { | ||
return noop.tracer; | ||
} | ||
// By default does nothing | ||
_setOperationName(name) { | ||
} | ||
// By default does nothing | ||
_setBaggageItem(key, value) { | ||
} | ||
// By default does nothing | ||
_getBaggageItem(key) { | ||
} | ||
// By default does nothing | ||
// | ||
// NOTE: both setTag() and addTags() map to this function. keyValuePairs | ||
// will always be an associative array. | ||
_addTags(keyValuePairs) { | ||
} | ||
// By default does nothing | ||
// | ||
// NOTE: both log() and logEvent() map to this function. fields will always | ||
// be an associative array. | ||
_log(fields) { | ||
} | ||
// By default does nothing | ||
// | ||
// finishTime is expected to be either a number or undefined. | ||
_finish(finishTime) { | ||
} | ||
} |
@@ -1,7 +0,6 @@ | ||
'use strict'; | ||
import Span from './span'; | ||
import SpanContext from './span_context'; | ||
import Constants from './constants'; | ||
import Reference from './reference'; | ||
import * as Constants from './constants'; | ||
import * as Functions from './functions'; | ||
import * as Noop from './noop'; | ||
@@ -13,2 +12,7 @@ /** | ||
* The default object acts as a no-op implementation. | ||
* | ||
* Note to implementators: derived classes can choose to directly implement the | ||
* methods in the "OpenTracing API methods" section, or optionally the subset of | ||
* underscore-prefixed methods to pick up the argument checking and handling | ||
* automatically from the base class. | ||
*/ | ||
@@ -31,9 +35,6 @@ export default class Tracer { | ||
* var child = Tracer.startSpan('Subroutine', { | ||
* reference: Tracer.childOf(parent.context()), | ||
* childOf: parent.context(), | ||
* }); | ||
* | ||
* @param {string|object} nameOrFields - if the given argument is a | ||
* string, it is the name of the operation and the second `fields` | ||
* argument is optional. If it is an object, it is treated as the | ||
* fields argument and a second argument should not be provided. | ||
* @param {string} name - the name of the operation. | ||
* @param {object} [fields] - the fields to set on the newly created span. | ||
@@ -59,91 +60,41 @@ * @param {string} [fields.operationName] - the name to use for the newly | ||
*/ | ||
startSpan(nameOrFields, fields) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
startSpan(name, fields) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length > 2) { | ||
throw new Error('Invalid number of arguments.'); | ||
} | ||
if (typeof nameOrFields !== 'string' && typeof nameOrFields !== 'object') { | ||
throw new Error('argument expected to be a string or object'); | ||
if (typeof name !== 'string') { | ||
throw new Error('argument expected to be a string'); | ||
} | ||
if (typeof nameOrFields === 'string' && nameOrFields.length === 0) { | ||
if (name.length === 0) { | ||
throw new Error('operation name cannot be length zero'); | ||
} | ||
if (typeof nameOrFields === 'object') { | ||
if (arguments.length !== 1) { | ||
throw new Error('Unexpected number of arguments'); | ||
} | ||
if (nameOrFields === null) { | ||
throw new Error('fields should not be null'); | ||
} | ||
if (!nameOrFields.operationName) { | ||
throw new Error('operationName is a required parameter'); | ||
} | ||
if (fields && fields.childOf && fields.references) { | ||
throw new Error('At most one of `childOf` and ' + | ||
'`references` may be specified'); | ||
} | ||
if (fields && fields.childOf && !( | ||
fields.childOf instanceof Span || | ||
fields.childOf instanceof SpanContext)) { | ||
throw new Error('childOf must be a Span or SpanContext instance'); | ||
} | ||
} | ||
let spanImp = null; | ||
if (this._imp) { | ||
// Normalize the argument so the implementation is always provided | ||
// an associative array of fields. | ||
if (arguments.length === 1) { | ||
if (typeof nameOrFields === 'string') { | ||
fields = { | ||
operationName : nameOrFields, | ||
}; | ||
} else { | ||
fields = nameOrFields; | ||
} | ||
// Convert fields.childOf to fields.references as needed. | ||
fields = fields || {}; | ||
if (fields.childOf) { | ||
// Convert from a Span or a SpanContext into a Reference. | ||
let childOf = Functions.childOf(fields.childOf); | ||
if (fields.references) { | ||
fields.references.push(childOf); | ||
} else { | ||
fields.operationName = nameOrFields; | ||
fields.references = [childOf]; | ||
} | ||
if (API_CONFORMANCE_CHECKS) { | ||
if (fields.childOf && fields.references) { | ||
throw new Error('At most one of `childOf` and ' + | ||
'`references` may be specified'); | ||
} | ||
if (fields.childOf && !( | ||
fields.childOf instanceof Span || | ||
fields.childOf instanceof SpanContext)) { | ||
throw new Error('childOf must be a Span or SpanContext instance'); | ||
} | ||
} | ||
// Convert fields.childOf to fields.references as needed. | ||
if (fields.childOf) { | ||
// Convert from a Span or a SpanContext into a Reference. | ||
let childOf = this.childOf(fields.childOf); | ||
if (fields.references) { | ||
fields.references.push(childOf); | ||
} else { | ||
fields.references = [childOf]; | ||
} | ||
delete(fields.childOf); | ||
} | ||
spanImp = this._imp.startSpan(fields); | ||
delete(fields.childOf); | ||
} | ||
return new Span(spanImp); | ||
return this._startSpan(name, fields); | ||
} | ||
/** | ||
* Return a new REFERENCE_CHILD_OF reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_CHILD_OF reference pointing to `spanContext` | ||
*/ | ||
childOf(spanContext) { | ||
return new Reference(Constants.REFERENCE_CHILD_OF, spanContext); | ||
} | ||
/** | ||
* Return a new REFERENCE_FOLLOWS_FROM reference. | ||
* | ||
* @param {SpanContext} spanContext - the parent SpanContext instance to | ||
* reference. | ||
* @return a REFERENCE_FOLLOWS_FROM reference pointing to `spanContext` | ||
*/ | ||
followsFrom(spanContext) { | ||
return new Reference(Constants.REFERENCE_FOLLOWS_FROM, spanContext); | ||
} | ||
/** | ||
* Injects the given SpanContext instance for cross-process propagation | ||
@@ -178,3 +129,4 @@ * within `carrier`. The expected type of `carrier` depends on the value of | ||
inject(spanContext, format, carrier) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 3) { | ||
@@ -200,9 +152,7 @@ throw new Error('Invalid number of arguments.'); | ||
if (this._imp) { | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof Span) { | ||
spanContext = spanContext.context(); | ||
} | ||
this._imp.inject(spanContext._imp, format, carrier); | ||
// Allow the user to pass a Span instead of a SpanContext | ||
if (spanContext instanceof Span) { | ||
spanContext = spanContext.context(); | ||
} | ||
return this._inject(spanContext, format, carrier); | ||
} | ||
@@ -233,3 +183,4 @@ | ||
extract(format, carrier) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
// Debug-only runtime checks on the arguments | ||
if (process.env.NODE_ENV === 'debug') { | ||
if (arguments.length !== 2) { | ||
@@ -253,62 +204,27 @@ throw new Error('Invalid number of arguments.'); | ||
} | ||
let spanContextImp = null; | ||
if (this._imp) { | ||
spanContextImp = this._imp.extract(format, carrier); | ||
} | ||
if (spanContextImp !== null) { | ||
return new SpanContext(spanContextImp); | ||
} | ||
return null; | ||
return this._extract(format, carrier); | ||
} | ||
/** | ||
* Request that any buffered or in-memory data is flushed out of the process. | ||
* | ||
* @param {function(err: objectg)} done - optional callback function with | ||
* the signature `function(err)` that will be called as soon as the | ||
* flush completes. `err` should be null or undefined if the flush | ||
* was successful. | ||
*/ | ||
flush(done) { | ||
if (API_CONFORMANCE_CHECKS) { | ||
if (arguments.length > 1) { | ||
throw new Error('Invalid number of arguments'); | ||
} | ||
if (done !== undefined && typeof done !== 'function') { | ||
throw new Error('callback expected to be a function'); | ||
} | ||
} | ||
if (!this._imp) { | ||
done(null); | ||
return; | ||
} | ||
this._imp.flush(done); | ||
} | ||
// ---------------------------------------------------------------------- // | ||
// Private and non-standard methods | ||
// Derived classes can choose to implement the below | ||
// ---------------------------------------------------------------------- // | ||
/** | ||
* Note: this constructor should not be called directly by consumers of this | ||
* code. The singleton's initNewTracer() method should be invoked instead. | ||
*/ | ||
constructor(imp) { | ||
this._imp = imp || null; | ||
// NOTE: the input to this method is *always* an associative array. The | ||
// public-facing startSpan() method normalizes the arguments so that | ||
// all N implementations do not need to worry about variations in the call | ||
// signature. | ||
// | ||
// The default behavior returns a no-op span. | ||
_startSpan(name, fields) { | ||
return Noop.span; | ||
} | ||
/** | ||
* Handle to implementation object. | ||
* | ||
* Use of this method is discouraged as it greatly reduces the portability of | ||
* the calling code. Use only when implementation-specific functionality must | ||
* be used and cannot accessed otherwise. | ||
* | ||
* @return {object} | ||
* An implementation-dependent object. | ||
*/ | ||
imp() { | ||
return this._imp; | ||
// The default behavior is a no-op. | ||
_inject(spanContext, format, carrier) { | ||
} | ||
// The default behavior is to return null. | ||
_extract(format, carrier) { | ||
return Noop.spanContext; | ||
} | ||
} |
@@ -1,109 +0,9 @@ | ||
// For the convenience of unit testing, add these to the global namespace | ||
global._ = require('underscore'); | ||
global.expect = require('chai').expect; | ||
// Ensure the stack trace lines numbers are correct on errors | ||
require('source-map-support').install(); | ||
// Unit testing is done against the debug version of the library as it has | ||
// additional conformance checks that are optimized out of the production | ||
// library. | ||
global.Tracer = require('../dist/opentracing-node-debug.js'); | ||
var apiCompatibilityChecks = require('./api_compatibility.js'); | ||
var NoopTracerImp; | ||
describe('OpenTracing API', function() { | ||
// Test that the API layer, while in debug mode, catches API misuse | ||
// before the implementation is even invoked (i.e. even with the no-op | ||
// implementation). | ||
describe('surface area', function() { | ||
it('should have the required functions on the singleton', function() { | ||
expect(Tracer.initGlobalTracer).to.be.a('function'); | ||
expect(Tracer.initNewTracer).to.be.a('function'); | ||
}); | ||
it('should have the required constants', function() { | ||
expect(Tracer.FORMAT_TEXT_MAP).to.be.a('string'); | ||
expect(Tracer.FORMAT_BINARY).to.be.a('string'); | ||
expect(Tracer.REFERENCE_CHILD_OF).to.be.a('string'); | ||
expect(Tracer.REFERENCE_FOLLOWS_FROM).to.be.a('string'); | ||
}); | ||
it('should have the required Tracer functions', function() { | ||
expect(Tracer.startSpan).to.be.a('function'); | ||
expect(Tracer.inject).to.be.a('function'); | ||
expect(Tracer.extract).to.be.a('function'); | ||
expect(Tracer.flush).to.be.a('function'); | ||
}); | ||
it('should have the required Span functions', function() { | ||
var span = Tracer.startSpan('test_operation'); | ||
expect(span.tracer).to.be.a('function'); | ||
expect(span.context).to.be.a('function'); | ||
expect(span.setTag).to.be.a('function'); | ||
expect(span.addTags).to.be.a('function'); | ||
expect(span.log).to.be.a('function'); | ||
expect(span.logEvent).to.be.a('function'); | ||
expect(span.finish).to.be.a('function'); | ||
}); | ||
it('should have the required SpanContext functions', function() { | ||
var spanContext = Tracer.startSpan('test_operation').context(); | ||
expect(spanContext.setBaggageItem).to.be.a('function'); | ||
expect(spanContext.getBaggageItem).to.be.a('function'); | ||
}); | ||
it('should enforce the required carrier types', function() { | ||
var spanContext = Tracer.startSpan('test_operation').context(); | ||
var textCarrier = {}; | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_TEXT_MAP, textCarrier); }).to.not.throw(Error); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_TEXT_MAP, ''); }).to.throw(Error); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_TEXT_MAP, 5); }).to.throw(Error); | ||
var binCarrier = new Tracer.BinaryCarrier(); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_BINARY, binCarrier); }).to.not.throw(Error); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_BINARY, new Object); }).to.not.throw(Error); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_BINARY, {}); }).to.not.throw(Error); | ||
expect(function() { Tracer.inject(spanContext, Tracer.FORMAT_BINARY, { buffer : null }); }).to.not.throw(Error); | ||
expect(function() { Tracer.extract(Tracer.FORMAT_BINARY, binCarrier); }).to.not.throw(Error); | ||
expect(function() { Tracer.extract(Tracer.FORMAT_BINARY, {}); }).to.not.throw(Error); | ||
expect(function() { Tracer.extract(Tracer.FORMAT_BINARY, { buffer : null }); }).to.not.throw(Error); | ||
expect(function() { Tracer.extract(Tracer.FORMAT_BINARY, { buffer : '' }); }).to.throw(Error); | ||
expect(function() { Tracer.extract(Tracer.FORMAT_BINARY, { buffer : 5 }); }).to.throw(Error); | ||
}); | ||
it('should coerce to spanContext as needed', function() { | ||
var span = Tracer.startSpan('test_operation'); | ||
var textCarrier = {}; | ||
expect(function() { Tracer.inject(span, Tracer.FORMAT_TEXT_MAP, textCarrier); }).to.not.throw(Error); | ||
expect(function() { Tracer.startSpan('child', { childOf : span }); }).to.not.throw(Error); | ||
expect(function() { var _ = new Tracer.Reference(Tracer.REFERENCE_CHILD_OF, span); }).to.not.throw(Error); | ||
}); | ||
}); | ||
describe('No-op tracer', function() { | ||
it('should return a valid no-op tracer object when given a null implementation', function() { | ||
var tracer; | ||
expect(function() { | ||
tracer = Tracer.initNewTracer(null); | ||
}).not.to.throw(); | ||
expect(tracer).to.be.an('object'); | ||
var span = tracer.startSpan('test_span') | ||
expect(span).to.be.an('object'); | ||
span.finish(); | ||
}); | ||
}); | ||
describe('Memory usage', function() { | ||
before(function() { | ||
NoopTracerImp = require('./imp/noop_imp.js'); | ||
}); | ||
it('should not report leaks after setting the global tracer', function() { | ||
Tracer.initGlobalTracer(new NoopTracerImp()); | ||
}); | ||
}); | ||
// Run the tests on the default OpenTracing no-op Tracer. | ||
apiCompatibilityChecks(function() { | ||
return new opentracing.Tracer(); | ||
}); |
var webpack = require("webpack"); | ||
// Pass in the build configuration as environment variables | ||
const CONFIG = process.env.BUILD_CONFIG | ||
const PLATFORM = process.env.BUILD_PLATFORM; | ||
const CONFIG = process.env.BUILD_CONFIG | ||
// Modify the webpack settings based on the configuration | ||
var plugins = []; | ||
var defines = { | ||
DEBUG : false, | ||
PLATFORM_NODE : false, | ||
PLATFORM_BROWSER : false, | ||
API_CONFORMANCE_CHECKS : false, | ||
}; | ||
var bundlePlatform = ""; | ||
var bundleSuffix = ""; | ||
var libraryTarget = ""; | ||
var target = ""; | ||
var bundleSuffix = ''; | ||
var devtool = undefined; | ||
switch (CONFIG) { | ||
case "debug": | ||
defines.DEBUG = true; | ||
defines.API_CONFORMANCE_CHECKS = true; | ||
bundleSuffix = "-debug"; | ||
devtool = "source-map"; | ||
break; | ||
case "prod": | ||
plugins.push(new webpack.optimize.UglifyJsPlugin({ | ||
if (CONFIG === 'debug') { | ||
devtool = "source-map"; | ||
plugins.push( | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
'NODE_ENV': '"debug"' | ||
} | ||
}) | ||
); | ||
} else { | ||
bundleSuffix = ".min"; | ||
plugins.push( | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
'NODE_ENV': '"production"' | ||
} | ||
}), | ||
new webpack.optimize.UglifyJsPlugin({ | ||
minimize: true, | ||
@@ -39,59 +36,22 @@ compress : { | ||
warnings : false, | ||
} | ||
})); | ||
plugins.push(new webpack.optimize.DedupePlugin()); | ||
break; | ||
default: | ||
console.error("Unexpected BUILD_CONFIG!"); | ||
process.exit(1); | ||
}, | ||
}), | ||
new webpack.optimize.DedupePlugin() | ||
); | ||
} | ||
switch (PLATFORM) { | ||
case "node": | ||
bundlePlatform = "-node"; | ||
bundleSuffix = (CONFIG == 'debug') ? '-debug' : ''; | ||
defines.PLATFORM_NODE = true; | ||
target = "node"; | ||
libraryTarget = "commonjs2"; | ||
if (CONFIG === "debug") { | ||
plugins.push(new webpack.BannerPlugin('require("source-map-support").install();', { | ||
raw: true, | ||
entryOnly: false | ||
})); | ||
} | ||
break; | ||
case "browser": | ||
bundlePlatform = "-browser"; | ||
bundleSuffix = (CONFIG == 'debug') ? '' : '.min'; | ||
defines.PLATFORM_BROWSER = true; | ||
target = "web"; | ||
libraryTarget = "umd"; | ||
break; | ||
default: | ||
console.error("Unexpected BUILD_PLATFORM!"); | ||
process.exit(1); | ||
} | ||
// | ||
// Webpack configuration | ||
// | ||
var bundleName = "opentracing" + bundlePlatform + bundleSuffix; | ||
module.exports = { | ||
entry : "./src/index.js", | ||
target : target, | ||
target : 'web', | ||
devtool : devtool, | ||
output : { | ||
path : "dist/", | ||
filename : bundleName + ".js", | ||
library : "Tracer", | ||
libraryTarget : libraryTarget, | ||
filename : 'opentracing-browser' + bundleSuffix + ".js", | ||
library : "opentracing", | ||
libraryTarget : 'umd', | ||
}, | ||
plugins :[ | ||
new webpack.DefinePlugin(defines), | ||
].concat(plugins), | ||
plugins : plugins, | ||
module : { | ||
@@ -98,0 +58,0 @@ loaders : [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
508176
117
5122
153
39
29