mirror of https://github.com/caronc/apprise
syslog://facility url support added
parent
aee893152c
commit
ccc9aba55a
|
@ -124,16 +124,25 @@ class NotifySyslog(NotifyBase):
|
||||||
|
|
||||||
# Define object templates
|
# Define object templates
|
||||||
templates = (
|
templates = (
|
||||||
'{schema}://_/',
|
'{schema}://',
|
||||||
|
'{schema}://{facility}',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Define our template tokens
|
||||||
|
template_tokens = dict(NotifyBase.template_tokens, **{
|
||||||
|
'facility': {
|
||||||
|
'name': _('Facility'),
|
||||||
|
'type': 'choice:string',
|
||||||
|
'values': [k for k in SYSLOG_FACILITY_MAP.keys()],
|
||||||
|
'default': SyslogFacility.USER,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
# Define our template arguments
|
# Define our template arguments
|
||||||
template_args = dict(NotifyBase.template_args, **{
|
template_args = dict(NotifyBase.template_args, **{
|
||||||
'facility': {
|
'facility': {
|
||||||
'name': _('Facility'),
|
# We map back to the same element defined in template_tokens
|
||||||
'type': 'choice:int',
|
'alias_of': 'facility',
|
||||||
'values': [k for k in SYSLOG_FACILITY_MAP.keys()],
|
|
||||||
'default': SyslogFacility.USER,
|
|
||||||
},
|
},
|
||||||
'logpid': {
|
'logpid': {
|
||||||
'name': _('Log PID'),
|
'name': _('Log PID'),
|
||||||
|
@ -168,7 +177,7 @@ class NotifySyslog(NotifyBase):
|
||||||
else:
|
else:
|
||||||
self.facility = \
|
self.facility = \
|
||||||
SYSLOG_FACILITY_MAP[
|
SYSLOG_FACILITY_MAP[
|
||||||
self.template_args['facility']['default']]
|
self.template_tokens['facility']['default']]
|
||||||
|
|
||||||
# Logging Options
|
# Logging Options
|
||||||
self.logoptions = 0
|
self.logoptions = 0
|
||||||
|
@ -230,12 +239,13 @@ class NotifySyslog(NotifyBase):
|
||||||
'logpid': 'yes' if self.log_pid else 'no',
|
'logpid': 'yes' if self.log_pid else 'no',
|
||||||
'format': self.notify_format,
|
'format': self.notify_format,
|
||||||
'overflow': self.overflow_mode,
|
'overflow': self.overflow_mode,
|
||||||
'facility': 'info' if self.facility not in SYSLOG_FACILITY_RMAP
|
|
||||||
else SYSLOG_FACILITY_RMAP[self.facility],
|
|
||||||
'verify': 'yes' if self.verify_certificate else 'no',
|
'verify': 'yes' if self.verify_certificate else 'no',
|
||||||
}
|
}
|
||||||
|
|
||||||
return '{schema}://_/?{args}'.format(
|
return '{schema}://{facility}/?{args}'.format(
|
||||||
|
facility=self.template_tokens['facility']['default']
|
||||||
|
if self.facility not in SYSLOG_FACILITY_RMAP
|
||||||
|
else SYSLOG_FACILITY_RMAP[self.facility],
|
||||||
schema=self.secure_protocol,
|
schema=self.secure_protocol,
|
||||||
args=NotifySyslog.urlencode(args),
|
args=NotifySyslog.urlencode(args),
|
||||||
)
|
)
|
||||||
|
@ -251,17 +261,26 @@ class NotifySyslog(NotifyBase):
|
||||||
if not results:
|
if not results:
|
||||||
return results
|
return results
|
||||||
|
|
||||||
if 'facility' in results['qsd'] and len(results['qsd']['facility']):
|
# if specified; save hostname into facility
|
||||||
key = results['qsd']['facility'].lower()
|
facility = None if not results['host'] \
|
||||||
|
else NotifySyslog.unquote(results['host'])
|
||||||
|
|
||||||
|
# However if specified on the URL, that will over-ride what was
|
||||||
|
# identified
|
||||||
|
if 'facility' in results['qsd'] and len(results['qsd']['facility']):
|
||||||
|
facility = results['qsd']['facility'].lower()
|
||||||
|
|
||||||
|
if facility and facility not in SYSLOG_FACILITY_MAP:
|
||||||
# Find first match; if no match is found we set the result
|
# Find first match; if no match is found we set the result
|
||||||
# to the matching key. This allows us to throw a TypeError
|
# to the matching key. This allows us to throw a TypeError
|
||||||
# during the __init__() call. The benifit of doing this
|
# during the __init__() call. The benifit of doing this
|
||||||
# check here is if we do have a valid match, we can support
|
# check here is if we do have a valid match, we can support
|
||||||
# short form matches like 'u' which will match against user
|
# short form matches like 'u' which will match against user
|
||||||
results['facility'] = \
|
facility = next((f for f in SYSLOG_FACILITY_MAP.keys()
|
||||||
next((f for f in SYSLOG_FACILITY_MAP.keys()
|
if f.startswith(facility)), facility)
|
||||||
if f.startswith(key)), key)
|
|
||||||
|
# Save facility
|
||||||
|
results['facility'] = facility
|
||||||
|
|
||||||
# Include PID as part of the message logged
|
# Include PID as part of the message logged
|
||||||
results['log_pid'] = \
|
results['log_pid'] = \
|
||||||
|
|
|
@ -45,16 +45,18 @@ def test_notify_syslog_by_url(openlog, syslog):
|
||||||
assert apprise.plugins.NotifySyslog.parse_url(42) is None
|
assert apprise.plugins.NotifySyslog.parse_url(42) is None
|
||||||
assert apprise.plugins.NotifySyslog.parse_url(None) is None
|
assert apprise.plugins.NotifySyslog.parse_url(None) is None
|
||||||
|
|
||||||
assert isinstance(
|
obj = apprise.Apprise.instantiate('syslog://')
|
||||||
apprise.Apprise.instantiate('syslog://'), apprise.plugins.NotifySyslog)
|
assert obj.url().startswith('syslog://user') is True
|
||||||
|
assert re.search(r'logpid=yes', obj.url()) is not None
|
||||||
|
assert re.search(r'logperror=no', obj.url()) is not None
|
||||||
|
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
apprise.Apprise.instantiate(
|
apprise.Apprise.instantiate(
|
||||||
'syslog://:@/'), apprise.plugins.NotifySyslog)
|
'syslog://:@/'), apprise.plugins.NotifySyslog)
|
||||||
|
|
||||||
obj = apprise.Apprise.instantiate('syslog://_/?logpid=no&logperror=yes')
|
obj = apprise.Apprise.instantiate('syslog://?logpid=no&logperror=yes')
|
||||||
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
assert re.search(r'facility=user', obj.url()) is not None
|
assert obj.url().startswith('syslog://user') is True
|
||||||
assert re.search(r'logpid=no', obj.url()) is not None
|
assert re.search(r'logpid=no', obj.url()) is not None
|
||||||
assert re.search(r'logperror=yes', obj.url()) is not None
|
assert re.search(r'logperror=yes', obj.url()) is not None
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ def test_notify_syslog_by_url(openlog, syslog):
|
||||||
|
|
||||||
obj = apprise.Apprise.instantiate('syslog://_/?facility=local5')
|
obj = apprise.Apprise.instantiate('syslog://_/?facility=local5')
|
||||||
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
assert re.search(r'facility=local5', obj.url()) is not None
|
assert obj.url().startswith('syslog://local5') is True
|
||||||
assert re.search(r'logpid=yes', obj.url()) is not None
|
assert re.search(r'logpid=yes', obj.url()) is not None
|
||||||
assert re.search(r'logperror=no', obj.url()) is not None
|
assert re.search(r'logperror=no', obj.url()) is not None
|
||||||
|
|
||||||
|
@ -76,10 +78,22 @@ def test_notify_syslog_by_url(openlog, syslog):
|
||||||
# j will cause a search to take place and match to daemon
|
# j will cause a search to take place and match to daemon
|
||||||
obj = apprise.Apprise.instantiate('syslog://_/?facility=d')
|
obj = apprise.Apprise.instantiate('syslog://_/?facility=d')
|
||||||
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
assert re.search(r'facility=daemon', obj.url()) is not None
|
assert obj.url().startswith('syslog://daemon') is True
|
||||||
assert re.search(r'logpid=yes', obj.url()) is not None
|
assert re.search(r'logpid=yes', obj.url()) is not None
|
||||||
assert re.search(r'logperror=no', obj.url()) is not None
|
assert re.search(r'logperror=no', obj.url()) is not None
|
||||||
|
|
||||||
|
# Facility can also be specified on the url as a hostname
|
||||||
|
obj = apprise.Apprise.instantiate('syslog://kern?logpid=no&logperror=y')
|
||||||
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
|
assert obj.url().startswith('syslog://kern') is True
|
||||||
|
assert re.search(r'logpid=no', obj.url()) is not None
|
||||||
|
assert re.search(r'logperror=yes', obj.url()) is not None
|
||||||
|
|
||||||
|
# Facilities specified as an argument always over-ride host
|
||||||
|
obj = apprise.Apprise.instantiate('syslog://kern?facility=d')
|
||||||
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
|
assert obj.url().startswith('syslog://daemon') is True
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('syslog.syslog')
|
@mock.patch('syslog.syslog')
|
||||||
@mock.patch('syslog.openlog')
|
@mock.patch('syslog.openlog')
|
||||||
|
@ -92,7 +106,7 @@ def test_notify_syslog_by_class(openlog, syslog):
|
||||||
# Default
|
# Default
|
||||||
obj = apprise.plugins.NotifySyslog(facility=None)
|
obj = apprise.plugins.NotifySyslog(facility=None)
|
||||||
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
assert isinstance(obj, apprise.plugins.NotifySyslog)
|
||||||
assert re.search(r'facility=user', obj.url()) is not None
|
assert obj.url().startswith('syslog://user') is True
|
||||||
assert re.search(r'logpid=yes', obj.url()) is not None
|
assert re.search(r'logpid=yes', obj.url()) is not None
|
||||||
assert re.search(r'logperror=no', obj.url()) is not None
|
assert re.search(r'logperror=no', obj.url()) is not None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue