AWS ALB Access Log Regex Parser & Format Spec
A complete guide to parsing AWS Application Load Balancer access logs across Vector, Fluent Bit, Amazon Athena, and Elasticsearch with zero dropped events.
Parsing AWS Application Load Balancer (ALB) access logs requires matching 29 space-delimited fields, with URI paths and user agents enclosed in quotes. Because downstream target failures and timeouts emit hyphens instead of IPs and timestamps, production regular expressions must use nullable groups like (?<target_ip>[^ ]+)? to prevent dropped telemetry events.
1. Complete AWS ALB 29-Field Specification
AWS Application Load Balancers record access logs as compressed .log.gz files in Amazon S3. Each line contains up to 29 space-delimited positional tokens:
| # | Field Name | Type | Sample Value | Nullable |
|---|---|---|---|---|
| 1 | type | String | https, h2, ws | No |
| 2 | time | ISO 8601 | 2026-09-06T14:40:12.451Z | No |
| 3 | elb | String | app/prod-alb/50dc6c495c0c9188 | No |
| 4 | client:port | IP:Port | 192.0.2.1:2817 | No |
| 5 | target:port | IP:Port | 10.0.0.1:80 or - | Yes (-) |
| 6-8 | processing_times | Float (s) | 0.001 0.042 0.000 | Yes (-1) |
| 9 | elb_status_code | Integer | 200 | No |
| 10 | target_status_code | Integer | 200 or - | Yes (-) |
| 11-12 | bytes_rcvd / sent | Integer | 341 4528 | No |
| 13 | request | String | "GET https://api.io:443/v1 HTTP/2.0" | No |
| 14 | user_agent | String | "curl/7.88.1" | No |
| 15-16 | ssl_cipher / protocol | String | ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 | Yes (-) |
| 17 | target_group_arn | ARN | arn:aws:elasticloadbalancing:... | No |
| 18 | trace_id | String | "Root=1-58337262-36d420..." | No |
| 19-29 | extended_telemetry | Mixed | domain, cert, rule, classification | Yes (-) |
2. Production-Grade Grok & PCRE Regex
Vector / Logstash Grok Expression
Resilient pattern covering all 29 fields with support for target timeouts and -1 float metrics:
^%{NOTSPACE:type} %{TIMESTAMP_ISO8601:timestamp} %{NOTSPACE:elb} %{IPORHOST:client_ip}:%{POSINT:client_port:int} (?:%{IPORHOST:target_ip}:%{POSINT:target_port:int}|-) %{NUMBER:request_processing_time:float} %{NUMBER:target_processing_time:float} %{NUMBER:response_processing_time:float} %{NUMBER:elb_status_code:int} (?:%{NUMBER:target_status_code:int}|-) %{NUMBER:received_bytes:int} %{NUMBER:sent_bytes:int} "%{WORD:verb} %{NOTSPACE:request_url} HTTP/%{NUMBER:http_version}" "%{DATA:user_agent}" %{NOTSPACE:ssl_cipher} %{NOTSPACE:ssl_protocol} %{NOTSPACE:target_group_arn} "%{DATA:trace_id}" "(?:%{NOTSPACE:domain_name}|-)" "(?:%{NOTSPACE:chosen_cert_arn}|-)" %{NUMBER:matched_rule_priority:int} %{TIMESTAMP_ISO8601:request_creation_time} "(?:%{DATA:actions_executed}|-)" "(?:%{DATA:redirect_url}|-)" "(?:%{DATA:error_reason}|-)" "(?:%{DATA:target_port_list}|-)" "(?:%{DATA:target_status_code_list}|-)" "(?:%{DATA:classification}|-)" "(?:%{DATA:classification_reason}|-)"$ 3. Amazon Athena DDL & CloudWatch Queries
Amazon Athena DDL RegexSerDe Query
CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs ( type string, time string, elb string, client_ip string, client_port int, target_ip string, target_port int, request_processing_time double, target_processing_time double, response_processing_time double, elb_status_code int, target_status_code string, received_bytes bigint, sent_bytes bigint, request_verb string, request_url string, request_proto string, user_agent string, ssl_cipher string, ssl_protocol string, target_group_arn string, trace_id string, domain_name string, chosen_cert_arn string, matched_rule_priority string, request_creation_time string, actions_executed string, redirect_url string, error_reason string, target_port_list string, target_status_code_list string, classification string, classification_reason string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( 'serialization.format' = '1', 'input.regex' = '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) "([^ ]*) (.*) (- |[^ ]*)" "([^"]*)" ([A-Z0-9-_]+) ([A-Za-z0-9.-]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^"]*)" ([-.0-9]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^ ]*)" "([^\s]+?)" "([^\s]+?)" "([^ ]*)" "([^ ]*)"' ) LOCATION 's3://my-alb-logs-bucket/AWSLogs/123456789012/elasticloadbalancing/us-east-1/';
CloudWatch Log Insights P95 Latency by Target Group
fields @timestamp, target_group_arn, target_processing_time, elb_status_code | filter elb_status_code >= 500 or target_processing_time > 1.0 | stats pct(target_processing_time, 95) as p95_latency, count(*) as err_count by target_group_arn | sort p95_latency desc | limit 20