@google-cloud/trace-agent
Advanced tools
Comparing version 3.5.2 to 3.6.0
@@ -102,8 +102,2 @@ /** | ||
/** | ||
* Buffer the captured traces for `flushDelaySeconds` seconds before | ||
* publishing to the trace API, unless the buffer fills up first. | ||
* Also see `bufferSize`. | ||
*/ | ||
flushDelaySeconds?: number; | ||
/** | ||
* URLs that partially match any regex in ignoreUrls will not be traced. | ||
@@ -153,5 +147,12 @@ * In addition, URLs that are _exact matches_ of strings in ignoreUrls will | ||
/** | ||
* The number of transactions we buffer before we publish to the trace | ||
* API, unless `flushDelaySeconds` seconds have elapsed first. | ||
* Buffer the captured traces for `flushDelaySeconds` seconds before | ||
* publishing to the Stackdriver Trace API, unless the buffer fills up first. | ||
* Also see `bufferSize`. | ||
*/ | ||
flushDelaySeconds?: number; | ||
/** | ||
* The number of spans in buffered traces needed to trigger a publish of all | ||
* traces to the Stackdriver Trace API, unless `flushDelaySeconds` seconds | ||
* has elapsed first. | ||
*/ | ||
bufferSize?: number; | ||
@@ -236,2 +237,3 @@ /** | ||
plugins: { | ||
'bluebird': string; | ||
'connect': string; | ||
@@ -244,3 +246,2 @@ 'express': string; | ||
'http2': string; | ||
'knex': string; | ||
'koa': string; | ||
@@ -247,0 +248,0 @@ 'mongodb-core': string; |
@@ -37,2 +37,3 @@ "use strict"; | ||
// enable all by default | ||
'bluebird': path.join(pluginDirectory, 'plugin-bluebird.js'), | ||
'connect': path.join(pluginDirectory, 'plugin-connect.js'), | ||
@@ -45,3 +46,2 @@ 'express': path.join(pluginDirectory, 'plugin-express.js'), | ||
'http2': path.join(pluginDirectory, 'plugin-http2.js'), | ||
'knex': path.join(pluginDirectory, 'plugin-knex.js'), | ||
'koa': path.join(pluginDirectory, 'plugin-koa.js'), | ||
@@ -48,0 +48,0 @@ 'mongodb-core': path.join(pluginDirectory, 'plugin-mongodb-core.js'), |
@@ -17,4 +17,3 @@ /** | ||
import { SpanType } from './constants'; | ||
import * as types from './plugin-types'; | ||
import { Span, SpanOptions } from './plugin-types'; | ||
import { RootSpan, Span, SpanOptions } from './plugin-types'; | ||
import { Trace, TraceSpan } from './trace'; | ||
@@ -45,4 +44,5 @@ /** | ||
*/ | ||
export declare class RootSpanData extends BaseSpanData implements types.RootSpan { | ||
export declare class RootSpanData extends BaseSpanData implements RootSpan { | ||
readonly type = SpanType.ROOT; | ||
private children; | ||
constructor(trace: Trace, spanName: string, parentSpanId: string, skipFrames: number); | ||
@@ -57,3 +57,5 @@ createChildSpan(options?: SpanOptions): Span; | ||
readonly type = SpanType.CHILD; | ||
shouldSelfPublish: boolean; | ||
constructor(trace: Trace, spanName: string, parentSpanId: string, skipFrames: number); | ||
endSpan(timestamp?: Date): void; | ||
} | ||
@@ -64,3 +66,3 @@ /** | ||
*/ | ||
export declare const UNCORRELATED_CHILD_SPAN: types.Span & { | ||
export declare const UNCORRELATED_CHILD_SPAN: Span & { | ||
readonly type: SpanType.UNCORRELATED; | ||
@@ -73,3 +75,3 @@ }; | ||
*/ | ||
export declare const UNTRACED_CHILD_SPAN: types.Span & { | ||
export declare const UNTRACED_CHILD_SPAN: Span & { | ||
readonly type: SpanType.UNTRACED; | ||
@@ -82,6 +84,6 @@ }; | ||
export declare const UNCORRELATED_ROOT_SPAN: Readonly<{ | ||
createChildSpan(): types.Span & { | ||
createChildSpan(): Span & { | ||
readonly type: SpanType.UNCORRELATED; | ||
}; | ||
} & types.Span & { | ||
} & Span & { | ||
readonly type: SpanType.UNCORRELATED; | ||
@@ -94,7 +96,7 @@ }>; | ||
export declare const UNTRACED_ROOT_SPAN: Readonly<{ | ||
createChildSpan(): types.Span & { | ||
createChildSpan(): Span & { | ||
readonly type: SpanType.UNTRACED; | ||
}; | ||
} & types.Span & { | ||
} & Span & { | ||
readonly type: SpanType.UNTRACED; | ||
}>; |
@@ -87,2 +87,5 @@ "use strict"; | ||
endSpan(timestamp) { | ||
if (!!this.span.endTime) { | ||
return; | ||
} | ||
timestamp = timestamp || new Date(); | ||
@@ -100,2 +103,5 @@ this.span.endTime = timestamp.toISOString(); | ||
this.type = constants_1.SpanType.ROOT; | ||
// Locally-tracked list of children. Used only to determine, once this span | ||
// ends, whether a child still needs to be published. | ||
this.children = []; | ||
this.span.kind = trace_1.SpanKind.RPC_SERVER; | ||
@@ -106,7 +112,21 @@ } | ||
const skipFrames = options.skipFrames ? options.skipFrames + 1 : 1; | ||
return new ChildSpanData(this.trace, /* Trace object */ options.name, /* Span name */ this.span.spanId, /* Parent's span ID */ skipFrames); /* # of frames to skip in stack trace */ | ||
const child = new ChildSpanData(this.trace, /* Trace object */ options.name, /* Span name */ this.span.spanId, /* Parent's span ID */ skipFrames); /* # of frames to skip in stack trace */ | ||
this.children.push(child); | ||
return child; | ||
} | ||
endSpan(timestamp) { | ||
if (!!this.span.endTime) { | ||
return; | ||
} | ||
super.endSpan(timestamp); | ||
trace_writer_1.traceWriter.get().writeTrace(this.trace); | ||
this.children.forEach(child => { | ||
if (!child.span.endTime) { | ||
// Child hasn't ended yet. | ||
// Inform the child that it needs to self-publish. | ||
child.shouldSelfPublish = true; | ||
} | ||
}); | ||
// We no longer need to keep track of our children. | ||
this.children = []; | ||
} | ||
@@ -122,4 +142,21 @@ } | ||
this.type = constants_1.SpanType.CHILD; | ||
// Whether this span should publish itself. This is meant to be set to true | ||
// by the parent RootSpanData. | ||
this.shouldSelfPublish = false; | ||
this.span.kind = trace_1.SpanKind.RPC_CLIENT; | ||
} | ||
endSpan(timestamp) { | ||
if (!!this.span.endTime) { | ||
return; | ||
} | ||
super.endSpan(timestamp); | ||
if (this.shouldSelfPublish) { | ||
// Also, publish just this span. | ||
trace_writer_1.traceWriter.get().writeTrace({ | ||
projectId: this.trace.projectId, | ||
traceId: this.trace.traceId, | ||
spans: [this.span] | ||
}); | ||
} | ||
} | ||
} | ||
@@ -126,0 +163,0 @@ exports.ChildSpanData = ChildSpanData; |
@@ -36,2 +36,26 @@ /** | ||
} | ||
export declare class TraceBuffer { | ||
/** | ||
* Buffered traces. | ||
*/ | ||
private traces; | ||
/** | ||
* Number of buffered spans; this number must be at least as large as | ||
* buffer.length. | ||
*/ | ||
private numSpans; | ||
/** | ||
* Add a new trace to the buffer. | ||
* @param trace The trace to add. | ||
*/ | ||
add(trace: Trace): void; | ||
/** | ||
* Gets the number of spans contained within buffered traces. | ||
*/ | ||
getNumSpans(): number; | ||
/** | ||
* Clears the buffer, returning its original contents. | ||
*/ | ||
drain(): Trace[]; | ||
} | ||
/** | ||
@@ -43,4 +67,4 @@ * A class representing a service that publishes traces in the background. | ||
private readonly logger; | ||
/** Stringified traces to be published */ | ||
buffer: string[]; | ||
/** Traces to be published */ | ||
protected buffer: TraceBuffer; | ||
/** Default labels to be attached to written spans */ | ||
@@ -67,4 +91,3 @@ defaultLabels: LabelObject; | ||
/** | ||
* Ensures that all sub spans of the provided Trace object are | ||
* closed and then queues the span data to be published. | ||
* Queues a trace to be published. Spans with no end time are excluded. | ||
* | ||
@@ -71,0 +94,0 @@ * @param trace The trace to be queued. |
@@ -42,2 +42,39 @@ "use strict"; | ||
const SCOPES = ['https://www.googleapis.com/auth/trace.append']; | ||
class TraceBuffer { | ||
constructor() { | ||
/** | ||
* Buffered traces. | ||
*/ | ||
this.traces = []; | ||
/** | ||
* Number of buffered spans; this number must be at least as large as | ||
* buffer.length. | ||
*/ | ||
this.numSpans = 0; | ||
} | ||
/** | ||
* Add a new trace to the buffer. | ||
* @param trace The trace to add. | ||
*/ | ||
add(trace) { | ||
this.traces.push(trace); | ||
this.numSpans += trace.spans.length; | ||
} | ||
/** | ||
* Gets the number of spans contained within buffered traces. | ||
*/ | ||
getNumSpans() { | ||
return this.numSpans; | ||
} | ||
/** | ||
* Clears the buffer, returning its original contents. | ||
*/ | ||
drain() { | ||
const result = this.traces; | ||
this.traces = []; | ||
this.numSpans = 0; | ||
return result; | ||
} | ||
} | ||
exports.TraceBuffer = TraceBuffer; | ||
/** | ||
@@ -65,3 +102,3 @@ * A class representing a service that publishes traces in the background. | ||
this.logger = logger; | ||
this.buffer = []; | ||
this.buffer = new TraceBuffer(); | ||
this.defaultLabels = {}; | ||
@@ -177,4 +214,3 @@ this.isActive = true; | ||
/** | ||
* Ensures that all sub spans of the provided Trace object are | ||
* closed and then queues the span data to be published. | ||
* Queues a trace to be published. Spans with no end time are excluded. | ||
* | ||
@@ -184,8 +220,4 @@ * @param trace The trace to be queued. | ||
writeTrace(trace) { | ||
for (const span of trace.spans) { | ||
if (span.endTime === '') { | ||
span.endTime = (new Date()).toISOString(); | ||
} | ||
} | ||
trace.spans.forEach(spanData => { | ||
const publishableSpans = trace.spans.filter(span => !!span.endTime); | ||
publishableSpans.forEach(spanData => { | ||
if (spanData.kind === trace_1.SpanKind.RPC_SERVER) { | ||
@@ -196,28 +228,13 @@ // Copy properties from the default labels. | ||
}); | ||
const afterProjectId = (projectId) => { | ||
trace.projectId = projectId; | ||
this.buffer.push(JSON.stringify(trace)); | ||
this.logger.info(`TraceWriter#writeTrace: buffer.size = ${this.buffer.length}`); | ||
// Publish soon if the buffer is getting big | ||
if (this.buffer.length >= this.config.bufferSize) { | ||
this.logger.info('TraceWriter#writeTrace: Trace buffer full, flushing.'); | ||
setImmediate(() => this.flushBuffer()); | ||
} | ||
}; | ||
// TODO(kjin): We should always be following the 'else' path. | ||
// Any test that doesn't mock the Trace Writer will assume that traces get | ||
// buffered synchronously. We need to refactor those tests to remove that | ||
// assumption before we can make this fix. | ||
if (this.projectId !== NO_PROJECT_ID_TOKEN) { | ||
afterProjectId(this.projectId); | ||
this.buffer.add({ | ||
traceId: trace.traceId, | ||
projectId: trace.projectId, | ||
spans: publishableSpans | ||
}); | ||
this.logger.info(`TraceWriter#writeTrace: number of buffered spans = ${this.buffer.getNumSpans()}`); | ||
// Publish soon if the buffer is getting big | ||
if (this.buffer.getNumSpans() >= this.config.bufferSize) { | ||
this.logger.info('TraceWriter#writeTrace: Trace buffer full, flushing.'); | ||
setImmediate(() => this.flushBuffer()); | ||
} | ||
else { | ||
this.getProjectId().then(afterProjectId, (err) => { | ||
// Because failing to get a project ID means that the trace agent will | ||
// get disabled, there is a very small window for this code path to be | ||
// taken. For this reason we don't do anything more complex than just | ||
// notifying that we are dropping the current trace. | ||
this.logger.info('TraceWriter#queueTrace: No project ID, dropping trace.'); | ||
}); | ||
} | ||
} | ||
@@ -245,10 +262,28 @@ /** | ||
flushBuffer() { | ||
if (this.buffer.length === 0) { | ||
// Privatize and clear the buffer. | ||
const flushedTraces = this.buffer.drain(); | ||
if (flushedTraces.length === 0) { | ||
return; | ||
} | ||
// Privatize and clear the buffer. | ||
const buffer = this.buffer; | ||
this.buffer = []; | ||
this.logger.debug('TraceWriter#flushBuffer: Flushing traces', buffer); | ||
this.publish(`{"traces":[${buffer.join()}]}`); | ||
const afterProjectId = (projectId) => { | ||
flushedTraces.forEach(trace => trace.projectId = projectId); | ||
this.logger.debug('TraceWriter#flushBuffer: Flushing traces', flushedTraces); | ||
this.publish(JSON.stringify({ traces: flushedTraces })); | ||
}; | ||
// TODO(kjin): We should always be following the 'else' path. | ||
// Any test that doesn't mock the Trace Writer will assume that traces get | ||
// buffered synchronously. We need to refactor those tests to remove that | ||
// assumption before we can make this fix. | ||
if (this.projectId !== NO_PROJECT_ID_TOKEN) { | ||
afterProjectId(this.projectId); | ||
} | ||
else { | ||
this.getProjectId().then(afterProjectId, (err) => { | ||
// Because failing to get a project ID means that the trace agent will | ||
// get disabled, there is a very small window for this code path to be | ||
// taken. For this reason we don't do anything more complex than just | ||
// notifying that we are dropping the current traces. | ||
this.logger.info('TraceWriter#flushBuffer: No project ID, dropping traces.'); | ||
}); | ||
} | ||
} | ||
@@ -255,0 +290,0 @@ /** |
{ | ||
"name": "@google-cloud/trace-agent", | ||
"version": "3.5.2", | ||
"version": "3.6.0", | ||
"description": "Node.js Support for StackDriver Trace", | ||
@@ -27,3 +27,5 @@ "main": "build/src/index.js", | ||
"script": "ts-node -P ./scripts/tsconfig.json ./scripts", | ||
"license-check": "jsgl --local ." | ||
"license-check": "jsgl --local .", | ||
"docs-test": "linkinator docs -r --skip www.googleapis.com", | ||
"predocs-test": "npm run docs" | ||
}, | ||
@@ -52,3 +54,3 @@ "files": [ | ||
"devDependencies": { | ||
"@grpc/proto-loader": "^0.3.0", | ||
"@grpc/proto-loader": "^0.4.0", | ||
"@types/builtin-modules": "^2.0.0", | ||
@@ -72,3 +74,3 @@ "@types/console-log-level": "^1.4.0", | ||
"@types/shimmer": "^1.0.1", | ||
"@types/tmp": "0.0.33", | ||
"@types/tmp": "0.0.34", | ||
"@types/uuid": "^3.4.3", | ||
@@ -85,3 +87,3 @@ "axios": "^0.18.0", | ||
"jshint": "^2.9.1", | ||
"mocha": "^5.0.0", | ||
"mocha": "^6.0.0", | ||
"ncp": "^2.0.0", | ||
@@ -92,13 +94,14 @@ "nock": "^10.0.0", | ||
"pify": "^4.0.0", | ||
"retry-axios": "^0.4.0", | ||
"retry-axios": "^0.5.0", | ||
"rimraf": "^2.6.2", | ||
"source-map-support": "^0.5.6", | ||
"standard-version": "^4.2.0", | ||
"standard-version": "^5.0.0", | ||
"timekeeper": "^2.0.0", | ||
"tmp": "0.0.33", | ||
"ts-node": "^7.0.0", | ||
"typescript": "~3.1.0" | ||
"ts-node": "^8.0.0", | ||
"typescript": "~3.3.0", | ||
"linkinator": "^1.1.2" | ||
}, | ||
"dependencies": { | ||
"@google-cloud/common": "^0.30.0", | ||
"@google-cloud/common": "^0.31.0", | ||
"builtin-modules": "^3.0.0", | ||
@@ -108,3 +111,3 @@ "console-log-level": "^1.4.0", | ||
"extend": "^3.0.0", | ||
"gcp-metadata": "^0.9.0", | ||
"gcp-metadata": "^1.0.0", | ||
"hex2dec": "^1.0.1", | ||
@@ -111,0 +114,0 @@ "is": "^3.2.0", |
@@ -158,2 +158,8 @@ # Stackdriver Trace Agent for Node.js | ||
### Tracing bundled or webpacked server code. | ||
*unsupported* | ||
The way we trace modules we does not support bundled server code. Bundlers like webpack or @zeit/ncc will not work. | ||
## Contributing changes | ||
@@ -160,0 +166,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
308313
6684
191
46
+ Added@google-cloud/common@0.31.1(transitive)
+ Added@google-cloud/promisify@0.4.0(transitive)
- Removed@google-cloud/common@0.30.2(transitive)
- Removed@google-cloud/promisify@0.3.1(transitive)
- Removedgcp-metadata@0.9.3(transitive)
Updated@google-cloud/common@^0.31.0
Updatedgcp-metadata@^1.0.0