Hi,
I’ve installed Promtail on a Windows machine to collect Windows Security logs (specifically Event ID 4625), and send them to Loki, which is connected to Grafana.
The logs are successfully ingested, but in Grafana the log lines are too long and hard to read, because they include the entire raw JSON.
I just want to display the essential fields, such as:
- Timestamp
TargetUserName
IpAddress
How can I configure Grafana (or Promtail) to show only those key fields instead of the full raw message?
Thanks in advance!
It is in general not easy to break up and reform JSON strings with promtail. It can be done, but I wouldn’t recommend it. It is also my preference to not alter original logs when possible.
If you are just worried about displaying the logs, you can use line_format in your logql and show only the text you care about. For example:
{<label_filter>}
| json
| line_format "{{ .TargetUserName }} {{ .IpAddress }}"
You’re right — breaking up or modifying JSON strings in Promtail is not easy and should be avoided when possible. To preserve the original log structure, I’ve adopted the line_format
approach in LogQL queries to display only the relevant information.
Sample Query
{logsource="windows-eventlog", job="windows-security", username!="", ip!=""}
| json
| event_id == 4625
| line_format "- Login failed: user {{ .username }} from IP {{ .ip }} to {{ .computer }} ({{.destination_ip}})"
Sample promtail-config.yaml
server:
http_listen_port: 9090
grpc_listen_port: 0
positions:
filename: C:\promtail\positions.yaml
clients:
- url: http://<ip-loki>:<port>/loki/api/v1/push
scrape_configs:
- job_name: windows-security
windows_events:
locale: 1033
use_incoming_timestamp: true
exclude_event_data: false
exclude_user_data: false
bookmark_path: C:\promtail\bookmark_security.xml
eventlog_name: "Security"
xpath_query: '*'
labels:
logsource: windows-eventlog
job: windows-security
type: security
hostname: ${COMPUTERNAME}
destination_ip: Your-server-IP
pipeline_stages:
- json:
expressions:
event_data: event_data
- template:
source: event_data
template: '{{ .Value | replace "\\u003c" "<" | replace "\\u003e" ">" }}'
output: event_data
- regex:
source: event_data
expression: "<Data Name='TargetUserName'>(?P<username>[^<]*)</Data>.*?<Data Name='IpAddress'>(?P<ip>[^<]*)</Data>.*?<Data Name='TargetDomainName'>(?P<computer>[^<]*)</Data>"
- labels:
username:
ip:
computer:
This way, the log remains intact, and parsing is simplified. For alerting or dashboard use cases, I extract only necessary fields into labels using pipeline_stages, and only when absolutely required.
Thank you for the suggestion @tonyswumac