Comparing version 1.2.0 to 1.2.1
@@ -53,4 +53,3 @@ /** | ||
'express': path.join(__dirname, 'src/plugins/plugin-express.js'), | ||
'google-gax': path.join(__dirname, 'src/plugins/plugin-google-gax.js'), | ||
'grpc': path.join(__dirname, 'src/plugins/plugin-grpc.js'), | ||
'generic-pool': path.join(__dirname, 'src/plugins/plugin-generic-pool.js'), | ||
'hapi': path.join(__dirname, 'src/plugins/plugin-hapi.js'), | ||
@@ -57,0 +56,0 @@ 'http': path.join(__dirname, 'src/plugins/plugin-http.js'), |
{ | ||
"name": "vxx", | ||
"version": "1.2.0", | ||
"version": "1.2.1", | ||
"description": "Node.js Tracing Driver", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -31,2 +31,3 @@ /** | ||
name: urlParse(req.originalUrl).pathname, | ||
url: req.originalUrl, | ||
traceContext: req.headers[api.constants.TRACE_CONTEXT_HEADER_NAME.toLowerCase()], | ||
@@ -38,2 +39,9 @@ ip: req.connection.remoteAddress, | ||
api.runInRootSpan(options, function(root) { | ||
// Set response trace context. | ||
var responseTraceContext = | ||
api.getResponseTraceContext(options.traceContext, !!root); | ||
if (responseTraceContext) { | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, responseTraceContext); | ||
} | ||
if (!root) { | ||
@@ -56,7 +64,2 @@ return next(); | ||
var context = root.getTraceContext(); | ||
if (context) { | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, context); | ||
} | ||
// wrap end | ||
@@ -63,0 +66,0 @@ var originalEnd = res.end; |
@@ -49,2 +49,9 @@ /** | ||
api.runInRootSpan(options, function(rootSpan) { | ||
// Set response trace context. | ||
var responseTraceContext = | ||
api.getResponseTraceContext(options.traceContext, !!rootSpan); | ||
if (responseTraceContext) { | ||
res.set(api.constants.TRACE_CONTEXT_HEADER_NAME, responseTraceContext); | ||
} | ||
if (!rootSpan) { | ||
@@ -55,6 +62,2 @@ next(); | ||
// Set outgoing trace context. | ||
res.set(api.constants.TRACE_CONTEXT_HEADER_NAME, | ||
rootSpan.getTraceContext()); | ||
api.wrapEmitter(req); | ||
@@ -61,0 +64,0 @@ api.wrapEmitter(res); |
@@ -52,2 +52,9 @@ /** | ||
api.runInRootSpan(options, function(root) { | ||
// Set response trace context. | ||
var responseTraceContext = | ||
api.getResponseTraceContext(options.traceContext, !!root); | ||
if (responseTraceContext) { | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, responseTraceContext); | ||
} | ||
if (!root) { | ||
@@ -65,3 +72,3 @@ return reply.continue(); | ||
// url as a label | ||
// req.path would be more desirable but is not set at the time our middlewear runs. | ||
// req.path would be more desirable but is not set at the time our middleware runs. | ||
root.addLabel(api.labels.HTTP_METHOD_LABEL_KEY, req.method); | ||
@@ -72,5 +79,2 @@ root.addLabel(api.labels.HTTP_PATH_LABEL_KEY, options.name); | ||
var context = root.getTraceContext(); | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, context); | ||
// wrap end | ||
@@ -77,0 +81,0 @@ res.end = function(chunk, encoding) { |
@@ -16,7 +16,2 @@ /** | ||
*/ | ||
/** | ||
* This file has been modified by Keymetrics | ||
*/ | ||
'use strict'; | ||
@@ -27,14 +22,54 @@ | ||
const SUPPORTED_VERSIONS = '1.x'; | ||
function startSpanForRequest(api, req, res, next) { | ||
var originalEnd = res.end; | ||
var options = { | ||
name: urlParse(req.url).pathname, | ||
url: req.url, | ||
traceContext: req.headers[api.constants.TRACE_CONTEXT_HEADER_NAME], | ||
ip: req.connection.remoteAddress, | ||
method: req.method, | ||
skipFrames: 4 | ||
}; | ||
api.runInRootSpan(options, function(root) { | ||
// Set response trace context. | ||
var responseTraceContext = | ||
api.getResponseTraceContext(options.traceContext, !!root); | ||
if (responseTraceContext) { | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, responseTraceContext); | ||
} | ||
if (!root) { | ||
return; | ||
} | ||
function createUseWrap(api) { | ||
return function useWrap(use) { | ||
return function useTrace() { | ||
if (!this._google_trace_patched) { | ||
this._google_trace_patched = true; | ||
this.use(createMiddleware(api)); | ||
api.wrapEmitter(req); | ||
api.wrapEmitter(res); | ||
const url = (req.headers['X-Forwarded-Proto'] || 'http') + | ||
'://' + req.headers.host + req.url; | ||
// we use the path part of the url as the span name and add the full | ||
// url as a label | ||
// req.path would be more desirable but is not set at the time our middlewear runs. | ||
root.addLabel(api.labels.HTTP_METHOD_LABEL_KEY, req.method); | ||
root.addLabel(api.labels.HTTP_URL_LABEL_KEY, url); | ||
root.addLabel(api.labels.HTTP_SOURCE_IP, req.connection.remoteAddress); | ||
// wrap end | ||
res.end = function(chunk, encoding) { | ||
res.end = originalEnd; | ||
const returned = res.end(chunk, encoding); | ||
if (req.route && req.route.path) { | ||
root.addLabel( | ||
'koa/request.route.path', req.route.path); | ||
} | ||
return use.apply(this, arguments); | ||
root.addLabel( | ||
api.labels.HTTP_RESPONSE_CODE_LABEL_KEY, res.statusCode); | ||
root.endSpan(); | ||
return returned; | ||
}; | ||
}; | ||
api.wrap(next); | ||
}); | ||
} | ||
@@ -47,62 +82,38 @@ | ||
const res = this.res; | ||
const originalEnd = res.end; | ||
var options = { | ||
name: urlParse(req.url).pathname, | ||
traceContext: this.req.headers[api.constants.TRACE_CONTEXT_HEADER_NAME], | ||
ip: req.connection.remoteAddress, | ||
method: req.method, | ||
skipFrames: 3 | ||
}; | ||
api.runInRootSpan(options, function(root) { | ||
if (!root) { | ||
return; | ||
} | ||
api.wrapEmitter(req); | ||
api.wrapEmitter(res); | ||
startSpanForRequest(api, req, res, next); | ||
const url = (req.headers['X-Forwarded-Proto'] || 'http') + | ||
'://' + req.headers.host + req.url; | ||
yield next; | ||
}; | ||
} | ||
// we use the path part of the url as the span name and add the full | ||
// url as a label | ||
// req.path would be more desirable but is not set at the time our middlewear runs. | ||
root.addLabel(api.labels.HTTP_METHOD_LABEL_KEY, req.method); | ||
root.addLabel(api.labels.HTTP_URL_LABEL_KEY, url); | ||
root.addLabel(api.labels.HTTP_PATH_LABEL_KEY, options.name); | ||
root.addLabel(api.labels.HTTP_SOURCE_IP, req.connection.remoteAddress); | ||
function createMiddleware2x(api) { | ||
return function middleware(ctx, next) { | ||
const req = ctx.req; | ||
const res = ctx.res; | ||
var context = root.getTraceContext(); | ||
if (context) { | ||
res.setHeader(api.constants.TRACE_CONTEXT_HEADER_NAME, context); | ||
} | ||
startSpanForRequest(api, req, res, next); | ||
// wrap end | ||
res.end = function(chunk, encoding) { | ||
res.end = originalEnd; | ||
const returned = res.end(chunk, encoding); | ||
if (req.route && req.route.path) { | ||
root.addLabel( | ||
'koa/request.route.path', req.route.path); | ||
} | ||
root.addLabel( | ||
api.labels.HTTP_RESPONSE_CODE_LABEL_KEY, res.statusCode); | ||
root.endSpan(); | ||
return returned; | ||
}; | ||
api.wrap(next); | ||
}); | ||
yield next; | ||
return next(); | ||
}; | ||
} | ||
function patchUse(koa, api, createMiddlewareFunction) { | ||
shimmer.wrap(koa.prototype, 'use', function useWrap(use) { | ||
return function useTrace() { | ||
if (!this._google_trace_patched) { | ||
this._google_trace_patched = true; | ||
this.use(createMiddlewareFunction(api)); | ||
} | ||
return use.apply(this, arguments); | ||
}; | ||
}); | ||
} | ||
module.exports = [ | ||
{ | ||
file: '', | ||
versions: SUPPORTED_VERSIONS, | ||
versions: '1.x', | ||
patch: function(koa, api) { | ||
shimmer.wrap(koa.prototype, 'use', createUseWrap(api)); | ||
patchUse(koa, api, createMiddleware); | ||
}, | ||
@@ -112,3 +123,13 @@ unpatch: function(koa) { | ||
} | ||
}, | ||
{ | ||
file: '', | ||
versions: '2.x', | ||
patch: function(koa, api) { | ||
patchUse(koa, api, createMiddleware2x); | ||
}, | ||
unpatch: function(koa) { | ||
shimmer.unwrap(koa.prototype, 'use'); | ||
} | ||
} | ||
]; |
@@ -55,2 +55,9 @@ /** | ||
api.runInRootSpan(options, function(rootSpan) { | ||
// Set response trace context. | ||
var responseTraceContext = | ||
api.getResponseTraceContext(options.traceContext, !!rootSpan); | ||
if (responseTraceContext) { | ||
res.header(api.constants.TRACE_CONTEXT_HEADER_NAME, responseTraceContext); | ||
} | ||
if (!rootSpan) { | ||
@@ -63,6 +70,2 @@ return next(); | ||
// Propagate the trace context to the response. | ||
res.header(api.constants.TRACE_CONTEXT_HEADER_NAME, | ||
rootSpan.getTraceContext()); | ||
var fullUrl = req.header('X-Forwarded-Proto', 'http') + '://' + | ||
@@ -69,0 +72,0 @@ req.header('host') + req.url; |
@@ -130,3 +130,11 @@ /** | ||
* @param {object} options An object that specifies options for how the root | ||
* span is created and propogated. @see TraceApiImplementation.prototype.createRootSpan | ||
* span is created and propogated. | ||
* @param {string} options.name The name to apply to the root span. | ||
* @param {?string} options.url A URL associated with the root span, if | ||
* applicable. | ||
* @param {?string} options.traceContext The serialized form of an object that | ||
* contains information about an existing trace context. | ||
* @param {?number} options.skipFrames The number of stack frames to skip when | ||
* collecting call stack information for the root span, starting from the top; | ||
* this should be set to avoid including frames in the plugin. Defaults to 0. | ||
* @param {function(?RootSpan)} fn A function that will be called exactly | ||
@@ -162,2 +170,6 @@ * once. If the incoming request should be traced, a root span will be created, | ||
* span is created and propogated. | ||
* @param {string} options.name The name to apply to the child span. | ||
* @param {?number} options.skipFrames The number of stack frames to skip when | ||
* collecting call stack information for the root span, starting from the top; | ||
* this should be set to avoid including frames in the plugin. Defaults to 0. | ||
* @returns A new ChildSpan object, or null if there is no active root span. | ||
@@ -184,2 +196,27 @@ */ | ||
/** | ||
* Generates a stringified trace context that should be set as the trace context | ||
* header in a response to an incoming web request. This value is based on | ||
* the trace context header value in the corresponding incoming request, as well | ||
* as the result from the local trace policy on whether this request will be | ||
* traced or not. | ||
* @param {string} incomingTraceContext The trace context that was attached to | ||
* the incoming web request, or null if the incoming request didn't have one. | ||
* @param {boolean} isTraced Whether the incoming was traced. This is determined | ||
* by the local tracing policy. | ||
* @returns {string} If the response should contain the trace context within its | ||
* header, the string to be set as this header's value. Otherwise, an empty | ||
* string. | ||
*/ | ||
TraceApiImplementation.prototype.getResponseTraceContext = function( | ||
incomingTraceContext, isTraced) { | ||
var traceContext = this.agent_.parseContextFromHeader(incomingTraceContext); | ||
if (!traceContext) { | ||
return ''; | ||
} | ||
traceContext.options = traceContext.options & isTraced; | ||
return traceContext.traceId + '/' + traceContext.spanId + ';o=' + | ||
traceContext.options; | ||
}; | ||
/** | ||
* Binds the trace context to the given function. | ||
@@ -227,2 +264,3 @@ * This is necessary in order to create child spans correctly in functions | ||
createChildSpan: function(opts) { return null; }, | ||
getResponseTraceContext: function(context, traced) { return ''; }, | ||
wrap: function(fn) { return fn; }, | ||
@@ -261,2 +299,5 @@ wrapEmitter: function(ee) {}, | ||
}, | ||
getResponseTraceContext: function(incomingTraceContext, isTraced) { | ||
return impl.getResponseTraceContext(incomingTraceContext, isTraced); | ||
}, | ||
wrap: function(fn) { | ||
@@ -263,0 +304,0 @@ return impl.wrap(fn); |
@@ -73,3 +73,3 @@ /** | ||
*/ | ||
TraceLabels.GAE_VERSION = 'trace.cloud.google.com/gae/app/version'; | ||
TraceLabels.GAE_VERSION = 'g.co/gae/app/version'; | ||
@@ -79,3 +79,3 @@ /** | ||
*/ | ||
TraceLabels.GAE_MODULE_NAME = 'trace.cloud.google.com/gae/app/module'; | ||
TraceLabels.GAE_MODULE_NAME = 'g.co/gae/app/module'; | ||
@@ -85,3 +85,3 @@ /** | ||
*/ | ||
TraceLabels.GAE_MODULE_VERSION = 'trace.cloud.google.com/gae/app/module_version'; | ||
TraceLabels.GAE_MODULE_VERSION = 'g.co/gae/app/module_version'; | ||
@@ -92,3 +92,3 @@ /** | ||
*/ | ||
TraceLabels.GCE_INSTANCE_ID = 'trace.cloud.google.com/gce/instanceid'; | ||
TraceLabels.GCE_INSTANCE_ID = 'g.co/gce/instanceid'; | ||
@@ -99,3 +99,3 @@ /** | ||
*/ | ||
TraceLabels.GCE_HOSTNAME = 'trace.cloud.google.com/gce/hostname'; | ||
TraceLabels.GCE_HOSTNAME = 'g.co/gce/hostname'; | ||
@@ -102,0 +102,0 @@ /** |
@@ -68,3 +68,3 @@ /** | ||
} | ||
var matches = str.match(/^([0-9a-fA-F]+)(?:\/([0-9a-fA-F]+))?(?:;o=(.*))?/); | ||
var matches = str.match(/^([0-9a-fA-F]+)(?:\/([0-9]+))(?:;o=(.*))?/); | ||
if (!matches || matches.length !== 4 || matches[0] !== str || | ||
@@ -77,3 +77,3 @@ (matches[2] && isNaN(matches[2]))) { | ||
spanId: matches[2], | ||
options: Number(matches[3]) | ||
options: isNaN(matches[3]) ? undefined : Number(matches[3]) | ||
}; | ||
@@ -80,0 +80,0 @@ } |
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
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
158136
38
2830