@@ -25,11 +25,39 @@ transforms:
2525 .message = .short_message
2626 }
2727
28+ # Extract structured log fields from message using regex pattern
29+ if exists(.message) {
30+ # python service logs
31+ parsed_fields, err = parse_regex(.message, r'log_level=(?P<log_level>[^|]*) \| log_timestamp=(?P<log_timestamp>[^|]*) \| log_source=(?P<log_source>[^|]*) \| log_uid=(?P<log_uid>[^|]*) \| log_oec=(?P<log_oec>[^|]*) \| log_trace_id=(?P<log_trace_id>[^|]*) \| log_span_id=(?P<log_span_id>[^|]*) \| log_msg=(?P<log_msg>.*)$')
32+ if err == null {
33+ .log_level = parsed_fields.log_level
34+ .log_timestamp = parsed_fields.log_timestamp
35+ .log_source = parsed_fields.log_source
36+ .log_uid = parsed_fields.log_uid
37+ .log_oec = parsed_fields.log_oec
38+ .log_trace_id = parsed_fields.log_trace_id
39+ .log_span_id = parsed_fields.log_span_id
40+ .log_msg = parsed_fields.log_msg
41+ }
42+ # traefik logs
43+ traefik_fields, traefik_err = parse_regex(.message, r'time="(?P<log_timestamp>[^"]*)" level=(?P<log_level>\w+) msg="(?P<log_msg>.*)"')
44+ if traefik_err == null {
45+ .log_timestamp = traefik_fields.log_timestamp
46+ .log_level = traefik_fields.log_level
47+ .log_msg = traefik_fields.log_msg
48+ }
49+ }
50+
2851 # Handle container name - GELF uses _container_name (with underscore prefix)
2952 if exists(._container_name) {
3053 .container_name = ._container_name
54+
55+ # Extract Docker service name from container name (everything before first dot)
56+ match = parse_regex!(.container_name, r'^(?P<service_name>[^.]+)')
57+ .service_name = match.service_name
3158 } else {
3259 .container_name = "unknown"
60+ .service_name = "unknown"
3361 }
3462
3563 # Handle container ID
@@ -58,13 +86,13 @@ sinks:
5886 encoding :
5987 codec : json
6088 labels :
61- job : " docker"
6289 source : " vector"
63- # Pass through the GELF 'host' field from the original log event
6490 host : " {{ host }}"
6591 container_name : " {{ container_name }}"
66- # Remove label fields from the log line to avoid duplication
67- remove_label_fields : true
92+ service_name : " {{ service_name }}"
93+ # Override level label with extracted log_level from structured logs. This ensures correct color coding in Loki/Grafana
94+ level : " {{ log_level }}"
95+
6896 healthcheck :
6997 enabled : true
7098
0 commit comments