#!/usr/bin/python3 # -*- coding: utf-8 -*- # key-mapper - GUI for device specific keyboard mappings # Copyright (C) 2020 sezanzeb # # This file is part of key-mapper. # # key-mapper 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. # # key-mapper 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 key-mapper. If not, see . """Logging setup for key-mapper.""" import os import logging import pkg_resources def spam(self, message, *args, **kws): if self.isEnabledFor(SPAM): # https://stackoverflow.com/a/13638084 self._log(SPAM, message, args, **kws) SPAM = 5 logging.addLevelName(SPAM, "SPAM") logging.Logger.spam = spam class Formatter(logging.Formatter): """Overwritten Formatter to print nicer logs.""" def format(self, record): debug = logger.level <= logging.DEBUG if record.levelno == logging.INFO and not debug: # if not launched with --debug, then don't print "INFO:" self._style._fmt = '%(message)s' # noqa else: # see https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit # for those numbers color = { logging.WARNING: 33, logging.ERROR: 31, logging.FATAL: 31, logging.DEBUG: 36, SPAM: 34, logging.INFO: 32, }.get(record.levelno, 0) if debug: self._style._fmt = ( # noqa '\033[1m' # bold f'\033[{color}m' # color f'%(levelname)s' '\033[0m' # end style f'\033[{color}m' # color ': %(filename)s, line %(lineno)d, %(message)s' '\033[0m' # end style ) else: self._style._fmt = ( # noqa f'\033[{color}m%(levelname)s\033[0m: %(message)s' ) return super().format(record) logger = logging.getLogger() handler = logging.StreamHandler() handler.setFormatter(Formatter()) logger.addHandler(handler) logger.setLevel(logging.INFO) logging.getLogger('asyncio').setLevel(logging.WARNING) def is_debug(): return logger.level <= logging.DEBUG def log_info(): """Log version and name to the console""" # read values from setup.py version = pkg_resources.require('key-mapper')[0].version name = pkg_resources.require('key-mapper')[0].project_name logger.info('%s %s', version, name) def update_verbosity(debug): """Set the logging verbosity according to the settings object.""" if debug: logger.setLevel(SPAM) else: logger.setLevel(logging.INFO) def debug_log_on(): return logger.level == logging.DEBUG def add_filehandler(): """Clear the existing logfile and start logging to it.""" # jack also logs to ~/.log log_path = os.path.expanduser('~/.log/key-mapper') log_file = os.path.join(log_path, 'log') if not os.path.exists(log_path): os.makedirs(log_path) if os.path.exists(log_file): # keep the log path small, start from scratch each time os.remove(log_file) file_handler = logging.FileHandler(log_file) file_handler.setFormatter(Formatter()) logger.addHandler(file_handler)