You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of:#2696 · Needs first:#2697 (click-through to the Log Explorer and the value/count table) Related:#1715 (parsers and rules for this integration, owned by the detection team)
Goal
Ship a built-in SonicWall dashboard that shows, at a glance, how much SonicWall is sending, whether it is still sending, and what kinds of events they are. The heart of it is the list of SonicWall logs grouped by event types (widget W7): click one and the Log Explorer opens on exactly those logs.
Where the data comes from
Integration (catalog name)
SONIC_WALL
Data type
firewall-sonicwall
How the logs arrive
The SonicWall firewall sends syslog over UDP or TCP port 7009 to the UTMStack forwarder, which passes each line unchanged to the server; the UTMStack setup guide tells users to set the SonicWall syslog format to ArcSight (CEF).
The IP address the syslog message came from, as seen by the forwarder: the firewall itself, or a relay in between. If the sender is 127.0.0.1 it is the forwarder machine's hostname. Proof: collectors/forwarder/collector/syslog/listener.go (UDP) and handler.go (TCP) set DataSource: resolveRemoteAddr(addr); log-input/ingest/server.go applyDefaults only writes 'unknown' when it is empty; the parser never writes dataSource. So W6 is 'Logs by firewall IP'.
Grouped by
log.eventName (event types)
Why log.eventName: SonicWall gives every event a fixed name (for example 'Connection Opened') and a numeric message ID. In the CEF format that the UTMStack setup guide asks for (frontend en.json integrations.setup.collector.sonicwall.step2.body), the parser's CEF header grok writes the name to log.eventName and the ID to log.eventCode on every line. The name is readable and of moderate cardinality (a few dozen common names). log.eventCode is the numeric companion (text such as '537') and exists in both syslog formats, so it is shown in the latest-logs table. In the default (non-CEF) SonicWall format log.eventName does not exist and the same text is in log.message instead (see caveats and parser issues). The examples below come from SonicWall's log reference and the repo's SonicWall rules, not from parser code.
Typical values: Connection Opened, Connection Closed, Web site hit, IPS Prevention Alert: <signature name>, Administrator login denied due to bad credentials
Widgets
Standard layout from the parent issue; rows W2, W3 and W9 onward are specific to this integration.
#
Title
Shown as
Query
Why
W1
Total logs
number
logs: count
All SonicWall logs in the selected time range.
W2
Denied connections
number
logs: count; filter actionResult = denied
Traffic the firewall dropped or denied; the parser maps fw_action drop/deny/block to actionResult 'denied'.
W3
Critical events
number
logs: count; filter severity = critical
SonicWall priority 0 to 2 (emergency, alert, critical), which the parser maps to severity 'critical'.
W4
Alerts
number
alerts: count
Alerts raised from SonicWall logs.
W5
Log volume over time
area chart
logs: count over time
Shows gaps and spikes in what the firewalls send.
W6
Logs by firewall IP
bar chart
logs: top 10 values of dataSource
dataSource is the sending firewall's IP address, so this shows which firewall is busiest or silent.
W7
Top event types
value and count table
logs: top 25 values of log.eventName; filter log.eventName exists
The main list: SonicWall event names by count; click one to open those logs. The exists filter hides a blank row.
W8
Event types over time (top 5)
line chart
logs: count over time, one line per value of log.eventName (top 5); filter log.eventName exists
When each of the five most common event types happened.
W9
Top source IPs
bar chart
logs: top 10 values of origin.ip; filter origin.ip exists
Hosts that start the most connections.
W10
Top destination ports
bar chart
logs: top 10 values of target.port; filter target.port exists
Which services the traffic goes to.
W11
Top source countries
bar chart
logs: top 10 values of origin.geolocation.country; filter origin.geolocation.country exists
Where connections from public IPs come from (private addresses get no country).
W12a
Top firewall rules
bar chart
logs: top 10 values of log.rule; filter log.rule exists
Which access rules match the most traffic.
W12b
Top users
bar chart
logs: top 10 values of origin.user; filter origin.user exists
Most active signed-in users (logins, VPN, and traffic identified by single sign-on).
W13
Alerts by rule
bar chart
alerts: top 10 values of name
Which SonicWall detection rules fire most.
W14
Alerts by severity
bar chart
alerts: top 50 values of severity
Split of SonicWall alerts into low, medium and high.
The newest raw records; log.eventCode identifies the event even on lines without log.eventName.
Fields used and where they come from
log.eventName: Event name from the CEF header (the 'Name' slot). Examples: Connection Opened, Web site hit. Source: CEF header grok on raw, pattern with fieldName log.eventName, where: contains("raw", "CEF:")
log.message: Event name in the default (non-CEF) format, from msg="...". Examples: Connection Opened. Source: delete log.msg + rescue grok '{{.data}}(msg=)' -> log.message, then the trailing 'key=' strip grok and the quote trims
actionResult: 'success' when action is forward; 'denied' when action is drop, dropped, deny, denied, block or blocked. Examples: success, denied. Source: add actionResult 'success' where equals("action", "forward"); add actionResult 'denied' where oneOf("action", [drop, dropped, deny, denied, block, blocked])
severity: From the SonicWall priority pri=: 0-2 critical, 3 error, 4 warning, 5-6 info, 7 debug. Examples: info, critical. Source: rename log.pri -> log.priority; cast to string; add severity steps
log.groupCategory: SonicWall group category label mapped from gcat=1..17. Examples: Security Services, Network, VPN. Source: rename log.gcat -> log.groupCategoryId; cast to string; add log.groupCategory steps
origin.ip: Source IPv4 address. Examples: 192.168.1.10. Source: grok on log.src (ipv4 ':' integer ':' word -> origin.ip, origin.port, log.sourceInterface); rename log.src -> origin.ip when there is no ':'
target.port: Destination port (number). Examples: 443, 53. Source: grok on log.dst -> target.ip, target.port, log.targetInterface; cast target.port to int
origin.geolocation.country: Country name of a public source IP. Examples: United States. Source: dynamic plugin com.utmstack.geolocation, source origin.ip, destination origin.geolocation (JSON key 'country' per go-sdk plugins.Geolocation)
origin.user: User name from usr="...". Examples: jdoe. Source: usr rescue grok -> log.userRaw -> quote trims -> rename log.userRaw -> origin.user
protocol: Transport protocol (the part of proto= before '/'). Examples: tcp, udp. Source: grok on log.proto ('{{.word}}' -> protocol, '/' , '{{.notSpace}}' -> log.appProto); rename log.proto -> protocol when there is no '/'
Watch out for
Field names will change: since 24 Sep 2026 the event engine keeps underscores in field names (go-sdk v1.1.35, threatwinds/EventProcessor e6d9bd307e). The v11 parsers were updated for it the same day (utmstack/UTMStack 06e2746), but this v12 parser still renames the old underscore-free names. SonicWall's key is fw_action, so the rename from log.fwaction to action stops matching on the new engine, and every widget on action or actionResult (including W2) goes empty until the v12 SonicWall parser is updated.
Syslog format decides the event-name field. The setup guide tells users to choose ArcSight (CEF); then log.eventName and log.eventCode come from the CEF header and exist on every line. A firewall left on the default SonicWall format has no log.eventName (the same text is in log.message), so W7 and W8 are empty for it. log.eventCode exists in both formats.
Everything outside the CEF header (addresses, ports, fw_action, pri, gcat, usr, rule) comes from a key=value pass over the whole line. The parser's own header comment says the CEF extension carries the same keys as the default format. This could not be verified with a real SonicWall CEF line. If a firmware uses standard CEF keys instead (spt, dpt, suser, act, and no pri or gcat), then target.port, origin.user, log.rule, action, actionResult and severity are missing and W2, W3, W10, W12a and W12b stay at zero.
actionResult is only set to 'success' (fw_action forward) or 'denied' (drop, dropped, deny, denied, block, blocked). Other fw_action values, such as management traffic or 'NA', get no actionResult.
origin.ip and target.ip exist only when src/dst is a plain IPv4 address or exactly IPv4:port:interface. IPv6 addresses and other shapes are deleted by the parser (see parser issues).
Countries exist only for public source IPs: the geolocation plugin skips private ranges (plugins/geolocation/geolocate.go IsLocal).
origin.user exists only on events that carry usr= (logins, VPN, and traffic identified by single sign-on). log.rule exists only on events that carry rule=.
Per SonicWall's log reference, some event names include a detail such as the intrusion signature name or a blocked country and IP address, so one kind of event can spread over several rows in W7.
Values are case sensitive: severity and actionResult values are lowercase ('critical', 'denied').
Parser behavior was read from the filter and from library code, not run: the engine ships as a binary. Two rules used above are stated or implied by the shipped filters: a grok writes nothing unless its whole pattern matches (comment in definitions/filters/fortinet/fortinet.yaml), and the key=value step strips characters other than letters, digits and dots from key names (go-sdk utils.SanitizeField; the Sophos filter's renames such as log.srcip depend on it).
Parser problems found while designing this
These are not dashboard work, but they limit what the dashboard can show. They belong to #1715; raise them there rather than working around them in the dashboard.
fw_action is lost when it is the last key on the line: 'delete log.fwaction where contains(raw, fw_action=")' runs first, and the rescue grok then needs another key=value after the quoted value to match. On such lines action and actionResult are missing, so W2 undercounts. Fix: let the rescue pattern accept the end of the line, or delete only after a successful rescue.
src/dst addresses can disappear: the grok on log.src (and log.dst) only matches IPv4:port:interface, but the next step deletes log.src whenever it contains ':' even if the grok failed. IPv6 addresses, an empty port (IP::X0) or a missing interface lose the address, so the IP, port and country widgets miss those events. Fix: delete only when origin.ip (target.ip) was set.
The event name lives in two fields: log.eventName (CEF header) and log.message (default format). The seven SonicWall rules use log.message for their text checks and never log.eventName, so in the CEF format the setup guide recommends those checks only work if the CEF extension also carries msg="...". Fix: have the CEF header grok also write log.message, or copy msg into log.eventName, so rules and this dashboard work in both formats.
The only standard CEF extension keys the parser renames are smac, dmac and cs6. If SonicWall CEF lines use spt, dpt, suser or act, or carry the priority only in the header severity (log.cefSeverity), then ports, user, action and severity stay empty. Could not verify which keys SonicWall sends.
Does not affect this dashboard: the renames of log.af_service and log.af_type never match because the key=value step strips '_' from key names (this same filter already relies on that for log.fwaction). log.appFirewallService and log.appFirewallType therefore never exist, yet the botnet and Capture ATP rules test them.
Does not affect this dashboard: with the usual '<134>id=firewall' start, the first key becomes '134id' after '<' and '>' are stripped, so rename log.id -> log.sourceId never runs.
How to build it
Before you start: parser field names are changing while the parsers are updated for the engine's new underscore handling (see "Field names are about to move" in #2696). Check every field in this issue against the v12 parser at that moment and against real logs, and build against what you find.
Add definitions/dashboards/integration-sonic-wall.yaml. Keep it in the top folder: the test that checks shipped dashboards (TestEveryShippedDashboardDefinitionIsValid) only reads the top folder.
Start from the file below; it follows the table above and passes the same checks as the backend (domain.Spec.Validate).
definitions/dashboards/integration-sonic-wall.yaml is merged to release/v12.0.0 and go test ./modules/dashboards/... passes in backend/.
With SonicWall logs flowing on a v12 test server, every widget shows data. A widget that stays empty while logs arrive means a wrong field or value: fix it, don't ship it.
Clicking a row, bar or line point opens the Log Explorer on the same logs, and the Log Explorer count matches the widget.
A time range with no logs shows empty states, not errors.
A screenshot of the finished dashboard is attached to this issue.
Part of: #2696 · Needs first: #2697 (click-through to the Log Explorer and the value/count table)
Related: #1715 (parsers and rules for this integration, owned by the detection team)
Goal
Ship a built-in SonicWall dashboard that shows, at a glance, how much SonicWall is sending, whether it is still sending, and what kinds of events they are. The heart of it is the list of SonicWall logs grouped by event types (widget W7): click one and the Log Explorer opens on exactly those logs.
Where the data comes from
SONIC_WALLfirewall-sonicwalldefinitions/filters/sonicwall/sonic_wall.yamldataSourceholdslog.eventName(event types)Why
log.eventName: SonicWall gives every event a fixed name (for example 'Connection Opened') and a numeric message ID. In the CEF format that the UTMStack setup guide asks for (frontend en.json integrations.setup.collector.sonicwall.step2.body), the parser's CEF header grok writes the name to log.eventName and the ID to log.eventCode on every line. The name is readable and of moderate cardinality (a few dozen common names). log.eventCode is the numeric companion (text such as '537') and exists in both syslog formats, so it is shown in the latest-logs table. In the default (non-CEF) SonicWall format log.eventName does not exist and the same text is in log.message instead (see caveats and parser issues). The examples below come from SonicWall's log reference and the repo's SonicWall rules, not from parser code.Typical values:
Connection Opened,Connection Closed,Web site hit,IPS Prevention Alert: <signature name>,Administrator login denied due to bad credentialsWidgets
Standard layout from the parent issue; rows W2, W3 and W9 onward are specific to this integration.
actionResult= deniedseverity= criticaldataSourcelog.eventName; filterlog.eventNameexistslog.eventName(top 5); filterlog.eventNameexistsorigin.ip; filterorigin.ipexiststarget.port; filtertarget.portexistsorigin.geolocation.country; filterorigin.geolocation.countryexistslog.rule; filterlog.ruleexistsorigin.user; filterorigin.userexistsnameseverity@timestamp,dataSource,log.eventName,log.eventCode,origin.ip,target.ip,target.port,actionFields used and where they come from
log.eventName: Event name from the CEF header (the 'Name' slot). Examples:Connection Opened,Web site hit. Source: CEF header grok on raw, pattern with fieldName log.eventName, where: contains("raw", "CEF:")log.eventCode: SonicWall message ID, stored as text. Examples:537,98. Source: CEF header grok (fieldName log.eventCode); rename log.m -> log.eventCode; cast log.eventCode to stringlog.message: Event name in the default (non-CEF) format, from msg="...". Examples:Connection Opened. Source: delete log.msg + rescue grok '{{.data}}(msg=)' -> log.message, then the trailing 'key=' strip grok and the quote trimsaction: Firewall action from fw_action="...". Examples:forward,drop. Source: fw_action rescue grok -> log.actionRaw -> quote trims -> rename log.actionRaw -> actionactionResult: 'success' when action is forward; 'denied' when action is drop, dropped, deny, denied, block or blocked. Examples:success,denied. Source: add actionResult 'success' where equals("action", "forward"); add actionResult 'denied' where oneOf("action", [drop, dropped, deny, denied, block, blocked])severity: From the SonicWall priority pri=: 0-2 critical, 3 error, 4 warning, 5-6 info, 7 debug. Examples:info,critical. Source: rename log.pri -> log.priority; cast to string; add severity stepslog.groupCategory: SonicWall group category label mapped from gcat=1..17. Examples:Security Services,Network,VPN. Source: rename log.gcat -> log.groupCategoryId; cast to string; add log.groupCategory stepsorigin.ip: Source IPv4 address. Examples:192.168.1.10. Source: grok on log.src (ipv4 ':' integer ':' word -> origin.ip, origin.port, log.sourceInterface); rename log.src -> origin.ip when there is no ':'target.port: Destination port (number). Examples:443,53. Source: grok on log.dst -> target.ip, target.port, log.targetInterface; cast target.port to intorigin.geolocation.country: Country name of a public source IP. Examples:United States. Source: dynamic plugin com.utmstack.geolocation, source origin.ip, destination origin.geolocation (JSON key 'country' per go-sdk plugins.Geolocation)origin.user: User name from usr="...". Examples:jdoe. Source: usr rescue grok -> log.userRaw -> quote trims -> rename log.userRaw -> origin.userlog.rule: Firewall rule text from rule="...". Examples:5 (LAN->WAN). Source: delete log.rule + rule rescue grok -> log.rule, strip grok, quote trimsprotocol: Transport protocol (the part of proto= before '/'). Examples:tcp,udp. Source: grok on log.proto ('{{.word}}' -> protocol, '/' , '{{.notSpace}}' -> log.appProto); rename log.proto -> protocol when there is no '/'Watch out for
Parser problems found while designing this
These are not dashboard work, but they limit what the dashboard can show. They belong to #1715; raise them there rather than working around them in the dashboard.
How to build it
Before you start: parser field names are changing while the parsers are updated for the engine's new underscore handling (see "Field names are about to move" in #2696). Check every field in this issue against the v12 parser at that moment and against real logs, and build against what you find.
definitions/dashboards/integration-sonic-wall.yaml. Keep it in the top folder: the test that checks shipped dashboards (TestEveryShippedDashboardDefinitionIsValid) only reads the top folder.domain.Spec.Validate).categoryquery shown with chart typetable. It already renders; v12 dashboards: groundwork for integration dashboards (click-through to the Log Explorer, value/count table, Agents dashboard fix) #2697 makes its rows clickable and its headers readable.Starting dashboard file
Done when
definitions/dashboards/integration-sonic-wall.yamlis merged torelease/v12.0.0andgo test ./modules/dashboards/...passes inbackend/.