Wazuh ships with thousands of decoders and rules, but custom applications need custom detection. All custom logic lives in two files on the manager: /var/ossec/etc/decoders/local_decoder.xml and /var/ossec/etc/rules/local_rules.xml. Never edit the default ruleset, it gets overwritten on upgrade.
1. Sample log to parse
2026-06-16 12:00:00 myapp ERROR user=admin action=login_failed src_ip=10.0.0.52. Custom decoder
<decoder name="myapp">
<prematch>myapp ERROR</prematch>
</decoder>
<decoder name="myapp-fields">
<parent>myapp</parent>
<regex>user=(\S+) action=(\S+) src_ip=(\S+)</regex>
<order>user,action,srcip</order>
</decoder>3. Custom rule
<group name="myapp,">
<rule id="100001" level="5">
<decoded_as>myapp</decoded_as>
<field name="action">login_failed</field>
<description>MyApp: failed login from $(srcip)</description>
</rule>
<rule id="100002" level="10" frequency="5" timeframe="60">
<if_matched_sid>100001</if_matched_sid>
<same_field>srcip</same_field>
<description>MyApp: brute force from $(srcip)</description>
</rule>
</group>4. Test with ossec-logtest
/var/ossec/bin/wazuh-logtest
# paste the sample log and confirm decoder/rule match5. Restart the manager
systemctl restart wazuh-managerNote: Always use rule IDs >= 100000 for custom rules, IDs below are reserved for the official ruleset.
We build rule packs for SaaS, custom apps and OT protocols, reach out via contact.
Official reference
Commands and configuration in this guide are based on the official Wazuh documentation. For the canonical source, see: