This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Modify messages using rewrite rules
The AxoSyslog application can rewrite parts of the messages using rewrite rules. Rewrite rules are global objects similar to parsers and filters and can be used in log paths. The AxoSyslog application has two methods to rewrite parts of the log messages: substituting (setting) a part of the message to a fix value, and a general search-and-replace mode.
- Substitution completely replaces a specific part of the message that is referenced using a built-in or user-defined macro.
- General rewriting searches for a string in the entire message (or only a part of the message specified by a macro) and replaces it with another string. Optionally, this replacement string can be a template that contains macros.
Rewriting messages is often used in conjunction with message parsing parser: Parse and segment structured messages.
Rewrite rules are similar to filters: they must be defined in the syslog-ng.conf configuration file and used in the log statement. You can also define the rewrite rule inline in the log path.
Note
The order of filters, rewriting rules, and parsers in the log statement is important, as they are processed sequentially.
1 - Replace message parts
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. You can also rewrite the structured-data fields of messages complying to the RFC5424 (IETF-syslog) message format.
See also the equivalent FilterX function, regexp_subst(), or str_replace() for literal strings.
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.
Note
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"));
};
<!-- DISCLAIMER: This file is based on the syslog-ng Open Source Edition documentation https://github.com/balabit/syslog-ng-ose-guides/commit/2f4a52ee61d1ea9ad27cb4f3168b95408fddfdf2 and is used under the terms of The syslog-ng Open Source Edition Documentation License. The file has been modified by Axoflow. -->
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"));};
Options
The subst() rewrite rule has the following options.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
flags()
|
|
| Type: |
list of flags |
| Default: |
empty set |
Description: The flags of the regular expression. The available flags depend on the type() of the regular expression. For case-insensitive searches, use flags(ignore-case). To replace every occurrence of the pattern, use flags(global). Note that the store-matches flag is automatically enabled in rewrite rules. For details, see Regular expressions.
internal()
|
|
| Accepted values: |
yes, no |
| Default: |
no |
Description: Marks this pipeline element as internal. Elements marked as internal() are treated as an implementation detail, so for example statistics of the given pipe are available only on higher stats level. This option is mainly useful for developers or when writing SCL blocks and integrations.
type()
|
|
| Type: |
pcre, string, glob |
| Default: |
pcre |
Description: Sets how AxoSyslog interprets the search pattern: as a Perl Compatible Regular Expression (pcre, used by default), a literal string search (string), or a glob pattern without regular expression support (glob). For details, see Options of regular expressions.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
value()
|
|
| Type: |
name of a message field |
| Default: |
MESSAGE |
Description: Selects the field of the message that the rewrite rule modifies. If you don’t set it, the rule operates on the MESSAGE field.
Write the name of the field without the $ prefix, for example, value("HOST"), not value("$HOST"). The $ prefix is only needed in templates, and AxoSyslog logs a warning if you use it here. You cannot set a hard macro in the value() option, AxoSyslog rejects the configuration with an error.
2 - Set message fields to specific values
To set a field of the message to a specific value, you have to:
- define the string to include in the message, and
- select the field where it should be included.
-
You can set the type of the field. Where you can use of templates in set() and groupset(), you can use type-casting, and the type information is properly promoted. For details, see Specifying data types in value-pairs.
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 db-parser: Process message content with a pattern database (patterndb)). Note that the rewrite operation completely replaces any previous value of that field.
See also the equivalent FilterX operation, assigning a value.
Use the following syntax:
Declaration
rewrite <name_of_the_rule> {
set("<string to include>", value(<field name>));
};
Example: Set 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 Create custom SDATA fields.
Note
The
severity and
facility fields can only be set by the
set-severity() rewrite functions. For more information, see
Set the severity field.
Options
The set() rewrite rule has the following options. In addition to condition(), internal(), and value(), set() accepts the template options listed below, which control how AxoSyslog expands the template in its first argument.
rewrite <name_of_the_rule> {
set("<string to include>", value(<field name>), on-error("fallback-to-string"));
};
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
frac-digits()
Description: The number of digits that AxoSyslog stores when it expands a timestamp macro with fractions of a second. Overrides the global frac-digits() option for this rule.
internal()
|
|
| Accepted values: |
yes, no |
| Default: |
no |
Description: Marks this pipeline element as internal. Elements marked as internal() are treated as an implementation detail, so for example statistics of the given pipe are available only on higher stats level. This option is mainly useful for developers or when writing SCL blocks and integrations.
local-time-zone()
|
|
| Type: |
name of the timezone, or the timezone offset |
| Default: |
The local timezone. |
Description: Sets the timezone that AxoSyslog uses when it expands a timestamp macro as a local time.
<!-- DISCLAIMER: This file is based on the syslog-ng Open Source Edition documentation https://github.com/balabit/syslog-ng-ose-guides/commit/2f4a52ee61d1ea9ad27cb4f3168b95408fddfdf2 and is used under the terms of The syslog-ng Open Source Edition Documentation License. The file has been modified by Axoflow. -->
The timezone can be specified by using the name, for example, time-zone("Europe/Budapest")), or as the timezone offset in +/-HH:MM format, for example, +01:00). On Linux and UNIX platforms, the valid timezone names are listed under the /usr/share/zoneinfo directory.
on-error()
| Type: |
One of: drop-message, drop-property, fallback-to-string, silently-drop-message, silently-drop-property, silently-fallback-to-string |
| Default: |
Use the global setting (which defaults to drop-message) |
<!-- DISCLAIMER: This file is based on the syslog-ng Open Source Edition documentation https://github.com/balabit/syslog-ng-ose-guides/commit/2f4a52ee61d1ea9ad27cb4f3168b95408fddfdf2 and is used under the terms of The syslog-ng Open Source Edition Documentation License. The file has been modified by Axoflow. -->
Description: Controls what happens when type-casting fails and AxoSyslog cannot convert some data to the specified type. By default, AxoSyslog drops the entire message and logs the error. Currently the value-pairs() option uses the settings of on-error().
drop-message: Drop the entire message and log an error message to the internal() source. This is the default behavior of AxoSyslog.
drop-property: Omit the affected property (macro, template, or message-field) from the log message and log an error message to the internal() source.
fallback-to-string: Convert the property to string and log an error message to the internal() source.
silently-drop-message: Drop the entire message silently, without logging the error.
silently-drop-property: Omit the affected property (macro, template, or message-field) silently, without logging the error.
silently-fallback-to-string: Convert the property to string silently, without logging the error.
send-time-zone()
|
|
| Type: |
name of the timezone, or the timezone offset |
| Default: |
The local timezone. |
Description: Sets the timezone that AxoSyslog uses when it expands a timestamp macro. The time-zone() option is an alias of send-time-zone().
<!-- DISCLAIMER: This file is based on the syslog-ng Open Source Edition documentation https://github.com/balabit/syslog-ng-ose-guides/commit/2f4a52ee61d1ea9ad27cb4f3168b95408fddfdf2 and is used under the terms of The syslog-ng Open Source Edition Documentation License. The file has been modified by Axoflow. -->
The timezone can be specified by using the name, for example, time-zone("Europe/Budapest")), or as the timezone offset in +/-HH:MM format, for example, +01:00). On Linux and UNIX platforms, the valid timezone names are listed under the /usr/share/zoneinfo directory.
template-escape()
|
|
| Type: |
yes, no |
| Default: |
no |
Description: Turns on escaping for the ', ", and backspace characters in the expanded value.
time-zone()
|
|
| Type: |
name of the timezone, or the timezone offset |
| Default: |
The local timezone. |
Description: Alias of send-time-zone().
|
|
| Type: |
rfc3164, bsd, rfc3339, iso |
| Default: |
rfc3164 |
Description: Overrides the global ts-format() option for the timestamp macros that this rule expands.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
value()
|
|
| Type: |
name of a message field |
| Default: |
MESSAGE |
Description: Selects the field of the message that the rewrite rule modifies. If you don’t set it, the rule operates on the MESSAGE field.
Write the name of the field without the $ prefix, for example, value("HOST"), not value("$HOST"). The $ prefix is only needed in templates, and AxoSyslog logs a warning if you use it here. You cannot set a hard macro in the value() option, AxoSyslog rejects the configuration with an error.
3 - Set the severity field
It is possible to configure the severity field with the set-severity() rewrite function. When configured, the set-severity() rewrite function will only rewrite the $SEVERITY field in the message to the first parameter value specified in the function.
Note
If the parameter value is not a valid parameter value, the function ignores it and sends a debug message, but the AxoSyslog application still sends the message.
FilterX has no set_severity() counterpart. See the related set_pri() function, which sets the combined PRI value (facility * 8 + severity), so you cannot set the severity without also setting the facility. It also takes a number, not a severity name.
Declaration
rewrite <name_of_the_rule> {
set-severity("severity string or number");
};
Parameters
The set-severity() rewrite function has a single, mandatory parameter that can be defined as follows:
set-severity( "parameter1" );
Accepted values
The set-severity() rewrite function accepts numeric values, named values, and aliases. Aliases are available in AxoSyslog version 4.6 and later.
| Numerical Code |
Named Value |
Alias |
| 0 |
emerg |
SYSLOG_SEVERITY_CODE(0) |
| 0 |
emergency |
SYSLOG_SEVERITY_CODE(0) |
| 0 |
panic |
SYSLOG_SEVERITY_CODE(0) |
| 1 |
alert |
SYSLOG_SEVERITY_CODE(1) |
| 2 |
crit |
SYSLOG_SEVERITY_CODE(2) |
| 2 |
critical |
SYSLOG_SEVERITY_CODE(2) |
| 2 |
fatal |
SYSLOG_SEVERITY_CODE(2) |
| 3 |
err |
SYSLOG_SEVERITY_CODE(3) |
| 3 |
error |
SYSLOG_SEVERITY_CODE(3) |
| 4 |
warning |
SYSLOG_SEVERITY_CODE(4) |
| 4 |
warn |
SYSLOG_SEVERITY_CODE(4) |
| 5 |
notice |
SYSLOG_SEVERITY_CODE(5) |
| 6 |
info |
SYSLOG_SEVERITY_CODE(6) |
| 6 |
log |
SYSLOG_SEVERITY_CODE(6) |
| 7 |
debug |
SYSLOG_SEVERITY_CODE(7) |
Example usage for the set-severity() rewrite function
The following examples use the set-severity() rewrite function.
Using a named value:
rewrite {
set-severity("info");
};
Using a numeric value:
rewrite {
set-severity("6");
};
Using a template:
rewrite {
set-severity("${.json.severity}");
};
Options
The set-severity() rewrite rule has the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
4 - Set the facility field
It is possible to set the facility field with the set-facility() rewrite function. When set, the set-facility() rewrite function will only rewrite the ${FACILITY} field in the message to the first parameter value specified in the function.
Note
If the parameter value is not a valid parameter value, the function ignores it and sends a debug message, but the application still sends the message.
FilterX has no set_facility() counterpart. See the related set_pri() function, which sets the combined PRI value (facility * 8 + severity), so you cannot set the facility without also setting the severity.
Declaration
log {
source { system(); };
if (program("postfix")) {
rewrite { set-facility("mail"); };
};
destination { file("/var/log/mail.log"); };
flags(flow-control);
};
Parameters
The set-facility() rewrite function has a single, mandatory parameter that can be defined as follows:
set-facility( "parameter1" );
Accepted values
The set-facility() rewrite function accepts the following numeric strings and named values:
| Numerical Code |
Facility name |
Facility |
| 0 |
kern |
kernel messages |
| 1 |
user |
user-level messages |
| 2 |
mail |
mail system |
| 3 |
daemon |
system daemons |
| 4 |
auth |
security/authorization messages |
| 5 |
syslog |
messages generated internally by syslogd |
| 6 |
lpr |
line printer subsystem |
| 7 |
news |
network news subsystem |
| 8 |
uucp |
UUCP subsystem |
| 9 |
cron |
clock daemon |
| 10 |
authpriv |
security/authorization messages |
| 11 |
ftp |
FTP daemon |
| 12 |
ntp |
NTP subsystem |
| 13 |
security |
log audit |
| 14 |
console |
log alert |
| 15 |
solaris-cron |
clock daemon |
| 16-23 |
local0..local7 |
locally used facilities (local0-local7) |
Example usage for the set-facility() rewrite function
The following two set-facility() examples are equivalent:
rewrite {
set-facility("security");
set-facility("13");
};
Options
The set-facility() rewrite rule has the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
5 - Set the priority of a message
You can set the PRI value of a BSD or IETF syslog message with the set-pri() rewrite function by specifying a template string. This is useful, for example, if incoming messages do not have a PRI value specified by default, but a PRI value is required for filtering purposes.
When configured, the set-pri() function will only rewrite the PRI value of the message field.
Note
If the specified parameter value is not a valid value, the function ignores it and sends a debug message. However, the AxoSyslog application will still send the message.
See also the equivalent FilterX function, set_pri(), which takes an integer instead of a template string.
Declaration
rewrite <rule-name> {
set-pri("template-string");
};
Parameters
The set-pri() rewrite function expects a template string as its only parameter, for example:
set-pri("42");
set-pri("$.json.priority");
Accepted values
The template string specified for the set-pri() rewrite function must expand to a natural number in the interval of 0–1023, inclusive. This means that if you, for example, extract the value from a syslog <PRI> header (such as <42>), then you need to remove the opening and closing brackets (< >) in the specified template string.
Example: Temporarily raising the priority of an application
In the following example, the set-pri() rewrite function is used to temporarily raise the priority of the application myprogram:
log {
source { system(); };
if (program("myprogram")){
rewrite { set-pri("92"); };
};
destination { file("/var/log/mail.log"); };
flags(flow-control);
}
In the following example, an application sends log messages in the following JSON format:
{
"time": "2003-10-11T22:14:15.003Z",
"host": "mymachine",
"priority": "165",
"message": "An application event log entry."
}
You can parse these logs with the JSON parser function:
{
parser p_json {
json-parser (prefix(".json."));
}
As the application message contains a valid priority field, you can use the set-pri() rewrite function to modify the priority of the message:
set-pri("$.json.priority");
Options
The set-pri() rewrite rule has the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
6 - Set match variables
Match macros ($1, $2, ... $255) are temporary variables. You can use them for general purposes when operating with list-like items. For example, the match() filter stores capture group results in match variables when the store-matches flag is set, or the JSON parser produces match variables if the parsed JSON data is an array.
It is possible to set match variables in a single operation with the set-matches() rewrite function. set-matches() uses AxoSyslog list expressions to set $1, $2, ... $255, so it can be considered as a conversion function between AxoSyslog lists and match variables.
Note
To convert match variables into a AxoSyslog list, use the
$* macro, which can be further manipulated using
list template functions, or turned into a list in type-aware destinations.
Note
To reset match variables to be empty, use the
unset-matches() rewrite rule.
Declaration
rewrite <name_of_the_rule> {
set-matches("<list-expression or list-based template function>");
};
Example for the set-matches() rewrite function
In the following two examples, $1, $2, and $3 will be set to foo, bar, and baz, respectively.
Using strings:
rewrite {
set-matches("foo,bar,baz");
};
Using a list template function:
rewrite {
set-matches("$(explode ':' 'foo:bar:baz')");
};
unset-matches()
The unset-matches() rewrite rule clears every match variable, that is, it resets $1, $2, ... $255 to empty. Use it when you want to make sure that match variables left over from an earlier filter, parser, or rewrite rule do not leak into later parts of the log path.
rewrite <name_of_the_rule> {
unset-matches();
};
Example for the unset-matches() rewrite function
The following log path sets three match variables, then clears them again, so $1, $2, and $3 are empty when the message reaches the destination.
log {
source(s_local);
rewrite { set-matches("foo,bar,baz"); };
rewrite { unset-matches(); };
destination(d_local);
};
Options
Both set-matches() and unset-matches() have the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
7 - Unset message fields
You can unset macros or fields of the message, including any user-defined macros created using parsers (for details, see parser: Parse and segment structured messages and db-parser: Process message content with a pattern database (patterndb)). Note that the unset operation completely deletes any previous value of the field that you apply it on.
Unset a field
Use the following syntax:
rewrite <name_of_the_rule> {
unset(value("<field-name>"));
};
Example: Unset a message field
The following example unsets the HOST field of the message.
rewrite r_rewrite_unset{
unset(value("HOST"));
};
If you’re using FilterX, see also the equivalent unset() function.
Unset group
To unset a group of fields, you can use the groupunset() rewrite rule.
rewrite <name_of_the_rule> {
groupunset(values("<expression-for-field-names>"));
};
Example: Unset a group of fields
The following rule clears all SDATA fields:
rewrite r_rewrite_unset_SDATA{
groupunset(values(".SDATA.*"));
};
Options
The unset() rewrite rule has the following options.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
internal()
|
|
| Accepted values: |
yes, no |
| Default: |
no |
Description: Marks this pipeline element as internal. Elements marked as internal() are treated as an implementation detail, so for example statistics of the given pipe are available only on higher stats level. This option is mainly useful for developers or when writing SCL blocks and integrations.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
value()
|
|
| Type: |
name of a message field |
| Default: |
MESSAGE |
Description: Selects the field of the message that the rewrite rule modifies. If you don’t set it, the rule operates on the MESSAGE field.
Write the name of the field without the $ prefix, for example, value("HOST"), not value("$HOST"). The $ prefix is only needed in templates, and AxoSyslog logs a warning if you use it here. You cannot set a hard macro in the value() option, AxoSyslog rejects the configuration with an error.
The groupunset() rewrite rule has the condition() option described above, and the following option.
values()
|
|
| Type: |
list of field names or globs |
| Default: |
N/A |
Description: Specifies the fields to unset. You can list the fields explicitly as a space-separated list of double-quoted names, or select multiple fields with glob expressions, for example, values(".SDATA.*"). This option is mandatory.
8 - Rename message fields
If you want to change the name of a field of a message, you can use rename() rewrite rules. This can be also achieved via using set() and unset() but those require extra conditions and two operation instead of one.
The rename() rewrite rule uses positional arguments and they are both required. It supports condition rewrite. For more information, see Conditional rewrites.
See also the related FilterX function move(). Note that rename() does nothing if the source field is missing, while move() fails in that case.
Declaration
rewrite r_rewrite_rename {
rename("<string1>" "<string2>");
};
Example usage for the rename() rewrite function
The following example renames the .app.name into .container if the .app.name exists. Otherwise, it does nothing.
rewrite r_rewrite_rename {
rename(".app.name" ".container");
};
Options
The rename() rewrite rule has the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
9 - Create custom SDATA fields
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 Axoflow, the developer of AxoSyslog.)
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.
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.
In FilterX, you can set the same fields with an assignment, for example, ${.SDATA.meta.sequenceId} = 55555;. To read SDATA fields, see the related Handle SDATA in RFC5424 log records functions.
10 - Set multiple message fields to specific values
The groupset() rewrite rule allows you to modify the value of multiple message fields at once, for example, to change the value of sensitive fields extracted using patterndb, or received in a JSON format. (If you want to modify the names of message fields, see map-value-pairs: Rename value-pairs to normalize logs.)
- The first parameter is the new value of the modified fields. This can be a simple string, a macro, or a template (which can include template functions as well).
- The second parameter (
values()) specifies the fields to modify. You can explicitly list the macros or fields (a space-separated list with the values enclosed in double-quotes), or use wildcards and glob expressions to select multiple fields.
- Note that
groupset() does not create new fields, it only modifies existing fields.
- You can refer to the old value of the field using the
$_ macro. This is resolved to the value of the current field, and is available only in groupset() rules.
-
You can set the type of the field. Where you can use of templates in set() and groupset(), you can use type-casting, and the type information is properly promoted. For details, see Specifying data types in value-pairs.
See also the related FilterX function set_fields(), which sets multiple keys of a dict. It differs from groupset(): it selects keys explicitly instead of by glob expression, has no equivalent of the $_ macro, and it can also create new keys.
Declaration
rewrite <name_of_the_rule> {
groupset("<new-value-of-the-fields>", values("<field-name-or-glob>" ["<another-field-name-or-glob>"]));
};
Example: Using groupset rewrite rules
The following examples show how to change the values of multiple fields at the same time.
-
Change the value of the HOST field to myhost.
groupset ("myhost" values("HOST"))
-
Change the value of the HOST and FULLHOST fields to myhost.
groupset ("myhost" values("HOST" "FULLHOST"))
-
Change the value of the HOST, FULLHOST and fields to lowercase.
groupset ("$(lowercase "$_")" values("HOST" "FULLHOST"))
-
Change the value of each field and macro that begins with .USER to nobody.
groupset ("nobody" values(".USER.*"))
-
Change the value of each field and macro that begins with .USER to its SHA-1 hash (truncated to 6 characters).
groupset ("$(sha1 --length 6 $_)" values(".USER.*"))
Options
The groupset() rewrite rule has the following options.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
values()
|
|
| Type: |
list of field names or globs |
| Default: |
N/A |
Description: Specifies the fields to modify. You can list the fields explicitly as a space-separated list of double-quoted names, or select multiple fields with glob expressions, for example, values(".USER.*"). This option is mandatory. Note that groupset() only modifies existing fields, it doesn’t create new ones.
11 - map-value-pairs: Rename value-pairs to normalize logs
The map-value-pairs() parser allows you to map existing name-value pairs to a different set of name-value pairs. You can rename them in bulk, making it easy to use for log normalization tasks (for example, when you parse information from different log messages, and want to convert them into a uniform naming scheme). You can use the normal value-pairs expressions, similarly to value-pairs based destinations. Using map-value-pairs() retains type data if available.
Available in AxoSyslog version 3.10 and later.
FilterX has no bulk equivalent. To rename fields one by one, see the related move() function.
Declaration
parser parser_name {
map-value-pairs(
<list-of-value-pairs-options>
);
};
Example: Map name-value pairs
The following example creates a new name-value pair called username, adds the hashed value of the .apache.username to this new name-value pair, then adds the webserver prefix to the name of every name-value pair of the message that starts with .apache
parser p_remap_name_values {
map-value-pairs(
pair("username", "'($sha1 $.apache.username)")
key('.apache.*' rekey(add-prefix("webserver")))
);
};
Options
The map-value-pairs() parser accepts the value-pairs() options listed below. Note that map-value-pairs() takes these options directly, without wrapping them into a value-pairs() block.
cast()
|
|
| Accepted values: |
yes, no |
| Default: |
no |
Description: If set to yes, AxoSyslog converts every mapped value to string, discarding the type information of the name-value pairs. By default, map-value-pairs() retains the type of the values.
exclude()
Description: Excludes the name-value pairs matching the specified glob patterns from the mapping. For details, see exclude().
include-bytes()
|
|
| Accepted values: |
yes, no |
| Default: |
no |
Description: If set to yes, AxoSyslog also maps the name-value pairs that have the bytes or protobuf type. By default, these are skipped.
key()
Description: Selects the name-value pairs to map, using glob patterns. You can combine it with rekey() to rename the selected name-value pairs. For details, see key().
pair()
Description: Adds a new name-value pair with the specified name and value. The value can be a template or a template function. For details, see pair().
rekey()
Description: Renames the selected name-value pairs, for example, by adding or replacing a prefix, changing the case of the names, or removing levels from the names. For details, see rekey().
scope()
Description: Selects a predefined group of name-value pairs to map, for example, nv-pairs or all-nv-pairs. For details, see scope().
12 - Conditional rewrites
Starting with 3.2, it is possible to apply a rewrite rule to a message only if certain conditions are met. The condition() option effectively embeds a filter expression into the rewrite rule: the message is modified only if the message passes the filter. If the condition is not met, the message is passed to the next element of the log path (that is, the element following the rewrite rule in the log statement, for example, the destination). Any filter expression normally used in filters can be used as a rewrite condition. Existing filter statements can be referenced using the filter() function within the condition. For details on filters, see Filters.
Note
Using conditions in rewrite rules can simplify your AxoSyslog configuration file, as you do not need to create separate log paths to modify certain messages.
See also the equivalent FilterX construct, conditional statements. Use an if statement to match the behavior of condition(): a bare comparison statement drops the messages that do not match it, while condition() passes them on unmodified.
Using conditional rewrite
The following procedure summarizes how conditional rewrite rules (rewrite rules that have the condition() parameter set) work. The following configuration snippet is used to illustrate the procedure:
rewrite r_rewrite_set{
set(
"myhost",
value("HOST")
condition(program("myapplication"))
);
};
log {
source(s1);
rewrite(r_rewrite_set);
destination(d1);
};
- The log path receives a message from the source (
s1).
- The rewrite rule (
r_rewrite_set) evaluates the condition. If the message matches the condition (the PROGRAM field of the message is myapplication), AxoSyslog rewrites the log message (sets the value of the HOST field to myhost), otherwise it is not modified.
- The next element of the log path processes the message (
d1).
Example: Using conditional rewriting
The following example sets the HOST field of the message to myhost only if the message was sent by the myapplication program.
rewrite r_rewrite_set{set("myhost", value("HOST") condition(program("myapplication")));};
The following example is identical to the previous one, except that the condition references an existing filter template.
filter f_rewritefilter {program("myapplication");};
rewrite r_rewrite_set{set("myhost", value("HOST") condition(filter(f_rewritefilter)));};
13 - Add and delete tags
To add or delete a tag, you can use rewrite rules. To add a tag, use the following syntax:
rewrite <name_of_the_rule> {
set-tag("<tag-to-add>");
};
To delete a tag, use the following syntax:
rewrite <name_of_the_rule> {
clear-tag("<tag-to-delete>");
};
Templates (macros, template functions) can be used when specifying tags, for example, set-tag("dyn::$HOST");.
Options
The set-tag() and clear-tag() rewrite rules have the following option.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
14 - Rewrite the timezone of a message
Starting with version 3.24 of the AxoSyslog application, you can manipulate the timezone information of messages using rewrite rules. You can:
By default, these operations modify the date-related macros of the message that correspond to the date the message was sent (that is, the S_ macros). You can modify the dates when AxoSyslog has received the messages (that is, the R_ macros), but this is rarely needed. To do so, include the time-stamp(recvd) option in the operation, for example:
rewrite { fix-time-zone("EST5EDT" time-stamp(recvd)); };
If you’re using FilterX, see also the equivalent set_timezone() function.
fix-time-zone()
Use the fix-time-zone() operation to correct the timezone of a message if it was parsed incorrectly for some reason, or if the client did not include any timezone information in the message. You can specify the new timezone as the name of a timezone, or as a template string. For example, use the following rewrite rule to set the timezone to EST5EDT:
rewrite { fix-time-zone("EST5EDT"); };
If you have lots of clients that do not send timezone information in the log messages, you can create a database file that stores the timezone of the clients, and feed this data to AxoSyslog using the add-contextual-data() feature. For details, see Adding metadata from an external file.
See also the equivalent FilterX function, fix_timezone().
guess-time-zone()
Use the guess-time-zone() operation attempts to set the timezone of the message automatically, using heuristics on the timestamps. Normally the AxoSyslog application performs this operation automatically when it parses the incoming message. Using this operation in a rewrite rule can be useful if you cannot parse the incoming message for some reason (and use the flags(no-parse) option in your source, but you want to set the timezone automatically later (for example, after you have preprocessed the message).
Using this operation is identical to using the flags(guess-timezone) flag in the source.
See also the equivalent FilterX function, guess_timezone().
set-time-zone()
Use the set-time-zone() operation to set the timezone of the message to a specific value, that is to convert an existing timezone to a different one. This operation is identical to setting the time-zone() option in a destination or as a global option, but can be applied selectively to the messages using conditions.
Options
The fix-time-zone(), guess-time-zone(), and set-time-zone() rewrite rules have the following options.
<!-- This file is under the copyright of Axoflow, and licensed under Apache License 2.0, except for using the Axoflow and AxoSyslog trademarks. -->
condition()
|
|
| Type: |
filter expression |
| Default: |
N/A |
Description: Applies the rewrite rule only to the messages that match the specified filter expression. Messages that don’t match the filter pass through the rule unmodified, and continue to the next element of the log path. You can use any filter expression here, and you can reference an existing filter with the filter() function. For details, see Conditional rewrites.
time-stamp()
|
|
| Type: |
stamp, recvd |
| Default: |
stamp |
Description: Selects the timestamp that the rule modifies. With time-stamp(stamp), the rule changes the date the message was sent, that is, the S_ macros. With time-stamp(recvd), it changes the date AxoSyslog received the message, that is, the R_ macros.
15 - Anonymize credit card numbers
Log messages of banking and e-commerce applications might include credit card numbers (Primary Account Number or PAN). According to privacy best practices and the requirements of the Payment Card Industry Data Security Standards (PCI-DSS), PAN must be rendered unreadable. The AxoSyslog application uses a regular expression to detect credit card numbers, and provides two ways to accomplish this: you can either mask the credit card numbers, or replace them with a hash. To mask the credit card numbers, use the credit-card-mask() or the credit-card-hash() rewrite rules in a log path.
Declaration
@include "scl/rewrite/cc-mask.conf"
rewrite {
credit-card-mask(value("<message-field-to-process>"));
};
By default, these rewrite rules process the MESSAGE part of the log message.
credit-card-hash()
|
|
| Synopsis: |
credit-card-hash(value("")) |
Description: Process the specified message field (by default, ${MESSAGE}), and replace any credit card numbers (Primary Account Number or PAN) with a 16-character-long hash. This hash is generated by calculating the SHA-1 hash of the credit card number, selecting the first 64 bits of this hash, and representing this 64 bits in 16 characters.
credit-card-mask()
|
|
| Synopsis: |
credit-card-mask(value("")) |
Description: Process the specified message field (by default, ${MESSAGE}), and replace the 7-12th character of any credit card numbers (Primary Account Number or PAN) with asterisks (*). For example, AxoSyslog replaces the number 5542043004559005 with 554204******9005.