Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rename TraceAgent/TraceApi to Tracer #815

Merged
merged 2 commits into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down Expand Up @@ -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?

Expand Down
30 changes: 15 additions & 15 deletions doc/trace-api.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down Expand Up @@ -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.

Expand All @@ -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`
Expand Down
8 changes: 4 additions & 4 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
18 changes: 9 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -100,7 +100,7 @@ function initConfig(projectConfig: Forceable<Config>):
* @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.
Expand All @@ -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 {
Expand All @@ -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;
}
Expand Down
13 changes: 7 additions & 6 deletions src/plugin-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

// This file only describes public-facing interfaces.
// tslint:disable:no-any

import {Constants, SpanType} from './constants';
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -228,19 +229,19 @@ export interface TraceAgent {
};
}

export interface Patch<T> {
export interface Monkeypatch<T> {
file?: string;
versions?: string;
patch: (module: T, agent: TraceAgent) => void;
patch: (module: T, agent: Tracer) => void;
unpatch?: (module: T) => void;
}

export interface Intercept<T> {
file?: string;
versions?: string;
intercept: (module: T, agent: TraceAgent) => T;
intercept: (module: T, agent: Tracer) => T;
}

export type Instrumentation<T> = Patch<T>|Intercept<T>;
export type Patch<T> = Monkeypatch<T>|Intercept<T>;

export type Plugin = Array<Instrumentation<any>>;
export type Plugin = Array<Patch<any>>;
3 changes: 1 addition & 2 deletions src/plugins/plugin-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

import {IncomingMessage, ServerResponse} from 'http';
import * as shimmer from 'shimmer';
import {parse as urlParse} from 'url';

import {PluginTypes} from '..';
Expand All @@ -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 = {
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/plugin-express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const methods: Array<keyof express_4.Application> =

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,
Expand Down Expand Up @@ -106,6 +106,6 @@ const plugin: PluginTypes.Plugin = [{
versions: SUPPORTED_VERSIONS,
patch: patchModuleRoot,
unpatch: unpatchModuleRoot
} as PluginTypes.Patch<Express4Module>];
} as PluginTypes.Monkeypatch<Express4Module>];

export = plugin;
8 changes: 4 additions & 4 deletions src/plugins/plugin-grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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&{
Expand Down Expand Up @@ -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;
}
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/plugin-hapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function getFirstHeader(req: IncomingMessage, key: string): string|null {
}

function instrument<T>(
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;
Expand Down Expand Up @@ -124,7 +124,7 @@ const plugin: PluginTypes.Plugin = [
unpatch: (hapi) => {
shimmer.unwrap(hapi.Server.prototype, 'connection');
}
} as PluginTypes.Patch<Hapi16Module>,
} 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
Expand Down Expand Up @@ -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;
11 changes: 5 additions & 6 deletions src/plugins/plugin-http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
});
Expand Down Expand Up @@ -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);
});
Expand Down
Loading