@aws/aws-distro-opentelemetry-node-autoinstrumentation
Version:
This package provides Amazon Web Services distribution of the OpenTelemetry Node Instrumentation, which allows for auto-instrumentation of NodeJS applications.
136 lines • 5.95 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OTLPAwsBaseExporter = void 0;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
const otlp_exporter_base_1 = require("@opentelemetry/otlp-exporter-base");
const zlib_1 = require("zlib");
const core_1 = require("@opentelemetry/core");
const aws_authenticator_1 = require("./aws-authenticator");
/**
* Base class for AWS OTLP exporters
*/
class OTLPAwsBaseExporter extends otlp_exporter_base_1.OTLPExporterBase {
constructor(endpoint, service, parentExporter, parentSerializer, compression) {
super(parentExporter['_delegate']);
this.compression = compression;
this.endpoint = endpoint;
this.authenticator = new aws_authenticator_1.AwsAuthenticator(this.endpoint, service);
this.parentExporter = parentExporter;
this.parentSerializer = parentSerializer;
// To prevent performance degradation from serializing and compressing data twice, we handle serialization and compression
// locally in this exporter and pass the pre-processed data to the upstream export.
// This is used in order to prevent serializing and compressing the data again when calling parentExporter.export().
// To see why this works:
// https://github.com/open-telemetry/opentelemetry-js/blob/ec17ce48d0e5a99a122da5add612a20e2dd84ed5/experimental/packages/otlp-exporter-base/src/otlp-export-delegate.ts#L69
this.serializer = new PassthroughSerializer(this.parentSerializer.deserializeResponse);
this.parentExporter['_delegate']._serializer = this.serializer;
}
/**
* Overrides the upstream implementation of export.
* All behaviors are the same except if the endpoint is an AWS OTLP endpoint, we will sign the request with SigV4
* in headers before sending it to the endpoint.
* @param items - Array of signal data to export
* @param resultCallback - Callback function to handle export result
*/
async export(items, resultCallback) {
var _a, _b, _c;
// In OTel 2.x, headers() is an async function that returns a Promise
const headersGetter = (_c = (_b = (_a = this.parentExporter['_delegate']._transport) === null || _a === void 0 ? void 0 : _a._transport) === null || _b === void 0 ? void 0 : _b._parameters) === null || _c === void 0 ? void 0 : _c.headers;
if (!headersGetter) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error(`Request headers are unset - unable to export to ${this.endpoint}`),
});
return;
}
const headers = await headersGetter();
if (!headers) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error(`Headers returned undefined - unable to export to ${this.endpoint}`),
});
return;
}
let serializedData = this.parentSerializer.serializeRequest(items);
if (!serializedData) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error('Nothing to send'),
});
return;
}
delete headers['Content-Encoding'];
const shouldCompress = this.compression && this.compression !== otlp_exporter_base_1.CompressionAlgorithm.NONE;
if (shouldCompress) {
try {
serializedData = (0, zlib_1.gzipSync)(serializedData);
headers['Content-Encoding'] = 'gzip';
}
catch (exception) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error(`Failed to compress: ${exception}`),
});
return;
}
}
this.serializer.setSerializedData(serializedData);
const signedHeaders = await this.authenticator.authenticate(headers, serializedData);
if (!signedHeaders) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error('Sigv4 Signing Failed. Not exporting'),
});
return;
}
// OTel 2.x expects an async headers function
this.parentExporter['_delegate']._transport._transport._parameters.headers = async () => signedHeaders;
this.parentExporter.export(items, resultCallback);
}
shutdown() {
return this.parentExporter.shutdown();
}
forceFlush() {
return this.parentExporter.forceFlush();
}
}
exports.OTLPAwsBaseExporter = OTLPAwsBaseExporter;
/**
* A serializer that bypasses request serialization by returning pre-serialized data.
* @template Response The type of the deserialized response
*/
class PassthroughSerializer {
/**
* Creates a new PassthroughSerializer instance.
* @param deserializer Function to deserialize response data
*/
constructor(deserializer) {
this.serializedData = new Uint8Array();
this.deserializer = deserializer;
}
/**
* Sets the pre-serialized data to be returned when serializeRequest is called.
* @param data The serialized data to use
*/
setSerializedData(data) {
this.serializedData = data;
}
/**
* Returns the pre-serialized data, ignoring the request parameter.
* @param request Ignored parameter.
* @returns The pre-serialized data
*/
serializeRequest(request) {
return this.serializedData;
}
/**
* Deserializes response data using the provided deserializer function.
* @param data The response data to deserialize
* @returns The deserialized response
*/
deserializeResponse(data) {
return this.deserializer(data);
}
}
//# sourceMappingURL=otlp-aws-base-exporter.js.map