# -*- coding: utf-8 -*- # This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) # Copyright (C) 2019 pwr # # 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 3 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, see . from __future__ import division, print_function, unicode_literals import os import inspect import logging from logging import Formatter, StreamHandler from logging.handlers import RotatingFileHandler from .constants import BASE_DIR as _BASE_DIR ACCESS_FORMATTER = Formatter("%(message)s") FORMATTER = Formatter("[%(asctime)s] %(levelname)5s {%(name)s:%(lineno)d} %(message)s") DEFAULT_LOG_LEVEL = logging.INFO DEFAULT_LOG_FILE = os.path.join(_BASE_DIR, "calibre-web.log") DEFAULT_ACCESS_LOG = os.path.join(_BASE_DIR, "access.log") LOG_TO_STDERR = '/dev/stderr' DEFAULT_ACCESS_LEVEL= logging.INFO logging.addLevelName(logging.WARNING, "WARN") logging.addLevelName(logging.CRITICAL, "CRIT") def info(msg, *args, **kwargs): create(2).info(msg, *args, **kwargs) def warning(msg, *args, **kwargs): create(2).warning(msg, *args, **kwargs) def error(msg, *args, **kwargs): create(2).error(msg, *args, **kwargs) def critical(msg, *args, **kwargs): create(2).critical(msg, *args, **kwargs) def exception(msg, *args, **kwargs): create(2).exception(msg, *args, **kwargs) def debug(msg, *args, **kwargs): create(2).debug(msg, *args, **kwargs) def get(name=None): val = logging.getLogger("general") val.name = name return val def create(ini=1): parent_frame = inspect.stack(0)[ini] if hasattr(parent_frame, 'frame'): parent_frame = parent_frame.frame else: parent_frame = parent_frame[0] parent_module = inspect.getmodule(parent_frame) return get(parent_module.__name__) def is_debug_enabled(logger): return logging.getLogger(logger).level <= logging.DEBUG def is_info_enabled(logger): return logging.getLogger(logger).level <= logging.INFO def get_level_name(level): return logging.getLevelName(level) def is_valid_logfile(file_path): if not file_path: return True if os.path.isdir(file_path): return False log_dir = os.path.dirname(file_path) return (not log_dir) or os.path.isdir(log_dir) def setup(log_file, logger, log_level=None): if logger == "general": formatter = FORMATTER default_file = DEFAULT_LOG_FILE else: formatter = ACCESS_FORMATTER default_file = DEFAULT_ACCESS_LOG if log_file: if not os.path.dirname(log_file): log_file = os.path.join(_BASE_DIR, log_file) log_file = os.path.abspath(log_file) else: # log_file = LOG_TO_STDERR log_file = default_file # print ('%r -- %r' % (log_level, log_file)) r = logging.getLogger(logger) r.setLevel(log_level or DEFAULT_LOG_LEVEL) previous_handler = r.handlers[0] if r.handlers else None # print ('previous %r' % previous_handler) if previous_handler: # if the log_file has not changed, don't create a new handler if getattr(previous_handler, 'baseFilename', None) == log_file: return r.debug("logging to %s level %s", log_file, r.level) if log_file == LOG_TO_STDERR: file_handler = StreamHandler() file_handler.baseFilename = LOG_TO_STDERR else: try: file_handler = RotatingFileHandler(log_file, maxBytes=50000, backupCount=2) except IOError: if log_file == default_file: raise file_handler = RotatingFileHandler(default_file, maxBytes=50000, backupCount=2) file_handler.setFormatter(formatter) for h in r.handlers: r.removeHandler(h) h.close() r.addHandler(file_handler) # print ('new handler %r' % file_handler) # Enable logging of smtp lib debug output class StderrLogger(object): def __init__(self, name=None): self.log = get(name or self.__class__.__name__) self.buffer = '' def write(self, message): try: if message == '\n': self.log.debug(self.buffer.replace('\n', '\\n')) self.buffer = '' else: self.buffer += message except Exception: self.log.debug("Logging Error")