.. This file is part of Sympathy for Data. .. Copyright (c) 2023 Combine Control Systems AB .. .. Sympathy for Data 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, version 3 of the License. .. .. Sympathy for Data 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 Sympathy for Data. If not, see . .. _appendix_logging: Logging ------- The logging facility in Sympathy is built on the standard :mod:`logging` module, see https://docs.python.org/3/howto/logging.html#logging-basic-tutorial for introductory material about it. The level of logging used can be configured on the command line. There are three different ways to configure the logging, ranging from course to fine grained. Using the arguments `--loglevel`, `--logger` and `--logging-config-file`: these can not be mixed. Logging output is normally written to the the standard error stream. On Windows, when running without a console, the output is redirected to a file called `output.log` - in the session folder. The logging config file makes it possible to specify the configuration in a more detailed way and makes it possible to specify logging handlers to use. Our top level logger, `sympathy`, and its child loggers (`sympathy.core`, `sympathy.app`, etc.) are used for all logging in our package. Third-party packages would use different loggers. User logging ^^^^^^^^^^^^ To use logging in user code, outside of the `sympathy` logger, simply use the logging module directly. Another option is to use `sympathy.user` logger, other loggers under `sympathy` for our internal use are not intended for user code. Use the :func:`sympathy.api.log.get_user_logger` function to get the user logger. One benefit with using this logger is that the log level can be configured using the basic configuration options. Basic configuration ^^^^^^^^^^^^^^^^^^^ In the most basic case, where no configuration is made. The log level is simply set to `ERROR` for the root logger which is parent to `sympathy` and all other loggers. The `--loglevel` option takes one argument which specifies the log level for the `sympathy` logger and makes it possible to set another level than `ERROR`, used for the root logger. For example: `--loglevel warning`. The `--logger` option takes two arguments: the logger name and its log level. It can be repeated to specify the levels of multiple different loggers, for example, `--logger app error` and `--logger core warning`. The special logger name `all` can be used to configure the root logger and `sympathy` to configure our top level logger. Other logger names refer to loggers under `sympathy`, so `app` and `core` refers to `sympathy.app` and `sympathy.core` respectively. Advanced configuration ^^^^^^^^^^^^^^^^^^^^^^ For more advanced and detailed logging configuration, the `--logging-config-file` option is used to specify the dictionary used by `logging.config.dictConfig` (see https://docs.python.org/3/library/logging.config.html#configuration-functions) as a filename to a json file containing a dictionary. Config file corresponding to no logging configuration: .. literalinclude:: logging/basic_config.json :language: json Config file corresponding to `--loglevel warning`: .. literalinclude:: logging/loglevel_config.json :language: json Config file corresponding to `--logger app error` and `--logger core warning`: .. literalinclude:: logging/logger_config.json :language: json It is possible to do much more with the config file. Formatters, handlers and loggers can be configured allowing logging output to different locations and in different formats. Included :class:`sympathy.api.log.handlers.LockFileHandler` can be used to safely log output to a single file. Config file which outputs sympathy logger in debug mode to lock file: .. literalinclude:: logging/lock_file_config.json :language: json Before trying, make sure to change `lock_filename` and `filename` to where you want the output. It is also possible to use other formatting. Included :class:`sympathy.api.log.formatters.JsonFormatter` will output each log entry in JSON format: .. literalinclude:: logging/basic_json_config.json :language: json Also included are two handlers for sending log output as JSON over HTTP: :class:`sympathy.api.log.handlers.JsonBodyHTTPHandler` will post the entire log record converted to JSON and :class:`sympathy.api.log.handlers.FormatJsonBodyHTTPHandler` allows the conversion to be configured with the `JsonFormatter`. Config file which sends json formatted records over HTTP: .. literalinclude:: logging/http_json_config.json :language: json Other handlers from logging can also be used, for example, :class:`logging.handlers.SocketHandler` which pickles the log record and sends it over a TCP socket. Sending logging output to a server (HTTP or socket) can be used as an alternative to the LockFileHandler for safely logging output from different processes. Here is an example using the SocketHandler from the logging documentation: https://docs.python.org/3/howto/logging-cookbook.html#sending-and-receiving-logging-events-across-a-network.