Move dynamic log level logic to filter

This commit is contained in:
AlanCoding
2019-05-22 09:46:19 -04:00
parent dc1bf3ef07
commit d3f047d731
3 changed files with 49 additions and 44 deletions

View File

@@ -18,7 +18,7 @@ from django.conf import settings
from awx.main.constants import LOGGER_BLACKLIST from awx.main.constants import LOGGER_BLACKLIST
from awx.main.utils.common import get_search_fields from awx.main.utils.common import get_search_fields
__all__ = ['SmartFilter', 'ExternalLoggerEnabled'] __all__ = ['SmartFilter', 'ExternalLoggerEnabled', 'DynamicLevelFilter']
logger = logging.getLogger('awx.main.utils') logger = logging.getLogger('awx.main.utils')
@@ -48,9 +48,18 @@ class FieldFromSettings(object):
instance.settings_override[self.setting_name] = value instance.settings_override[self.setting_name] = value
def record_is_blacklisted(record):
"""Given a log record, return True if it is considered to be in
the logging blacklist, return False if not
"""
for logger_name in LOGGER_BLACKLIST:
if record.name.startswith(logger_name):
return True
return False
class ExternalLoggerEnabled(Filter): class ExternalLoggerEnabled(Filter):
lvl = FieldFromSettings('LOG_AGGREGATOR_LEVEL')
enabled_loggers = FieldFromSettings('LOG_AGGREGATOR_LOGGERS') enabled_loggers = FieldFromSettings('LOG_AGGREGATOR_LOGGERS')
enabled_flag = FieldFromSettings('LOG_AGGREGATOR_ENABLED') enabled_flag = FieldFromSettings('LOG_AGGREGATOR_ENABLED')
@@ -64,18 +73,16 @@ class ExternalLoggerEnabled(Filter):
setattr(self, field_name, field_value) setattr(self, field_name, field_value)
def filter(self, record): def filter(self, record):
""" """Filters out all log records if LOG_AGGREGATOR_ENABLED is False
Uses the database settings to determine if the current or if the particular logger is not in LOG_AGGREGATOR_LOGGERS
external log configuration says that this particular record should only be used for the external logger
should be sent to the external log aggregator
False - should not be logged False - should not be logged
True - should be logged True - should be logged
""" """
# Logger exceptions # Do not send exceptions to external logger
for logger_name in LOGGER_BLACKLIST: if record_is_blacklisted(record):
if record.name.startswith(logger_name): return False
return False
# General enablement # General enablement
if not self.enabled_flag: if not self.enabled_flag:
return False return False
@@ -95,6 +102,24 @@ class ExternalLoggerEnabled(Filter):
return bool(base_name in loggers) return bool(base_name in loggers)
class DynamicLevelFilter(Filter):
def filter(self, record):
"""Filters out logs that have a level below the threshold defined
by the databse setting LOG_AGGREGATOR_LEVEL
"""
if record_is_blacklisted(record):
# Fine to write blacklisted loggers to file, apply default filtering level
cutoff_level = logging.WARNING
else:
try:
cutoff_level = logging._nameToLevel[settings.LOG_AGGREGATOR_LEVEL]
except Exception:
cutoff_level = logging.WARNING
return bool(record.levelno >= cutoff_level)
def string_to_type(t): def string_to_type(t):
if t == u'null': if t == u'null':
return None return None

View File

@@ -19,12 +19,11 @@ from django.conf import settings
from requests_futures.sessions import FuturesSession from requests_futures.sessions import FuturesSession
# AWX # AWX
from awx.main.constants import LOGGER_BLACKLIST
from awx.main.utils.formatters import LogstashFormatter from awx.main.utils.formatters import LogstashFormatter
__all__ = ['BaseHTTPSHandler', 'TCPHandler', 'UDPHandler', __all__ = ['BaseHTTPSHandler', 'TCPHandler', 'UDPHandler',
'AWXProxyHandler', 'RotatingProductionLogHandler'] 'AWXProxyHandler']
logger = logging.getLogger('awx.main.utils.handlers') logger = logging.getLogger('awx.main.utils.handlers')
@@ -92,28 +91,6 @@ class SocketResult:
return self return self
class DynamicLevelMixin(object):
@property
def level(self):
from django.conf import settings
for logger_name in LOGGER_BLACKLIST:
if self.name.startswith(logger_name):
return 30 # WARNING
try:
return logging._nameToLevel[settings.LOG_AGGREGATOR_LEVEL]
except Exception:
return 30 # WARNING
@level.setter
def level(self, level):
pass # no-op, this value comes from the database
class RotatingProductionLogHandler(logging.handlers.RotatingFileHandler, DynamicLevelMixin):
pass
class BaseHandler(logging.Handler): class BaseHandler(logging.Handler):
def __init__(self, host=None, port=None, indv_facts=None, **kwargs): def __init__(self, host=None, port=None, indv_facts=None, **kwargs):
super(BaseHandler, self).__init__() super(BaseHandler, self).__init__()
@@ -295,7 +272,7 @@ HANDLER_MAPPING = {
} }
class AWXProxyHandler(logging.Handler, DynamicLevelMixin): class AWXProxyHandler(logging.Handler):
''' '''
Handler specific to the AWX external logging feature Handler specific to the AWX external logging feature

View File

@@ -966,6 +966,9 @@ LOGGING = {
'external_log_enabled': { 'external_log_enabled': {
'()': 'awx.main.utils.filters.ExternalLoggerEnabled' '()': 'awx.main.utils.filters.ExternalLoggerEnabled'
}, },
'dynamic_level_filter': {
'()': 'awx.main.utils.filters.DynamicLevelFilter'
}
}, },
'formatters': { 'formatters': {
'simple': { 'simple': {
@@ -1005,7 +1008,7 @@ LOGGING = {
'external_logger': { 'external_logger': {
'class': 'awx.main.utils.handlers.AWXProxyHandler', 'class': 'awx.main.utils.handlers.AWXProxyHandler',
'formatter': 'json', 'formatter': 'json',
'filters': ['external_log_enabled'], 'filters': ['external_log_enabled', 'dynamic_level_filter'],
}, },
'mail_admins': { 'mail_admins': {
'level': 'ERROR', 'level': 'ERROR',
@@ -1014,8 +1017,8 @@ LOGGING = {
}, },
'tower_warnings': { 'tower_warnings': {
# don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL # don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL
'class':'awx.main.utils.handlers.RotatingProductionLogHandler', 'class': 'logging.handlers.RotatingFileHandler',
'filters': ['require_debug_false'], 'filters': ['require_debug_false', 'dynamic_level_filter'],
'filename': os.path.join(LOG_ROOT, 'tower.log'), 'filename': os.path.join(LOG_ROOT, 'tower.log'),
'maxBytes': 1024 * 1024 * 5, # 5 MB 'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5, 'backupCount': 5,
@@ -1023,8 +1026,8 @@ LOGGING = {
}, },
'callback_receiver': { 'callback_receiver': {
# don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL # don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL
'class':'awx.main.utils.handlers.RotatingProductionLogHandler', 'class': 'logging.handlers.RotatingFileHandler',
'filters': ['require_debug_false'], 'filters': ['require_debug_false', 'dynamic_level_filter'],
'filename': os.path.join(LOG_ROOT, 'callback_receiver.log'), 'filename': os.path.join(LOG_ROOT, 'callback_receiver.log'),
'maxBytes': 1024 * 1024 * 5, # 5 MB 'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5, 'backupCount': 5,
@@ -1032,8 +1035,8 @@ LOGGING = {
}, },
'dispatcher': { 'dispatcher': {
# don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL # don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL
'class':'awx.main.utils.handlers.RotatingProductionLogHandler', 'class': 'logging.handlers.RotatingFileHandler',
'filters': ['require_debug_false'], 'filters': ['require_debug_false', 'dynamic_level_filter'],
'filename': os.path.join(LOG_ROOT, 'dispatcher.log'), 'filename': os.path.join(LOG_ROOT, 'dispatcher.log'),
'maxBytes': 1024 * 1024 * 5, # 5 MB 'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5, 'backupCount': 5,
@@ -1050,8 +1053,8 @@ LOGGING = {
}, },
'task_system': { 'task_system': {
# don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL # don't define a level here, it's set by settings.LOG_AGGREGATOR_LEVEL
'class':'awx.main.utils.handlers.RotatingProductionLogHandler', 'class': 'logging.handlers.RotatingFileHandler',
'filters': ['require_debug_false'], 'filters': ['require_debug_false', 'dynamic_level_filter'],
'filename': os.path.join(LOG_ROOT, 'task_system.log'), 'filename': os.path.join(LOG_ROOT, 'task_system.log'),
'maxBytes': 1024 * 1024 * 5, # 5 MB 'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5, 'backupCount': 5,