receivers:
awscloudwatch:
region: us-east-1 # Change to your AWS region
logs:
poll_interval: 1m
groups:
named:
# Add your CloudWatch log groups here
/aws/lambda/my-function:
/aws/eks/production/my-cluster:
/aws/ecs/my-service:
processors:
batch:
send_batch_size: 256
send_batch_max_size: 512
timeout: 1s
transform:
log_statements:
- context: resource
statements:
# Store original attributes for reference
- set(attributes["aws.log_group.original"], attributes["cloudwatch.log.group.name"]) where attributes["cloudwatch.log.group.name"] != nil
- set(attributes["aws.log_stream.original"], attributes["cloudwatch.log.stream"]) where attributes["cloudwatch.log.stream"] != nil
# Extract cloud provider attributes
- set(attributes["cloud.provider"], "aws")
- set(attributes["cloud.region"], attributes["aws.region"]) where attributes["aws.region"] != nil
# === Lambda Detection: /aws/lambda/<function-name> ===
- set(attributes["service.name"], Split(attributes["cloudwatch.log.group.name"], "/")[3]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/lambda/.*")
- set(attributes["faas.name"], Split(attributes["cloudwatch.log.group.name"], "/")[3]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/lambda/.*")
- set(attributes["cloud.platform"], "aws_lambda") where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/lambda/.*")
# === EKS Detection: /aws/eks/<cluster-name>/cluster ===
- set(attributes["k8s.cluster.name"], Split(attributes["cloudwatch.log.group.name"], "/")[3]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/[^/]+/cluster$")
- set(attributes["service.name"], Concat(["eks-", Split(attributes["cloudwatch.log.group.name"], "/")[3]], "")) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/[^/]+/cluster$")
- set(attributes["cloud.platform"], "aws_eks") where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/.*")
# Handle custom EKS patterns like /aws/eks/<env>/<cluster>
- set(attributes["deployment.environment"], Split(attributes["cloudwatch.log.group.name"], "/")[3]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/[^/]+/[^/]+$") and Len(Split(attributes["cloudwatch.log.group.name"], "/")) == 5
- set(attributes["k8s.cluster.name"], Split(attributes["cloudwatch.log.group.name"], "/")[4]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/[^/]+/[^/]+$") and Len(Split(attributes["cloudwatch.log.group.name"], "/")) == 5
- set(attributes["k8s.pod.name"], attributes["cloudwatch.log.stream"]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/eks/.*")
# === ECS/Fargate Detection: /ecs/<task-definition> ===
- set(attributes["service.name"], Split(attributes["cloudwatch.log.group.name"], "/")[2]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/ecs/.*")
- set(attributes["aws.ecs.task.family"], Split(attributes["cloudwatch.log.group.name"], "/")[2]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/ecs/.*")
- set(attributes["cloud.platform"], "aws_ecs") where IsMatch(attributes["cloudwatch.log.group.name"], "^/ecs/.*")
- set(attributes["container.name"], Split(attributes["cloudwatch.log.stream"], "/")[1]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/ecs/.*") and Len(Split(attributes["cloudwatch.log.stream"], "/")) >= 2
- set(attributes["aws.ecs.task.id"], Split(attributes["cloudwatch.log.stream"], "/")[2]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/ecs/.*") and Len(Split(attributes["cloudwatch.log.stream"], "/")) >= 3
# === RDS Detection: /aws/rds/instance/<instance>/<log-type> ===
- set(attributes["db.system"], "rds") where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/.*")
- set(attributes["db.instance.id"], Split(attributes["cloudwatch.log.group.name"], "/")[4]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/instance/.*")
- set(attributes["service.name"], Concat(["rds-instance-", Split(attributes["cloudwatch.log.group.name"], "/")[4]], "")) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/instance/.*")
- set(attributes["db.cluster.id"], Split(attributes["cloudwatch.log.group.name"], "/")[4]) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/cluster/.*")
- set(attributes["service.name"], Concat(["rds-cluster-", Split(attributes["cloudwatch.log.group.name"], "/")[4]], "")) where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/cluster/.*")
- set(attributes["cloud.platform"], "aws_rds") where IsMatch(attributes["cloudwatch.log.group.name"], "^/aws/rds/.*")
# === API Gateway Detection: API-Gateway-Execution-Logs_<api-id>/<stage> ===
- set(attributes["service.name"], Split(attributes["cloudwatch.log.group.name"], "_")[1]) where IsMatch(attributes["cloudwatch.log.group.name"], "^API-Gateway-Execution-Logs_.*")
- set(attributes["aws.api_gateway.api_id"], Split(Split(attributes["cloudwatch.log.group.name"], "_")[1], "/")[0]) where IsMatch(attributes["cloudwatch.log.group.name"], "^API-Gateway-Execution-Logs_.*")
- set(attributes["cloud.platform"], "aws_api_gateway") where IsMatch(attributes["cloudwatch.log.group.name"], "^API-Gateway-Execution-Logs_.*")
# === Fallback: Use log group name as service name if no pattern matched ===
- set(attributes["service.name"], attributes["cloudwatch.log.group.name"]) where attributes["service.name"] == nil and attributes["cloudwatch.log.group.name"] != nil
exporters:
otlp:
endpoint: localhost:4317 # Dstl 8 Docker agent OTLP endpoint
compression: none
tls:
insecure: true
service:
pipelines:
logs:
receivers:
- awscloudwatch
processors:
- batch
- transform
exporters:
- otlp