Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F118310231
syslog.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
syslog.py
View Options
#!/usr/bin/env python3
#
# Copyright (C) 2018 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
import
sys
import
os
import
re
import
jinja2
from
vyos.config
import
Config
from
vyos
import
ConfigError
########### config templates
#### /etc/rsyslog.d/vyos-rsyslog.conf ###
configs
=
'''
## generated by syslog.py ##
## file based logging
{% for file in files %}
$outchannel {{file}},{{files[file]['log-file']}},{{files[file]['max-size']}},{{files[file]['action-on-max-size']}}
{{files[file]['selectors']}} :omfile:${{file}}
{% endfor %}
{% if console %}
## console logging
{% for con in console %}
{{console[con]['selectors']}} /dev/console
{% endfor %}
{% endif %}
{% if hosts %}
## remote logging
{% for host in hosts %}
{% if hosts[host]['proto'] == 'tcp' %}
{{hosts[host]['selectors']}} @@{{host}}
{% else %}
{{hosts[host]['selectors']}} @{{host}}
{% endif %}
{% endfor %}
{% endif %}
{% if user %}
{% for u in user %}
{{user[u]['selectors']}} :omusrmsg:{{u}}
{% endfor %}
{% endif %}
'''
logrotate_configs
=
'''
{% for file in files %}
{{files[file]['log-file']}} {
missingok
notifempty
create
rotate {{files[file]['max-files']}}
size={{ files[file]['max-size']//1024}}k
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
{% endfor %}
'''
############# config templates end
def
get_config
():
c
=
Config
()
if
not
c
.
exists
(
'system syslog'
):
return
None
c
.
set_level
(
'system syslog'
)
config_data
=
{
'files'
:
{},
'console'
:
{},
'hosts'
:
{},
'user'
:
{}
}
#####
# /etc/rsyslog.d/vyos-rsyslog.conf
# 'set system syslog global'
#####
config_data
[
'files'
]
.
update
(
{
'global'
:
{
'log-file'
:
'/var/log/vyos-rsyslog'
,
'max-size'
:
262144
,
'action-on-max-size'
:
'/usr/sbin/logrotate /etc/logrotate.d/vyos-rsyslog'
,
'selectors'
:
'*.notice;local7.debug'
,
'max-files'
:
'5'
}
}
)
if
c
.
exists
(
'global facility'
):
config_data
[
'files'
][
'global'
][
'selectors'
]
=
generate_selectors
(
c
,
'global facility'
)
if
c
.
exists
(
'global archive size'
):
config_data
[
'files'
][
'global'
][
'max-size'
]
=
int
(
c
.
return_value
(
'global archive size'
))
*
1024
if
c
.
exists
(
'global archive files'
):
config_data
[
'files'
][
'global'
][
'max-files'
]
=
c
.
return_value
(
'global archive files'
)
###
# set system syslog file
###
if
c
.
exists
(
'file'
):
filenames
=
c
.
list_nodes
(
'file'
)
for
filename
in
filenames
:
config_data
[
'files'
]
.
update
(
{
filename
:
{
'log-file'
:
'/var/log/user/'
+
filename
,
'max-files'
:
'5'
,
'action-on-max-size'
:
'/usr/sbin/logrotate /etc/logrotate.d/'
+
filename
,
'selectors'
:
'*.err'
,
'max-size'
:
262144
}
}
)
if
c
.
exists
(
'file '
+
filename
+
' facility'
):
config_data
[
'files'
][
filename
][
'selectors'
]
=
generate_selectors
(
c
,
'file '
+
filename
+
' facility'
)
if
c
.
exists
(
'file '
+
filename
+
' archive size'
):
config_data
[
'files'
][
filename
][
'max-size'
]
=
int
(
c
.
return_value
(
'file '
+
filename
+
' archive size'
))
*
1024
if
c
.
exists
(
'file '
+
filename
+
' archive files'
):
config_data
[
'files'
][
filename
][
'max-files'
]
=
c
.
return_value
(
'file '
+
filename
+
' archive files'
)
## set system syslog console
if
c
.
exists
(
'console'
):
config_data
[
'console'
]
=
{
'/dev/console'
:
{
'selectors'
:
'*.err'
}
}
for
f
in
c
.
list_nodes
(
'console facility'
):
if
c
.
exists
(
'console facility '
+
f
+
' level'
):
config_data
[
'console'
]
=
{
'/dev/console'
:
{
'selectors'
:
generate_selectors
(
c
,
'console facility'
)
}
}
## set system syslog host
if
c
.
exists
(
'host'
):
rhosts
=
c
.
list_nodes
(
'host'
)
for
rhost
in
rhosts
:
for
fac
in
c
.
list_nodes
(
'host '
+
rhost
+
' facility'
):
if
c
.
exists
(
'host '
+
rhost
+
' facility '
+
fac
+
' protocol'
):
proto
=
c
.
return_value
(
'host '
+
rhost
+
' facility '
+
fac
+
' protocol'
)
else
:
proto
=
'udp'
config_data
[
'hosts'
]
.
update
(
{
rhost
:
{
'selectors'
:
generate_selectors
(
c
,
'host '
+
rhost
+
' facility'
),
'proto'
:
proto
}
}
)
## set system syslog user
if
c
.
exists
(
'user'
):
usrs
=
c
.
list_nodes
(
'user'
)
for
usr
in
usrs
:
config_data
[
'user'
]
.
update
(
{
usr
:
{
'selectors'
:
generate_selectors
(
c
,
'user '
+
usr
+
' facility'
)
}
}
)
return
config_data
def
generate_selectors
(
c
,
config_node
):
## protocols and security are being mapped here
## for backward compatibility with old configs
## security and protocol mappings can be removed later
if
c
.
is_tag
(
config_node
):
nodes
=
c
.
list_nodes
(
config_node
)
selectors
=
""
for
node
in
nodes
:
lvl
=
c
.
return_value
(
config_node
+
' '
+
node
+
' level'
)
if
lvl
==
None
:
lvl
=
"err"
if
lvl
==
'all'
:
lvl
=
'*'
if
node
==
'all'
and
node
!=
nodes
[
-
1
]:
selectors
+=
"*."
+
lvl
+
";"
elif
node
==
'all'
:
selectors
+=
"*."
+
lvl
elif
node
!=
nodes
[
-
1
]:
if
node
==
'protocols'
:
node
=
'local7'
if
node
==
'security'
:
node
=
'auth'
selectors
+=
node
+
"."
+
lvl
+
";"
else
:
if
node
==
'protocols'
:
node
=
'local7'
if
node
==
'security'
:
node
=
'auth'
selectors
+=
node
+
"."
+
lvl
return
selectors
def
generate
(
c
):
tmpl
=
jinja2
.
Template
(
configs
,
trim_blocks
=
True
)
config_text
=
tmpl
.
render
(
c
)
#print (config_text)
with
open
(
'/etc/rsyslog.d/vyos-rsyslog.conf'
,
'w'
)
as
f
:
f
.
write
(
config_text
)
## eventually write for each file its own logrotate file, since size is defined it shouldn't matter
tmpl
=
jinja2
.
Template
(
logrotate_configs
,
trim_blocks
=
True
)
config_text
=
tmpl
.
render
(
c
)
#print (config_text)
with
open
(
'/etc/logrotate.d/vyos-rsyslog'
,
'w'
)
as
f
:
f
.
write
(
config_text
)
def
verify
(
c
):
if
c
==
None
:
return
None
fac
=
[
'*'
,
'auth'
,
'authpriv'
,
'cron'
,
'daemon'
,
'kern'
,
'lpr'
,
'mail'
,
'mark'
,
'news'
,
'protocols'
,
'security'
,
\
'syslog'
,
'user'
,
'uucp'
,
'local0'
,
'local1'
,
'local2'
,
'local3'
,
'local4'
,
'local5'
,
'local6'
,
'local7'
]
lvl
=
[
'emerg'
,
'alert'
,
'crit'
,
'err'
,
'warning'
,
'notice'
,
'info'
,
'debug'
,
'*'
]
for
conf
in
c
:
if
c
[
conf
]:
for
item
in
c
[
conf
]:
for
s
in
c
[
conf
][
item
][
'selectors'
]
.
split
(
";"
):
f
=
re
.
sub
(
"\..*$"
,
""
,
s
)
if
f
not
in
fac
:
print
(
c
[
conf
])
raise
ConfigError
(
'Invalid facility '
+
s
+
' set in '
+
conf
+
' '
+
item
)
l
=
re
.
sub
(
"^.+\."
,
""
,
s
)
if
l
not
in
lvl
:
raise
ConfigError
(
'Invalid logging level '
+
s
+
' set in '
+
conf
+
' '
+
item
)
def
apply
(
c
):
### vyatta-log.conf is being generated somewhere
### this is just a quick hack to remove the old configfile
if
os
.
path
.
exists
(
'/etc/rsyslog.d/vyatta-log.conf'
):
os
.
remove
(
'/etc/rsyslog.d/vyatta-log.conf'
)
os
.
system
(
"sudo systemctl restart rsyslog >/dev/null"
)
if
__name__
==
'__main__'
:
try
:
c
=
get_config
()
verify
(
c
)
generate
(
c
)
apply
(
c
)
except
ConfigError
as
e
:
print
(
e
)
sys
.
exit
(
1
)
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Sat, Oct 17, 12:56 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4376533
Default Alt Text
syslog.py (7 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment