-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
247 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Monitoring Logging | ||
This library provides utilities for initializing logging that is check friendly and simple to deploy and manage, the logger used is loguru. | ||
|
||
## Constants | ||
`DEFAULT_LOG_LEVELS = ['TRACE', 'DEBUG', 'INFO', 'SUCCESS', 'WARNING', 'ERROR', 'CRITICAL']`: List of valid logging levels used to validate logging level supplied. Append to this last and pass it to initization if you add custom logging levels. | ||
|
||
## Functions | ||
### initLogging() | ||
Initization of the logging with sensible defaults and output format for monitoring checks. | ||
|
||
The function performs the following tasks: | ||
|
||
1. Removes existing loggers. | ||
1. Adds a screen logger to standard error if `enable_screen_debug` is `True`. | ||
1. Adds a file logger with rotation and retention policies if `enable_log_file` is `True`. | ||
1. Logs an initialization message with the final configuration if `log_level` is `DEBUG`. | ||
|
||
Log retention is short and log level is `WARNING` as by default so only problems are logged and they aren't kept for long. | ||
|
||
```python | ||
initLogging(debug=False, | ||
enable_screen_debug=False, | ||
enable_log_file=True, | ||
log_file='/var/log/icinga2/check_monitoring.log', | ||
log_rotate='1 day', | ||
log_retention='3 days', | ||
log_level='WARNING', | ||
available_log_levels=DEFAULT_LOG_LEVELS, | ||
**kwargs) | ||
``` | ||
__Parameters:__ | ||
`debug` (optional): If True, sets the log level to `DEBUG`. Defaults to `False`. | ||
`enable_screen_debug` (optional): If True, enables screen logging to standard error. Defaults to `False`. | ||
`enable_log_file` (optional): If True, enables file logging. Defaults to `True`. | ||
`log_file` (optional): The path to the log file. Defaults to `/var/log/icinga2/check_monitoring.log`. | ||
`log_rotate` (optional): The log file rotation policy. Defaults to `1 day`. | ||
`log_retention` (optional): The log file retention policy. Defaults to `3 days`. | ||
`log_level` (optional): The logging level. Defaults to `WARNING`. | ||
`available_log_levels` (optional): A list of available logging levels. Defaults to `DEFAULT_LOG_LEVELS`. | ||
`**kwargs` : Legacy variables to override function arguments if they exist. | ||
|
||
|
||
## initLoggingArgparse() | ||
Adds Argparse arguments to be passed to `initLogging()` | ||
|
||
```python | ||
initLoggingArgparse(parser, | ||
log_file='/var/log/icinga2/check_monitoring.log', | ||
log_rotate='1 day', | ||
log_retention='3 days', | ||
log_level='WARNING', | ||
available_log_levels=DEFAULT_LOG_LEVELS) | ||
``` | ||
|
||
__Parameters:__ | ||
`log_file` (optional): The path to the log file. Defaults to `/var/log/icinga2/check_monitoring.log`. | ||
`log_rotate` (optional): The log file rotation policy. Defaults to `1 day`. | ||
`log_retention` (optional): The log file retention policy. Defaults to `3 days`. | ||
`log_level` (optional): The logging level. Defaults to `WARNING`. | ||
`available_log_levels` (optional): A list of available logging levels. Defaults to `DEFAULT_LOG_LEVELS`. | ||
|
||
__Argparse Arguments Added:__ | ||
Flags | ||
`--debug` | ||
`--enable-screen-debug` | ||
`--disable-log-file` | ||
_Note: `--disable-log-file` should get inversly passed to the `enable_log_file`, this is done so the user is explictly disabling the log file, the opposite of the default which is enabled._ | ||
|
||
Keyword arguments | ||
`--log-file` | ||
`--log-rotate` | ||
`--log-retention` | ||
`--log-level` | ||
_Note: there is no argument `--available-log-levels` added to argparse, the avaiable log levels are only used to provide choices for `--log-level`._ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from .monitoring_plugins import MonitoringPlugin | ||
from .logging import initLogging, initLoggingArgparse, DEFAULT_LOG_LEVELS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
|
||
import os | ||
import sys | ||
from loguru import logger | ||
|
||
DEFAULT_LOG_LEVELS = ['TRACE', 'DEBUG', 'INFO', 'SUCCESS', 'WARNING', 'ERROR', 'CRITICAL'] | ||
|
||
|
||
def initLoggingArgparse(parser, | ||
log_file='/var/log/icinga2/check_monitoring.log', | ||
log_rotate='1 day', | ||
log_retention='3 days', | ||
log_level='WARNING', | ||
available_log_levels=DEFAULT_LOG_LEVELS, | ||
): | ||
""" | ||
Initalize argparse arguments for logging, you can change the argparse argument defaults with the function arguments | ||
Args: | ||
parser (obj): Argparse parser object | ||
log_file (str, optional): Override default argument value for --log-file. Defaults to '/var/log/icinga2/check_monitoring.log'. | ||
log_rotate (str, optional): Override default argument value for --log-rotate. Defaults to '1 day'. | ||
log_retention (str, optional): Override default argument value for --log-retention. Defaults to '3 days'. | ||
log_level (str, optional): Override default argument value for --log-level. Defaults to 'WARNING'. | ||
available_log_levels (list, optional): Override default argument value for --available-log-levels. Defaults to DEFAULT_LOG_LEVELS. | ||
""" | ||
parser.add_argument('--debug', action="store_true", help="Sets the log level to DEBUG.") | ||
parser.add_argument('--enable-screen-debug', action="store_true", help="Enables screen logging to standard error.") | ||
parser.add_argument('--disable-log-file', action="store_true", help="Disables file logging") | ||
parser.add_argument('--log-file', type=str, default=log_file, help="The path to the log file") | ||
parser.add_argument('--log-rotate', type=str, default=log_rotate, help="The log file rotation policy") | ||
parser.add_argument('--log-retention', type=str, default=log_retention, help="The log file retention policy") | ||
parser.add_argument('--log-level', type=str, choices=available_log_levels, | ||
default=log_level, help="The logging level") | ||
|
||
|
||
def initLogging(debug=False, | ||
enable_screen_debug=False, | ||
enable_log_file=True, | ||
log_file='/var/log/icinga2/check_monitoring.log', | ||
log_rotate='1 day', | ||
log_retention='3 days', | ||
log_level='WARNING', | ||
available_log_levels=DEFAULT_LOG_LEVELS, | ||
**kwargs | ||
): | ||
""" | ||
Initalize logging for monitoring checks. | ||
It defaults to logging to file for WARNING level and above, the log files autorotate with compression and retention. | ||
The log format includes the date and process id so you can identify all log entries from the same run. | ||
Args: | ||
debug (bool, optional): If True, sets the log level to DEBUG. Defaults to False. | ||
enable_screen_debug (bool, optional): If True, enables screen logging to standard error. Defaults to False. | ||
enable_log_file (bool, optional): If True, enables file logging. Defaults to True. | ||
log_file (str, optional): The path to the log file. Defaults to '/var/log/icinga2/check_monitoring.log'. | ||
log_rotate (str, optional): The log file rotation policy. Defaults to '1 day'. | ||
log_retention (str, optional): The log file retention policy. Defaults to '3 days'. | ||
log_level (str, optional): The logging level. Defaults to 'WARNING'. | ||
available_log_levels (list, optional): A list of available logging levels. Aliased as available_log_levels. Defaults to DEFAULT_LOG_LEVELS. | ||
""" | ||
# | ||
# Legacy vars, will override function args if they exist | ||
# If true screen logging is added to standard error | ||
enable_screen_debug = kwargs.get('enableScreenDebug', enable_screen_debug) | ||
enable_log_file = kwargs.get('enableLogFile', enable_log_file) | ||
log_file = kwargs.get('logFile', log_file) | ||
log_rotate = kwargs.get('logRotate', log_rotate) | ||
log_retention = kwargs.get('logRetention', log_retention) | ||
log_level = str(kwargs.get('logLevel', log_level)).upper() | ||
available_log_levels = kwargs.get('availableLogLevels', available_log_levels) | ||
|
||
if debug: | ||
log_level = 'DEBUG' | ||
|
||
if log_level not in available_log_levels: | ||
log_level = 'INFO' | ||
|
||
# Because the library comes with a logger to std.err initalized and we get rid of that | ||
logger.remove() | ||
# Now add the screen std.err logger back using the right log level | ||
if enable_screen_debug: | ||
logger.add(sys.stderr, colorize=True, | ||
level='DEBUG', | ||
backtrace=True, | ||
diagnose=True, | ||
format="<blue>{time:YYYY-MM-DD HH:mm:ss.SSS}</blue> <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> <level>{level}</level>: {message}" | ||
) | ||
|
||
# Add file logging if required | ||
if enable_log_file: | ||
if os.path.isfile(log_file): | ||
if not os.access(log_file, os.W_OK): | ||
print("Permissions error, unable to write to log file ({})".format(log_file)) | ||
sys.exit(os.EX_CONFIG) | ||
|
||
logger.add(log_file, colorize=True, | ||
format="<blue>{time:YYYY-MM-DD HH:mm:ss.SSS}</blue> <yellow>({process.id})</yellow> <level>{level}</level>: {message}", | ||
level=log_level, | ||
rotation=log_rotate, | ||
retention=log_retention, | ||
compression="gz" | ||
) | ||
|
||
logger.debug( | ||
f"Log initalized with level: {log_level}, enable screen debug: {enable_screen_debug}, enable log file: {enable_log_file}, file: {log_file}, rotate: {log_rotate}, retention: {log_retention}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from __future__ import print_function | ||
|
||
import pytest | ||
import argparse | ||
import pytest | ||
from sol1_monitoring_plugins_lib import initLogging, initLoggingArgparse, DEFAULT_LOG_LEVELS | ||
|
||
|
||
def test_initLoggingArgparse(): | ||
parser = argparse.ArgumentParser() | ||
initLoggingArgparse(parser) | ||
args = parser.parse_args([]) | ||
assert args.debug == False | ||
assert args.enable_screen_debug == False | ||
assert args.disable_log_file == False | ||
assert args.log_file == '/var/log/icinga2/check_monitoring.log' | ||
assert args.log_rotate == '1 day' | ||
assert args.log_retention == '3 days' | ||
assert args.log_level == 'WARNING' | ||
assert args.available_log_levels == DEFAULT_LOG_LEVELS | ||
|
||
args = parser.parse_args(['--debug', '--enable-screen-debug', '--disable-log-file', '--log-file', 'test.log']) | ||
assert args.debug == True | ||
assert args.enable_screen_debug == True | ||
assert args.disable_log_file == True | ||
assert args.log_file == 'test.log' | ||
|
||
def test_initLogging(capfd): | ||
initLogging(debug=True, enable_screen_debug=True, enable_log_file=False) | ||
out, err = capfd.readouterr() | ||
assert "enable log file: False" in err | ||
assert "debug: True" in err | ||
assert "Log initalized with level: DEBUG" in err | ||
|