nice-grpc-opentelemetry
Version:
OpenTelemetry instrumentation for nice-grpc
84 lines • 3.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.openTelemetryClientMiddleware = openTelemetryClientMiddleware;
const api_1 = require("@opentelemetry/api");
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
const abort_controller_x_1 = require("abort-controller-x");
const nice_grpc_common_1 = require("nice-grpc-common");
const attributes_1 = require("./attributes");
const propagation_1 = require("./propagation");
const traces_1 = require("./traces");
const bindAsyncGenerator_1 = require("./utils/bindAsyncGenerator");
function openTelemetryClientMiddleware() {
return (call, options) => traces_1.tracer.startActiveSpan((0, traces_1.getSpanName)(call.method.path), {
kind: api_1.SpanKind.CLIENT,
}, span => {
const metadata = (0, nice_grpc_common_1.Metadata)(options.metadata);
api_1.propagation.inject(api_1.context.active(), metadata, propagation_1.metadataSetter);
return (0, bindAsyncGenerator_1.bindAsyncGenerator)(api_1.context.active(), openTelemetryClientMiddlewareGenerator(span, call, {
...options,
metadata,
}));
});
}
async function* openTelemetryClientMiddlewareGenerator(span, call, options) {
const attributes = (0, attributes_1.getMethodAttributes)(call.method.path);
span.setAttributes(attributes);
let settled = false;
let status = nice_grpc_common_1.Status.OK;
let errorMessage;
try {
let request;
if (!call.requestStream) {
request = call.request;
}
else {
request = (0, traces_1.emitSpanEvents)(call.request, span, semantic_conventions_1.MESSAGETYPEVALUES_SENT);
}
if (!call.responseStream) {
const response = yield* call.next(request, options);
settled = true;
return response;
}
else {
yield* (0, traces_1.emitSpanEvents)(call.next(request, options), span, semantic_conventions_1.MESSAGETYPEVALUES_RECEIVED);
settled = true;
return;
}
}
catch (err) {
settled = true;
if (err instanceof nice_grpc_common_1.ClientError) {
status = err.code;
errorMessage = err.details;
}
else if ((0, abort_controller_x_1.isAbortError)(err)) {
status = nice_grpc_common_1.Status.CANCELLED;
errorMessage = 'The operation was cancelled';
}
else {
status = nice_grpc_common_1.Status.UNKNOWN;
errorMessage = 'Unknown server error occurred';
span.recordException(err);
}
throw err;
}
finally {
if (!settled) {
status = nice_grpc_common_1.Status.CANCELLED;
errorMessage =
'Stream iteration was aborted by client, e.g. by breaking from the for .. of loop';
}
const statusAttributes = (0, attributes_1.getStatusAttributes)(status);
span.setAttributes(statusAttributes);
// https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/rpc/#grpc-status
if (status !== nice_grpc_common_1.Status.OK) {
span.setStatus({
code: api_1.SpanStatusCode.ERROR,
message: `${nice_grpc_common_1.Status[status]}: ${errorMessage}`,
});
}
span.end();
}
}
//# sourceMappingURL=client.js.map