1 继承日志模块生成自定义日志
from __future__ import absolute_import import os import sys import time import datetime import logging import logging.handlers import tempfile DATE_FORMAT = '%Y-%m-%d %H:%M:%S' def create_logfile(): if 'SYAPI_LOG_TEST' in os.environ: value = tempfile.mkdtemp() elif 'SYAPI_LOG' in os.environ: value = os.environ['SYAPI_LOG'] else: value = os.path.join('/var/log','syapi') try: value = os.path.abspath(value) if os.path.exists(value): if not os.path.isdir(value): raise IOError('No such directory: "%s"' % value) if not os.access(value, os.W_OK): raise IOError('Permission denied: "%s"' % value) if not os.path.exists(value): os.makedirs(value) except: print('"%s" is not a valid value for syapi_log.' % value) print('Set the envvar SYAPI_LOG to fix your configuration.') raise return value class JobIdLogger(logging.Logger): def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): """ Customizing it to set a default value for extra['job_id'] """ rv = logging.LogRecord(name, level, fn, lno, msg, args, exc_info, func) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] if 'job_id' not in rv.__dict__: rv.__dict__['job_id'] = '' return rv class JobIdLoggerAdapter(logging.LoggerAdapter): """ Accepts an optional keyword argument: 'job_id' You can use this in 2 ways: 1. On class initialization adapter = JobIdLoggerAdapter(logger, {'job_id': job_id}) adapter.debug(msg) 2. On method invocation adapter = JobIdLoggerAdapter(logger, {}) adapter.debug(msg, job_id=id) """ def process(self, msg, kwargs): if 'job_id' in kwargs: if 'extra' not in kwargs: kwargs['extra'] = {} kwargs['extra']['job_id'] = ' [%s]' % kwargs['job_id'] del kwargs['job_id'] elif 'job_id' in self.extra: if 'extra' not in kwargs: kwargs['extra'] = {} kwargs['extra']['job_id'] = ' [%s]' % self.extra['job_id'] return msg, kwargs def setup_logging(flag,job_id): # Set custom logger logging.setLoggerClass(JobIdLogger) formatter = logging.Formatter( fmt="%(asctime)s%(job_id)s [%(levelname)-5s] %(message)s", datefmt=DATE_FORMAT, ) sh_logger = logging.getLogger('sy_stream') sh_logger.setLevel(logging.DEBUG) sh = logging.StreamHandler(sys.stdout) sh.setFormatter(formatter) sh.setLevel(logging.DEBUG) sh_logger.addHandler(sh) log_dir = create_logfile() log_name = str(flag)+"-"+ str(job_id) + ".log" log_path = os.path.join(log_dir, log_name) if log_path is not None: file_logger = logging.getLogger('sy_file') file_logger.setLevel(logging.DEBUG) fh = logging.FileHandler(log_path, "w") fh.setFormatter(formatter) fh.setLevel(logging.DEBUG) file_logger.addHandler(fh) # Useful shortcut for the webapp, which may set job_id return JobIdLoggerAdapter(file_logger,{'job_id':job_id}) else: print('WARNING: log_file config option not found - no log file is being saved') return JobIdLoggerAdapter(sh_logger, {'job_id':job_id}) def init_kubelog_logger(flag,job_id): logger = setup_logging(flag,job_id) return logger # job_id = '%s-%s' % (time.strftime('%Y%m%d-%H%M%S'), os.urandom(2).encode('hex')) # log_obj = init_kubelog_logger("syapi",job_id) log_obj = init_kubelog_logger("syapi","user001") log_obj.info("hello world log start") # create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # create_time_c = time.time()