What a Palo Alto Networks PAN-OS (CEF) line looks like
The CEF sample below is fed verbatim into the engine to produce every parser on this page.
CEF:0|Palo Alto Networks|PAN-OS|11.1|THREAT|url|5|rt=Jul 03 2026 14:22:15 src=192.0.2.55 dst=198.51.100.99 spt=52881 dpt=443 suser=bhapci app=web-browsing act=block-url request=https://malware-cdn.example.net/payload.bin cat=malware
CEF:0|Palo Alto Networks|PAN-OS|11.1|THREAT|virus|4|rt=Jul 03 2026 14:23:07 src=192.0.2.61 dst=203.0.113.12 spt=51002 dpt=80 suser=akaya app=web-browsing act=alert request=http://tracker.example.org/pixel.gif cat=spyware Detected fields
The engine classified this sample as kv and consolidated 17 fields across 2 lines. Fields marked literal were identical on every sample line, so they are baked into the pattern as anchors rather than captured.
- cef_version : number · literal
- cef_vendor : literal · literal
- cef_product : literal · literal
- cef_device_version : number · literal
- cef_signature_id : literal · literal
- cef_name : literal
- cef_severity : number
- rt : timestamp
- src : ipv4
- dst : ipv4
- spt : port
- dpt : port
- suser : username
- app : literal · literal
- act : severity
- request : url
- cat : literal
Regex (named capture groups)
# sample: CEF:0|Palo Alto Networks|PAN-OS|11.1|THREAT|url|5|rt=Jul 03 2026 14:22:15 src=192.0.2.55 dst=198.51.100.99 spt=52881 dpt=443 suser=bhapci app=web-browsing act=block-url request=https://malware-cdn.example.net/payload.bin cat=malware
# groups: cef_name=url, cef_severity=5, rt=Jul 03 2026 14:22:15, src=192.0.2.55, dst=198.51.100.99, spt=52881, dpt=443, suser=bhapci, act=block-url, request=https://malware-cdn.example.net/payload.bin, cat=malware
^CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?<cef_name>[A-Za-z]+)\|(?<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?<spt>\d{1,5}) dpt=(?<dpt>\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*://[^\s"']+) cat=(?<cat>[A-Za-z]+)$ Grok pattern (Logstash / Elastic)
# custom patterns
PALO_ALTO_MDYTIME %{MONTH} %{MONTHDAY} %{YEAR} %{TIME}
CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|%{DATA:cef_name}\|%{NUMBER:cef_severity}\|rt=%{PALO_ALTO_MDYTIME:rt} src=%{IPV4:src} dst=%{IPV4:dst} spt=%{INT:spt} dpt=%{INT:dpt} suser=%{USERNAME:suser} app=web-browsing act=%{NOTSPACE:act} request=%{URI:request} cat=%{GREEDYDATA:cat} - note kv-structured input — consider the Logstash kv filter instead of (or after) grok
- note constant field "cef_version" embedded as literal anchor "0" (varying=false)
- note constant field "cef_device_version" embedded as literal anchor "11.1" (varying=false)
- note field "act" (severity): samples do not all match %{LOGLEVEL}; using %{NOTSPACE} instead
- note custom patterns emitted — save the '# custom patterns' block to a file in your patterns_dir
Wazuh decoder (OS_Regex XML)
<!--
Generated by LogForge - Wazuh decoder (OS_Regex dialect, not PCRE)
sample: CEF:0|Palo Alto Networks|PAN-OS|11.1|THREAT|url|5|rt=Jul 03 2026 14:22:15 src=192.0.2.55 dst=198.51.100.99 spt=52881 dpt=443 suser=bhapci app=web-browsing act=b
test with: /var/ossec/bin/wazuh-logtest
-->
<decoder name="palo-alto-kv">
<prematch>^CEF:\d+\|</prematch>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent">\|rt=(\w+ \d+ \d+ \d+:\d+:\d+)</regex>
<order>rt</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> src=(\d+.\d+.\d+.\d+)</regex>
<order>srcip</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> dst=(\d+.\d+.\d+.\d+)</regex>
<order>dstip</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> spt=(\d+)</regex>
<order>srcport</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> dpt=(\d+)</regex>
<order>dstport</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> suser=(\w+)</regex>
<order>srcuser</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> act=(\w+)</regex>
<order>action</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> request=(\w+://\S+)</regex>
<order>url</order>
</decoder>
<decoder name="palo-alto-kv">
<parent>palo-alto-kv</parent>
<regex offset="after_parent"> cat=(\w+)</regex>
<order>cat</order>
</decoder>
<!-- ============================================================
ALERT RULE (starter) — put this in a RULES file, e.g.
/var/ossec/etc/rules/local_rules.xml. Decoders and rules live
in SEPARATE files. The rule matches the decoder above through
<decoded_as>; set <level> and add <field>/<match> conditions so
it alerts only on the events you care about. Rule ids 100000+
are the user range — change them if they collide with yours.
============================================================ -->
<group name="palo-alto,">
<rule id="100000" level="3">
<decoded_as>palo-alto-kv</decoded_as>
<description>palo-alto: srcuser=$(srcuser) srcip=$(srcip) dstip=$(dstip)</description>
</rule>
<!-- Example — a higher-level alert gated on one field (uncomment and edit):
<rule id="100001" level="10">
<if_sid>100000</if_sid>
<field name="action">^deny$</field>
<description>palo-alto: a denied action from $(action)</description>
</rule>
-->
</group>
- note constant field "cef_version" skipped (identical in every line)
- note constant field "cef_vendor" skipped (identical in every line)
- note constant field "cef_product" skipped (identical in every line)
- note constant field "cef_device_version" skipped (identical in every line)
- note constant field "cef_signature_id" skipped (identical in every line)
- note field "cef_name" skipped: positional header field without a key literal cannot be safely captured in OS_Regex (values may contain spaces; \.+ is unsafe mid-pattern)
- note field "cef_severity" skipped: positional header field without a key literal cannot be safely captured in OS_Regex (values may contain spaces; \.+ is unsafe mid-pattern)
- note field "src" mapped to Wazuh conventional field "srcip"
- note field "dst" mapped to Wazuh conventional field "dstip"
- note field "spt" mapped to Wazuh conventional field "srcport"
- note field "dpt" mapped to Wazuh conventional field "dstport"
- note field "suser" mapped to Wazuh conventional field "srcuser"
- note constant field "app" skipped (identical in every line)
- note field "act" mapped to Wazuh conventional field "action"
- note field "request" mapped to Wazuh conventional field "url"
- note kv fields are extracted by same-named sibling decoders (offset="after_parent"), so per-line field order/absence is tolerated — the shared name is what makes Wazuh evaluate every sibling
- note added a starter alert <rule> (level 3, matched to the decoder via <decoded_as>) — put it in a RULES file (not the decoders file), set the level, and add <field>/<match> conditions; the commented example child rule shows the pattern
- note decoder order and prematch specificity may need site-specific tuning (other decoders in your ruleset can shadow these) — validate with /var/ossec/bin/wazuh-logtest
Wazuh's OS_Regex is not PCRE — a bare . is a literal dot and \. matches any character.
Test Wazuh OS_Regex patterns →
rsyslog template / liblognorm rulebase
version=2
# palo_alto — liblognorm v2 rulebase (generated by LogForge)
# Usage with rsyslog (mmnormalize runs liblognorm):
# module(load="mmnormalize")
# action(type="mmnormalize" rulebase="/etc/rsyslog.d/palo_alto.rb" useRawMsg="on")
# Literal "%" is escaped as "%%"; raw tabs are written as \x09.
rule=palo_alto:CEF:0|Palo Alto Networks|PAN-OS|11.1|THREAT|%cef_name:char-to{"extradata":"|"}%|%cef_severity:number%|rt=%rt:word% src=%src:ipv4% dst=%dst:ipv4% spt=%spt:number% dpt=%dpt:number% suser=%suser:word% app=web-browsing act=%act:word% request=%request:word% cat=%cat:word%
- note kv structure: rsyslog offers mmfields (fast, fixed single-char separator, untyped) and mmnormalize (this rulebase, typed fields + literal anchors); mmnormalize was chosen for typed extraction
- note field "rt": samples do not uniformly match engine type "timestamp"; using a generic parser
- note field "rt": values contain spaces but the only terminator is a space; matched as a single word (may under-match)
- note chosen parser types: cef_name=char-to(|), cef_severity=number, rt=word, src=ipv4, dst=ipv4, spt=number, dpt=number, suser=word, act=word, request=word, cat=word
Splunk
# props.conf (search-time extraction)
[<REPLACE_WITH_SOURCETYPE>]
EXTRACT-logforge = CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?<cef_name>[A-Za-z]+)\|(?<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?<spt>\d{1,5}) dpt=(?<dpt>\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*://[^\s"']+) cat=(?<cat>[A-Za-z]+)
# Quick search-time test in SPL:
# | rex field=_raw "CEF:0\\|Palo Alto Networks\\|PAN-OS\\|11\\.1\\|THREAT\\|(?<cef_name>[A-Za-z]+)\\|(?<cef_severity>-?\\d+(?:\\.\\d+)?)\\|rt=(?<rt>[A-Za-z]+ \\d+ \\d+ \\d+:\\d+:\\d+) src=(?<src>\\d{1,3}(?:\\.\\d{1,3}){3}) dst=(?<dst>\\d{1,3}(?:\\.\\d{1,3}){3}) spt=(?<spt>\\d{1,5}) dpt=(?<dpt>\\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*://[^\\s\"']+) cat=(?<cat>[A-Za-z]+)" - note EXTRACT-<class> names must be unique within a sourcetype stanza — rename EXTRACT-logforge if you already use that class for this sourcetype
- note a timestamp field was detected: this EXTRACT only makes it a searchable field. To set the event _time at index time, add TIME_PREFIX and TIME_FORMAT to this props.conf stanza (TIME_FORMAT uses Splunk strptime, e.g. %Y-%m-%dT%H:%M:%S) — this generator does not guess the strptime format.
ES ingest
PUT _ingest/pipeline/palo-alto
{
"description": "LogForge-generated ingest pipeline for palo-alto",
"processors": [
{
"kv": {
"field": "message",
"field_split": " ",
"value_split": "="
}
}
]
} - note grok: kv-structured input — consider the Logstash kv filter instead of (or after) grok
- note grok: constant field "cef_version" embedded as literal anchor "0" (varying=false)
- note grok: constant field "cef_device_version" embedded as literal anchor "11.1" (varying=false)
- note grok: field "act" (severity): samples do not all match %{LOGLEVEL}; using %{NOTSPACE} instead
- note grok: custom patterns emitted — save the '# custom patterns' block to a file in your patterns_dir
- note kv structure: emitted a { kv: { field: "message", field_split: " ", value_split: "=" } } processor — it extracts key=value pairs natively; adjust field_split/value_split if your delimiter differs
- note a grok alternative is available too (the reused grok pattern is shown in the notes above); prefer the kv processor unless you need typed/anchored extraction
- note test in Kibana Dev Tools with: POST _ingest/pipeline/palo-alto/_simulate (supply a docs[] array whose _source.message holds a sample line)
Graylog
# Grok patterns to add under System > Grok Patterns:
# (Graylog needs these custom patterns installed globally BEFORE the rule/extractor below will work.)
# PALO_ALTO_MDYTIME %{MONTH} %{MONTHDAY} %{YEAR} %{TIME}
# --- Graylog processing pipeline rule (primary) ---
# Paste under System > Pipelines > Manage rules, then attach the rule to a pipeline stage.
rule "palo-alto-parse"
when
has_field("message")
then
let gp = grok(pattern: "CEF:0\\|Palo Alto Networks\\|PAN-OS\\|11\\.1\\|THREAT\\|%{DATA:cef_name}\\|%{NUMBER:cef_severity}\\|rt=%{PALO_ALTO_MDYTIME:rt} src=%{IPV4:src} dst=%{IPV4:dst} spt=%{INT:spt} dpt=%{INT:dpt} suser=%{USERNAME:suser} app=web-browsing act=%{NOTSPACE:act} request=%{URI:request} cat=%{GREEDYDATA:cat}", value: to_string($message.message), only_named_captures: true);
set_fields(gp);
end
# --- Graylog import-ready extractor JSON (secondary) ---
# Save as a .json file and import under System > Inputs > (input) > Manage extractors > Actions > Import extractors.
{
"extractors": [
{
"title": "palo-alto",
"extractor_type": "grok",
"converters": [],
"order": 0,
"cursor_strategy": "copy",
"source_field": "message",
"target_field": "",
"extractor_config": {
"grok_pattern": "CEF:0\\|Palo Alto Networks\\|PAN-OS\\|11\\.1\\|THREAT\\|%{DATA:cef_name}\\|%{NUMBER:cef_severity}\\|rt=%{PALO_ALTO_MDYTIME:rt} src=%{IPV4:src} dst=%{IPV4:dst} spt=%{INT:spt} dpt=%{INT:dpt} suser=%{USERNAME:suser} app=web-browsing act=%{NOTSPACE:act} request=%{URI:request} cat=%{GREEDYDATA:cat}",
"named_captures_only": true
},
"condition_type": "none",
"condition_value": ""
}
],
"version": "5.0.0"
} - note grok: kv-structured input — consider the Logstash kv filter instead of (or after) grok
- note grok: constant field "cef_version" embedded as literal anchor "0" (varying=false)
- note grok: constant field "cef_device_version" embedded as literal anchor "11.1" (varying=false)
- note grok: field "act" (severity): samples do not all match %{LOGLEVEL}; using %{NOTSPACE} instead
- note grok: custom patterns emitted — save the '# custom patterns' block to a file in your patterns_dir
- note 1 custom grok pattern(s) (PALO_ALTO_MDYTIME) must be installed globally first under System > Grok Patterns — see the block at the top of the output
- note primary artifact is the processing-pipeline rule; the extractor JSON is an equivalent import-ready alternative for the classic extractor UI
Datadog
logforge_rule CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|%{notSpace:cef_name}\|%{number:cef_severity}\|rt=%{data:rt} src=%{ipv4:src} dst=%{ipv4:dst} spt=%{integer:spt} dpt=%{integer:dpt} suser=%{notSpace:suser} app=web-browsing act=%{word:act} request=%{notSpace:request} cat=%{notSpace:cat} - note emitted rule name is "logforge_rule"; rename it to match your "palo-alto" convention if desired
- note kv input — consider Datadog's key-value/`keyvalue()` filter in the Grok Parser instead of anchoring each key by hand
- note constant field "cef_version" embedded as literal anchor "0" (varying=false)
- note constant field "cef_device_version" embedded as literal anchor "11.1" (varying=false)
- note field "rt" (timestamp): could not derive a Joda/Java date format from the sample shape; using %{data} — add a date("…") format by hand if you need a parsed timestamp
- note paste this line into a Grok Parser processor in a Datadog Log Pipeline; matchers are anchored left-to-right and rule whitespace matches log whitespace. Complex or multi-shape logs may need Helper Rules.
Fluent Bit
[PARSER]
Name palo-alto
Format regex
Regex ^CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?<cef_name>[A-Za-z]+)\|(?<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?<spt>\d{1,5}) dpt=(?<dpt>\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*://[^\s"']+) cat=(?<cat>[A-Za-z]+)$
Time_Key rt
# Time_Format <unrecognized timestamp shape — set a strptime format, e.g. %Y-%m-%dT%H:%M:%S>
# Fluentd <parse> block:
# <parse>
# @type regexp
# expression /^CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?<cef_name>[A-Za-z]+)\|(?<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?<spt>\d{1,5}) dpt=(?<dpt>\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s"']+) cat=(?<cat>[A-Za-z]+)$/
# time_key rt
# </parse>
- note Time_Key set to "rt", but the timestamp shape was not recognized — fill in Time_Format (strptime) yourself; for epoch values consider Fluent Bit's time_as_integer / a Lua filter instead
Vector
[transforms.palo_alto_parse]
type = "remap"
inputs = ["REPLACE_WITH_SOURCE"]
source = '''
. |= parse_regex!(.message, r'CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?P<cef_name>[A-Za-z]+)\|(?P<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?P<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?P<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?P<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?P<spt>\d{1,5}) dpt=(?P<dpt>\d{1,5}) suser=(?P<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?P<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?P<request>[A-Za-z][A-Za-z0-9+.-]*://[^\s"\x27]+) cat=(?P<cat>[A-Za-z]+)')
''' - note the pattern contains a single quote, which would close a VRL r'…' regex literal — rewrote each as the RE2 hex escape \x27 (same match semantics) so the argument stays a valid regex literal (parse_regex requires a regex literal, not a string)
- note kv input — parse_key_value!(.message) is the idiomatic Vector parser and is usually preferable to a regex
Loki
# promtail pipeline for "palo-alto" (generated by LogForge)
# Add these stages under a scrape_config in your promtail config:
# scrape_configs:
# - job_name: palo-alto
# pipeline_stages:
# (the stages below are indented to sit under pipeline_stages)
pipeline_stages:
- regex:
expression: '^CEF:0\|Palo Alto Networks\|PAN-OS\|11\.1\|THREAT\|(?P<cef_name>[A-Za-z]+)\|(?P<cef_severity>-?\d+(?:\.\d+)?)\|rt=(?P<rt>[A-Za-z]+ \d+ \d+ \d+:\d+:\d+) src=(?P<src>\d{1,3}(?:\.\d{1,3}){3}) dst=(?P<dst>\d{1,3}(?:\.\d{1,3}){3}) spt=(?P<spt>\d{1,5}) dpt=(?P<dpt>\d{1,5}) suser=(?P<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?P<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?P<request>[A-Za-z][A-Za-z0-9+.-]*://[^\s"'']+) cat=(?P<cat>[A-Za-z]+)$'
- labels:
act:
- note promoted low-cardinality field(s) to Loki labels: act
- note left in the extracted map (NOT promoted to labels — high cardinality would explode Loki streams): cef_name, cef_severity, rt, src, dst, spt, dpt, suser, request, cat
syslog-ng
parser p_palo_alto {
regexp-parser(
prefix(".palo_alto.")
patterns("CEF:0\\|Palo Alto Networks\\|PAN-OS\\|11\\.1\\|THREAT\\|(?<cef_name>[A-Za-z]+)\\|(?<cef_severity>-?\\d+(?:\\.\\d+)?)\\|rt=(?<rt>[A-Za-z]+ \\d+ \\d+ \\d+:\\d+:\\d+) src=(?<src>\\d{1,3}(?:\\.\\d{1,3}){3}) dst=(?<dst>\\d{1,3}(?:\\.\\d{1,3}){3}) spt=(?<spt>\\d{1,5}) dpt=(?<dpt>\\d{1,5}) suser=(?<suser>[A-Za-z0-9._@-]+) app=web-browsing act=(?<act>(?:[A-Za-z]+-[A-Za-z]+|[A-Za-z]+)) request=(?<request>[A-Za-z][A-Za-z0-9+.-]*://[^\\s\"']+) cat=(?<cat>[A-Za-z]+)")
);
}; - note captured fields are stored as name-value pairs under the prefix ".palo_alto." (e.g. a group (?<srcip>…) becomes ".palo_alto.srcip")
- note kv structure: syslog-ng has a dedicated kv-parser() that is simpler and more robust than regexp-parser for key=value logs — consider kv-parser(prefix(".logforge.")) instead of the emitted regexp-parser
FAQ
- What are the six fields in a CEF header?
- After the CEF:0 version marker: Device Vendor, Device Product, Device Version, Signature ID (the event class/type), Name (a human-readable label), and Severity (0–10). They are pipe-delimited, and a literal pipe inside any of them is escaped as \|. Everything after the seventh pipe is the key=value extension.
- Does PAN-OS only support CEF, or are there other log formats?
- PAN-OS can forward logs in several formats — its native comma-separated syslog, LEEF, and CEF among them. CEF is a popular choice for SIEM portability because so many platforms parse it natively. Which one you receive depends on the Log Forwarding profile and syslog server settings configured on the firewall, so confirm the encoding before choosing a parser.
- Why does splitting the CEF extension on spaces corrupt my fields?
- Because extension values can contain spaces. CEF's rule is that a key=value pair runs until the next ' key=' token begins, so you must split on the key-boundary, not on every space. A field like request=https://host/path with a space in it will otherwise bleed into the following key. Backslash-escaped equals and pipes inside values also need unescaping after you split.
- Which CEF extension fields map to the connection five-tuple?
- CEF's standard short keys are src and dst for source and destination IP, spt and dpt for source and destination port, and proto for the protocol. suser is the source user and act is the action. PAN-OS adds app, cat (category), and request on top of these standard keys.
Try it on your own Palo Alto Networks PAN-OS (CEF) lines
Paste a few real lines, review the detected fields, and copy whichever format your stack needs. Free, no account, nothing uploaded.
Open this sample in LogForge →