diff --git a/docs/configuration.rst b/docs/configuration.rst index 30ade98..4ff694e 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -233,7 +233,43 @@ to files in your home directory named ``.i3pystatus-``. Some modules might log additional information. -.. rubric:: Log level +Setting a specific logfile +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When instantiating your ``Status`` object, the path to a log file can be +specified. If this is done, then log messages will be sent to that file and not +to an ``.i3pystatus-`` file in your home directory. This is +useful in that it helps keep your home directory from becoming cluttered with +files containing errors. + +.. code-block:: python + + from i3pystatus import Status + + status = Status(logfile='/home/username/var/i3pystatus.log') + +Changing log format +~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 3.35 + +The ``logformat`` option can be useed to change the format of the log files, +using `LogRecord attributes`__. + +.. code-block:: python + + from i3pystatus import Status + + status = Status( + logfile='/home/username/var/i3pystatus.log', + logformat='%(asctime)s %(levelname)s:', + ) + +.. __: https://docs.python.org/3/library/logging.html#logrecord-attributes + + +Log level +~~~~~~~~~ Every module has a ``log_level`` option which sets the *minimum* severity required for an event to be logged. diff --git a/i3pystatus/core/__init__.py b/i3pystatus/core/__init__.py index 4bd54a6..1c0a9d1 100644 --- a/i3pystatus/core/__init__.py +++ b/i3pystatus/core/__init__.py @@ -8,6 +8,8 @@ from i3pystatus.core.exceptions import ConfigError from i3pystatus.core.imputil import ClassFinder from i3pystatus.core.modules import Module +DEFAULT_LOG_FORMAT = '%(asctime)s [%(levelname)-8s][%(name)s %(lineno)d] %(message)s' + class CommandEndpoint: """ @@ -59,17 +61,21 @@ class Status: """ def __init__(self, standalone=True, click_events=True, interval=1, - input_stream=None, logfile=None, internet_check=None): + input_stream=None, logfile=None, internet_check=None, + logformat=DEFAULT_LOG_FORMAT): self.standalone = standalone self.click_events = standalone and click_events input_stream = input_stream or sys.stdin + logger = logging.getLogger("i3pystatus") if logfile: - logger = logging.getLogger("i3pystatus") for handler in logger.handlers: logger.removeHandler(handler) handler = logging.FileHandler(logfile, delay=True) logger.addHandler(handler) logger.setLevel(logging.CRITICAL) + if logformat: + for index in range(len(logger.handlers)): + logger.handlers[index].setFormatter(logging.Formatter(logformat)) if internet_check: util.internet.address = internet_check diff --git a/i3pystatus/core/threading.py b/i3pystatus/core/threading.py index c4ff0a5..1e3d8bb 100644 --- a/i3pystatus/core/threading.py +++ b/i3pystatus/core/threading.py @@ -67,7 +67,7 @@ class ExceptionWrapper(Wrapper): try: self.workload() except: - message = "\n> Exception in {thread} at {time}, module {name}".format( + message = "Exception in {thread} at {time}, module {name}".format( thread=threading.current_thread().name, time=time.strftime("%c"), name=self.workload.__class__.__name__