Skip to content

Commit 011852a

Browse files
committed
feat: support custom templates
Feature: Allow users to specify custom templates to use for `files` and `forwards` outputs. Users can specify a list of templates to use with `logging_custom_templates`. Users can specify the default template to use for all `files` outputs with `logging_files_template_format`, or specify on a per output basis by using `template`. Users can specify the default template to use for all `forwards` outputs with `logging_forwards_template_format`, or specify on a per output basis by using `template`. Reason: Users need the ability to format log entries in different ways other than the built-in defaults, using custom templates. Result: Users can specify custom templates to use for files and forwards outputs. Signed-off-by: Rich Megginson <rmeggins@redhat.com>
1 parent fb5e6f6 commit 011852a

14 files changed

Lines changed: 132 additions & 12 deletions

File tree

.ansible-lint

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
profile: production
33
kinds:
4+
- tasks: "**/tasks/*.yml"
45
- yaml: "**/meta/collection-requirements.yml"
56
- playbook: "**/tests/get_coverage.yml"
67
- yaml: "**/tests/collection-requirements.yml"

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,42 @@ Available options:
214214
tcp_ports: [1514]
215215
```
216216

217+
### logging_custom_templates
218+
219+
`logging_custom_templates`: A list of custom template definitions, for use with
220+
`logging_outputs` `type` `files` and `type` `forwards`. You can specify the
221+
template for a particular output to use by setting the `template` field in a
222+
particular `logging_outputs` specification, or by setting the default for all
223+
such outputs to use in `logging_files_template_format` and
224+
`logging_forwards_template_format`.
225+
226+
Specify custom templates like this, in either the legacy format or the new style
227+
format:
228+
229+
```yaml
230+
logging_custom_templates:
231+
- |
232+
template(name="tpl1" type="list") {
233+
constant(value="Syslog MSG is: '")
234+
property(name="msg")
235+
constant(value="', ")
236+
property(name="timereported" dateFormat="rfc3339" caseConversion="lower")
237+
constant(value="\n")
238+
}
239+
- >-
240+
$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated::fulltime%,%HOSTNAME%,%syslogtag%,%msg%\n"
241+
```
242+
243+
Then use like this:
244+
245+
```yaml
246+
logging_outputs:
247+
- name: custom_file_output
248+
type: files
249+
path: /var/log/custom_file_output.log
250+
template: tpl1 # override logging_files_template_format if set
251+
```
252+
217253
### Logging_outputs options
218254

219255
`logging_outputs`: A list of following dictionary to configure outputs.
@@ -285,8 +321,6 @@ Available options:
285321
* `property_op`: Operation in property-based filter; In case of not `!`, put the `property_op` value in quotes; default to `contains`
286322
* `property_value`: Value in property-based filter; default to `error`
287323
* `path`: Path to the output file.
288-
* `logging_files_template_format`: Set default template for the files output.
289-
Allowed values are `traditional`, `syslog`, and `modern`. Default to `modern`.
290324
* File/Directory properties - same as corresponding variables of the Ansible `file` module:
291325
* `mode` - sets the rsyslog `omfile` module `FileCreateMode` parameter
292326
* `owner` - sets the rsyslog `omfile` module `fileOwner` or `fileOwnerNum` parameter. If the value
@@ -298,6 +332,15 @@ Available options:
298332
is an integer, set `dirOwnerNum`, otherwise, set `dirOwner`.
299333
* `dir_group` - sets the rsyslog `omfile` module `dirGroup` or `dirGroupNum` parameter. If the value
300334
is an integer, set `dirGroupNum`, otherwise, set `dirGroup`.
335+
* `template`: Template format for the particular files output. Allowed values
336+
are `traditional`, `syslog`, and `modern`, or one of the templates defined in
337+
`logging_custom_templates`. Default to `modern`.
338+
339+
Global options:
340+
341+
`logging_files_template_format`: Set default template for the files output.
342+
Allowed values are `traditional`, `syslog`, and `modern`, or one of the
343+
templates defined in `logging_custom_templates`. Default to `modern`.
301344

302345
**Note:** Selector options and property-based filter options are exclusive. If Property-based filter options are defined, selector options will be ignored.
303346

@@ -332,10 +375,15 @@ Available options:
332375
* `tls`: Set to `true` to encrypt the connection using the default TLS implementation used by the provider. Default to `false`.
333376
* `pki_authmode`: Specifying the default network driver authentication mode. `x509/name`, `x509/fingerprint`, or `anon` is accepted. Default to `x509/name`.
334377
* `permitted_server`: Hostname, IP address, fingerprint(sha1) or wildcard DNS domain of the server which this client will be allowed to connect and send logs over TLS. Default to `*.{{ logging_domain }}`
335-
* `template`: Template format for the particular forwards output. Allowed values are `traditional`, `syslog`, and `modern`. Default to `modern`.
378+
* `template`: Template format for the particular forwards output. Allowed values
379+
are `traditional`, `syslog`, and `modern`, or one of the templates defined in
380+
`logging_custom_templates`. Default to `modern`.
381+
382+
Global options:
336383

337-
logging_forwards_template_format: Set default template for the forwards output.
338-
Allowed values are `traditional`, `syslog`, and `modern`. Default to `modern`.
384+
`logging_forwards_template_format`: Set default template for the forwards
385+
output. Allowed values are `traditional`, `syslog`, and `modern`, or one of the
386+
templates defined in `logging_custom_templates`. Default to `modern`.
339387

340388
**Note:** Selector options and property-based filter options are exclusive. If Property-based filter options are defined, selector options will be ignored.
341389

defaults/main.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ logging_custom_config_files: []
115115
# ca: self-sign
116116
logging_certificates: []
117117

118+
# logging_custom_templates
119+
#
120+
# List of custom templates to provide
121+
# Each element is the string definition of
122+
# an rsyslog output template as defined here:
123+
# https://www.rsyslog.com/doc/configuration/templates.html
124+
logging_custom_templates: []
125+
118126
# ansible_facts required by the role
119127
__logging_required_facts:
120128
- distribution

roles/rsyslog/defaults/main.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,11 @@ rsyslog_extra_packages: []
3131
# List of additional custom config files.
3232
# Each element: full paths to the files to be deployed.
3333
rsyslog_custom_config_files: []
34+
35+
# rsyslog_custom_templates
36+
#
37+
# List of custom templates to provide
38+
# Each element is the string definition of
39+
# an rsyslog output template as defined here:
40+
# https://www.rsyslog.com/doc/configuration/templates.html
41+
rsyslog_custom_templates: []

roles/rsyslog/tasks/main_core.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@
125125
options: |-
126126
$RepeatedMsgReduction {{ "on"
127127
if rsyslog_message_reduction | bool else "off" }}
128+
- name: 'templates'
129+
type: 'templates'
130+
sections:
131+
- comment: 'User provided output templates'
132+
options: "{{ lookup('template', 'custom_templates.j2') }}"
128133
set_fact:
129134
__rsyslog_common_rules: "{{ __rsyslog_global_common_rule }}"
130135

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% for template in rsyslog_custom_templates %}
2+
{{ template }}
3+
{% endfor %}

roles/rsyslog/templates/output_files.j2

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,19 @@ ruleset(name="{{ __rsyslog_output.name }}"
4242
ruleset(name="{{ __rsyslog_output.name }}") {
4343
{% endif %}
4444
{{ print_file_attrs(__rsyslog_output) -}}
45+
{% set template = " ;RSYSLOG_TraditionalFileFormat"
46+
if __rsyslog_output.template | d("") == "traditional"
47+
else " ;RSYSLOG_SyslogProtocol23Format"
48+
if __rsyslog_output.template | d("") == "syslog"
49+
else " ;" ~ __rsyslog_output.template
50+
if __rsyslog_output.template | d("") not in ["", "modern"]
51+
else "" %}
4552
{% if __rsyslog_output.property | d() %}
46-
:{{ __rsyslog_output.property }}, {{ __rsyslog_output.property_op | d('contains') }}, "{{ __rsyslog_output.property_value | d('error') }}" {{ __rsyslog_output.path }}
53+
:{{ __rsyslog_output.property }}, {{ __rsyslog_output.property_op | d('contains') }}, "{{ __rsyslog_output.property_value | d('error') }}" {{ __rsyslog_output.path }}{{ template }}
4754
{% elif __rsyslog_output.exclude | d([]) %}
48-
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }};{{ __rsyslog_output.exclude | join(';') }} {{ __rsyslog_output.path }}
55+
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }};{{ __rsyslog_output.exclude | join(';') }} {{ __rsyslog_output.path }}{{ template }}
4956
{% else %}
50-
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }} {{ __rsyslog_output.path }}
57+
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }} {{ __rsyslog_output.path }}{{ template }}
5158
{% endif %}
5259
}
5360
{% else %}

roles/rsyslog/templates/output_forwards.j2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ ruleset(name="{{ __rsyslog_output.name }}") {
3434
Template="RSYSLOG_TraditionalForwardFormat"
3535
{% elif __rsyslog_output.template | d('') == 'syslog' %}
3636
Template="RSYSLOG_SyslogProtocol23Format"
37-
{% else %}
37+
{% elif __rsyslog_output.template | d('modern') == 'modern' %}
3838
Template="RSYSLOG_ForwardFormat"
39+
{% else %}
40+
Template="{{ __rsyslog_output.template }}"
3941
{% endif %}
4042
{% if __rsyslog_output.action is defined %}
4143
{{ lookup('template', 'general_action_params.j2') | indent(8) | trim }}

roles/rsyslog/templates/output_relp.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ ruleset(name="{{ __rsyslog_output.name }}") {
4141
{% else %}
4242
tls.permittedpeer=["{{ '*.' + logging_domain }}"]
4343
{% endif %}
44+
{% if __rsyslog_output.template | d("") | length > 0 %}
45+
template="{{ __rsyslog_output.template }}"
46+
{% endif %}
4447
{% endif %}
4548
)
4649
}

roles/rsyslog/templates/output_remote_files.j2

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,19 @@ ruleset(name="{{ __rsyslog_output.name }}"
3232
{{ lookup('template', 'general_queue_params.j2') | indent(8) | trim }}
3333
{% endif %}) {
3434
# Store remote logs in separate logfiles
35+
{% set template = ' template="RSYSLOG_TraditionalFileFormat"'
36+
if __rsyslog_output.template | d("") == "traditional"
37+
else ' template="RSYSLOG_SyslogProtocol23Format"'
38+
if __rsyslog_output.template | d("") == "syslog"
39+
else ' template="' ~ __rsyslog_output.template ~ '"'
40+
if __rsyslog_output.template | d("") not in ["", "modern"]
41+
else "" %}
3542
{% if __rsyslog_output.property | d() %}
36-
:{{ __rsyslog_output.property }}, {{ __rsyslog_output.property_op | d('contains') }}, "{{ __rsyslog_output.property_value | d('error') }}" action(name="{{ __rsyslog_output.name }}" type="omfile" DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
43+
:{{ __rsyslog_output.property }}, {{ __rsyslog_output.property_op | d('contains') }}, "{{ __rsyslog_output.property_value | d('error') }}" action(name="{{ __rsyslog_output.name }}" type="omfile"{{ template }} DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
3744
{% elif __rsyslog_output.exclude | d([]) %}
38-
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }};{{ __rsyslog_output.exclude | join(';') }} action(name="{{ __rsyslog_output.name }}" type="omfile" DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
45+
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }};{{ __rsyslog_output.exclude | join(';') }} action(name="{{ __rsyslog_output.name }}" type="omfile"{{ template }} DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
3946
{% else %}
40-
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }} action(name="{{ __rsyslog_output.name }}" type="omfile" DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
47+
{{ __rsyslog_output.facility | d('*') }}.{{ __rsyslog_output.severity | d('*') }} action(name="{{ __rsyslog_output.name }}" type="omfile"{{ template }} DynaFile="{{ __rsyslog_output.name }}_template" DynaFileCacheSize="{{ __rsyslog_output.client_count | d(10) }}" ioBufferSize="{{ __rsyslog_output.io_buffer_size | d('65536') }}" asyncWriting="{{ 'on' if __rsyslog_output.async_writing | d(false) | bool else 'off' }}"{{ lookup('template', 'general_action_params.j2') | indent(1,true) | regex_replace("\s?\n","") }})
4148
{% endif %}
4249
}
4350
{% else %}

0 commit comments

Comments
 (0)