Source code for backend.daemons.log

# coding: utf-8

import json

import logging
import logging.handlers
import os
from setproctitle import setproctitle


# TODO: remove when RedisLogHandler works fine
from .. import constants
from .. import helpers
from ..constants import default_log_format


[docs]class RedisLogHandler(object): """ Single point to collect logs through redis pub/sub and write them through standard python logging lib """ def __init__(self, opts): self.opts = opts self.log_dir = os.path.dirname(self.opts.log_dir) if not os.path.exists(self.log_dir): os.makedirs(self.log_dir, mode=0o750) self.components = ["spawner", "terminator", "vmm", "build_dispatcher", "action_dispatcher", "backend", "actions", "worker"]
[docs] def setup_logging(self): self.main_logger = logging.Logger("logger", level=logging.DEBUG) self.main_handler = logging.handlers.WatchedFileHandler( filename=os.path.join(self.log_dir, "logger.log")) self.main_handler.setFormatter(default_log_format) self.main_logger.addHandler(self.main_handler) level = getattr(logging, self.opts.log_level.upper(), None) self.loggers = {} for component in self.components: logger = logging.Logger(component) handler = logging.handlers.WatchedFileHandler( filename=os.path.join(self.log_dir, "{}.log".format(component))) handler.setFormatter(default_log_format) handler.setLevel(level) logger.addHandler(handler) self.loggers[component] = logger
[docs] def handle_msg(self, raw): try: event = json.loads(raw["data"]) who = event.get('who', None) if not who: raise Exception("No LogRecord.who field, raw: {}".format(event)) if who not in self.loggers: raise Exception("Unknown LogRecord.who field: {}, raw event: {}" .format(who, event)) log_record = logging.makeLogRecord(event) self.loggers[who].handle(log_record) except Exception as err: self.main_logger.exception(err)
[docs] def run(self): self.setup_logging() setproctitle("RedisLogHandler") rc = helpers.get_redis_connection(self.opts) channel = rc.pubsub(ignore_subscribe_messages=True) channel.subscribe(constants.LOG_PUB_SUB) for raw in channel.listen(): if raw is not None and raw.get("type") == "message" and "data" in raw: self.handle_msg(raw)