To replace a part of the log message, you have to:
-
define a string or regular expression to find the text to replace
-
define a string to replace the original text (macros can be used as well)
-
select the field of the message that the rewrite rule should process
Substitution rules can operate on any soft macros, for example, MESSAGE, PROGRAM, or any user-defined macros created using parsers. Hard macros cannot be modified. For details on the hard and soft macros, see Hard versus soft macros). You can also rewrite the structured-data fields of messages complying to the RFC5424 (IETF-syslog) message format. Substitution rules use the following syntax:
Declaration
rewrite <name_of_the_rule> {
subst("<string or regular expression to find>",
"<replacement string>", value(<field name>), flags() );
};
The type() and flags() options are optional. The type() specifies the type of regular expression to use, while the flags() are the flags of the regular expressions. For details on regular expressions, see Regular expressions.
A single substitution rule can include multiple substitutions that are applied sequentially to the message. Note that rewriting rules must be included in the log statement to have any effect.
TIP: For case-insensitive searches, add the flags(ignore-case) option. To replace every occurrence of the string, add flags(global) option. Note that the store-matches flag is automatically enabled in rewrite rules.
Example: Using substitution rules
The following example replaces the IP in the text of the message with the string IP-Address.
rewrite r_rewrite_subst{subst("IP", "IP-Address", value("MESSAGE"));};
To replace every occurrence, use:
rewrite r_rewrite_subst{
subst("IP", "IP-Address", value("MESSAGE"), flags("global"));
};
Multiple substitution rules are applied sequentially. The following rules replace the first occurrence of the string IP with the string IP-Addresses.
rewrite r_rewrite_subst{
subst("IP", "IP-Address", value("MESSAGE"));
subst("Address", "Addresses", value("MESSAGE"));
};
Example: Anonymizing IP addresses
The following example replaces every IPv4 address in the MESSAGE part with its SHA-1 hash:
rewrite pseudonymize_ip_addresses_in_message {subst ("((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])[.]){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))", "$(sha1 $0)", value("MESSAGE"));};
To set a field of the message to a specific value, you have to:
You can set the value of available macros, for example, HOST, MESSAGE, PROGRAM, or any user-defined macros created using parsers (for details, see parser: Parse and segment structured messages and Processing message content with a pattern database). Hard macros cannot be modified. For details on the hard and soft macros, see Hard versus soft macros). Note that the rewrite operation completely replaces any previous value of that field. Use the following syntax:
Declaration
rewrite <name_of_the_rule> {
set("<string to include>", value(<field name>));
};
Example: Setting message fields to a particular value
The following example sets the HOST field of the message to myhost.
rewrite r_rewrite_set{set("myhost", value("HOST"));};
The following example appends the "suffix" string to the MESSAGE field:
rewrite r_rewrite_set{set("$MESSAGE suffix", value("MESSAGE"));};
For details on rewriting SDATA fields, see Creating custom SDATA fields.
You can also use the following options in rewrite rules that use the set() operator.
rewrite <name_of_the_rule> {
set("<string to include>", value(<field name>), on-error("fallback-to-string");
};
You can unset a macro or a field of the message, including any user-defined macros created using parsers (for details, see parser: Parse and segment structured messages and Processing message content with a pattern database). Hard macros cannot be modified. For details on hard and soft macros, see Hard versus soft macros). Note that the unset operation completely deletes any previous value of the field that you apply it on. Use the following syntax:
Declaration
rewrite <name_of_the_rule> {
unset(value("<field name>"));
};
Example: Unsetting a message field
The following example unsets the HOST field of the message.
rewrite r_rewrite_unset{unset(value("HOST"));};
To unset a group of fields, you can use the groupunset() rewrite rule.
Declaration
rewrite <name_of_the_rule> {
groupunset(values("<expression-for-field-names>"));
};
Example: Unsetting a group of fields
The following rule clears all SDATA fields:
rewrite r_rewrite_unset_SDATA{ groupunset(values(".SDATA.*"));};
If you use RFC5424-formatted (IETF-syslog) messages, you can also create custom fields in the SDATA part of the message (For details on the SDATA message part, see The STRUCTURED-DATA message part). According to RFC5424, the name of the field (its SD-ID) must not contain the @ character for reserved SD-IDs. Custom SDATA fields must be in the following format: .SDATA.group-name@<private enterprise number>.field-name, for example, .SDATA.mySDATA-field-group@18372.4.mySDATA-field. (18372.4 is the private enterprise number of One Identity LLC, the developer of syslog-ng PE.)
Example: Rewriting custom SDATA fields
The following example sets the sequence ID field of the RFC5424-formatted (IETF-syslog) messages to a fixed value. This field is a predefined SDATA field with a reserved SD-ID, therefore its name does not contain the @ character.
rewrite r_sd {
set("55555" value(".SDATA.meta.sequenceId"));
};
It is also possible to set the value of a field that does not exist yet, and create a new, custom name-value pair that is associated with the message. The following example creates the .SDATA.groupID.fieldID@18372.4 field and sets its value to yes. If you use the ${.SDATA.groupID.fieldID@18372.4} macro in a template or SQL table, its value will be yes for every message that was processed with this rewrite rule, and empty for every other message.
rewrite r_yes {
set("yes" value(".SDATA.groupID.fieldID@18372.4"));
};
The next example creates a new SDATA field-group and field called custom and sourceip, respectively:
rewrite r_rewrite_set {
set("${SOURCEIP}" value(".SDATA.custom@18372.4.sourceip"));
};
If you use the ${.SDATA.custom@18372.4.sourceip} macro in a template or SQL table, its value will be that of the SOURCEIP macro (as seen on the machine where the SDATA field was created) for every message that was processed with this rewrite rule, and empty for every other message.
You can verify whether or not the format is correct by looking at the actual network traffic. The SDATA field-group will be called custom@18372.4, and sourceip will become a field within that group. If you decide to set up several fields, they will be listed in consecutive order within the field-group's SDATA block.