cls |
Default value : new Singleton(TraceCLS)
|
Constants |
Type : object
|
Default value : {
/** The metadata key under which trace context is stored as a binary value. */
TRACE_CONTEXT_GRPC_METADATA_NAME: 'grpc-trace-bin',
/** Header that carries trace context across Google infrastructure. */
TRACE_CONTEXT_HEADER_NAME: 'x-cloud-trace-context',
/** Header that is used to identify outgoing http made by the agent. */
TRACE_AGENT_REQUEST_HEADER: 'x-cloud-trace-agent-request',
/** Bitmask to determine whether trace is enabled in trace options. */
TRACE_OPTIONS_TRACE_ENABLED: 1 << 0,
/**
* Maximum size of a span name in bytes.
* See: cloud.google.com/trace/api/reference/rest/v1/projects.traces for
* limits.
*/
TRACE_SERVICE_SPAN_NAME_LIMIT: 127,
/** Maximum size of a label key in bytes. */
TRACE_SERVICE_LABEL_KEY_LIMIT: 127,
/** Maximum size of a label value in bytes. */
TRACE_SERVICE_LABEL_VALUE_LIMIT: 16 * 1024 - 1,
}
|
Constant values. |
defaultConfig |
Type : object
|
Default value : {
logLevel: 1,
disableUntracedModulesWarning: false,
enabled: true,
enhancedDatabaseReporting: false,
rootSpanNameOverride: (name: string) => name,
clsMechanism: 'auto' as CLSMechanism,
spansPerTraceSoftLimit: 200,
spansPerTraceHardLimit: 1000,
maximumLabelValueSize: 512,
plugins: {
// enable all by default
bluebird: path.join(pluginDirectory, 'plugin-bluebird.js'),
connect: path.join(pluginDirectory, 'plugin-connect.js'),
express: path.join(pluginDirectory, 'plugin-express.js'),
'generic-pool': path.join(pluginDirectory, 'plugin-generic-pool.js'),
grpc: path.join(pluginDirectory, 'plugin-grpc.js'),
hapi: path.join(pluginDirectory, 'plugin-hapi.js'),
'@hapi/hapi': path.join(pluginDirectory, 'plugin-hapi.js'),
http: path.join(pluginDirectory, 'plugin-http.js'),
http2: path.join(pluginDirectory, 'plugin-http2.js'),
koa: path.join(pluginDirectory, 'plugin-koa.js'),
mongodb: path.join(pluginDirectory, 'plugin-mongodb.js'),
'mongodb-core': path.join(pluginDirectory, 'plugin-mongodb-core.js'),
mongoose: path.join(pluginDirectory, 'plugin-mongoose.js'),
mysql: path.join(pluginDirectory, 'plugin-mysql.js'),
mysql2: path.join(pluginDirectory, 'plugin-mysql2.js'),
pg: path.join(pluginDirectory, 'plugin-pg.js'),
redis: path.join(pluginDirectory, 'plugin-redis.js'),
restify: path.join(pluginDirectory, 'plugin-restify.js'),
},
stackTraceLimit: 10,
flushDelaySeconds: 30,
ignoreUrls: ['/_ah/health'],
ignoreMethods: [],
samplingRate: 10,
contextHeaderBehavior: 'default',
bufferSize: 1000,
onUncaughtException: 'ignore',
serviceContext: {},
}
|
Default configuration. For fields with primitive values, any user-provided value will override the corresponding default value. For fields with non-primitive values (plugins and serviceContext), the user-provided value will be used to extend the default value. |
pluginDirectory |
Default value : path.join(
path.resolve(__dirname, '..'),
'src',
'plugins'
)
|
DISABLED_CHILD_SPAN |
Default value : createPhantomSpanData(SpanType.DISABLED)
|
A virtual trace span that indicates that a real child span couldn't be created because the Trace Agent was disabled. |
randomBytes |
Default value : crypto.randomBytes
|
randomFillSync |
Default value : crypto.randomFillSync
|
SPAN_ID_RANDOM_BYTES |
Type : number
|
Default value : 6
|
spanIdBuffer |
Default value : Buffer.alloc(SPAN_ID_RANDOM_BYTES)
|
spanRandomBuffer |
Default value : randomFillSync
? () => randomFillSync(spanIdBuffer)
: () => randomBytes(SPAN_ID_RANDOM_BYTES)
|
ERR_HTTP_HEADERS_SENT |
Type : string
|
Default value : 'ERR_HTTP_HEADERS_SENT'
|
ERR_HTTP_HEADERS_SENT_MSG |
Type : string
|
Default value : "Can't set headers after they are sent."
|
isURL |
Default value : (value: any): value is URL => value instanceof URL
|
plugin |
Type : Plugin
|
Default value : [
{
file: 'http',
patch: patchHttp,
unpatch: unpatchHttp,
},
{
file: 'https',
versions: '<8.9.0 || ^8.9.1',
// require http if it wasn't patched yet, because the https client uses
// the public 'http' module.
patch: () => require('http'),
},
{
file: 'https',
versions: '=8.9.0 || >=9.0.0',
patch: patchHttps,
unpatch: unpatchHttps,
},
]
|
EVENT_EMITTER_METHODS |
Type : Array<EventEmitter>
|
Default value : [
'addListener',
'on',
'once',
'prependListener',
'prependOnceListener',
]
|
WRAPPED |
Default value : Symbol('@google-cloud/trace-agent:AsyncHooksCLS:WRAPPED')
|
filesLoadedBeforeTrace |
Default value : Object.keys(require.cache)
|
traceAgent |
Type : StackdriverTracer
|
FORCE_NEW |
Default value : Symbol('force-new')
|
kSingleton |
Default value : Symbol()
|
moduleRegex |
Default value : new RegExp(
[
'.*?node_modules(?!.*node_modules)\\',
'(@[^\\',
']*\\',
'[^\\',
']*|[^\\',
']*).*',
].join(path.sep)
)
|
Type : literal type
|
Default value : require('hex2dec')
|
headers |
Type : OutgoingHttpHeaders
|
Default value : {}
|
NO_PROJECT_ID_TOKEN |
Type : string
|
Default value : '{{projectId}}'
|
onUncaughtExceptionValues |
Type : []
|
Default value : ['ignore', 'flush', 'flushAndExit']
|
pjson |
Default value : require('../../package.json')
|
SCOPES |
Type : string[]
|
Default value : ['https://www.googleapis.com/auth/trace.append']
|
TRACE_API_ENDPOINT |
Type : string
|
Default value : 'cloudtrace.googleapis.com'
|
traceWriter |
Default value : new Singleton(TraceWriter)
|
LEVELS |
Type : ReadonlyArray<LogLevel>
|
Default value : [
'silent',
'error',
'warn',
'info',
'debug',
]
|
The list of log levels. |
MetadataModuleValue |
Type : MetadataModule
|
plugin |
Type : Plugin
|
Default value : [
{
file: 'src/node/src/client.js',
versions: '0.13 - 1.6',
patch: patchClient,
unpatch: unpatchClient,
},
{
file: 'src/node/src/metadata.js',
versions: '0.13 - 1.6',
patch: patchMetadata,
unpatch: unpatchMetadata,
},
{
file: 'src/node/src/server.js',
versions: '0.13 - 1.6',
patch: patchServer,
unpatch: unpatchServer,
},
{
file: 'src/client.js',
versions: '^1.7',
patch: patchClient,
unpatch: unpatchClient,
},
{
file: 'src/metadata.js',
versions: '^1.7',
patch: patchMetadata,
unpatch: unpatchMetadata,
},
{
file: 'src/server.js',
versions: '^1.7',
patch: patchServer,
unpatch: unpatchServer,
},
]
|
SKIP_FRAMES |
Type : number
|
Default value : 1
|
methods |
Type : Array<express_4.Application>
|
Default value : (
httpMethods as Array<keyof express_4.Application>
).concat('use', 'route', 'param', 'all')
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
versions: SUPPORTED_VERSIONS,
patch: patchModuleRoot,
unpatch: unpatchModuleRoot,
} as PluginTypes.Monkeypatch<Express4Module>,
]
|
SUPPORTED_VERSIONS |
Type : string
|
Default value : '4.x'
|
noOp |
Default value : () => {}
|
plugin |
Type : Plugin
|
Default value : [
{
file: 'lib/client.js',
versions: '^6.x',
// TS: Client is a class name.
patch: (Client, api) => {
const pgPatch = new PostgresPatchUtility(api);
shimmer.wrap(Client.prototype, 'query', query => {
// Every call to Client#query will have a Submittable object associated
// with it. We need to patch two handlers (handleReadyForQuery and
// handleError) to end a span.
// There are a few things to note here:
// * query accepts a Submittable or a string. A Query is a Submittable.
// So if we can get a Submittable from the input we patch it
// proactively, otherwise (in the case of a string) we patch the
// output Query instead.
// * If query is passed a callback, the callback will be invoked from
// either handleReadyForQuery or handleError. So we don't need to
// separately patch the callback.
return function query_trace(
this: pg_6.Client,
...args: ClientQueryArguments
) {
if (args.length >= 1) {
const span = api.createChildSpan({name: 'pg-query'});
if (!api.isRealSpan(span)) {
return query.apply(this, args);
}
// Extract query text and values, if needed.
pgPatch.maybePopulateLabelsFromInputs(span, args);
if (typeof args[0] === 'object') {
pgPatch.patchSubmittable(args[0], span);
return query.apply(this, args);
} else {
return pgPatch.patchSubmittable(
query.apply(this, args) as Submittable,
span
);
}
} else {
// query was called with no arguments.
// This doesn't make sense, but don't do anything that might cause
// an error to get thrown here, or a span to be started.
return query.apply(this, args);
}
};
});
},
// TS: Client is a class name.
unpatch(Client) {
shimmer.unwrap(Client.prototype, 'query');
},
} as Patch<typeof pg_6.Client>,
{
file: 'lib/client.js',
versions: '^7.x',
// TS: Client is a class name.
patch: (Client, api) => {
const pgPatch = new PostgresPatchUtility(api);
shimmer.wrap(Client.prototype, 'query', query => {
return function query_trace(this: pg_7.Client) {
const span = api.createChildSpan({name: 'pg-query'});
if (!api.isRealSpan(span)) {
// eslint-disable-next-line prefer-rest-params
return query.apply(this, arguments);
}
let pgQuery: PG7QueryReturnValue;
// In 7.x, the value of pgQuery depends on how the query() was called.
// It can be one of:
// - (query: pg.Submittable) => EventEmitter
// - Note: return value is the same as the argument.
// - ([*], callback: (err, res: pg.Result) => void) => void
// - ([*]) => Promise<pg.Result>
// where [*] is one of:
// - ...[query: { text: string, values?: Array<any> }]
// - ...[text: string, values?: Array<any>]
// See: https://node-postgres.com/guides/upgrading
const argLength = arguments.length;
if (argLength >= 1) {
const args: ClientQueryArguments = Array.prototype.slice.call(
// eslint-disable-next-line prefer-rest-params
arguments,
0
);
// Extract query text and values, if needed.
pgPatch.maybePopulateLabelsFromInputs(span, args);
// If we received a callback, bind it to the current context,
// optionally adding labels as well.
const callback = args[args.length - 1];
if (typeof callback === 'function') {
args[args.length - 1] = pgPatch.patchCallback(
callback as Callback<pg_7.QueryResult>,
span
);
} else if (typeof args[0] === 'object') {
pgPatch.patchSubmittable(args[0] as Submittable, span);
}
pgQuery = query.apply(this, args);
} else {
// eslint-disable-next-line prefer-rest-params
pgQuery = query.apply(this, arguments);
}
if (pgQuery) {
if (pgQuery instanceof EventEmitter) {
api.wrapEmitter(pgQuery);
} else if (typeof pgQuery.then === 'function') {
// Unlike in pg 6, the returned value can't be both a Promise and
// a Submittable. So we don't run the risk of double-patching
// here.
pgQuery = pgPatch.patchPromise(pgQuery, span);
}
}
return pgQuery;
};
});
},
// TS: Client is a class name.
unpatch(Client) {
shimmer.unwrap(Client.prototype, 'query');
},
} as Patch<typeof pg_7.Client>,
]
|
ORIGINAL |
Default value : Symbol()
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
versions: '8 - 16',
patch: (hapi, api) => {
shimmer.wrap(hapi.Server.prototype, 'connection', connection => {
return function connectionTrace(this: hapi_16.Server) {
// eslint-disable-next-line prefer-rest-params
const server = connection.apply(this, arguments);
server.ext('onRequest', function handler(request, reply) {
return instrument(api, request, () => reply.continue());
} as hapi_16.ServerExtRequestHandler);
return server;
};
});
},
unpatch: hapi => {
shimmer.unwrap(hapi.Server.prototype, 'connection');
},
} as PluginTypes.Monkeypatch<Hapi16Module>,
/**
* In Hapi 17, the work that is done on behalf of a request stems from
* Request#_execute. We patch that function to ensure that context is
* available in every handler.
*/
{
versions: '>=17',
file: 'lib/request.js',
// Request is a class name.
patch: (Request, api) => {
// TODO(kjin): shimmer cannot wrap AsyncFunction objects.
// Once shimmer introduces this functionality, change this code to use it.
const origExecute = Request.prototype._execute;
Request.prototype._execute = Object.assign(
function _executeWrap(this: hapi_17.Request) {
return instrument(api, this, () => {
// eslint-disable-next-line prefer-rest-params
return origExecute.apply(this, arguments);
});
},
{[ORIGINAL]: origExecute}
);
},
// Request is a class name.
unpatch: Request => {
if (Request.prototype._execute[ORIGINAL]) {
Request.prototype._execute = Request.prototype._execute[ORIGINAL]!;
}
},
} as PluginTypes.Monkeypatch<{prototype: Hapi17Request}>,
]
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
// Bluebird is a class.
patch: (Bluebird, tracer) => {
// any is a type arg; args are type checked when read directly, otherwise
// passed through to a function with the same type signature.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const wrapIfFunction = (fn: any) =>
typeof fn === 'function' ? tracer.wrap(fn) : fn;
shimmer.wrap(Bluebird.prototype, '_then', (thenFn: Function) => {
// Inherit context from the call site of .then().
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return function <T>(this: bluebird_3<T>, ...args: any[]) {
return thenFn.apply(this, [
wrapIfFunction(args[0]),
wrapIfFunction(args[1]),
...args.slice(2),
]);
};
});
},
} as PluginTypes.Monkeypatch<BluebirdModule>,
]
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
file: '',
versions: SUPPORTED_VERSIONS,
intercept: (connect, api) => {
return function (this: {}) {
const app = connect();
app.use(createMiddleware(api));
return app;
};
},
} as PluginTypes.Intercept<Connect3>,
]
|
SUPPORTED_VERSIONS |
Type : string
|
Default value : '3.x'
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
file: '',
versions: '1.x',
patch: (koa, api) => {
patchUse(koa, api, createMiddleware);
},
unpatch: koa => {
shimmer.unwrap(koa.prototype, 'use');
},
} as PluginTypes.Monkeypatch<Koa1Module>,
{
file: '',
versions: '2.x',
patch: (koa, api) => {
patchUse(koa, api, createMiddleware2x);
},
unpatch: koa => {
shimmer.unwrap(koa.prototype, 'use');
},
} as PluginTypes.Monkeypatch<Koa2Module>,
]
|
plugin |
Type : PluginTypes.Plugin
|
Default value : [
{
versions: SUPPORTED_VERSIONS,
patch: patchRestify,
unpatch: unpatchRestify,
} as PluginTypes.Monkeypatch<Restify5>,
]
|
SUPPORTED_VERSIONS |
Type : string
|
Default value : '<=11.x'
|
pluginLoader |
Default value : new Singleton(PluginLoader)
|
TraceLabels |
Type : object
|
Default value : {
/**
* The well-known label for http status code.
*/
HTTP_RESPONSE_CODE_LABEL_KEY: '/http/status_code',
/**
* The well-known label for http request url.
*/
HTTP_URL_LABEL_KEY: '/http/url',
/**
* The well-known label for http method.
*/
HTTP_METHOD_LABEL_KEY: '/http/method',
/**
* The well-known label for http response size.
*/
HTTP_RESPONSE_SIZE_LABEL_KEY: '/http/response/size',
/**
* The well-known label for stack-traces
*/
STACK_TRACE_DETAILS_KEY: '/stacktrace',
/**
* The well-known label for network error name.
*/
ERROR_DETAILS_NAME: '/error/name',
/**
* The well-known label for network error message.
*/
ERROR_DETAILS_MESSAGE: '/error/message',
/**
* The well-known label for the app version on AppEngine.
*/
GAE_VERSION: 'g.co/gae/app/version',
/**
* @type {string} The well-known label for the module name on AppEngine.
*/
GAE_MODULE_NAME: 'g.co/gae/app/module',
/**
* The well-known label for the module version on AppEngine.
*/
GAE_MODULE_VERSION: 'g.co/gae/app/module_version',
/**
* The label for GCE instance id. This is not a label recognized by the trace
* API.
*/
GCE_INSTANCE_ID: 'g.co/gce/instanceid',
/**
* The label for GCE hostname. This is not a label recognized by the trace
* API.
*/
GCE_HOSTNAME: 'g.co/gce/hostname',
/**
* The label for http request source ip. This is not a label recognized by the
* trace API.
*/
HTTP_SOURCE_IP: '/http/source/ip',
/**
* The well-known label for agent metadata. Values should have the form
* "<name> <version>".
*/
AGENT_DATA: '/agent',
}
|
Well-known trace span label values. |
tracing |
Default value : new Singleton(Tracing)
|