@@ -80,6 +80,8 @@ import { BaggageSpanProcessor } from '@opentelemetry/baggage-span-processor';
8080import { logs } from '@opentelemetry/api-logs' ;
8181import { AWS_ATTRIBUTE_KEYS } from './aws-attribute-keys' ;
8282import { 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
8486const AWS_TRACES_OTLP_ENDPOINT_PATTERN = '^https://xray\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/traces$' ;
8587const 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