@@ -77,6 +77,9 @@ import { OTLPAwsLogExporter } from './exporter/otlp/aws/logs/otlp-aws-log-export
7777const AWS_TRACES_OTLP_ENDPOINT_PATTERN = '^https://xray\\.([a-z0-9-]+)\\.amazonaws\\.com/v1/traces$' ;
7878const 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+
8083const APPLICATION_SIGNALS_ENABLED_CONFIG : string = 'OTEL_AWS_APPLICATION_SIGNALS_ENABLED' ;
8184const APPLICATION_SIGNALS_EXPORTER_ENDPOINT_CONFIG : string = 'OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT' ;
8285const 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+
820835function 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
0 commit comments