Datadog Agent Log Processing
The Datadog Agent applies log processing rules before forwarding log records to Kloudfuse.
Rules are configured either globally in datadog.yaml (to apply to all log sources) or per source in conf.d/<source>.d/conf.yaml.
Overview
Log processing rules are set in log_processing_rules and support three operations:
| Rule type | Effect |
|---|---|
|
Replace regex matches in the log body with a fixed placeholder string |
|
Drop log records whose body matches the regex — matched records are not forwarded |
|
Forward only log records whose body matches the regex — all other records are dropped |
Rules in conf.d/<source>.d/conf.yaml apply only to that source.
Rules in datadog.yaml under logs_config.processing_rules apply to every log source the agent collects.
Mask Sensitive Data
Use log_processing_rules with type: mask_sequences to replace sensitive values before logs leave the agent.
Each rule applies a regular expression to the raw log line and replaces every match with replace_placeholder.
Because masking happens in the agent, the original value never reaches Kloudfuse or crosses the network.
log_processing_rules can be set per log source in a check config file, or globally in datadog.yaml to apply to every log source the agent collects.
datadog.yaml — mask card numbers, card security codes, and credentials across all log sourceslogs_config:
processing_rules:
- type: mask_sequences
name: mask_card_security_codes
replace_placeholder: "$1$2[CSC REDACTED]"
pattern: "(?i)\\b(cvv2?|cvc2?|cid|pin_?block|track[12]|service_code)([\"']?\\s*[:=]\\s*[\"']?)[;%]?[^\\s,;\"'&}]+" (1)
- type: mask_sequences
name: mask_credentials
replace_placeholder: "$1$2[SECRET REDACTED]"
pattern: "(?i)\\b(password|passwd|secret(?:_?key)?|api[_-]?key|x-api-key|auth(?:oriz(?:ation|ed))?_?token|access_?token|bearer)([\"']?\\s*[:=]\\s*[\"']?)[^\\s,;\"'&}]+"
- type: mask_sequences
name: mask_card_numbers
replace_placeholder: "[CARD REDACTED]"
pattern: "\\b(?:4\\d{3}|5[1-5]\\d{2}|2(?:22[1-9]|2[3-9]\\d|[3-6]\\d\\d|7[01]\\d|720)|3[47]\\d{2}|30[0-5]\\d|3(?:09|[689]\\d)\\d|6(?:011|5\\d\\d|4[4-9]\\d|22\\d)|35(?:2[89]|[3-8]\\d)|62\\d\\d)(?:[ -]?\\d){9,15}\\b" (2)
- type: mask_sequences
name: mask_emails
replace_placeholder: "***@***.***"
pattern: "\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b"
| 1 | The key and separator are captured and echoed back through $1$2 (Agent 7.17+), so only the value is replaced and a JSON line stays valid JSON. Requiring an explicit : or = keeps prose such as "the password was reset" untouched. Keep these key-anchored rules before the card-number rule: they mask the whole value of a keyed field — including a card number embedded in track2 — so the broad card rule below cannot fragment it. Extend the keyword lists to the field names your applications actually use. |
| 2 | Anchored on the issuing-network prefixes of the major card brands, then 13–19 digits with an optional single space or dash between any two of them — so contiguous numbers and every grouped layout (4-4-4-4, Amex 4-6-5, Diners 4-6-4, 13-digit Visa 4-3-3-3) all match, while 16-digit numbers starting with other digits do not. Maestro ranges are not included. It runs last, after the key-anchored rules above. A card-shaped value that is not under one of those keys and is longer than 19 digits — such as raw Track 2 discretionary data — is not caught by this rule, so treat raw track/PAN dumps as data the application should not emit in the first place. |
To add rules for a single log source, put them under log_processing_rules in that source’s check config (conf.d/<source>.d/conf.yaml).
A source’s log_processing_rules are applied in addition to the global logs_config.processing_rules; the global rules continue to apply to every source, so do not duplicate them in source configs.
Before you deploy a pattern
Patterns are compiled with the Go regexp engine (RE2).
It has no lookahead or lookbehind, so a pattern that works in Python or PCRE can be rejected here — and an invalid pattern in the global list stops the logs agent from starting.
No logs are collected from that host until it is fixed; metrics and traces are unaffected. agent status reports it as Invalid processing rules.
Validate every pattern against the same engine before rolling it out, for example with regexp.MustCompile in a short Go test, and run the rule against a sample of real log lines.
The card-number rule above will also mask other long numeric identifiers that begin with a valid card prefix — trace and span IDs, order numbers, and similar.
For cardholder data that is the safe direction, but it can break log-to-trace correlation.
log_processing_rules has no per-rule condition, so if that matters, scope the rule to the log sources of services that handle payments rather than setting it globally.
(Do not reach for exclude_at_match here: it drops the whole record, it does not exempt it from masking.)
The agent’s own APM obfuscator (apm_config.obfuscation.credit_cards, on by default) only recognizes a card number when it is the entire value of a span tag, and it skips error.msg, error.stack, and sql.query by design. To cover those, add apm_config.replace_tags rules for the same keys.
|
Masking matched card and credential values in the agent reduces the amount of sensitive data sent to the observability platform. Compliance scope still depends on the complete data flow and the requirements of the applicable framework. For how this fits with ingest authentication, access policies, and audit logging on the Kloudfuse side, see Keeping Sensitive Data Out of Kloudfuse.
Add Tags to Logs
Tags set on a log source are attached to every log record collected by that source. Set them in the check config file:
conf.d/my-app.d/conf.yaml — add tags to a specific log sourcelogs:
- type: file
path: /var/log/my-app/*.log
service: my-service
source: my-app
tags:
- env:production
- team:platform
To add tags to all metrics, logs, and events collected by the agent, set them globally in datadog.yaml:
datadog.yaml — add tags to all collected datatags:
- env:production
- team:platform
- region:us-east-1
Global tags are merged with any source-level tags, so both sets are forwarded to Kloudfuse.
Parse JSON Logs
The Datadog Agent automatically detects and parses log bodies that are valid JSON. When a log body is a JSON object, each top-level key is promoted to a log attribute and is available as a queryable label in Kloudfuse — no additional configuration is required.
For example, if a log record arrives with this body:
{"level":"error","msg":"connection refused","service":"payments","trace_id":"abc123"}
The agent extracts the following attributes, each of which becomes a searchable label:
| Attribute key | Value |
|---|---|
|
|
|
|
|
|
|
|
JSON auto-detection is always active when logs_enabled: true.
If your logs are not being parsed, confirm the log body is valid JSON and that no wrapping text precedes the opening {.
Filter Out Unwanted Logs
Use type: exclude_at_match to drop log records whose body matches a regex.
Matched records are dropped before forwarding to Kloudfuse:
conf.d/my-app.d/conf.yaml — drop health check and readiness probe logslogs:
- type: file
path: /var/log/my-app/*.log
service: my-service
source: my-app
log_processing_rules:
- type: exclude_at_match
name: exclude_healthchecks
pattern: "GET /(healthz|readyz|ping)"
- type: exclude_at_match
name: exclude_debug
pattern: "\\[DEBUG\\]"
To forward only logs that match a pattern and drop everything else, use type: include_at_match.
Only records matching the pattern are forwarded:
conf.d/my-app.d/conf.yaml — forward only ERROR and FATAL logslogs:
- type: file
path: /var/log/my-app/*.log
service: my-service
source: my-app
log_processing_rules:
- type: include_at_match
name: errors_only
pattern: "ERROR|FATAL|CRITICAL" (1)
| 1 | Only log records whose body contains ERROR, FATAL, or CRITICAL are forwarded. All other records are dropped. |