@google-cloud/trace-agent
Advanced tools
Comparing version 3.2.1 to 3.3.0
@@ -43,3 +43,4 @@ "use strict"; | ||
// context as its "parent" AsyncResource. The criteria for the parent | ||
// depends on the type of the AsyncResource. | ||
// depends on the type of the AsyncResource. (If the parent doesn't have | ||
// an associated context, don't do anything.) | ||
if (type === 'PROMISE') { | ||
@@ -50,3 +51,6 @@ // Opt not to use the trigger ID for Promises, as this causes context | ||
// currently running. | ||
this.contexts[id] = this.contexts[this.ah.executionAsyncId()]; | ||
const currentId = this.ah.executionAsyncId(); | ||
if (this.contexts[currentId] !== undefined) { | ||
this.contexts[id] = this.contexts[currentId]; | ||
} | ||
} | ||
@@ -63,8 +67,11 @@ else { | ||
// selection. | ||
this.contexts[id] = this.contexts[triggerId]; | ||
if (this.contexts[triggerId] !== undefined) { | ||
this.contexts[id] = this.contexts[triggerId]; | ||
} | ||
} | ||
// Note that this function always assigns values in this.contexts to | ||
// values under other keys, which may or may not be undefined. Consumers | ||
// of the CLS API will get the sentinel (default) value if they query | ||
// the current context when it is stored as undefined. | ||
// Note that this function only assigns values in this.contexts to | ||
// values under other keys; it never generates new context values. | ||
// Consumers of the CLS API will get the sentinel (default) value if | ||
// they query the current context when it is not stored in | ||
// this.contexts. | ||
}, | ||
@@ -75,2 +82,13 @@ destroy: (id) => { | ||
delete this.contexts[id]; | ||
}, | ||
promiseResolve: (id) => { | ||
// Promise async resources may not get their destroy hook entered for | ||
// a long time, so we listen on promiseResolve hooks as well. If this | ||
// event is emitted, the async scope of the Promise will not be entered | ||
// again, so it is generally safe to delete its entry in the map. (There | ||
// is a possibility that a future async resource will directly reference | ||
// this Promise as its trigger parent -- in this case, it will have | ||
// the wrong parent, but this is still better than a potential memory | ||
// leak.) | ||
delete this.contexts[id]; | ||
} | ||
@@ -77,0 +95,0 @@ }); |
@@ -24,4 +24,4 @@ /** | ||
export declare class AsyncListenerCLS<Context extends {}> implements CLS<Context> { | ||
static readonly TRACE_NAMESPACE: string; | ||
static readonly ROOT_CONTEXT_KEY: string; | ||
static readonly TRACE_NAMESPACE = "com.google.cloud.trace"; | ||
static readonly ROOT_CONTEXT_KEY = "root"; | ||
private readonly cls; | ||
@@ -28,0 +28,0 @@ private readonly defaultContext; |
@@ -17,3 +17,7 @@ /** | ||
export declare type CLSMechanism = 'async-hooks' | 'async-listener' | 'auto' | 'none' | 'singular'; | ||
/** Available configuration options. */ | ||
export declare type ContextHeaderBehavior = 'default' | 'ignore' | 'require'; | ||
/** | ||
* Available configuration options. All fields are optional. See the | ||
* defaultConfig object defined in this file for default assigned values. | ||
*/ | ||
export interface Config { | ||
@@ -123,2 +127,21 @@ /** | ||
/** | ||
* Specifies how to use incoming trace context headers. The following options | ||
* are available: | ||
* 'default' -- Trace context will be propagated for incoming requests that | ||
* contain the context header. A new trace will be created for requests | ||
* without trace context headers. All traces are still subject to local | ||
* sampling and url filter policies. | ||
* 'require' -- Same as default, but traces won't be created for requests | ||
* without trace context headers. This should not be set for end user-facing | ||
* services, as this header is usually set by other traced services rather | ||
* than by users. | ||
* 'ignore' -- Trace context headers will always be ignored, so a new trace | ||
* with a unique ID will be created for every request. This means that a | ||
* sampling decision specified on an incoming request will be ignored. | ||
* This might be useful for aggregating traces generated by different cloud | ||
* platform projects. | ||
* All traces are still subject to local tracing policy. | ||
*/ | ||
contextHeaderBehavior?: ContextHeaderBehavior; | ||
/** | ||
* The number of transactions we buffer before we publish to the trace | ||
@@ -150,9 +173,6 @@ * API, unless `flushDelaySeconds` seconds have elapsed first. | ||
/** | ||
* EXPERIMENTAL: | ||
* Allows to ignore the requests X-Cloud-Trace-Context header if set. Setting | ||
* this to true will cause traces generated by this module to appear | ||
* separately from other distributed work done by other services on behalf of | ||
* the same incoming request. Setting this will also cause sampling decisions | ||
* made by other distributed components to be ignored. This is useful for | ||
* aggregating traces generated by different cloud platform projects. | ||
* Setting this to true or false is the same as setting contextHeaderBehavior | ||
* to 'ignore' or 'default' respectively. If both are explicitly set, | ||
* contextHeaderBehavior will be prioritized over this value. | ||
* Deprecated: This option will be removed in a future release. | ||
*/ | ||
@@ -230,6 +250,6 @@ ignoreContextHeader?: boolean; | ||
samplingRate: number; | ||
contextHeaderBehavior: string; | ||
bufferSize: number; | ||
onUncaughtException: string; | ||
ignoreContextHeader: boolean; | ||
serviceContext: {}; | ||
}; |
@@ -57,7 +57,7 @@ "use strict"; | ||
samplingRate: 10, | ||
contextHeaderBehavior: 'default', | ||
bufferSize: 1000, | ||
onUncaughtException: 'ignore', | ||
ignoreContextHeader: false, | ||
serviceContext: {} | ||
}; | ||
//# sourceMappingURL=config.js.map |
@@ -55,2 +55,9 @@ "use strict"; | ||
} | ||
// Internally, ignoreContextHeader is no longer being used, so convert the | ||
// user's value into a value for contextHeaderBehavior. But let this value | ||
// be overridden by the user's explicitly set value for contextHeaderBehavior. | ||
const contextHeaderBehaviorUnderride = { | ||
contextHeaderBehavior: projectConfig.ignoreContextHeader ? 'ignore' : | ||
'default' | ||
}; | ||
// Configuration order of precedence: | ||
@@ -61,3 +68,3 @@ // 1. Environment Variables | ||
// 4. Default Config (as specified in './config') | ||
const config = extend(true, { [util_1.FORCE_NEW]: projectConfig[util_1.FORCE_NEW] }, config_1.defaultConfig, envSetConfig, projectConfig, envConfig, { plugins: {} }); | ||
const config = extend(true, { [util_1.FORCE_NEW]: projectConfig[util_1.FORCE_NEW] }, config_1.defaultConfig, envSetConfig, contextHeaderBehaviorUnderride, projectConfig, envConfig, { plugins: {} }); | ||
// The empty plugins object guarantees that plugins is a plain object, | ||
@@ -64,0 +71,0 @@ // even if it's explicitly specified in the config to be a non-object. |
@@ -45,3 +45,3 @@ /** | ||
export declare class RootSpanData extends BaseSpanData implements types.RootSpan { | ||
readonly type: SpanType; | ||
readonly type = SpanType.ROOT; | ||
constructor(trace: Trace, spanName: string, parentSpanId: string, skipFrames: number); | ||
@@ -55,3 +55,3 @@ createChildSpan(options?: SpanOptions): Span; | ||
export declare class ChildSpanData extends BaseSpanData { | ||
readonly type: SpanType; | ||
readonly type = SpanType.CHILD; | ||
constructor(trace: Trace, spanName: string, parentSpanId: string, skipFrames: number); | ||
@@ -58,0 +58,0 @@ } |
@@ -21,11 +21,31 @@ /** | ||
import { Func, RootSpan, RootSpanOptions, Span, SpanOptions, Tracer } from './plugin-types'; | ||
import * as TracingPolicy from './tracing-policy'; | ||
import { TracePolicyConfig } from './tracing-policy'; | ||
import * as util from './util'; | ||
/** | ||
* An enumeration of the different possible types of behavior when dealing with | ||
* incoming trace context. Requests are still subject to local tracing policy. | ||
*/ | ||
export declare enum TraceContextHeaderBehavior { | ||
/** | ||
* Respect the trace context header if it exists; otherwise, trace the | ||
* request as a new trace. | ||
*/ | ||
DEFAULT = "default", | ||
/** | ||
* Respect the trace context header if it exists; otherwise, treat the | ||
* request as unsampled and don't trace it. | ||
*/ | ||
REQUIRE = "require", | ||
/** | ||
* Trace every request as a new trace, even if trace context exists. | ||
*/ | ||
IGNORE = "ignore" | ||
} | ||
/** | ||
* An interface describing configuration fields read by the StackdriverTracer | ||
* object. This includes fields read by the trace policy. | ||
*/ | ||
export interface StackdriverTracerConfig extends TracingPolicy.TracePolicyConfig { | ||
export interface StackdriverTracerConfig extends TracePolicyConfig { | ||
enhancedDatabaseReporting: boolean; | ||
ignoreContextHeader: boolean; | ||
contextHeaderBehavior: TraceContextHeaderBehavior; | ||
rootSpanNameOverride: (path: string) => string; | ||
@@ -76,3 +96,3 @@ spansPerTraceSoftLimit: number; | ||
private config; | ||
policy: TracingPolicy.TracePolicy | null; | ||
private policy; | ||
/** | ||
@@ -79,0 +99,0 @@ * Constructs a new StackdriverTracer instance. |
@@ -25,5 +25,26 @@ "use strict"; | ||
const trace_writer_1 = require("./trace-writer"); | ||
const TracingPolicy = require("./tracing-policy"); | ||
const tracing_policy_1 = require("./tracing-policy"); | ||
const util = require("./util"); | ||
/** | ||
* An enumeration of the different possible types of behavior when dealing with | ||
* incoming trace context. Requests are still subject to local tracing policy. | ||
*/ | ||
var TraceContextHeaderBehavior; | ||
(function (TraceContextHeaderBehavior) { | ||
/** | ||
* Respect the trace context header if it exists; otherwise, trace the | ||
* request as a new trace. | ||
*/ | ||
TraceContextHeaderBehavior["DEFAULT"] = "default"; | ||
/** | ||
* Respect the trace context header if it exists; otherwise, treat the | ||
* request as unsampled and don't trace it. | ||
*/ | ||
TraceContextHeaderBehavior["REQUIRE"] = "require"; | ||
/** | ||
* Trace every request as a new trace, even if trace context exists. | ||
*/ | ||
TraceContextHeaderBehavior["IGNORE"] = "ignore"; | ||
})(TraceContextHeaderBehavior = exports.TraceContextHeaderBehavior || (exports.TraceContextHeaderBehavior = {})); | ||
/** | ||
* Type guard that returns whether an object is a string or not. | ||
@@ -57,3 +78,2 @@ */ | ||
this.config = null; | ||
// TODO(kjin): Make this private. | ||
this.policy = null; | ||
@@ -75,3 +95,3 @@ this.pluginName = name; | ||
this.config = config; | ||
this.policy = TracingPolicy.createTracePolicy(config); | ||
this.policy = new tracing_policy_1.TracePolicy(config); | ||
this.enabled = true; | ||
@@ -89,3 +109,3 @@ } | ||
// short-circuit out of trace generation logic. | ||
this.policy = new TracingPolicy.TraceNonePolicy(); | ||
this.policy = tracing_policy_1.TracePolicy.never(); | ||
this.enabled = false; | ||
@@ -123,14 +143,19 @@ } | ||
// Attempt to read incoming trace context. | ||
let incomingTraceContext = {}; | ||
if (isString(options.traceContext) && !this.config.ignoreContextHeader) { | ||
const parsedContext = util.parseContextFromHeader(options.traceContext); | ||
if (parsedContext) { | ||
incomingTraceContext = parsedContext; | ||
} | ||
const incomingTraceContext = { options: 1 }; | ||
let parsedContext = null; | ||
if (isString(options.traceContext) && | ||
this.config.contextHeaderBehavior !== | ||
TraceContextHeaderBehavior.IGNORE) { | ||
parsedContext = util.parseContextFromHeader(options.traceContext); | ||
} | ||
if (parsedContext) { | ||
Object.assign(incomingTraceContext, parsedContext); | ||
} | ||
else if (this.config.contextHeaderBehavior === | ||
TraceContextHeaderBehavior.REQUIRE) { | ||
incomingTraceContext.options = 0; | ||
} | ||
// Consult the trace policy. | ||
const locallyAllowed = this.policy.shouldTrace(Date.now(), options.url || ''); | ||
const remotelyAllowed = incomingTraceContext.options === undefined || | ||
!!(incomingTraceContext.options & | ||
constants_1.Constants.TRACE_OPTIONS_TRACE_ENABLED); | ||
const locallyAllowed = this.policy.shouldTrace({ timestamp: Date.now(), url: options.url || '' }); | ||
const remotelyAllowed = !!(incomingTraceContext.options & constants_1.Constants.TRACE_OPTIONS_TRACE_ENABLED); | ||
let rootContext; | ||
@@ -137,0 +162,0 @@ // Don't create a root span if the trace policy disallows it. |
@@ -131,3 +131,3 @@ /** | ||
private readonly logger; | ||
static readonly CORE_MODULE: string; | ||
static readonly CORE_MODULE = "[core]"; | ||
private enableRequireHook; | ||
@@ -134,0 +134,0 @@ private readonly pluginMap; |
@@ -133,4 +133,4 @@ "use strict"; | ||
gcpMetadata.instance({ property: 'hostname', headers }) | ||
.then((res) => { | ||
cb(res.data); // hostname | ||
.then((data) => { | ||
cb(data); // hostname | ||
}) | ||
@@ -147,4 +147,4 @@ .catch((err) => { | ||
gcpMetadata.instance({ property: 'id', headers }) | ||
.then((res) => { | ||
cb(res.data); // instance ID | ||
.then((data) => { | ||
cb(data); // instance ID | ||
}) | ||
@@ -151,0 +151,0 @@ .catch((err) => { |
@@ -17,30 +17,36 @@ /** | ||
/** | ||
* An object that determines whether a request should be traced. | ||
* Options for constructing a TracePolicy instance. | ||
*/ | ||
export interface TracePolicy { | ||
shouldTrace(dateMillis: number, url: string): boolean; | ||
} | ||
export declare class RateLimiterPolicy implements TracePolicy { | ||
private traceWindow; | ||
private nextTraceStart; | ||
constructor(samplesPerSecond: number); | ||
shouldTrace(dateMillis: number): boolean; | ||
} | ||
export declare class FilterPolicy implements TracePolicy { | ||
private basePolicy; | ||
private filterUrls; | ||
constructor(basePolicy: TracePolicy, filterUrls: Array<string | RegExp>); | ||
private matches; | ||
shouldTrace(dateMillis: number, url: string): boolean; | ||
} | ||
export declare class TraceAllPolicy implements TracePolicy { | ||
shouldTrace(): boolean; | ||
} | ||
export declare class TraceNonePolicy implements TracePolicy { | ||
shouldTrace(): boolean; | ||
} | ||
export interface TracePolicyConfig { | ||
/** | ||
* A field that controls time-based sampling. | ||
*/ | ||
samplingRate: number; | ||
ignoreUrls?: Array<string | RegExp>; | ||
/** | ||
* A field that controls a url-based filter. | ||
*/ | ||
ignoreUrls: Array<string | RegExp>; | ||
} | ||
export declare function createTracePolicy(config: TracePolicyConfig): TracePolicy; | ||
/** | ||
* A class that makes decisions about whether a trace should be created. | ||
*/ | ||
export declare class TracePolicy { | ||
private readonly sampler; | ||
private readonly urlFilter; | ||
/** | ||
* Constructs a new TracePolicy instance. | ||
* @param config Configuration for the TracePolicy instance. | ||
*/ | ||
constructor(config: TracePolicyConfig); | ||
/** | ||
* Given a timestamp and URL, decides if a trace should be created. | ||
* @param options Fields that help determine whether a trace should be | ||
* created. | ||
*/ | ||
shouldTrace(options: { | ||
timestamp: number; | ||
url: string; | ||
}): boolean; | ||
static always(): TracePolicy; | ||
static never(): TracePolicy; | ||
} |
@@ -18,3 +18,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class RateLimiterPolicy { | ||
class Sampler { | ||
constructor(samplesPerSecond) { | ||
@@ -35,10 +35,8 @@ if (samplesPerSecond > 1000) { | ||
} | ||
exports.RateLimiterPolicy = RateLimiterPolicy; | ||
class FilterPolicy { | ||
constructor(basePolicy, filterUrls) { | ||
this.basePolicy = basePolicy; | ||
class URLFilter { | ||
constructor(filterUrls) { | ||
this.filterUrls = filterUrls; | ||
} | ||
matches(url) { | ||
return this.filterUrls.some((candidate) => { | ||
shouldTrace(url) { | ||
return !this.filterUrls.some((candidate) => { | ||
return (typeof candidate === 'string' && candidate === url) || | ||
@@ -48,36 +46,45 @@ !!url.match(candidate); | ||
} | ||
shouldTrace(dateMillis, url) { | ||
return !this.matches(url) && this.basePolicy.shouldTrace(dateMillis, url); | ||
} | ||
} | ||
exports.FilterPolicy = FilterPolicy; | ||
class TraceAllPolicy { | ||
shouldTrace() { | ||
return true; | ||
/** | ||
* A class that makes decisions about whether a trace should be created. | ||
*/ | ||
class TracePolicy { | ||
/** | ||
* Constructs a new TracePolicy instance. | ||
* @param config Configuration for the TracePolicy instance. | ||
*/ | ||
constructor(config) { | ||
if (config.samplingRate === 0) { | ||
this.sampler = { shouldTrace: () => true }; | ||
} | ||
else if (config.samplingRate < 0) { | ||
this.sampler = { shouldTrace: () => false }; | ||
} | ||
else { | ||
this.sampler = new Sampler(config.samplingRate); | ||
} | ||
if (config.ignoreUrls.length === 0) { | ||
this.urlFilter = { shouldTrace: () => true }; | ||
} | ||
else { | ||
this.urlFilter = new URLFilter(config.ignoreUrls); | ||
} | ||
} | ||
} | ||
exports.TraceAllPolicy = TraceAllPolicy; | ||
class TraceNonePolicy { | ||
shouldTrace() { | ||
return false; | ||
/** | ||
* Given a timestamp and URL, decides if a trace should be created. | ||
* @param options Fields that help determine whether a trace should be | ||
* created. | ||
*/ | ||
shouldTrace(options) { | ||
return this.sampler.shouldTrace(options.timestamp) && | ||
this.urlFilter.shouldTrace(options.url); | ||
} | ||
} | ||
exports.TraceNonePolicy = TraceNonePolicy; | ||
// TODO(kjin): This could be a class as well. | ||
function createTracePolicy(config) { | ||
let basePolicy; | ||
if (config.samplingRate < 1) { | ||
basePolicy = new TraceAllPolicy(); | ||
static always() { | ||
return new TracePolicy({ samplingRate: 0, ignoreUrls: [] }); | ||
} | ||
else { | ||
basePolicy = new RateLimiterPolicy(config.samplingRate); | ||
static never() { | ||
return new TracePolicy({ samplingRate: -1, ignoreUrls: [] }); | ||
} | ||
if (config.ignoreUrls && config.ignoreUrls.length > 0) { | ||
return new FilterPolicy(basePolicy, config.ignoreUrls); | ||
} | ||
else { | ||
return basePolicy; | ||
} | ||
} | ||
exports.createTracePolicy = createTracePolicy; | ||
exports.TracePolicy = TracePolicy; | ||
//# sourceMappingURL=tracing-policy.js.map |
@@ -26,5 +26,5 @@ /** | ||
} | ||
export declare type NormalizedConfig = (TraceWriterConfig & PluginLoaderConfig & TopLevelConfig) | { | ||
export declare type NormalizedConfig = ((TraceWriterConfig & PluginLoaderConfig & TopLevelConfig) | { | ||
enabled: false; | ||
}; | ||
}); | ||
/** | ||
@@ -64,2 +64,4 @@ * A class that represents automatic tracing. | ||
} | ||
export declare const tracing: Singleton<Tracing, NormalizedConfig, StackdriverTracer>; | ||
export declare const tracing: Singleton<Tracing, { | ||
enabled: false; | ||
} | (TraceWriterConfig & PluginLoaderConfig & TopLevelConfig), StackdriverTracer>; |
{ | ||
"name": "@google-cloud/trace-agent", | ||
"version": "3.2.1", | ||
"version": "3.3.0", | ||
"description": "Node.js Support for StackDriver Trace", | ||
@@ -55,3 +55,3 @@ "main": "build/src/index.js", | ||
"@types/extend": "^3.0.0", | ||
"@types/glob": "^5.0.32", | ||
"@types/glob": "^7.0.0", | ||
"@types/is": "0.0.20", | ||
@@ -77,3 +77,3 @@ "@types/methods": "^1.1.0", | ||
"glob": "^7.0.3", | ||
"grpc": "1.14.2", | ||
"grpc": "1.16.0", | ||
"gts": "^0.8.0", | ||
@@ -85,3 +85,3 @@ "intelli-espower-loader": "^1.0.1", | ||
"ncp": "^2.0.0", | ||
"nock": "^9.1.3", | ||
"nock": "^10.0.0", | ||
"nyc": "^13.0.0", | ||
@@ -97,6 +97,6 @@ "once": "^1.4.0", | ||
"ts-node": "^7.0.0", | ||
"typescript": "~3.0.0" | ||
"typescript": "~3.1.0" | ||
}, | ||
"dependencies": { | ||
"@google-cloud/common": "^0.25.3", | ||
"@google-cloud/common": "^0.26.0", | ||
"builtin-modules": "^3.0.0", | ||
@@ -106,3 +106,3 @@ "console-log-level": "^1.4.0", | ||
"extend": "^3.0.0", | ||
"gcp-metadata": "^0.7.0", | ||
"gcp-metadata": "^0.9.0", | ||
"hex2dec": "^1.0.1", | ||
@@ -109,0 +109,0 @@ "is": "^3.2.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
300915
6520
+ Added@google-cloud/common@0.26.2(transitive)
+ Addedbignumber.js@9.1.2(transitive)
+ Addedgcp-metadata@0.9.3(transitive)
+ Addedjson-bigint@0.3.1(transitive)
+ Addedthrough2@3.0.2(transitive)
- Removed@google-cloud/common@0.25.3(transitive)
- Removedthrough2@2.0.5(transitive)
- Removedxtend@4.0.2(transitive)
Updated@google-cloud/common@^0.26.0
Updatedgcp-metadata@^0.9.0