Skip to content

Commit 2299245

Browse files
committed
EMF Support in Lambda
1 parent cc55fa3 commit 2299245

File tree

9 files changed

+876
-608
lines changed

9 files changed

+876
-608
lines changed

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

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ import { BaggageSpanProcessor } from '@opentelemetry/baggage-span-processor';
8080
import { logs } from '@opentelemetry/api-logs';
8181
import { AWS_ATTRIBUTE_KEYS } from './aws-attribute-keys';
8282
import { AwsCloudWatchOtlpBatchLogRecordProcessor } from './exporter/otlp/aws/logs/aws-cw-otlp-batch-log-record-processor';
83+
import { ConsoleEMFExporter } from './exporter/aws/metrics/console-emf-exporter';
84+
import { EMFExporterBase } from './exporter/aws/metrics/emf-exporter-base';
8385

8486
const AWS_TRACES_OTLP_ENDPOINT_PATTERN = '^https://xray\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/traces$';
8587
const AWS_LOGS_OTLP_ENDPOINT_PATTERN = '^https://logs\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/logs$';
@@ -382,14 +384,17 @@ export class AwsOpentelemetryConfigurator {
382384
}
383385

384386
private customizeMetricReader(isEmfEnabled: boolean) {
387+
let exporter: PushMetricExporter | undefined = undefined;
388+
385389
if (isEmfEnabled) {
386-
const emfExporter = createEmfExporter();
387-
if (emfExporter) {
388-
const periodicExportingMetricReader = new PeriodicExportingMetricReader({
389-
exporter: emfExporter,
390-
});
391-
this.metricReader = periodicExportingMetricReader;
392-
}
390+
exporter = createEmfExporter();
391+
}
392+
393+
if (exporter) {
394+
const periodicExportingMetricReader = new PeriodicExportingMetricReader({
395+
exporter: exporter,
396+
});
397+
this.metricReader = periodicExportingMetricReader;
393398
}
394399
}
395400

@@ -523,8 +528,7 @@ export class AwsLoggerProcessorProvider {
523528
return exporters.map(exporter => {
524529
if (exporter instanceof ConsoleLogRecordExporter) {
525530
return new SimpleLogRecordProcessor(exporter);
526-
}
527-
if (exporter instanceof OTLPAwsLogExporter && isAgentObservabilityEnabled()) {
531+
} else if (exporter instanceof OTLPAwsLogExporter && isAgentObservabilityEnabled()) {
528532
return new AwsCloudWatchOtlpBatchLogRecordProcessor(exporter);
529533
}
530534
return new BatchLogRecordProcessor(exporter);
@@ -951,15 +955,17 @@ export function validateAndFetchLogsHeader(): OtlpLogHeaderSetting {
951955
const logHeaders = process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS;
952956

953957
if (!logHeaders) {
954-
diag.warn(
955-
'Missing required configuration: The environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS must be set with ' +
956-
`required headers ${AWS_OTLP_LOGS_GROUP_HEADER} and ${AWS_OTLP_LOGS_STREAM_HEADER}. ` +
957-
`Example: OTEL_EXPORTER_OTLP_LOGS_HEADERS="${AWS_OTLP_LOGS_GROUP_HEADER}=my-log-group,${AWS_OTLP_LOGS_STREAM_HEADER}=my-log-stream"`
958-
);
958+
if (!isLambdaEnvironment()) {
959+
diag.warn(
960+
'Missing required configuration: The environment variable OTEL_EXPORTER_OTLP_LOGS_HEADERS must be set with ' +
961+
`required headers ${AWS_OTLP_LOGS_GROUP_HEADER} and ${AWS_OTLP_LOGS_STREAM_HEADER}. ` +
962+
`Example: OTEL_EXPORTER_OTLP_LOGS_HEADERS="${AWS_OTLP_LOGS_GROUP_HEADER}=my-log-group,${AWS_OTLP_LOGS_STREAM_HEADER}=my-log-stream"`
963+
);
964+
}
959965
return {
960-
logGroup: '',
961-
logStream: '',
962-
namespace: '',
966+
logGroup: undefined,
967+
logStream: undefined,
968+
namespace: undefined,
963969
isValid: false,
964970
};
965971
}
@@ -1029,8 +1035,30 @@ export function checkEmfExporterEnabled(): boolean {
10291035
return true;
10301036
}
10311037

1032-
export function createEmfExporter(): AWSCloudWatchEMFExporter | undefined {
1033-
const headersResult = validateAndFetchLogsHeader();
1038+
/**
1039+
* Create the appropriate EMF exporter based on the environment and configuration.
1040+
*
1041+
* @returns {EMFExporterBase | undefined}
1042+
*/
1043+
export function createEmfExporter(): EMFExporterBase | undefined {
1044+
let exporter: EMFExporterBase | undefined = undefined;
1045+
const otlpLogHeaderSetting = validateAndFetchLogsHeader();
1046+
1047+
if (isLambdaEnvironment() && !otlpLogHeaderSetting.isValid) {
1048+
// Lambda without valid logs http headers - use Console EMF exporter
1049+
exporter = new ConsoleEMFExporter(otlpLogHeaderSetting.namespace);
1050+
} else {
1051+
// Non-Lambda environment - use CloudWatch EMF exporter
1052+
exporter = createCloudWatchEmfExporter(otlpLogHeaderSetting);
1053+
}
1054+
1055+
return exporter;
1056+
}
1057+
1058+
export function createCloudWatchEmfExporter(
1059+
otlpLogHeaderSetting?: OtlpLogHeaderSetting
1060+
): AWSCloudWatchEMFExporter | undefined {
1061+
const headersResult = otlpLogHeaderSetting ?? validateAndFetchLogsHeader();
10341062
if (!headersResult.isValid) {
10351063
return undefined;
10361064
}

0 commit comments

Comments
 (0)