Hello,
A decoder can only extract values that already exist in the log, and a rule <field> is used to match an existing field, not to create a new one.
For ClamAV, Wazuh already has built-in rules under 0320-clam_av_rules.xml, so one easy quick win is to use the existing rule groups like clamd, and dashboards, that also depends on if you need a literal field named integration or you just need to filter on the dashboard. "integration": "clamav"
If filtering is enough, use the existing rule groups, or add your own custom group in a local rule, something like the below.
<rule id="52502" level="8" overwrite="yes">
<if_sid>52500</if_sid>
<match>FOUND$</match>
<description>ClamAV: Virus detected</description>
<group>clamd,virus,integration_clamav,</group>
</rule>
If you need to have a real field in the indexed alert, one maintainable option is to enrich it at the indexer level with an ingest pipeline. For example, set a field when rule.groups contains clamd.
Example idea:
{
"set": {
"field": "data.integration",
"value": "clamav",
"if": "ctx.rule?.groups != null && ctx.rule.groups.contains('clamd')"
}
}Just note that this field would exist in the indexed document, not in /var/ossec/logs/alerts/alerts.json.
Another option is to add the value before the log gets to the Wazuh manager, for example, using out_format or by sending ClamAV logs as JSON and using <label>.
https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/localfile.html#out-formathttps://documentation.wazuh.com/current/user-manual/reference/ossec-conf/localfile.html?utm_source=chatgpt.com#label<localfile>
<log_format>syslog</log_format>
<location>/var/log/clamav/clamd.log</location>
<out_format>$(log) integration="clamav"</out_format>
</localfile>Result while capturing will look like:
<decoder name="clamd">
<parent>clamd</parent>
<regex>(\S+): (\S+) FOUND integration="(\w+)"$</regex>
<order>url, extra_data, integration</order>
</decoder>Please note this means the use of the Wazuh agent to capture the log, which explains the use of locafile.
That said, key points:
For filtering/reporting, just use the rule.groups.
For a real field in the dashboard, use an ingest pipeline.
For the field to exist, you can also use out_format.
Please let me know if you require further clarification.