[elbe-devel] [PATCH 02/32] log.py - New logging system
Torben Hohn
torben.hohn at linutronix.de
Mon Jun 17 14:55:01 CEST 2019
On Fri, Jun 14, 2019 at 10:13:16PM +0200, dion at linutronix.de wrote:
> From: Olivier Dion <dion at linutronix.de>
>
> The new ELBE logging system will be using the Python standard
> _logging_ module.
>
> The _logging_ module is line oriented and module oriented. What it
> means is that seperated modules should have seperated _logger_ object.
err... the logging is not really line oriented, how did you come to this
conclusion ?
its also not module oriented. How did you come to this conclusion ?
we want to get away from the asciidoc format, because its not good
to parse.
please make the code use logging.debug() and friends everywhere.
define 2 custom loglevels for validation.txt and elbe-report.txt
add a filter that collects contextual information.
https://docs.python.org/2/howto/logging-cookbook.html#using-filters-to-impart-contextual-information
this has to query the current project path, which is supposed to be
setup in a thread local variable.
https://docs.python.org/2/library/threading.html#threading.local
store the path and the current elbeproject.
these need to be setup in elbepack/asyncworker.py
then hook several handlers into the root logger.
one for elbe-report.txt, and validation.txt and log.txt each.
you probably need to filter things a bit. because you dont want
elbe-report things in log.txt....
then add another logger, that pushes the structured events into
a queue, and make the wait_busy code just read out that queue.
the soap interface allows to pass objects.
Map the LogRecord to a soap object.
(you need to convert a few internal python objects (like the ElbeProject
and exc_info to strings)
https://docs.python.org/2/library/logging.html#logging.LogRecord
and then change the code in wait_busy to continously drain that queue.
and print the logging infos.
> This is not working well with ELBE. Thus, the _logging_ module has
> being wrapped in "log.py".
>
> * Block message
>
> Logged message are format in _block_. A block is composed of 3
> parts.
>
> - Header (optional)
> - Message
> - Footer (optional)
>
> Headers are underline by '=' and footers are overline by '-'.
>
> A block's message can also be marked to be verbatim. In that case,
> the message is enclosed by ">>>>>\n" and "<<<<<".
>
> ** Example
>
> ```````````````````````````````````````````````````````````````````
> log.debug("My very very very long message\n", verbatim=True,
> header="This is a header",
> footer="Here's my footer")
> ```````````````````````````````````````````````````````````````````
>
> Will result in the following message to be log:
> ```````````````````````````````````````````````````````````````````
> This is a header
> ================
> >>>>>
> My very very very long message
> <<<<<
> ----------------
> Here's my footer
> ```````````````````````````````````````````````````````````````````
>
> * Log Level
>
> There's not difference between log levels. At least not in the
> formating of a message. Log levels exist only to filter different
> messages.
>
> * Redirection
>
> There's 3 modes of redirection of the logged messages. Only one of
> them can be choose at a time.
>
> ** File
>
> Using 'log.new(filename)', the log object will create a new 'file
> handler' at 'filename'. All consequent messages send to that log
> will be write to 'filename'. 'log::new' is often used when opening
> a project, since it's at this moment that we know the build
> directory of that project.
>
> ** Stdout
>
> Using 'log.stdout()' will redirect all further messages to the
> default 'stream handler' of the process.
>
> ** Null
>
> Using 'log.null()' will redirect all further messages to
> "/dev/null".
>
> * elbe-report
>
> The 'log' object is reserved for logging to "log.txt". To log to
> the "elbe-report.txt", use the 'report' object.
>
> ** Example
>
> ``````````````````````````````````````````````````````````````````
> from elbepack.log import log, report
> log.new("/var/cache/elbe/buildir-id/log.txt")
> report.stdout()
> log.info("This will log to log.txt")
> report.info("This will log to stdout")
> report.new("/var/cache/elbe/buildir-id/elbe-report.txt")
> report.critical("This will log to elbe-report.txt")
> ``````````````````````````````````````````````````````````````````
>
> Signed-off-by: Olivier Dion <dion at linutronix.de>
> ---
> elbepack/log.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 105 insertions(+)
> create mode 100644 elbepack/log.py
>
> diff --git a/elbepack/log.py b/elbepack/log.py
> new file mode 100644
> index 00000000..6188e163
> --- /dev/null
> +++ b/elbepack/log.py
> @@ -0,0 +1,105 @@
> +# ELBE - Debian Based Embedded Rootfilesystem Builder
> +# Copyright (c) 2019 Olivier Dion <dion at linutronix.de>
> +#
> +# SPDX-License-Identifier: GPL-3.0-or-later
> +
> +import os
> +import logging
> +import logging.config
> +
> +raw_fmt = logging.Formatter("\n%(message)s")
> +
> +class log:
> +
> + log = None
> + filename = None
> + handler = None
> +
> + @classmethod
> + def fmt_footer(cls, footer, c):
> + if footer:
> + return "\n%s\n%s" % ((c * len(footer)), footer)
> + return ""
> +
> + @classmethod
> + def fmt_header(cls, header, c, end="\n"):
> + if header:
> + return "%s\n%s%s" % (header, (c * len(header)), end)
> + return ""
> +
> + @classmethod
> + def fmt_msg(cls, msg, header, footer, verbatim):
> + if verbatim:
> + msg = ">>>>>\n%s<<<<<" % msg
> + return "%s%s%s" % (cls.fmt_header(header, '='),
> + msg,
> + cls.fmt_footer(footer, '-'))
> +
> + @classmethod
> + def new(cls, filename):
> + cls.filename = filename
> + cls.log = logging.getLogger(cls.__name__)
> + cls.log.setLevel(logging.DEBUG)
> + cls.log.propagate = False
> + if cls.handler is not None:
> + cls.log.removeHandler(cls.handler)
> + cls.handler = logging.FileHandler(cls.filename)
> + cls.handler.setFormatter(raw_fmt)
> + cls.log.addHandler(cls.handler)
> +
> + @classmethod
> + def stdout(cls):
> + cls.filename = "STDOUT"
> + cls.log = logging.getLogger(cls.__name__)
> + cls.log.setLevel(logging.DEBUG)
> + cls.log.propagate = False
> + if cls.handler is not None:
> + cls.log.removeHandler(cls.handler)
> + cls.handler = logging.StreamHandler()
> + cls.log.addHandler(cls.handler)
> +
> + @classmethod
> + def null(cls):
> + cls.filename = "/dev/null"
> + cls.log = logging.getLogger(cls.__name__)
> + cls.log.setLevel(logging.DEBUG)
> + cls.log.propagate = False
> + if cls.handler is not None:
> + cls.log.removeHandler(cls.handler)
> + cls.handler = logging.FileHandler("/dev/null")
> + cls.log.addHandler(cls.handler)
> +
> + @classmethod
> + def h1(cls, header):
> + cls.info("%s" % (log.fmt_header(header, '=', end="")))
> +
> + @classmethod
> + def h2(cls, header, msg=""):
> + cls.info("%s" % (log.fmt_header(header, '-', end="")))
> +
> + @classmethod
> + def debug(cls, msg, header="", footer="", verbatim=False):
> + cls.log.debug(cls.fmt_msg(msg, header, footer, verbatim))
> +
> + @classmethod
> + def info(cls, msg, header="", footer="", verbatim=False):
> + cls.log.info(cls.fmt_msg(msg, header, footer, verbatim))
> +
> + @classmethod
> + def warning(cls, msg, header="", footer="", verbatim=False):
> + cls.log.warning(cls.fmt_msg(msg, header, footer, verbatim))
> +
> + @classmethod
> + def error(cls, msg, header="", footer="", verbatim=False):
> + cls.log.error(cls.fmt_msg(msg, header, footer, verbatim))
> +
> + @classmethod
> + def critical(cls, msg, header="", footer="", verbatim=False):
> + cls.log.critical(cls.fmt_msg(msg, header, footer, verbatim))
> +
> + @classmethod
> + def exception(cls, msg, header="", footer="", verbatim=False):
> + cls.log.exception(cls.fmt_msg(msg, header, footer, verbatim))
> +
> +class report(log):
> + pass
> --
> 2.11.0
>
>
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel
--
Torben Hohn
Linutronix GmbH | Bahnhofstrasse 3 | D-88690 Uhldingen-Mühlhofen
Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99
Hinweise zum Datenschutz finden Sie hier (Informations on data privacy
can be found here): https://linutronix.de/kontakt/Datenschutz.php
Linutronix GmbH | Firmensitz (Registered Office): Uhldingen-Mühlhofen |
Registergericht (Registration Court): Amtsgericht Freiburg i.Br., HRB700
806 | Geschäftsführer (Managing Directors): Heinz Egger, Thomas Gleixner
More information about the elbe-devel
mailing list