diff --git a/CHANGELOG.md b/CHANGELOG.md index 234dfe57b..9334e17d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,14 @@ All notable changes to this project will be documented in this file. - Add ignoreIncomingPaths and ignoreOutgoingUrls support to the http and https tracing instrumentations. - Add ```opencensus-resource-util``` to auto detect AWS, GCE and Kubernetes(K8S) monitored resource, based on the environment where the application is running. - Add optional `uncompressedSize` and `compressedSize` fields to `MessageEvent` interface. +- Add a ```setStatus``` method in the Span. **This release has multiple breaking changes. Please test your code accordingly after upgrading.** - Modify `Logger` interface: `level` made optional, `silly` removed. - The ```new Stats()``` has been deprecated on Stats class. The global singleton ```globalStats``` object should be used instead. Also, ```registerView()``` is separated out from ```createView()```. - Use ```TagKey```, ```TagValue``` and ```TagMap``` to create the tag keys, tag values. +- The `status` field on `Span` is no longer a number, use `CanonicalCode` instead. ##### Old code ```js diff --git a/packages/opencensus-core/src/trace/model/span-base.ts b/packages/opencensus-core/src/trace/model/span-base.ts index d9f7a2120..71e1a7d99 100644 --- a/packages/opencensus-core/src/trace/model/span-base.ts +++ b/packages/opencensus-core/src/trace/model/span-base.ts @@ -18,6 +18,9 @@ import {Clock} from '../../internal/clock'; import {randomSpanId} from '../../internal/util'; import * as types from './types'; +const STATUS_OK = { + code: types.CanonicalCode.OK +}; /** Defines a base model for spans. */ export abstract class SpanBase implements types.Span { @@ -52,7 +55,7 @@ export abstract class SpanBase implements types.Span { /** Kind of span. */ kind: string = null; /** A final status for this span */ - status: number; + status: types.Status = STATUS_OK; /** set isRootSpan */ abstract get isRootSpan(): boolean; @@ -183,6 +186,15 @@ export abstract class SpanBase implements types.Span { } as types.MessageEvent); } + /** + * Sets a status to the span. + * @param code The canonical status code. + * @param message optional A developer-facing error message. + */ + setStatus(code: types.CanonicalCode, message?: string) { + this.status = {code, message}; + } + /** Starts the span. */ start() { if (this.started) { diff --git a/packages/opencensus-core/src/trace/model/types.ts b/packages/opencensus-core/src/trace/model/types.ts index def9b5542..9ad689c10 100644 --- a/packages/opencensus-core/src/trace/model/types.ts +++ b/packages/opencensus-core/src/trace/model/types.ts @@ -30,6 +30,152 @@ export interface Attributes { [attributeKey: string]: string|number|boolean; } +/** + * The status of a Span by providing a standard CanonicalCode in conjunction + * with an optional descriptive message. + */ +export interface Status { + /** The canonical code of this message. */ + code: CanonicalCode; + /** A developer-facing error message. */ + message?: string; +} + +/** An enumeration of canonical status codes. */ +export enum CanonicalCode { + /** + * Not an error; returned on success + */ + OK = 0, + /** + * The operation was cancelled (typically by the caller). + */ + CANCELLED = 1, + /** + * Unknown error. An example of where this error may be returned is + * if a status value received from another address space belongs to + * an error-space that is not known in this address space. Also + * errors raised by APIs that do not return enough error information + * may be converted to this error. + */ + UNKNOWN = 2, + /** + * Client specified an invalid argument. Note that this differs + * from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments + * that are problematic regardless of the state of the system + * (e.g., a malformed file name). + */ + INVALID_ARGUMENT = 3, + /** + * Deadline expired before operation could complete. For operations + * that change the state of the system, this error may be returned + * even if the operation has completed successfully. For example, a + * successful response from a server could have been delayed long + * enough for the deadline to expire. + */ + DEADLINE_EXCEEDED = 4, + /** + * Some requested entity (e.g., file or directory) was not found. + */ + NOT_FOUND = 5, + /** + * Some entity that we attempted to create (e.g., file or directory) + * already exists. + */ + ALREADY_EXISTS = 6, + /** + * The caller does not have permission to execute the specified + * operation. PERMISSION_DENIED must not be used for rejections + * caused by exhausting some resource (use RESOURCE_EXHAUSTED + * instead for those errors). PERMISSION_DENIED must not be + * used if the caller can not be identified (use UNAUTHENTICATED + * instead for those errors). + */ + PERMISSION_DENIED = 7, + /** + * Some resource has been exhausted, perhaps a per-user quota, or + * perhaps the entire file system is out of space. + */ + RESOURCE_EXHAUSTED = 8, + /** + * Operation was rejected because the system is not in a state + * required for the operation's execution. For example, directory + * to be deleted may be non-empty, an rmdir operation is applied to + * a non-directory, etc. + * + * A litmus test that may help a service implementor in deciding + * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: + * + * - Use UNAVAILABLE if the client can retry just the failing call. + * - Use ABORTED if the client should retry at a higher-level + * (e.g., restarting a read-modify-write sequence). + * - Use FAILED_PRECONDITION if the client should not retry until + * the system state has been explicitly fixed. E.g., if an "rmdir" + * fails because the directory is non-empty, FAILED_PRECONDITION + * should be returned since the client should not retry unless + * they have first fixed up the directory by deleting files from it. + * - Use FAILED_PRECONDITION if the client performs conditional + * REST Get/Update/Delete on a resource and the resource on the + * server does not match the condition. E.g., conflicting + * read-modify-write on the same resource. + */ + FAILED_PRECONDITION = 9, + /** + * The operation was aborted, typically due to a concurrency issue + * like sequencer check failures, transaction aborts, etc. + * + * See litmus test above for deciding between FAILED_PRECONDITION, + * ABORTED, and UNAVAILABLE. + */ + ABORTED = 10, + /** + * Operation was attempted past the valid range. E.g., seeking or + * reading past end of file. + * + * Unlike INVALID_ARGUMENT, this error indicates a problem that may + * be fixed if the system state changes. For example, a 32-bit file + * system will generate INVALID_ARGUMENT if asked to read at an + * offset that is not in the range [0,2^32-1], but it will generate + * OUT_OF_RANGE if asked to read from an offset past the current + * file size. + * + * There is a fair bit of overlap between FAILED_PRECONDITION and + * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific + * error) when it applies so that callers who are iterating through + * a space can easily look for an OUT_OF_RANGE error to detect when + * they are done. + */ + OUT_OF_RANGE = 11, + /** + * Operation is not implemented or not supported/enabled in this service. + */ + UNIMPLEMENTED = 12, + /** + * Internal errors. Means some invariants expected by underlying + * system has been broken. If you see one of these errors, + * something is very broken. + */ + INTERNAL = 13, + /** + * The service is currently unavailable. This is a most likely a + * transient condition and may be corrected by retrying with + * a backoff. + * + * See litmus test above for deciding between FAILED_PRECONDITION, + * ABORTED, and UNAVAILABLE. + */ + UNAVAILABLE = 14, + /** + * Unrecoverable data loss or corruption. + */ + DATA_LOSS = 15, + /** + * The request does not have valid authentication credentials for the + * operation. + */ + UNAUTHENTICATED = 16, +} + /** A text annotation with a set of attributes. */ export interface Annotation { /** A user-supplied message describing the event. */ @@ -124,7 +270,7 @@ export interface Span { logger: loggerTypes.Logger; /** A final status for this span */ - status: number; + status: Status; /** A set of attributes, each in the format [KEY]:[VALUE] */ attributes: Attributes; @@ -209,6 +355,13 @@ export interface Span { */ addMessageEvent(type: string, id: string, timestamp?: number): void; + /** + * Sets a status to the span. + * @param code The canonical status code. + * @param message optional A developer-facing error message. + */ + setStatus(code: CanonicalCode, message?: string): void; + /** Starts a span. */ start(): void; diff --git a/packages/opencensus-core/test/test-span.ts b/packages/opencensus-core/test/test-span.ts index 69e3b7a87..04162cfbd 100644 --- a/packages/opencensus-core/test/test-span.ts +++ b/packages/opencensus-core/test/test-span.ts @@ -258,4 +258,32 @@ describe('Span', () => { assert.ok(instanceOfLink(span.messageEvents[0])); }); }); + + describe('setStatus()', () => { + it('should return default status', () => { + const rootSpan = new RootSpan(tracer); + rootSpan.start(); + + const span = new Span(rootSpan); + span.start(); + + assert.equal(rootSpan.status.code, 0); + assert.equal(rootSpan.status.message, null); + assert.equal(span.status.code, 0); + assert.equal(span.status.message, null); + }); + + it('should set an error status', () => { + const rootSpan = new RootSpan(tracer); + rootSpan.start(); + const span = new Span(rootSpan); + span.start(); + span.setStatus(types.CanonicalCode.PERMISSION_DENIED, 'This is an error'); + + assert.equal(rootSpan.status.code, 0); + assert.equal(rootSpan.status.message, null); + assert.equal(span.status.code, 7); + assert.equal(span.status.message, 'This is an error'); + }); + }); }); diff --git a/packages/opencensus-exporter-instana/src/instana.ts b/packages/opencensus-exporter-instana/src/instana.ts index 709c28f8e..87772fcbe 100644 --- a/packages/opencensus-exporter-instana/src/instana.ts +++ b/packages/opencensus-exporter-instana/src/instana.ts @@ -110,7 +110,7 @@ export class InstanaTraceExporter implements Exporter { duration: span.duration, name: span.name, type: spanKindTranslation[span.kind] || span.kind, - error: span.status != null && span.status !== 0, + error: span.status != null && span.status.code !== 0, data: Object.keys(span.attributes) .reduce( (agg: {[k: string]: string}, key) => { diff --git a/packages/opencensus-exporter-ocagent/src/adapters.ts b/packages/opencensus-exporter-ocagent/src/adapters.ts index e10c5d62d..58e00b635 100644 --- a/packages/opencensus-exporter-ocagent/src/adapters.ts +++ b/packages/opencensus-exporter-ocagent/src/adapters.ts @@ -193,15 +193,6 @@ const adaptTimeEvents = }; }; -/** - * Adapts a statusCode number to a `opencensus.proto.trace.v1.Status` type. - * @param statusCode number - * @returns opencensus.proto.trace.v1.Status - */ -const adaptStatus = (statusCode: number): opencensus.proto.trace.v1.Status => { - return {code: statusCode, message: null}; -}; - /** * Adapts a traceState string to a `opencensus.proto.trace.v1.Span.Tracestate` * type. The tracestate is a comma-delimited set of equals-delimited key-value @@ -285,7 +276,7 @@ export const adaptSpan = (span: Span): opencensus.proto.trace.v1.Span => { stackTrace: null, // Unsupported by nodejs timeEvents: adaptTimeEvents(span.annotations, span.messageEvents), links: adaptLinks(span.links), - status: adaptStatus(span.status), + status: span.status, sameProcessAsParentSpan: adaptBoolean(!span.remoteParent), childSpanCount: null, }; diff --git a/packages/opencensus-exporter-ocagent/test/test-ocagent.ts b/packages/opencensus-exporter-ocagent/test/test-ocagent.ts index d69bb5cac..768455eed 100644 --- a/packages/opencensus-exporter-ocagent/test/test-ocagent.ts +++ b/packages/opencensus-exporter-ocagent/test/test-ocagent.ts @@ -15,7 +15,7 @@ */ import * as protoLoader from '@grpc/proto-loader'; -import {RootSpan, TraceOptions, Tracing} from '@opencensus/core'; +import {CanonicalCode, RootSpan, TraceOptions, Tracing} from '@opencensus/core'; import * as nodeTracing from '@opencensus/nodejs'; import * as assert from 'assert'; import {EventEmitter} from 'events'; @@ -328,7 +328,7 @@ describe('OpenCensus Agent Exporter', () => { tracing.tracer.startRootSpan(rootSpanOptions, (rootSpan: RootSpan) => { // Status - rootSpan.status = 200; + rootSpan.setStatus(CanonicalCode.OK); // Attribute rootSpan.addAttribute('my_attribute_string', 'bar2'); @@ -385,12 +385,11 @@ describe('OpenCensus Agent Exporter', () => { span.tracestate.entries, [{key: 'foo', value: 'bar'}, {key: 'baz', value: 'buzz'}]); - // Status if (!span.status) { assert.fail('span.status is null or undefined'); - return; + } else { + assert.deepEqual(span.status, {code: 0, message: ''}); } - assert.equal(span.status.code, 200); // Attributes if (!span.attributes) { @@ -507,4 +506,4 @@ describe('OpenCensus Agent Exporter', () => { rootSpan.end(); }); }); -}); \ No newline at end of file +}); diff --git a/packages/opencensus-exporter-zpages/src/zpages-frontend/page-handlers/tracez.page-handler.ts b/packages/opencensus-exporter-zpages/src/zpages-frontend/page-handlers/tracez.page-handler.ts index b0471799c..1dd680a53 100644 --- a/packages/opencensus-exporter-zpages/src/zpages-frontend/page-handlers/tracez.page-handler.ts +++ b/packages/opencensus-exporter-zpages/src/zpages-frontend/page-handlers/tracez.page-handler.ts @@ -144,7 +144,7 @@ export class TracezPageHandler { // Building span list for (const span of spans) { - if (span.status && span.status !== 0) { + if (span.status && span.status.code !== 0) { spanCell.ERRORS += 1; } else if (span.ended) { const durationNs = @@ -208,14 +208,14 @@ export class TracezPageHandler { if (this.traceMap.has(params.tracename)) { for (const span of this.traceMap.get(params.tracename)!) { if (params.type === 'ERRORS') { - if (span.status !== 0) { + if (span.status.code !== 0) { traceList.push(span); } } else if (params.type === 'RUNNING') { if (span.started && !span.ended) { traceList.push(span); } - } else if (span.ended && span.status === 0) { + } else if (span.ended && span.status.code === 0) { const durationNs = LatencyBucketBoundaries.millisecondsToNanos(span.duration); const latency = diff --git a/packages/opencensus-exporter-zpages/src/zpages.ts b/packages/opencensus-exporter-zpages/src/zpages.ts index 2d7454126..d2de4d06c 100644 --- a/packages/opencensus-exporter-zpages/src/zpages.ts +++ b/packages/opencensus-exporter-zpages/src/zpages.ts @@ -139,17 +139,9 @@ export class ZpagesExporter implements Exporter, StatsEventListener { * @param trace the rootSpan to be sent to the array list */ private sendTrace(trace: RootSpan) { - /** If there is no status, put status 0 (OK) */ - if (!trace.status) { - trace.status = 0; - } this.pushSpan(trace); for (const span of trace.spans) { - /** If there is no status, put status 0 (OK) */ - if (!span.status) { - span.status = 0; - } this.pushSpan(span); } this.logger.debug('Z-PAGES: trace added'); diff --git a/packages/opencensus-instrumentation-grpc/src/grpc.ts b/packages/opencensus-instrumentation-grpc/src/grpc.ts index f910a0cfa..fb1e76fbc 100644 --- a/packages/opencensus-instrumentation-grpc/src/grpc.ts +++ b/packages/opencensus-instrumentation-grpc/src/grpc.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {BasePlugin, HeaderGetter, HeaderSetter, PluginInternalFiles, RootSpan, Span} from '@opencensus/core'; +import {BasePlugin, CanonicalCode, HeaderGetter, HeaderSetter, PluginInternalFiles, RootSpan, Span} from '@opencensus/core'; import {EventEmitter} from 'events'; import * as grpcTypes from 'grpc'; import * as lodash from 'lodash'; @@ -219,15 +219,15 @@ export class GrpcPlugin extends BasePlugin { // tslint:disable-next-line:no-any value: any, trailer: grpcTypes.Metadata, flags: grpcTypes.writeFlags) { if (err) { - rootSpan.status = GrpcPlugin.convertGrpcStatusToSpanStatus(err.code); + rootSpan.setStatus( + GrpcPlugin.convertGrpcStatusToSpanStatus(err.code), err.message); rootSpan.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, err.code.toString()); rootSpan.addAttribute(GrpcPlugin.ATTRIBUTE_GRPC_ERROR_NAME, err.name); rootSpan.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_ERROR_MESSAGE, err.message); } else { - rootSpan.status = - GrpcPlugin.convertGrpcStatusToSpanStatus(grpcTypes.status.OK); + rootSpan.setStatus(CanonicalCode.OK); rootSpan.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, grpcTypes.status.OK.toString()); @@ -256,8 +256,8 @@ export class GrpcPlugin extends BasePlugin { plugin.tracer.wrapEmitter(call); call.on('finish', () => { - rootSpan.status = - GrpcPlugin.convertGrpcStatusToSpanStatus(call.status.code); + rootSpan.setStatus( + GrpcPlugin.convertGrpcStatusToSpanStatus(call.status.code)); rootSpan.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, call.status.code.toString()); // if there is an error, span is ended on error event, otherwise here @@ -351,15 +351,15 @@ export class GrpcPlugin extends BasePlugin { // tslint:disable-next-line:no-any const wrappedFn = (err: grpcTypes.ServiceError, res: any) => { if (err) { - span.status = GrpcPlugin.convertGrpcStatusToSpanStatus(err.code); + span.setStatus( + GrpcPlugin.convertGrpcStatusToSpanStatus(err.code), err.message); span.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, err.code.toString()); span.addAttribute(GrpcPlugin.ATTRIBUTE_GRPC_ERROR_NAME, err.name); span.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_ERROR_MESSAGE, err.message); } else { - span.status = - GrpcPlugin.convertGrpcStatusToSpanStatus(grpcTypes.status.OK); + span.setStatus(CanonicalCode.OK); span.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, grpcTypes.status.OK.toString()); @@ -423,7 +423,7 @@ export class GrpcPlugin extends BasePlugin { }); call.on('status', (status: Status) => { - span.status = GrpcPlugin.convertGrpcStatusToSpanStatus(status.code); + span.setStatus(GrpcPlugin.convertGrpcStatusToSpanStatus(status.code)); span.addAttribute( GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE, status.code.toString()); diff --git a/packages/opencensus-instrumentation-grpc/test/test-grpc.ts b/packages/opencensus-instrumentation-grpc/test/test-grpc.ts index 1136c2b67..47060bcce 100644 --- a/packages/opencensus-instrumentation-grpc/test/test-grpc.ts +++ b/packages/opencensus-instrumentation-grpc/test/test-grpc.ts @@ -331,8 +331,7 @@ describe('GrpcPlugin() ', function() { assert.strictEqual(span.name, spanName); assert.strictEqual(span.kind, kind); assert.strictEqual( - span.status, GrpcPlugin.convertGrpcStatusToSpanStatus(status)); - + span.status.code, GrpcPlugin.convertGrpcStatusToSpanStatus(status)); assert.strictEqual(span.attributes[GrpcPlugin.ATTRIBUTE_GRPC_KIND], kind); assert.strictEqual( span.attributes[GrpcPlugin.ATTRIBUTE_GRPC_STATUS_CODE], `${status}`); @@ -340,6 +339,8 @@ describe('GrpcPlugin() ', function() { if (status !== grpcModule.status.OK) { assert.ok(span.attributes[GrpcPlugin.ATTRIBUTE_GRPC_ERROR_NAME]); assert.ok(span.attributes[GrpcPlugin.ATTRIBUTE_GRPC_ERROR_MESSAGE]); + } else { + assert.equal(span.status.message, undefined); } } diff --git a/packages/opencensus-instrumentation-http/src/http.ts b/packages/opencensus-instrumentation-http/src/http.ts index 7fa8ec1b0..e60acb4c8 100644 --- a/packages/opencensus-instrumentation-http/src/http.ts +++ b/packages/opencensus-instrumentation-http/src/http.ts @@ -14,13 +14,14 @@ * limitations under the License. */ -import {BasePlugin, Func, HeaderGetter, HeaderSetter, RootSpan, Span, Tracer} from '@opencensus/core'; +import {BasePlugin, CanonicalCode, Func, HeaderGetter, HeaderSetter, RootSpan, Span, Tracer} from '@opencensus/core'; import {logger, Logger} from '@opencensus/core'; import * as httpModule from 'http'; import * as semver from 'semver'; import * as shimmer from 'shimmer'; import * as url from 'url'; import * as uuid from 'uuid'; + import {HttpPluginConfig, IgnoreMatcher} from './types'; @@ -215,8 +216,8 @@ export class HttpPlugin extends BasePlugin { HttpPlugin.ATTRIBUTE_HTTP_STATUS_CODE, response.statusCode.toString()); - rootSpan.status = - HttpPlugin.convertTraceStatus(response.statusCode); + rootSpan.setStatus( + HttpPlugin.parseResponseStatus(response.statusCode)); // Message Event ID is not defined rootSpan.addMessageEvent( @@ -365,7 +366,7 @@ export class HttpPlugin extends BasePlugin { HttpPlugin.ATTRIBUTE_HTTP_STATUS_CODE, response.statusCode.toString()); - span.status = HttpPlugin.convertTraceStatus(response.statusCode); + span.setStatus(HttpPlugin.parseResponseStatus(response.statusCode)); // Message Event ID is not defined span.addMessageEvent( @@ -378,7 +379,7 @@ export class HttpPlugin extends BasePlugin { span.addAttribute(HttpPlugin.ATTRIBUTE_HTTP_ERROR_NAME, error.name); span.addAttribute( HttpPlugin.ATTRIBUTE_HTTP_ERROR_MESSAGE, error.message); - span.status = TraceStatusCodes.UNKNOWN; + span.setStatus(CanonicalCode.UNKNOWN, error.message); span.end(); }); }); @@ -387,7 +388,7 @@ export class HttpPlugin extends BasePlugin { span.addAttribute(HttpPlugin.ATTRIBUTE_HTTP_ERROR_NAME, error.name); span.addAttribute( HttpPlugin.ATTRIBUTE_HTTP_ERROR_MESSAGE, error.message); - span.status = TraceStatusCodes.UNKNOWN; + span.setStatus(CanonicalCode.UNKNOWN, error.message); span.end(); }); @@ -397,55 +398,38 @@ export class HttpPlugin extends BasePlugin { } /** - * Converts an HTTP status code to an OpenCensus Trace status code. - * @param statusCode The HTTP status code to convert. + * Parse OpenCensus Status from HTTP response status code. + * @param statusCode The HTTP response status code. */ - static convertTraceStatus(statusCode: number): number { + static parseResponseStatus(statusCode: number): number { if (statusCode < 200 || statusCode > 504) { - return TraceStatusCodes.UNKNOWN; + return CanonicalCode.UNKNOWN; } else if (statusCode >= 200 && statusCode < 400) { - return TraceStatusCodes.OK; + return CanonicalCode.OK; } else { switch (statusCode) { case (400): - return TraceStatusCodes.INVALID_ARGUMENT; + return CanonicalCode.INVALID_ARGUMENT; case (504): - return TraceStatusCodes.DEADLINE_EXCEEDED; + return CanonicalCode.DEADLINE_EXCEEDED; case (404): - return TraceStatusCodes.NOT_FOUND; + return CanonicalCode.NOT_FOUND; case (403): - return TraceStatusCodes.PERMISSION_DENIED; + return CanonicalCode.PERMISSION_DENIED; case (401): - return TraceStatusCodes.UNAUTHENTICATED; + return CanonicalCode.UNAUTHENTICATED; case (429): - return TraceStatusCodes.RESOURCE_EXHAUSTED; + return CanonicalCode.RESOURCE_EXHAUSTED; case (501): - return TraceStatusCodes.UNIMPLEMENTED; + return CanonicalCode.UNIMPLEMENTED; case (503): - return TraceStatusCodes.UNAVAILABLE; + return CanonicalCode.UNAVAILABLE; default: - return TraceStatusCodes.UNKNOWN; + return CanonicalCode.UNKNOWN; } } } } -/** - * An enumeration of OpenCensus Trace status codes. - */ -export enum TraceStatusCodes { - UNKNOWN = 2, - OK = 0, - INVALID_ARGUMENT = 3, - DEADLINE_EXCEEDED = 4, - NOT_FOUND = 5, - PERMISSION_DENIED = 7, - UNAUTHENTICATED = 16, - RESOURCE_EXHAUSTED = 8, - UNIMPLEMENTED = 12, - UNAVAILABLE = 14 -} - - const plugin = new HttpPlugin('http'); export {plugin}; diff --git a/packages/opencensus-instrumentation-http/test/test-http.ts b/packages/opencensus-instrumentation-http/test/test-http.ts index 178d5edf2..0c35537ee 100644 --- a/packages/opencensus-instrumentation-http/test/test-http.ts +++ b/packages/opencensus-instrumentation-http/test/test-http.ts @@ -68,7 +68,10 @@ function assertSpanAttributes( span: Span, httpStatusCode: number, httpMethod: string, hostName: string, path: string, userAgent: string) { assert.strictEqual( - span.status, HttpPlugin.convertTraceStatus(httpStatusCode)); + span.status.code, HttpPlugin.parseResponseStatus(httpStatusCode)); + assert.strictEqual( + span.attributes[HttpPlugin.ATTRIBUTE_HTTP_ERROR_MESSAGE], + span.status.message); assert.strictEqual(span.attributes[HttpPlugin.ATTRIBUTE_HTTP_HOST], hostName); assert.strictEqual( span.attributes[HttpPlugin.ATTRIBUTE_HTTP_METHOD], httpMethod); diff --git a/packages/opencensus-instrumentation-http2/src/http2.ts b/packages/opencensus-instrumentation-http2/src/http2.ts index 4800acb3e..695dbed80 100644 --- a/packages/opencensus-instrumentation-http2/src/http2.ts +++ b/packages/opencensus-instrumentation-http2/src/http2.ts @@ -141,8 +141,8 @@ export class Http2Plugin extends HttpPlugin { span.addAttribute( Http2Plugin.ATTRIBUTE_HTTP_STATUS_CODE, `${responseHeaders[':status']}`); - span.status = - Http2Plugin.convertTraceStatus(+responseHeaders[':status']); + span.setStatus( + Http2Plugin.parseResponseStatus(+responseHeaders[':status'])); }); request.on('end', () => { @@ -258,7 +258,7 @@ export class Http2Plugin extends HttpPlugin { Http2Plugin.ATTRIBUTE_HTTP_USER_AGENT, userAgent); rootSpan.addAttribute( Http2Plugin.ATTRIBUTE_HTTP_STATUS_CODE, `${statusCode}`); - rootSpan.status = Http2Plugin.convertTraceStatus(statusCode); + rootSpan.setStatus(Http2Plugin.parseResponseStatus(statusCode)); rootSpan.addMessageEvent( 'MessageEventTypeRecv', uuid.v4().split('-').join('')); diff --git a/packages/opencensus-instrumentation-http2/test/test-http2.ts b/packages/opencensus-instrumentation-http2/test/test-http2.ts index 6669597f7..1cf9eadcf 100644 --- a/packages/opencensus-instrumentation-http2/test/test-http2.ts +++ b/packages/opencensus-instrumentation-http2/test/test-http2.ts @@ -41,7 +41,7 @@ function assertSpanAttributes( span: Span, httpStatusCode: number, httpMethod: string, hostName: string, path: string, userAgent: string) { assert.strictEqual( - span.status, Http2Plugin.convertTraceStatus(httpStatusCode)); + span.status.code, Http2Plugin.parseResponseStatus(httpStatusCode)); assert.strictEqual( span.attributes[Http2Plugin.ATTRIBUTE_HTTP_HOST], hostName); assert.strictEqual( diff --git a/packages/opencensus-instrumentation-https/test/test-https.ts b/packages/opencensus-instrumentation-https/test/test-https.ts index 0571ef2d0..04851fb04 100644 --- a/packages/opencensus-instrumentation-https/test/test-https.ts +++ b/packages/opencensus-instrumentation-https/test/test-https.ts @@ -85,7 +85,7 @@ function assertSpanAttributes( span: Span, httpStatusCode: number, httpMethod: string, hostName: string, path: string, userAgent: string) { assert.strictEqual( - span.status, HttpsPlugin.convertTraceStatus(httpStatusCode)); + span.status.code, HttpsPlugin.parseResponseStatus(httpStatusCode)); assert.strictEqual( span.attributes[HttpsPlugin.ATTRIBUTE_HTTP_HOST], hostName); assert.strictEqual(