Skip to content

Commit da562a7

Browse files
committed
more unit testing
1 parent 48bae14 commit da562a7

File tree

5 files changed

+71
-19
lines changed

5 files changed

+71
-19
lines changed

aws-distro-opentelemetry-node-autoinstrumentation/src/aws-opentelemetry-configurator.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ import { OTLPAwsLogExporter } from './exporter/otlp/aws/logs/otlp-aws-log-export
7777
const AWS_TRACES_OTLP_ENDPOINT_PATTERN = '^https://xray\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/traces$';
7878
const AWS_LOGS_OTLP_ENDPOINT_PATTERN = '^https://logs\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/logs$';
7979

80+
const AWS_OTLP_LOGS_GROUP_HEADER = 'x-aws-log-group';
81+
const AWS_OTLP_LOGS_STREAM_HEADER = 'x-aws-log-stream';
82+
8083
const APPLICATION_SIGNALS_ENABLED_CONFIG: string = 'OTEL_AWS_APPLICATION_SIGNALS_ENABLED';
8184
const APPLICATION_SIGNALS_EXPORTER_ENDPOINT_CONFIG: string = 'OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT';
8285
const METRIC_EXPORT_INTERVAL_CONFIG: string = 'OTEL_METRIC_EXPORT_INTERVAL';
@@ -462,7 +465,11 @@ export class AwsLoggerProcessorProvider {
462465
exporters.push(new OTLPHttpLogExporter());
463466
break;
464467
case 'http/protobuf':
465-
if (otlpExporterLogsEndpoint && isAwsOtlpEndpoint(otlpExporterLogsEndpoint, 'logs')) {
468+
if (
469+
otlpExporterLogsEndpoint &&
470+
isAwsOtlpEndpoint(otlpExporterLogsEndpoint, 'logs') &&
471+
validateLogsHeaders()
472+
) {
466473
diag.debug('Detected CloudWatch Logs OTLP endpoint. Switching exporter to OTLPAwsLogExporter');
467474
exporters.push(new OTLPAwsLogExporter(otlpExporterLogsEndpoint));
468475
} else {
@@ -475,7 +482,11 @@ export class AwsLoggerProcessorProvider {
475482
break;
476483
default:
477484
diag.warn(`Unsupported OTLP logs protocol: "${protocol}". Using http/protobuf.`);
478-
if (otlpExporterLogsEndpoint && isAwsOtlpEndpoint(otlpExporterLogsEndpoint, 'logs')) {
485+
if (
486+
otlpExporterLogsEndpoint &&
487+
isAwsOtlpEndpoint(otlpExporterLogsEndpoint, 'logs') &&
488+
validateLogsHeaders()
489+
) {
479490
diag.debug('Detected CloudWatch Logs OTLP endpoint. Switching exporter to OTLPAwsLogExporter');
480491
exporters.push(new OTLPAwsLogExporter(otlpExporterLogsEndpoint));
481492
} else {
@@ -817,10 +828,51 @@ function getXrayDaemonEndpoint() {
817828
return process.env[AWS_XRAY_DAEMON_ADDRESS_CONFIG];
818829
}
819830

831+
/**
832+
* Determines if the given endpoint is either the AWS OTLP Traces or Logs endpoint.
833+
*/
834+
820835
function isAwsOtlpEndpoint(otlpEndpoint: string, service: string): boolean {
821836
const pattern = service === 'xray' ? AWS_TRACES_OTLP_ENDPOINT_PATTERN : AWS_LOGS_OTLP_ENDPOINT_PATTERN;
822837

823838
return new RegExp(pattern).test(otlpEndpoint.toLowerCase());
824839
}
825840

841+
/**
842+
* Checks if x-aws-log-group and x-aws-log-stream are present in the headers in order to send logs to
843+
* AWS OTLP Logs endpoint.
844+
*/
845+
function validateLogsHeaders() {
846+
const logsHeaders = process.env['OTEL_EXPORTER_OTLP_LOGS_HEADERS'];
847+
848+
if (!logsHeaders) {
849+
diag.warn(
850+
'Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS ' +
851+
'to include x-aws-log-group and x-aws-log-stream'
852+
);
853+
return false;
854+
}
855+
856+
let filteredLogHeadersCount = 0;
857+
858+
for (const pair of logsHeaders.split(',')) {
859+
if (pair.includes('=')) {
860+
const [key, value] = pair.split('=', 2);
861+
if ((key === AWS_OTLP_LOGS_GROUP_HEADER || key === AWS_OTLP_LOGS_STREAM_HEADER) && value) {
862+
filteredLogHeadersCount += 1;
863+
}
864+
}
865+
}
866+
867+
if (filteredLogHeadersCount !== 2) {
868+
diag.warn(
869+
'Improper configuration: Please configure the environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS ' +
870+
'to have values for x-aws-log-group and x-aws-log-stream'
871+
);
872+
return false;
873+
}
874+
875+
return true;
876+
}
877+
826878
// END The OpenTelemetry Authors code

aws-distro-opentelemetry-node-autoinstrumentation/src/exporter/otlp/aws/common/aws-authenticator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class AwsAuthenticator {
7777
return headers;
7878
}
7979

80-
// Cleans up Sigv4 headers from headers to avoid accidentally copying them to the new headers
80+
// Cleans up Sigv4 from headers to avoid accidentally copying them to the new headers
8181
private removeSigV4Headers(headers: Record<string, string>) {
8282
const newHeaders: Record<string, string> = {};
8383
const sigV4Headers = ['x-amz-date', 'authorization', 'x-amz-content-sha256', 'x-amz-security-token'];

aws-distro-opentelemetry-node-autoinstrumentation/src/exporter/otlp/aws/common/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3+
34
import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
45

56
export function changeUrlConfig(endpoint: string, config?: OTLPExporterNodeConfigBase): OTLPExporterNodeConfigBase {

aws-distro-opentelemetry-node-autoinstrumentation/test/exporter/otlp/aws/common/aws-authenticator.test.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@ import * as proxyquire from 'proxyquire';
66
import * as sinon from 'sinon';
77
import expect from 'expect';
88
import { AwsAuthenticator } from '../../../../../src/exporter/otlp/aws/common/aws-authenticator';
9-
10-
const PATH = '../../../../../src/exporter/otlp/aws/common/aws-authenticator';
11-
const SIGNATURE_V4_MODULE = '@smithy/signature-v4';
12-
const CREDENTIAL_PROVIDER_MODULE = '@aws-sdk/credential-provider-node';
13-
const SHA_256_MODULE = '@aws-crypto/sha256-js';
14-
const AWS_HTTP_MODULE = '@smithy/protocol-http';
15-
16-
const AWS_OTLP_TRACES_ENDPOINT = 'https://xray.us-east-1.amazonaws.com/v1/traces';
17-
18-
const AUTHORIZATION_HEADER = 'authorization';
19-
const X_AMZ_DATE_HEADER = 'x-amz-date';
20-
const X_AMZ_SECURITY_TOKEN_HEADER = 'x-amz-security-token';
9+
import {
10+
AUTHORIZATION_HEADER,
11+
AWS_AUTH_PATH,
12+
AWS_HTTP_MODULE,
13+
AWS_OTLP_TRACES_ENDPOINT,
14+
CREDENTIAL_PROVIDER_MODULE,
15+
SHA_256_MODULE,
16+
SIGNATURE_V4_MODULE,
17+
X_AMZ_DATE_HEADER,
18+
X_AMZ_SECURITY_TOKEN_HEADER,
19+
} from './test-utils.test';
2120

2221
const mockCredentials = {
2322
accessKeyId: 'test_access_key',
@@ -49,7 +48,7 @@ describe('AwsAuthenticator', () => {
4948
requireStub.withArgs(dependency).throws(new Error(`Cannot find module '${dependency}'`));
5049
requireStub.callThrough();
5150

52-
const { AwsAuthenticator: MockThrowableModuleAuthenticator } = require(PATH);
51+
const { AwsAuthenticator: MockThrowableModuleAuthenticator } = require(AWS_AUTH_PATH);
5352

5453
const result = await new MockThrowableModuleAuthenticator('us-east-1', 'xray').authenticate(
5554
AWS_OTLP_TRACES_ENDPOINT,
@@ -80,7 +79,7 @@ describe('AwsAuthenticator', () => {
8079
[X_AMZ_SECURITY_TOKEN_HEADER]: 'testSecurityToken',
8180
};
8281

83-
const AwsAuthenticatorWithMock = proxyquire(PATH, {
82+
const AwsAuthenticatorWithMock = proxyquire(AWS_AUTH_PATH, {
8483
[CREDENTIAL_PROVIDER_MODULE]: {
8584
defaultProvider: () => Promise.resolve(mockCredentials),
8685
},
@@ -124,7 +123,7 @@ describe('AwsAuthenticator', () => {
124123
[X_AMZ_SECURITY_TOKEN_HEADER]: 'testSecurityToken',
125124
};
126125

127-
const AwsAuthenticatorWithMock = proxyquire(PATH, {
126+
const AwsAuthenticatorWithMock = proxyquire(AWS_AUTH_PATH, {
128127
[CREDENTIAL_PROVIDER_MODULE]: {
129128
defaultProvider: () => Promise.resolve(mockCredentials),
130129
},

aws-distro-opentelemetry-node-autoinstrumentation/test/exporter/otlp/aws/logs/otlp-aws-log-exporter.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as sinon from 'sinon';
1414
import * as proxyquire from 'proxyquire';
1515
import * as nock from 'nock';
1616

17-
const EXPECTED_AUTH_HEADER = 'AWS4-HMAC-SHA256 Credential=test_key/some_date/us-east-1/xray/aws4_request';
17+
const EXPECTED_AUTH_HEADER = 'AWS4-HMAC-SHA256 Credential=test_key/some_date/us-east-1/logs/aws4_request';
1818
const EXPECTED_AUTH_X_AMZ_DATE = 'some_date';
1919
const EXPECTED_AUTH_SECURITY_TOKEN = 'test_token';
2020

0 commit comments

Comments
 (0)