Difference between revisions of "Logging system"

From Gramps
Jump to: navigation, search
(New page: ==GRAMPS Logging System== The logging system in Gramps is based on the logging facility of [http://docs.python.org/lib/module-logging.html Python]. ===Handler subclasses=== There are thre...)
 
m (If debugging is enabled)
(19 intermediate revisions by 8 users not shown)
Line 1: Line 1:
==GRAMPS Logging System==
+
The Gramps Logging System is based on [https://docs.python.org/library/logging.html Python]s logging facility.
The logging system in Gramps is based on the logging facility of [http://docs.python.org/lib/module-logging.html Python].
 
  
===Handler subclasses===
+
==Handler subclasses==
 
There are three Handler subclasses defined:
 
There are three Handler subclasses defined:
 
* RotateHandler
 
* RotateHandler
 
* GtkHandler
 
* GtkHandler
 
* WarnHandler
 
* WarnHandler
====RotateHandler(logging.Handle) (GrampsLogging._RotateHandler.py)====
+
 
 +
===RotateHandler(logging.Handle) (GrampsLogging._RotateHandler.py)===
 
The RotateHandler just keeps a rotating buffer of the last N (defined at instantiation) log messages sent to it. It can be used e.g. with the GtkHandler to pass a history of log messages to the ErrorReportAssistant().
 
The RotateHandler just keeps a rotating buffer of the last N (defined at instantiation) log messages sent to it. It can be used e.g. with the GtkHandler to pass a history of log messages to the ErrorReportAssistant().
====GtkHandler(logging.Handle) (GrampsLogging._GtkHandler.py)====
+
 
 +
===GtkHandler(logging.Handle) (GrampsLogging._GtkHandler.py)===
 
The GtkHandler will pop up a gtk dialog when a log message is sent to it. The dialog offers the user the chance to start ErrorReportAssistant() to send a bug report.
 
The GtkHandler will pop up a gtk dialog when a log message is sent to it. The dialog offers the user the chance to start ErrorReportAssistant() to send a bug report.
==== WarnHandler(RotateHandler) (DisplayState.py)====
+
 
 +
=== WarnHandler(RotateHandler) (DisplayState.py)===
 
The WarnHandler is a subclass of RotateHandler thus buffers the last N logs (log level WARNING or above) it received. Additionally it has a button assigned, which will be shown for 180 sec. after a log is received. Activating this button the WarnHandler will pop up a dialog with the list of the buffered logs.
 
The WarnHandler is a subclass of RotateHandler thus buffers the last N logs (log level WARNING or above) it received. Additionally it has a button assigned, which will be shown for 180 sec. after a log is received. Activating this button the WarnHandler will pop up a dialog with the list of the buffered logs.
===Handler instances===
+
 
 +
==Handler instances==
 
Currently there is one instance of each of the above Handler classes in Gramps. Additionally there's also a StreamHandler() defined with <tt>sys.stderr</tt> as output stream for debugging purposes. All of these Handlers are attached to the root logger, thus active for any later defined logger.
 
Currently there is one instance of each of the above Handler classes in Gramps. Additionally there's also a StreamHandler() defined with <tt>sys.stderr</tt> as output stream for debugging purposes. All of these Handlers are attached to the root logger, thus active for any later defined logger.
 +
 
The RotateHandler, GtkHandler and StreamHandler are all instantiated in <tt>gramps.py</tt> (setup_logging), while Warnhandler is instantiated in <tt>DisplayState.py</tt> (DisplayState.__init__). Rotatehandler is attached also to GtkHandler for the purpose described in GtkHandler description. Each Handler instance has a custom formatter assigned.
 
The RotateHandler, GtkHandler and StreamHandler are all instantiated in <tt>gramps.py</tt> (setup_logging), while Warnhandler is instantiated in <tt>DisplayState.py</tt> (DisplayState.__init__). Rotatehandler is attached also to GtkHandler for the purpose described in GtkHandler description. Each Handler instance has a custom formatter assigned.
{| border="1"
+
 
 +
{| class="wikitable sortable"
 
|+Handler instance parameters
 
|+Handler instance parameters
 
|-
 
|-
Line 29: Line 34:
 
|StreamHandler || DEBUG || "%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s" || -
 
|StreamHandler || DEBUG || "%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s" || -
 
|}
 
|}
===Loggers===
+
 
 +
==Loggers==
 
The log level of the root logger is set to WARNING by default. In case debugging is activated it may be set to DEBUG (see Enable Debugging). In each module it is recommended to define an own Logger object to be able to understand, which module a certain log (error) is generated from. Setting own log level to a logger is not recommended.
 
The log level of the root logger is set to WARNING by default. In case debugging is activated it may be set to DEBUG (see Enable Debugging). In each module it is recommended to define an own Logger object to be able to understand, which module a certain log (error) is generated from. Setting own log level to a logger is not recommended.
===Enable Debugging===
+
 
 +
==Enable Debugging==
 
Since the log level of the root logger is set to WARNING by default the StreamHandler will also receive only log at level WARNING and above. To enable debug logs the <tt>-d</tt> or <tt>--debug</tt> command line switch is defined. The debug log can be enabled globally by setting the log level of the root logger, or only for a specific module by setting the log level of the logger defined in that particular module.
 
Since the log level of the root logger is set to WARNING by default the StreamHandler will also receive only log at level WARNING and above. To enable debug logs the <tt>-d</tt> or <tt>--debug</tt> command line switch is defined. The debug log can be enabled globally by setting the log level of the root logger, or only for a specific module by setting the log level of the logger defined in that particular module.
 +
 
The usage of the switch is quite simple:
 
The usage of the switch is quite simple:
  python gramps.py -d="name_of_the_logger"
+
 
 +
  python Gramps.py -d "name_of_the_logger"
 +
 
 
or:
 
or:
  pyhon gramps.py --debug="name_of_the_logger"
+
 
 +
  python Gramps.py --debug="name_of_the_logger"
 +
 
 
The name of the root logger is an empty string, thus e.g. <tt>--debug=""</tt> will enable all debug logs.
 
The name of the root logger is an empty string, thus e.g. <tt>--debug=""</tt> will enable all debug logs.
<blockquote>'''Note!''' The argument of the switch is <u>not</u> optional.</blockquote>
+
{{man warn|Note!|The argument of the switch is <u>not</u> optional.}}
===So how logging works in Gramps after all?===
+
 
====If debugging is not enabled====
+
==So how logging works in Gramps after all?==
 +
===If debugging is not enabled===
 
* all WARNING and above level logs will be buffered by WarnHandler and can be seen by pressing the warn_button within 3 minutes after the latest log is received.
 
* all WARNING and above level logs will be buffered by WarnHandler and can be seen by pressing the warn_button within 3 minutes after the latest log is received.
* all ERROR and above level logs will raise a dialog showing the log. If user votes on reporting the error the ReportAssistant() window will be called with the latest 20 logs included.
+
* all ERROR and above level logs will raise a dialog showing the log. If user votes on reporting the error the ErrorReportAssistant() window will be called with the latest 20 logs included.
 
* all WARNING and above level logs are sent to the stderr stream.
 
* all WARNING and above level logs are sent to the stderr stream.
====If debugging is enabled====
+
 
 +
===If debugging is enabled===
 
*all DEBUG and INFO level logs are additionally sent to stderr stream from the enabled logger.
 
*all DEBUG and INFO level logs are additionally sent to stderr stream from the enabled logger.
 
<blockquote>'''Note!''' All unhandled exception will send an ERROR level log with the traceback included.</blockquote>
 
<blockquote>'''Note!''' All unhandled exception will send an ERROR level log with the traceback included.</blockquote>
 +
 +
* A developer can add to a module eg:
 +
 +
import logging
 +
_LOG = logging.getLogger('.pageview')
 +
 +
:And then in some function
 +
 +
_LOG.debug('a debug message')
 +
 +
:To see this message in a terminal, one starts Gramps with the debug option followed by the debug logger one wants to see:
 +
 +
python src/gramps.py -d '.pageview'
 +
 +
:Strings need to be double-quoted on Windows, this is the Windows equivalent of the above command (with the "all in one installer" executed from "C:\Program Files\GrampsAIO64-5.1.2"):
 +
 +
grampsw.exe -d ".pageview"
 +
 +
:On Windows the log output goes into the file "%AppData%\gramps\Gramps51.log" (which is cleared every time the app restarts).
 +
[[Category:Developers/Reference]]
 +
[[Category:Developers/Tutorials]]
 +
[[Category:Developers/General]]

Revision as of 23:46, 11 May 2020

The Gramps Logging System is based on Pythons logging facility.

Handler subclasses

There are three Handler subclasses defined:

  • RotateHandler
  • GtkHandler
  • WarnHandler

RotateHandler(logging.Handle) (GrampsLogging._RotateHandler.py)

The RotateHandler just keeps a rotating buffer of the last N (defined at instantiation) log messages sent to it. It can be used e.g. with the GtkHandler to pass a history of log messages to the ErrorReportAssistant().

GtkHandler(logging.Handle) (GrampsLogging._GtkHandler.py)

The GtkHandler will pop up a gtk dialog when a log message is sent to it. The dialog offers the user the chance to start ErrorReportAssistant() to send a bug report.

WarnHandler(RotateHandler) (DisplayState.py)

The WarnHandler is a subclass of RotateHandler thus buffers the last N logs (log level WARNING or above) it received. Additionally it has a button assigned, which will be shown for 180 sec. after a log is received. Activating this button the WarnHandler will pop up a dialog with the list of the buffered logs.

Handler instances

Currently there is one instance of each of the above Handler classes in Gramps. Additionally there's also a StreamHandler() defined with sys.stderr as output stream for debugging purposes. All of these Handlers are attached to the root logger, thus active for any later defined logger.

The RotateHandler, GtkHandler and StreamHandler are all instantiated in gramps.py (setup_logging), while Warnhandler is instantiated in DisplayState.py (DisplayState.__init__). Rotatehandler is attached also to GtkHandler for the purpose described in GtkHandler description. Each Handler instance has a custom formatter assigned.

Handler instance parameters
Handler Log level Formatter Capacity (buffer size)
RotateHandler - "%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s" 20
GtkHandler ERROR "%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s" -
WarnHandler WARNING "%(levelname)s %(name)s: %(message)s" 400
StreamHandler DEBUG "%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s" -

Loggers

The log level of the root logger is set to WARNING by default. In case debugging is activated it may be set to DEBUG (see Enable Debugging). In each module it is recommended to define an own Logger object to be able to understand, which module a certain log (error) is generated from. Setting own log level to a logger is not recommended.

Enable Debugging

Since the log level of the root logger is set to WARNING by default the StreamHandler will also receive only log at level WARNING and above. To enable debug logs the -d or --debug command line switch is defined. The debug log can be enabled globally by setting the log level of the root logger, or only for a specific module by setting the log level of the logger defined in that particular module.

The usage of the switch is quite simple:

python Gramps.py -d "name_of_the_logger"

or:

python Gramps.py --debug="name_of_the_logger"

The name of the root logger is an empty string, thus e.g. --debug="" will enable all debug logs.

Gnome-important.png
Note!

The argument of the switch is not optional.

So how logging works in Gramps after all?

If debugging is not enabled

  • all WARNING and above level logs will be buffered by WarnHandler and can be seen by pressing the warn_button within 3 minutes after the latest log is received.
  • all ERROR and above level logs will raise a dialog showing the log. If user votes on reporting the error the ErrorReportAssistant() window will be called with the latest 20 logs included.
  • all WARNING and above level logs are sent to the stderr stream.

If debugging is enabled

  • all DEBUG and INFO level logs are additionally sent to stderr stream from the enabled logger.

Note! All unhandled exception will send an ERROR level log with the traceback included.

  • A developer can add to a module eg:
import logging
_LOG = logging.getLogger('.pageview')
And then in some function
_LOG.debug('a debug message')
To see this message in a terminal, one starts Gramps with the debug option followed by the debug logger one wants to see:
python src/gramps.py -d '.pageview'
Strings need to be double-quoted on Windows, this is the Windows equivalent of the above command (with the "all in one installer" executed from "C:\Program Files\GrampsAIO64-5.1.2"):
grampsw.exe -d ".pageview"
On Windows the log output goes into the file "%AppData%\gramps\Gramps51.log" (which is cleared every time the app restarts).