Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions services/logging/loki.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ compactor:
retention_enabled: false

limits_config:
discover_log_levels: false
reject_old_samples: true
reject_old_samples_max_age: 4h
max_cache_freshness_per_query: 10m
Expand Down
36 changes: 32 additions & 4 deletions services/logging/vector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,39 @@ transforms:
.message = .short_message
}

# Extract structured log fields from message using regex pattern
if exists(.message) {
# python service logs
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>.*)$')
if err == null {
.log_level = parsed_fields.log_level
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this won't parse traefik logs.

We did fix this in Graylog #293

Might be interesting if you want to include traefik log level

.log_timestamp = parsed_fields.log_timestamp
.log_source = parsed_fields.log_source
.log_uid = parsed_fields.log_uid
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this becomes a label in Loki?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not labels, because labels should have low cardinality (https://grafana.com/docs/loki/latest/get-started/labels/bp-labels/). Instead this adds them as keys in the log json. Then there is a json parser directly in loki and after applying that one can filter on these fields.

image

.log_oec = parsed_fields.log_oec
.log_trace_id = parsed_fields.log_trace_id
.log_span_id = parsed_fields.log_span_id
.log_msg = parsed_fields.log_msg
}
# traefik logs
traefik_fields, traefik_err = parse_regex(.message, r'time="(?P<log_timestamp>[^"]*)" level=(?P<log_level>\w+) msg="(?P<log_msg>.*)"')
if traefik_err == null {
.log_timestamp = traefik_fields.log_timestamp
.log_level = traefik_fields.log_level
.log_msg = traefik_fields.log_msg
}
}

# Handle container name - GELF uses _container_name (with underscore prefix)
if exists(._container_name) {
.container_name = ._container_name

# Extract Docker service name from container name (everything before first dot)
match = parse_regex!(.container_name, r'^(?P<service_name>[^.]+)')
.service_name = match.service_name
} else {
.container_name = "unknown"
.service_name = "unknown"
}

# Handle container ID
Expand Down Expand Up @@ -58,13 +86,13 @@ sinks:
encoding:
codec: json
labels:
job: "docker"
source: "vector"
# Pass through the GELF 'host' field from the original log event
host: "{{ host }}"
container_name: "{{ container_name }}"
# Remove label fields from the log line to avoid duplication
remove_label_fields: true
service_name: "{{ service_name }}"
# Override level label with extracted log_level from structured logs. This ensures correct color coding in Loki/Grafana
level: "{{ log_level }}"

healthcheck:
enabled: true

Expand Down
Loading