logging as of 2022-02-01
Change-Id: I63c681bea9553cd822b214075b163ca6c42fe0cc
This commit is contained in:
127
secop/logging.py
Normal file
127
secop/logging.py
Normal file
@ -0,0 +1,127 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# 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, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Module authors:
|
||||
# Markus Zolliker <markus.zolliker@psi.ch>
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
import os
|
||||
from os.path import dirname, join
|
||||
import mlzlog
|
||||
from secop.lib import getGeneralConfig
|
||||
|
||||
|
||||
OFF = 99
|
||||
|
||||
LOG_LEVELS = dict(mlzlog.LOGLEVELS, off=OFF)
|
||||
LEVEL_NAMES = {v: k for k, v in LOG_LEVELS.items()}
|
||||
log = None
|
||||
rootlogdir = None
|
||||
|
||||
|
||||
def checkLevel(level):
|
||||
try:
|
||||
if isinstance(level, str):
|
||||
return LOG_LEVELS[level.lower()]
|
||||
if level in LEVEL_NAMES:
|
||||
return level
|
||||
except KeyError:
|
||||
pass
|
||||
raise ValueError('%r is not a valid level' % level)
|
||||
|
||||
|
||||
def initLogging(loglevel='info'):
|
||||
global log, rootlogdir # pylint: disable-global-statement
|
||||
|
||||
loglevel = checkLevel(loglevel)
|
||||
genConfig = getGeneralConfig()
|
||||
rootname = genConfig.get('rootname', 'secop')
|
||||
logdir = genConfig.get('logdir')
|
||||
rootlogdir = join(logdir, rootname)
|
||||
mlzlog.initLogging(rootname, 'debug', logdir)
|
||||
for hdl in mlzlog.log.handlers:
|
||||
hdl.setLevel(loglevel)
|
||||
return mlzlog.log
|
||||
|
||||
|
||||
class ComlogHandler(mlzlog.LogfileHandler):
|
||||
"""handler for logging communication
|
||||
|
||||
communication is
|
||||
"""
|
||||
|
||||
def format(self, record):
|
||||
return '%s %s' % (self.formatter.formatTime(record), record.getMessage())
|
||||
|
||||
def doRollover(self):
|
||||
super().doRollover()
|
||||
max_days = getGeneralConfig().get('comlog_days', 31)
|
||||
# keep only the last max_days files
|
||||
with os.scandir(dirname(self.baseFilename)) as it:
|
||||
files = sorted(entry.path for entry in it if entry.name != 'current')
|
||||
for filepath in files[-max_days:]:
|
||||
os.remove(filepath)
|
||||
|
||||
|
||||
def add_comlog_handler(modobj):
|
||||
global rootlogdir # pylint: disable-global-statement
|
||||
comlog = getGeneralConfig().get('comlog')
|
||||
if comlog:
|
||||
comlog = join(rootlogdir, comlog)
|
||||
modobj.log.addHandler(ComlogHandler(comlog, modobj.name))
|
||||
|
||||
|
||||
class RemoteLogHandler(mlzlog.Handler):
|
||||
"""handler for remote logging"""
|
||||
def __init__(self, modobj):
|
||||
super().__init__()
|
||||
self.subscriptions = {} # dict [conn] of level
|
||||
self.modobj = modobj
|
||||
self.modobj.log.addHandler(self)
|
||||
self.used_by = set()
|
||||
|
||||
def handle(self, record, name=None):
|
||||
result = False
|
||||
for conn, lev in self.subscriptions.items():
|
||||
if record.levelno >= lev:
|
||||
msg = record.getMessage()
|
||||
if self.modobj.DISPATCHER.send_log_msg(
|
||||
conn, name or self.modobj.name, LEVEL_NAMES[record.levelno], msg):
|
||||
result = True
|
||||
if result:
|
||||
return True
|
||||
for master in self.used_by:
|
||||
# this is an iodev, try to handle by one of our masters
|
||||
if master.remoteLogHandler.handle(record, self.modobj.name):
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_conn_level(self, conn, level):
|
||||
level = checkLevel(level)
|
||||
if level == mlzlog.DEBUG:
|
||||
iodev = getattr(self.modobj, '_iodev', None)
|
||||
if iodev:
|
||||
# we want also to see debug messages of iodev
|
||||
if iodev.remoteLogHandler is None:
|
||||
iodev.remoteLogHandler = RemoteLogHandler(self)
|
||||
iodev.remoteLogHandler.used_by.add(self.modobj)
|
||||
level = checkLevel(level)
|
||||
if level == OFF:
|
||||
self.subscriptions.pop(conn, None)
|
||||
else:
|
||||
self.subscriptions[conn] = level
|
Reference in New Issue
Block a user