From dde86d34b2ff2152081fe461b9edb86b432a5f2a Mon Sep 17 00:00:00 2001 From: Kelvin Jin Date: Wed, 18 Jul 2018 17:21:40 -0700 Subject: [PATCH] feat: rename TraceAgent/TraceApi to Tracer (#815) BREAKING CHANGE: `TraceAgent` has been renamed to `Tracer`. In plugins, `Patch` has been renamed `Monkeypatch`, and `Patch` is now `Monkeypatch|Intercept` (this is a rename of `Instrumentation`). There are no user-visible JS changes. `TraceAgent` is a misnomer since the module as a whole is the "agent", not the object that is returned when the Trace Agent is started. (This is already reflected in the docs, where it has been called `TraceApi`). This change makes things consistent so it is called `Tracer` everywhere. The one implementation of `TraceAgent` (which was also called `TraceAgent`) is now `StackdriverTracer`. This object is never constructed by the user, so this is a no-op change for JS users. A couple of unused imports have also been removed. --- README.md | 14 ++++++------- doc/trace-api.md | 30 +++++++++++++-------------- src/constants.ts | 8 ++++---- src/index.ts | 18 ++++++++--------- src/plugin-types.ts | 13 ++++++------ src/plugins/plugin-connect.ts | 3 +-- src/plugins/plugin-express.ts | 4 ++-- src/plugins/plugin-grpc.ts | 8 ++++---- src/plugins/plugin-hapi.ts | 6 +++--- src/plugins/plugin-http.ts | 11 +++++----- src/plugins/plugin-http2.ts | 10 ++++----- src/plugins/plugin-koa.ts | 14 ++++++------- src/plugins/plugin-restify.ts | 4 ++-- src/trace-api.ts | 29 +++++++++++++------------- src/trace-plugin-loader.ts | 36 ++++++++++++++++----------------- src/tracing.ts | 20 +++++++++--------- test/plugins/common.ts | 6 +++--- test/test-agent-stopped.ts | 4 ++-- test/test-index.ts | 4 ++-- test/test-trace-api-none-cls.ts | 4 ++-- test/test-trace-api.ts | 7 +++---- test/trace.ts | 4 ++-- 22 files changed, 126 insertions(+), 131 deletions(-) diff --git a/README.md b/README.md index 3c46959b2..c216dc34b 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ require('@google-cloud/trace-agent').start({ The object returned by `start()` may be used to create [custom trace spans](#custom-tracing-api): ```js -const traceApi = require('@google-cloud/trace-agent').start(); -traceApi.runInRootSpan({ name: 'my-root-span' }, (rootSpan) => { +const tracer = require('@google-cloud/trace-agent').start(); +tracer.runInRootSpan({ name: 'my-root-span' }, (rootSpan) => { // ... rootSpan.endSpan(); }); @@ -99,22 +99,22 @@ For any of the web frameworks for which we provide [built-in plugins](#what-gets ### Accessing the API -Calling the `start` function returns an instance of `TraceApi`, which provides an interface for tracing: +Calling the `start` function returns an instance of `Tracer`, which provides an interface for tracing: ```js -const traceApi = require('@google-cloud/trace-agent').start(); +const tracer = require('@google-cloud/trace-agent').start(); ``` It can also be retrieved by subsequent calls to `get` elsewhere: ```js // after start() is called -const traceApi = require('@google-cloud/trace-agent').get(); +const tracer = require('@google-cloud/trace-agent').get(); ``` -A `TraceApi` object is guaranteed to be returned by both of these calls, even if the agent is disabled. +A `Tracer` object is guaranteed to be returned by both of these calls, even if the agent is disabled. -A fully detailed overview of the `TraceApi` object is available [here](doc/trace-api.md). +A fully detailed overview of the `Tracer` object is available [here](doc/trace-api.md). ## How does automatic tracing work? diff --git a/doc/trace-api.md b/doc/trace-api.md index c7a90308b..8ae273278 100644 --- a/doc/trace-api.md +++ b/doc/trace-api.md @@ -1,41 +1,41 @@ -# The `TraceApi` Object +# The `Tracer` Object -A `TraceApi` instance provides functions that facilitate the following: +A `Tracer` instance provides functions that facilitate the following: - Creating trace spans and add labels to them. - Getting information about how the trace agent was configured in the current application. - Parsing and serializing trace contexts to support distributed tracing between microservices. - Binding callbacks and event emitters in order to propagate trace contexts across asynchronous boundaries. -In addition to the above, `TraceApi` also provides a number of well-known label keys and constants through its `labels` and `constants` fields respectively. +In addition to the above, `Tracer` also provides a number of well-known label keys and constants through its `labels` and `constants` fields respectively. ## Trace Spans These functions provide the capability to create trace spans, add labels to them, and close them. -* `TraceApi#runInRootSpan(options, fn)` +* `Tracer#runInRootSpan(options, fn)` * `options`: [`TraceOptions`](#trace-span-options) * `fn`: `function(Span): any` * Returns `any` (return value of `fn`) * Creates a root span and runs the given callback, passing it a `Span` object. In some instances, this `Span` object doesn't correspond to an actual trace span; this can be checked by consulting the value of `Span#type`: - * `TraceApi#spanTypes.ROOT`: This object corresponds to a real trace span. - * `TraceApi#spanTypes.UNTRACED`: There isn't a real trace span corresponding to this object, for one of the following reasons: + * `Tracer#spanTypes.ROOT`: This object corresponds to a real trace span. + * `Tracer#spanTypes.UNTRACED`: There isn't a real trace span corresponding to this object, for one of the following reasons: * The trace policy, as specified by the user-given configuration, disallows a root span from being created under the current circumstances. * The trace agent is disabled, either because it wasn't started at all, started in disabled mode, or encountered an initialization error. * The incoming request had headers that explicitly specified that this request shouldn't be traced. - * `TraceApi#spanTypes.UNCORRELATED`: `runInRootSpan` was called for a request that already has a root span. This likely indicates a programmer error, as nested root spans are not allowed. + * `Tracer#spanTypes.UNCORRELATED`: `runInRootSpan` was called for a request that already has a root span. This likely indicates a programmer error, as nested root spans are not allowed. * **Note:** You must call `endSpan` on the span object provided as an argument for the span to be recorded. -* `TraceApi#createChildSpan(options)` +* `Tracer#createChildSpan(options)` * `options`: [`TraceOptions`](#trace-span-options) * Returns `Span` * Creates a child `Span` object and returns it. In some instances, this `Span` object doesn't correspond to an actual trace span; this can be checked by consulting the value of `Span#type`: - * `TraceApi#spanTypes.CHILD`: This object corresponds to a real trace span. - * `TraceApi#spanTypes.UNTRACED`: There isn't a real trace span corresponding to this object, because this span's parent is also an `UNTRACED` (root) span. - * `TraceApi#spanTypes.UNCORRELATED`: There isn't a real trace span corresponding to this object, for one of the following reasons: + * `Tracer#spanTypes.CHILD`: This object corresponds to a real trace span. + * `Tracer#spanTypes.UNTRACED`: There isn't a real trace span corresponding to this object, because this span's parent is also an `UNTRACED` (root) span. + * `Tracer#spanTypes.UNCORRELATED`: There isn't a real trace span corresponding to this object, for one of the following reasons: * A root span wasn't created beforehand because `runInRootSpan` was not called at all. This likely indicates a programmer error, because child spans should always be nested within a root span. * A root span was created beforehand, but context was lost between then and now. This may also be a programmer error, because child spans should always be created within the context of a root span. See [`Context Propagation`](#context-propagation) for details on properly propagating root span context. * **Note:** You must call `endSpan` on the returned span object for the span to be recorded. -* `TraceApi#spanTypes` +* `Tracer#spanTypes` * An enumeration of the types of spans: `ROOT`, `CHILD`, `UNTRACED`, `UNCORRELATED` * `Span#addLabel(key, value)` * `key`: `string` @@ -64,7 +64,7 @@ Some functions above accept a `TraceOptions` object, which has the following fie ## Trace Agent Configuration -* `TraceApi#enhancedDatabaseReportingEnabled()` +* `Tracer#enhancedDatabaseReportingEnabled()` * Returns `boolean` * Returns whether the trace agent was started with an enhanced level of reporting. See the [configuration][config-js] object definition for more details. @@ -78,11 +78,11 @@ Trace context is sent and received using the [`'x-cloud-trace-context'`][stackdr Plugins that trace incoming HTTP requests (in other words, web frameworks) should support cross-service tracing by reading serialized trace context from the `'x-cloud-trace-context'` header, and supplying it as the [`traceContext` option](#trace-span-options) when creating a new root span. The trace agent will automatically deserialize the trace context and associate any new spans with it. -The string `'x-cloud-trace-context'` is provided as `TraceApi#constants.TRACE_CONTEXT_HEADER_NAME`. +The string `'x-cloud-trace-context'` is provided as `Tracer#constants.TRACE_CONTEXT_HEADER_NAME`. It is highly recommended for plugins to set this header field in responses, _if_ the incoming request has this header. The trace context that should be written can be obtained with the following function: -* `TraceApi#getResponseTraceContext(incomingTraceContext, isTraced)` +* `Tracer#getResponseTraceContext(incomingTraceContext, isTraced)` * `incomingTraceContext`: `string` * `isTraced`: `boolean` * Returns `string` diff --git a/src/constants.ts b/src/constants.ts index 11dcfd7f9..3892b3ced 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -70,14 +70,14 @@ export enum SpanType { UNTRACED = 'UNTRACED', /** - * This span object was created by TraceAgent#runInRootSpan, and represents - * an incoming request. + * This span object was created by StackdriverTracer#runInRootSpan, and + * represents an incoming request. */ ROOT = 'ROOT', /** - * This span object was created by TraceAgent#createChildSpan, and represents - * an outgoing RPC on behalf of an incoming request. + * This span object was created by StackdriverTracer#createChildSpan, and + * represents an outgoing RPC on behalf of an incoming request. */ CHILD = 'CHILD' } diff --git a/src/index.ts b/src/index.ts index 9edeebfb6..f9fb406c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,14 +23,14 @@ import {Config, defaultConfig} from './config'; import * as extend from 'extend'; import * as path from 'path'; import * as PluginTypes from './plugin-types'; -import {tracing, Tracing, NormalizedConfig} from './tracing'; -import {Singleton, FORCE_NEW, Forceable} from './util'; +import {Tracing, NormalizedConfig} from './tracing'; +import {FORCE_NEW, Forceable} from './util'; import {Constants} from './constants'; -import {TraceAgent} from './trace-api'; +import {StackdriverTracer} from './trace-api'; export {Config, PluginTypes}; -let traceAgent: TraceAgent; +let traceAgent: StackdriverTracer; /** * Normalizes the user-provided configuration object by adding default values @@ -100,7 +100,7 @@ function initConfig(projectConfig: Forceable): * @example * trace.start(); */ -export function start(config?: Config): PluginTypes.TraceAgent { +export function start(config?: Config): PluginTypes.Tracer { const normalizedConfig = initConfig(config || {}); // Determine the preferred context propagation mechanism, as // continuation-local-storage should be loaded before any modules that do I/O. @@ -111,7 +111,7 @@ export function start(config?: Config): PluginTypes.TraceAgent { } if (!traceAgent) { - traceAgent = new (require('./trace-api').TraceAgent)(); + traceAgent = new (require('./trace-api').StackdriverTracer)(); } try { @@ -135,12 +135,12 @@ export function start(config?: Config): PluginTypes.TraceAgent { } /** - * Get the previously created TraceAgent object. + * Get the previously created StackdriverTracer object. * @returns An object exposing functions for creating custom spans. */ -export function get(): PluginTypes.TraceAgent { +export function get(): PluginTypes.Tracer { if (!traceAgent) { - traceAgent = new (require('./trace-api').TraceAgent)(); + traceAgent = new (require('./trace-api').StackdriverTracer)(); } return traceAgent; } diff --git a/src/plugin-types.ts b/src/plugin-types.ts index 14518bbeb..16538eff7 100644 --- a/src/plugin-types.ts +++ b/src/plugin-types.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +// This file only describes public-facing interfaces. // tslint:disable:no-any import {Constants, SpanType} from './constants'; @@ -106,7 +107,7 @@ export interface RootSpanOptions extends SpanOptions { traceContext?: string|null; } -export interface TraceAgent { +export interface Tracer { /** * Gets the value of enhancedDatabaseReporting in the trace agent's * configuration object. @@ -228,19 +229,19 @@ export interface TraceAgent { }; } -export interface Patch { +export interface Monkeypatch { file?: string; versions?: string; - patch: (module: T, agent: TraceAgent) => void; + patch: (module: T, agent: Tracer) => void; unpatch?: (module: T) => void; } export interface Intercept { file?: string; versions?: string; - intercept: (module: T, agent: TraceAgent) => T; + intercept: (module: T, agent: Tracer) => T; } -export type Instrumentation = Patch|Intercept; +export type Patch = Monkeypatch|Intercept; -export type Plugin = Array>; +export type Plugin = Array>; diff --git a/src/plugins/plugin-connect.ts b/src/plugins/plugin-connect.ts index 6debd1646..2f2f2acdb 100644 --- a/src/plugins/plugin-connect.ts +++ b/src/plugins/plugin-connect.ts @@ -15,7 +15,6 @@ */ import {IncomingMessage, ServerResponse} from 'http'; -import * as shimmer from 'shimmer'; import {parse as urlParse} from 'url'; import {PluginTypes} from '..'; @@ -37,7 +36,7 @@ function getFirstHeader(req: IncomingMessage, key: string): string|null { return headerValue; } -function createMiddleware(api: PluginTypes.TraceAgent): +function createMiddleware(api: PluginTypes.Tracer): connect_3.NextHandleFunction { return function middleware(req: Request, res, next) { const options = { diff --git a/src/plugins/plugin-express.ts b/src/plugins/plugin-express.ts index c48cb88fa..f5b43fac2 100644 --- a/src/plugins/plugin-express.ts +++ b/src/plugins/plugin-express.ts @@ -30,7 +30,7 @@ const methods: Array = const SUPPORTED_VERSIONS = '4.x'; -function patchModuleRoot(express: Express4Module, api: PluginTypes.TraceAgent) { +function patchModuleRoot(express: Express4Module, api: PluginTypes.Tracer) { const labels = api.labels; function middleware( req: express_4.Request, res: express_4.Response, @@ -106,6 +106,6 @@ const plugin: PluginTypes.Plugin = [{ versions: SUPPORTED_VERSIONS, patch: patchModuleRoot, unpatch: unpatchModuleRoot -} as PluginTypes.Patch]; +} as PluginTypes.Monkeypatch]; export = plugin; diff --git a/src/plugins/plugin-grpc.ts b/src/plugins/plugin-grpc.ts index 6c60f61c0..d5f498437 100644 --- a/src/plugins/plugin-grpc.ts +++ b/src/plugins/plugin-grpc.ts @@ -19,7 +19,7 @@ import * as grpcModule from 'grpc'; // for types only. import {Client, MethodDefinition, ServerReadableStream, ServerUnaryCall, StatusObject} from 'grpc'; import * as shimmer from 'shimmer'; -import {Plugin, RootSpan, RootSpanOptions, Span, TraceAgent} from '../plugin-types'; +import {Plugin, RootSpan, RootSpanOptions, Span, Tracer} from '../plugin-types'; // Re-definition of Metadata with private fields type Metadata = grpcModule.Metadata&{ @@ -97,7 +97,7 @@ const SKIP_FRAMES = 1; // tslint:disable-next-line:variable-name let MetadataModuleValue: MetadataModule; -function patchMetadata(metadata: MetadataModule, api: TraceAgent) { +function patchMetadata(metadata: MetadataModule, api: Tracer) { // metadata is the value of module.exports of src/node/src/metadata.js MetadataModuleValue = metadata; } @@ -107,7 +107,7 @@ function unpatchMetadata() { // So it's safe to provide a no-op unpatch function. } -function patchClient(client: ClientModule, api: TraceAgent) { +function patchClient(client: ClientModule, api: Tracer) { /** * Set trace context on a Metadata object if it exists. * @param metadata The Metadata object to which a trace context should be @@ -281,7 +281,7 @@ function unpatchClient(client: ClientModule) { shimmer.unwrap(client, 'makeClientConstructor'); } -function patchServer(server: ServerModule, api: TraceAgent) { +function patchServer(server: ServerModule, api: Tracer) { /** * Returns a trace context on a Metadata object if it exists and is * well-formed, or null otherwise. The result will be encoded as a string. diff --git a/src/plugins/plugin-hapi.ts b/src/plugins/plugin-hapi.ts index 781312690..eb67f1e87 100644 --- a/src/plugins/plugin-hapi.ts +++ b/src/plugins/plugin-hapi.ts @@ -43,7 +43,7 @@ function getFirstHeader(req: IncomingMessage, key: string): string|null { } function instrument( - api: PluginTypes.TraceAgent, request: hapi_16.Request|hapi_17.Request, + api: PluginTypes.Tracer, request: hapi_16.Request|hapi_17.Request, continueCb: () => T): T { const req = request.raw.req; const res = request.raw.res; @@ -124,7 +124,7 @@ const plugin: PluginTypes.Plugin = [ unpatch: (hapi) => { shimmer.unwrap(hapi.Server.prototype, 'connection'); } - } as PluginTypes.Patch, + } as PluginTypes.Monkeypatch, /** * 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 @@ -153,6 +153,6 @@ const plugin: PluginTypes.Plugin = [ Request.prototype._execute = Request.prototype._execute[ORIGINAL]!; } } - } as PluginTypes.Patch<{prototype: Hapi17Request}> + } as PluginTypes.Monkeypatch<{prototype: Hapi17Request}> ]; export = plugin; diff --git a/src/plugins/plugin-http.ts b/src/plugins/plugin-http.ts index f94711e30..8ad2ee3fb 100644 --- a/src/plugins/plugin-http.ts +++ b/src/plugins/plugin-http.ts @@ -22,7 +22,7 @@ import * as semver from 'semver'; import * as shimmer from 'shimmer'; import * as url from 'url'; -import {Plugin, TraceAgent} from '../plugin-types'; +import {Plugin, Tracer} from '../plugin-types'; type HttpModule = typeof httpModule; type HttpsModule = typeof httpsModule; @@ -78,14 +78,13 @@ function extractUrl( } // tslint:disable-next-line:no-any -function isTraceAgentRequest(options: any, api: TraceAgent) { +function isTraceAgentRequest(options: any, api: Tracer) { return options && options.headers && !!options.headers[api.constants.TRACE_AGENT_REQUEST_HEADER]; } function makeRequestTrace( - protocol: string, request: RequestFunction, - api: TraceAgent): RequestFunction { + protocol: string, request: RequestFunction, api: Tracer): RequestFunction { // On Node 8+ we use the following function to patch both request and get. // Here `request` may also happen to be `get`. return function requestTrace(options, callback): ClientRequest { @@ -187,7 +186,7 @@ function makeRequestTrace( }; } -function patchHttp(http: HttpModule, api: TraceAgent) { +function patchHttp(http: HttpModule, api: Tracer) { shimmer.wrap(http, 'request', (request) => { return makeRequestTrace('http:', request, api); }); @@ -217,7 +216,7 @@ function patchHttp(http: HttpModule, api: TraceAgent) { // https.get depends on Node http internals in 8.9.0 and 9+ instead of the // public http module. -function patchHttps(https: HttpsModule, api: TraceAgent) { +function patchHttps(https: HttpsModule, api: Tracer) { shimmer.wrap(https, 'request', (request) => { return makeRequestTrace('https:', request, api); }); diff --git a/src/plugins/plugin-http2.ts b/src/plugins/plugin-http2.ts index aeb28830c..71ebe5927 100644 --- a/src/plugins/plugin-http2.ts +++ b/src/plugins/plugin-http2.ts @@ -21,7 +21,7 @@ import * as http2 from 'http2'; import * as shimmer from 'shimmer'; import {URL} from 'url'; -import {TraceAgent} from '../plugin-types'; +import {Tracer} from '../plugin-types'; type Http2Module = typeof http2; @@ -60,13 +60,13 @@ function extractUrl( } function isTraceAgentRequest( - headers: http2.OutgoingHttpHeaders|undefined, api: TraceAgent): boolean { + headers: http2.OutgoingHttpHeaders|undefined, api: Tracer): boolean { return !!headers && !!headers[api.constants.TRACE_AGENT_REQUEST_HEADER]; } function makeRequestTrace( request: Http2SessionRequestFunction, authority: string|URL, - api: TraceAgent): Http2SessionRequestFunction { + api: Tracer): Http2SessionRequestFunction { return function( this: http2.Http2Session, headers?: http2.OutgoingHttpHeaders): http2.ClientHttp2Stream { @@ -152,14 +152,14 @@ function makeRequestTrace( function patchHttp2Session( session: http2.ClientHttp2Session, authority: string|URL, - api: TraceAgent): void { + api: Tracer): void { api.wrapEmitter(session); shimmer.wrap( session, 'request', (request) => makeRequestTrace(request, authority, api)); } -function patchHttp2(h2: Http2Module, api: TraceAgent): void { +function patchHttp2(h2: Http2Module, api: Tracer): void { shimmer.wrap( h2, 'connect', (connect) => function(this: Http2Module, authority: string|URL) { diff --git a/src/plugins/plugin-koa.ts b/src/plugins/plugin-koa.ts index f58b35c9b..926a88b54 100644 --- a/src/plugins/plugin-koa.ts +++ b/src/plugins/plugin-koa.ts @@ -34,7 +34,7 @@ interface KoaModule { } // Function signature for createMiddleware[2x] -type CreateMiddlewareFn = (api: PluginTypes.TraceAgent) => T; +type CreateMiddlewareFn = (api: PluginTypes.Tracer) => T; // Function signature for a function that returns the value of the "next" // middleware function parameter, wrapped to propagate context based on the // propagateContext flag. The type of "next" differs between Koa 1 and 2. @@ -49,7 +49,7 @@ function getFirstHeader(req: IncomingMessage, key: string): string|null { } function startSpanForRequest( - api: PluginTypes.TraceAgent, ctx: KoaContext, getNext: GetNextFn): T { + api: PluginTypes.Tracer, ctx: KoaContext, getNext: GetNextFn): T { const req = ctx.req; const res = ctx.res; const originalEnd = res.end; @@ -113,7 +113,7 @@ function startSpanForRequest( }); } -function createMiddleware(api: PluginTypes.TraceAgent): koa_1.Middleware { +function createMiddleware(api: PluginTypes.Tracer): koa_1.Middleware { return function* middleware(this: koa_1.Context, next: IterableIterator<{}>) { next = startSpanForRequest(api, this, (propagateContext: boolean) => { if (propagateContext) { @@ -125,7 +125,7 @@ function createMiddleware(api: PluginTypes.TraceAgent): koa_1.Middleware { }; } -function createMiddleware2x(api: PluginTypes.TraceAgent): koa_2.Middleware { +function createMiddleware2x(api: PluginTypes.Tracer): koa_2.Middleware { return function middleware(ctx, next) { next = startSpanForRequest( api, ctx, @@ -136,7 +136,7 @@ function createMiddleware2x(api: PluginTypes.TraceAgent): koa_2.Middleware { } function patchUse( - koa: KoaModule, api: PluginTypes.TraceAgent, + koa: KoaModule, api: PluginTypes.Tracer, createMiddlewareFunction: CreateMiddlewareFn) { shimmer.wrap(koa.prototype, 'use', (use) => { return function useTrace(this: typeof koa.prototype& @@ -161,7 +161,7 @@ const plugin: PluginTypes.Plugin = [ unpatch: (koa) => { shimmer.unwrap(koa.prototype, 'use'); } - } as PluginTypes.Patch, + } as PluginTypes.Monkeypatch, { file: '', versions: '2.x', @@ -171,7 +171,7 @@ const plugin: PluginTypes.Plugin = [ unpatch: (koa) => { shimmer.unwrap(koa.prototype, 'use'); } - } as PluginTypes.Patch + } as PluginTypes.Monkeypatch ]; export = plugin; diff --git a/src/plugins/plugin-restify.ts b/src/plugins/plugin-restify.ts index 4041f9556..722bd261e 100644 --- a/src/plugins/plugin-restify.ts +++ b/src/plugins/plugin-restify.ts @@ -34,7 +34,7 @@ function unpatchRestify(restify: Restify5) { shimmer.unwrap(restify, 'createServer'); } -function patchRestify(restify: Restify5, api: PluginTypes.TraceAgent) { +function patchRestify(restify: Restify5, api: PluginTypes.Tracer) { shimmer.wrap(restify, 'createServer', createServerWrap); function createServerWrap(createServer: CreateServerFn): CreateServerFn { @@ -102,6 +102,6 @@ const plugin: PluginTypes.Plugin = [{ versions: SUPPORTED_VERSIONS, patch: patchRestify, unpatch: unpatchRestify -} as PluginTypes.Patch]; +} as PluginTypes.Monkeypatch]; export = plugin; diff --git a/src/trace-api.ts b/src/trace-api.ts index dc2d60b63..cfeb5d79f 100644 --- a/src/trace-api.ts +++ b/src/trace-api.ts @@ -20,7 +20,7 @@ import * as uuid from 'uuid'; import {cls, RootContext} from './cls'; import {Constants, SpanType} from './constants'; -import {Func, RootSpan, RootSpanOptions, Span, SpanOptions, TraceAgent as TraceAgentInterface} from './plugin-types'; +import {Func, RootSpan, RootSpanOptions, Span, SpanOptions, Tracer} from './plugin-types'; import {RootSpanData, UNCORRELATED_CHILD_SPAN, UNCORRELATED_ROOT_SPAN, UNTRACED_CHILD_SPAN, UNTRACED_ROOT_SPAN} from './span-data'; import {TraceLabels} from './trace-labels'; import {traceWriter} from './trace-writer'; @@ -28,10 +28,11 @@ import * as TracingPolicy from './tracing-policy'; import * as util from './util'; /** - * An interface describing configuration fields read by the TraceAgent object. - * This includes fields read by the trace policy. + * An interface describing configuration fields read by the StackdriverTracer + * object. This includes fields read by the trace policy. */ -export interface TraceAgentConfig extends TracingPolicy.TracePolicyConfig { +export interface StackdriverTracerConfig extends + TracingPolicy.TracePolicyConfig { enhancedDatabaseReporting: boolean; ignoreContextHeader: boolean; } @@ -51,10 +52,10 @@ function isString(obj: any): obj is string { } /** - * TraceAgent exposes a number of methods to create trace spans and propagate - * trace context across asynchronous boundaries. + * StackdriverTracer exposes a number of methods to create trace spans and + * propagate trace context across asynchronous boundaries. */ -export class TraceAgent implements TraceAgentInterface { +export class StackdriverTracer implements Tracer { readonly constants = Constants; readonly labels = TraceLabels; readonly spanTypes = SpanType; @@ -68,13 +69,13 @@ export class TraceAgent implements TraceAgentInterface { private enabled = false; private pluginName: string; private logger: Logger|null = null; - private config: TraceAgentConfig|null = null; + private config: StackdriverTracerConfig|null = null; // TODO(kjin): Make this private. policy: TracingPolicy.TracePolicy|null = null; /** - * Constructs a new TraceAgent instance. - * @param name A string identifying this TraceAgent instance in logs. + * Constructs a new StackdriverTracer instance. + * @param name A string identifying this StackdriverTracer instance in logs. */ constructor(name: string) { this.pluginName = name; @@ -90,7 +91,7 @@ export class TraceAgent implements TraceAgentInterface { * @param logger A logger object. * @private */ - enable(config: TraceAgentConfig, logger: Logger) { + enable(config: StackdriverTracerConfig, logger: Logger) { this.logger = logger; this.config = config; this.policy = TracingPolicy.createTracePolicy(config); @@ -112,9 +113,9 @@ export class TraceAgent implements TraceAgentInterface { } /** - * Returns whether the TraceAgent instance is active. This function is only - * for internal use and unit tests; under normal circumstances it will always - * return true. + * Returns whether the StackdriverTracer instance is active. This function is + * only for internal use and unit tests; under normal circumstances it will + * always return true. * @private */ isActive(): boolean { diff --git a/src/trace-plugin-loader.ts b/src/trace-plugin-loader.ts index 642fff84d..703c4a0a1 100644 --- a/src/trace-plugin-loader.ts +++ b/src/trace-plugin-loader.ts @@ -15,15 +15,13 @@ */ import {Logger} from '@google-cloud/common'; -import Module = require('module'); -import * as hook from 'require-in-the-middle'; +import * as builtinModules from 'builtin-modules'; import * as path from 'path'; +import * as hook from 'require-in-the-middle'; import * as semver from 'semver'; -import * as shimmer from 'shimmer'; -import * as util from './util'; -import * as builtinModules from 'builtin-modules'; -import {TraceAgent, TraceAgentConfig} from './trace-api'; -import {Patch, Intercept, Plugin, Instrumentation} from './plugin-types'; + +import {Intercept, Monkeypatch, Plugin} from './plugin-types'; +import {StackdriverTracer, StackdriverTracerConfig} from './trace-api'; import {Singleton} from './util'; /** @@ -37,7 +35,7 @@ import {Singleton} from './util'; * should be patched. (See ./plugin-types for the exact interface.) */ -export interface PluginLoaderConfig extends TraceAgentConfig { +export interface PluginLoaderConfig extends StackdriverTracerConfig { // An object which contains paths to files that should be loaded as plugins // upon loading a module with a given name. plugins: {[pluginName: string]: string}; @@ -89,8 +87,8 @@ export class ModulePluginWrapper implements PluginWrapper { private readonly unpatchFns: Array<() => void> = []; // A logger. private readonly logger: Logger; - // Configuration for a TraceAgent instance. - private readonly traceConfig: TraceAgentConfig; + // Configuration for a StackdriverTracer instance. + private readonly traceConfig: StackdriverTracerConfig; // Display-friendly name of the module being patched by this plugin. private readonly name: string; // The path to the plugin. @@ -98,16 +96,16 @@ export class ModulePluginWrapper implements PluginWrapper { // The exported value of the plugin, or NOT_LOADED if it hasn't been // loaded yet. private pluginExportedValue: Plugin = ModulePluginWrapper.NOT_LOADED; - private readonly traceApiInstances: TraceAgent[] = []; + private readonly traceApiInstances: StackdriverTracer[] = []; /** * Constructs a new PluginWrapper instance. * @param options Initialization fields for this object. - * @param traceConfig Configuration for a TraceAgent instance. + * @param traceConfig Configuration for a StackdriverTracer instance. * @param logger The logger to use. */ constructor( - options: ModulePluginWrapperOptions, traceConfig: TraceAgentConfig, + options: ModulePluginWrapperOptions, traceConfig: StackdriverTracerConfig, logger: Logger) { this.logger = logger; this.name = options.name; @@ -150,7 +148,7 @@ export class ModulePluginWrapper implements PluginWrapper { const plugin = this.getPluginExportedValue(); // Get a list of supported patches. This is the subset of objects in the // plugin exported value with matching file/version fields. - const supportedPatches: Array&Intercept>> = + const supportedPatches: Array&Intercept>> = plugin.filter( patch => semver.satisfies(version, patch.versions || '*') && (file === patch.file || (!file && !patch.file))); @@ -161,9 +159,9 @@ export class ModulePluginWrapper implements PluginWrapper { // Apply each patch object. return supportedPatches.reduce((exportedValue, patch) => { - // TODO(kjin): The only benefit of creating a new TraceAgent object per - // patched file is to give us granularity in log messages. See if we can - // refactor the TraceAgent class to avoid this. + // TODO(kjin): The only benefit of creating a new StackdriverTracer object + // per patched file is to give us granularity in log messages. See if we + // can refactor the StackdriverTracer class to avoid this. this.logger.info( `PluginWrapper#applyPlugin: [${logString}] Applying plugin.`); @@ -200,7 +198,7 @@ export class ModulePluginWrapper implements PluginWrapper { } private createTraceAgentInstance(file: string) { - const traceApi = new TraceAgent(file); + const traceApi = new StackdriverTracer(file); traceApi.enable(this.traceConfig, this.logger); this.traceApiInstances.push(traceApi); return traceApi; @@ -218,7 +216,7 @@ export class CorePluginWrapper implements PluginWrapper { private readonly children: ModulePluginWrapper[]; constructor( - config: CorePluginWrapperOptions, traceConfig: TraceAgentConfig, + config: CorePluginWrapperOptions, traceConfig: StackdriverTracerConfig, logger: Logger) { this.logger = logger; this.children = config.children.map( diff --git a/src/tracing.ts b/src/tracing.ts index dfe7a54d3..63928724b 100644 --- a/src/tracing.ts +++ b/src/tracing.ts @@ -16,13 +16,10 @@ import {Logger, logger} from '@google-cloud/common'; import * as path from 'path'; -import * as semver from 'semver'; import {cls, TraceCLSConfig, TraceCLSMechanism} from './cls'; -import {CLSMechanism, Config, defaultConfig} from './config'; -import {Constants} from './constants'; -import * as PluginTypes from './plugin-types'; -import {TraceAgent} from './trace-api'; +import {CLSMechanism} from './config'; +import {StackdriverTracer} from './trace-api'; import {pluginLoader, PluginLoaderConfig} from './trace-plugin-loader'; import {traceWriter, TraceWriterConfig} from './trace-writer'; import {Component, FORCE_NEW, Forceable, packageNameFromPath, Singleton} from './util'; @@ -52,7 +49,8 @@ export class Tracing implements Component { * @param traceAgent An object representing the custom tracing API. */ constructor( - config: NormalizedConfig, private readonly traceAgent: TraceAgent) { + config: NormalizedConfig, + private readonly traceAgent: StackdriverTracer) { this.config = config; let logLevel = config.enabled ? config.logLevel : 0; // Clamp the logger level. @@ -89,7 +87,7 @@ export class Tracing implements Component { } if (modulesLoadedBeforeTrace.length > 0) { this.logger.error( - 'TraceAgent#start: Tracing might not work as the following modules', + 'StackdriverTracer#start: Tracing might not work as the following modules', 'were loaded before the trace agent was initialized:', `[${modulesLoadedBeforeTrace.sort().join(', ')}]`); } @@ -113,7 +111,7 @@ export class Tracing implements Component { cls.create(clsConfig, this.logger); } catch (e) { this.logger.error( - 'TraceAgent#start: Disabling the Trace Agent for the', + 'StackdriverTracer#start: Disabling the Trace Agent for the', `following reason: ${e.message}`); this.disable(); return; @@ -121,7 +119,7 @@ export class Tracing implements Component { traceWriter.get().initialize((err) => { if (err) { this.logger.error( - 'TraceAgent#start: Disabling the Trace Agent for the', + 'StackdriverTracer#start: Disabling the Trace Agent for the', `following reason: ${err.message}`); this.disable(); } @@ -133,7 +131,7 @@ export class Tracing implements Component { if (typeof this.config.projectId !== 'string' && typeof this.config.projectId !== 'undefined') { this.logger.error( - 'TraceAgent#start: config.projectId, if provided, must be a string.', + 'StackdriverTracer#start: config.projectId, if provided, must be a string.', 'Disabling trace agent.'); this.disable(); return; @@ -142,7 +140,7 @@ export class Tracing implements Component { // Make trace agent available globally without requiring package global._google_trace_agent = this.traceAgent; - this.logger.info('TraceAgent#start: Trace Agent activated.'); + this.logger.info('StackdriverTracer#start: Trace Agent activated.'); } /** diff --git a/test/plugins/common.ts b/test/plugins/common.ts index 1643d5ca4..d937966ba 100644 --- a/test/plugins/common.ts +++ b/test/plugins/common.ts @@ -26,7 +26,7 @@ declare global { import '../override-gcp-metadata'; import { cls, TraceCLS } from '../../src/cls'; -import { TraceAgent } from '../../src/trace-api'; +import { StackdriverTracer } from '../../src/trace-api'; import { traceWriter } from '../../src/trace-writer'; import * as TracingPolicy from '../../src/tracing-policy'; import { SpanType } from '../../src/constants'; @@ -65,11 +65,11 @@ var path = require('path'); var request = require('request'); var shimmer = require('shimmer'); -var testTraceAgent: TraceAgent; +var testTraceAgent: StackdriverTracer; shimmer.wrap(trace, 'start', function(original) { return function() { var result = original.apply(this, arguments); - testTraceAgent = new TraceAgent('test'); + testTraceAgent = new StackdriverTracer('test'); testTraceAgent.enable({ enhancedDatabaseReporting: false, ignoreContextHeader: false, diff --git a/test/test-agent-stopped.ts b/test/test-agent-stopped.ts index b9b8171ad..5851c0efe 100644 --- a/test/test-agent-stopped.ts +++ b/test/test-agent-stopped.ts @@ -19,7 +19,7 @@ import * as http from 'http'; import * as traceTestModule from './trace'; import { pluginLoader, PluginLoaderState } from '../src/trace-plugin-loader'; import { TraceWriter } from '../src/trace-writer'; -import { TraceAgent } from '../src/trace-api'; +import { StackdriverTracer } from '../src/trace-api'; describe('test-agent-stopped', () => { class InitErrorTraceWriter extends TraceWriter { @@ -34,7 +34,7 @@ describe('test-agent-stopped', () => { traceTestModule.start(); // Wait for agent to fail getting remote project id. setImmediate(() => { - assert.ok(!(traceTestModule.get() as TraceAgent).isActive()); + assert.ok(!(traceTestModule.get() as StackdriverTracer).isActive()); done(); }); }); diff --git a/test/test-index.ts b/test/test-index.ts index e379e159b..6fb3180cf 100644 --- a/test/test-index.ts +++ b/test/test-index.ts @@ -17,14 +17,14 @@ 'use strict'; import './override-gcp-metadata'; -import { TraceAgent } from '../src/trace-api'; +import { StackdriverTracer } from '../src/trace-api'; import { SpanType } from '../src/constants'; import { FORCE_NEW } from '../src/util'; var assert = require('assert'); var trace = require('../..'); -var disabledAgent: TraceAgent = trace.get(); +var disabledAgent: StackdriverTracer = trace.get(); describe('index.js', function() { it('should get a disabled agent with `Trace.get`', async function() { diff --git a/test/test-trace-api-none-cls.ts b/test/test-trace-api-none-cls.ts index b04154b35..68ec4fc59 100644 --- a/test/test-trace-api-none-cls.ts +++ b/test/test-trace-api-none-cls.ts @@ -17,7 +17,7 @@ import * as assert from 'assert'; import {SpanType} from '../src/constants'; -import {TraceAgent} from '../src/plugin-types'; +import {Tracer} from '../src/plugin-types'; import * as testTraceModule from './trace'; import {asChildSpanData, asRootSpanData} from './utils'; @@ -25,7 +25,7 @@ import {asChildSpanData, asRootSpanData} from './utils'; const identity = (x: T) => x; describe('Custom Trace API with CLS disabled', () => { - let traceApi: TraceAgent; + let traceApi: Tracer; before(() => { testTraceModule.setCLSForTest(); diff --git a/test/test-trace-api.ts b/test/test-trace-api.ts index 3bf35aaf0..9fb748eab 100644 --- a/test/test-trace-api.ts +++ b/test/test-trace-api.ts @@ -19,21 +19,20 @@ import * as assert from 'assert'; import {cls, TraceCLS, TraceCLSMechanism} from '../src/cls'; import {defaultConfig} from '../src/config'; import {SpanType} from '../src/constants'; -import {TraceAgent, TraceAgentConfig} from '../src/trace-api'; +import {StackdriverTracer, StackdriverTracerConfig} from '../src/trace-api'; import {traceWriter} from '../src/trace-writer'; import {FilterPolicy, TraceAllPolicy, TraceNonePolicy, TracePolicy} from '../src/tracing-policy'; import {FORCE_NEW} from '../src/util'; import {TestLogger} from './logger'; import * as testTraceModule from './trace'; -import {asChildSpanData, asRootSpanData} from './utils'; describe('Trace Interface', () => { const logger = new TestLogger(); function createTraceAgent( policy?: TracePolicy|null, - config?: Partial): TraceAgent { - const result = new TraceAgent('test'); + config?: Partial): StackdriverTracer { + const result = new StackdriverTracer('test'); result.enable( Object.assign( { diff --git a/test/trace.ts b/test/trace.ts index 8501d5dc2..2fa0866f7 100644 --- a/test/trace.ts +++ b/test/trace.ts @@ -92,13 +92,13 @@ setPluginLoaderForTest(TestPluginLoader); export type Predicate = (value: T) => boolean; -export function start(projectConfig?: Config): PluginTypes.TraceAgent { +export function start(projectConfig?: Config): PluginTypes.Tracer { const agent = trace.start(Object.assign( {samplingRate: 0, logLevel: 4, [FORCE_NEW]: true}, projectConfig)); return agent; } -export function get(): PluginTypes.TraceAgent { +export function get(): PluginTypes.Tracer { return trace.get(); }