Logging » History » Version 6
Rafael Bailon-Ruiz, 2020-10-27 12:01
1 | 1 | Rafael Bailon-Ruiz | h1. Logging |
---|---|---|---|
2 | |||
3 | Critical information about the execution of CAMS should be displayed to the user through the Graphical User Interface. Nevertheless, less important pieces of information that are only useful to developers to diagnose the system can be recorded in logs. Messages can be also displayed in the terminal window. |
||
4 | |||
5 | 4 | Rafael Bailon-Ruiz | p{border: solid 1px #00008B; padding: 1em; margin: 1em; background: #EEF}. %{color:darkblue; font-weight: bold; font-size: large}Note:% *_print_ statements must not be used* to issue messages about the state of CAMS. This is because *1)* Standard text output cannot be traced back to the file and line of code where it has been created; *2)* Messages can not be shown or hidden according to their severity *3)* Messages cannot be easily recorded for further analysis. |
6 | 1 | Rafael Bailon-Ruiz | |
7 | h2. CAMS logging configuration |
||
8 | |||
9 | Logging in CAMS uses python "logging library":https://docs.python.org/3/library/logging.html |
||
10 | |||
11 | Python loggers are typically named after the module they are defined in (i.e.: nephelae.database.CloudData) From the "advanced python logging tutorial":https://docs.python.org/3/howto/logging.html#logging-advanced-tutorial |
||
12 | |||
13 | bq. A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: |
||
14 | <pre><code class="python"> |
||
15 | logger = logging.getLogger(__name__) |
||
16 | </code></pre> |
||
17 | This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name. |
||
18 | |||
19 | CAMS uses this scheme with loggers defined per module/file. *Because the CAMS code base layout is one class = one module, the number of logger objects can be big. Check if this extensive logging approach has in impact in performance* |
||
20 | |||
21 | 5 | Rafael Bailon-Ruiz | The recommended logger initialization in CAMS is to run the following code *before any module imports*: |
22 | 1 | Rafael Bailon-Ruiz | |
23 | <pre><code class="python"> |
||
24 | import logger |
||
25 | 5 | Rafael Bailon-Ruiz | _logger = logging.getLogger(__name__) |
26 | 1 | Rafael Bailon-Ruiz | </code></pre> |
27 | |||
28 | 5 | Rafael Bailon-Ruiz | Single leading underscore indicates that the object is not part of the public API. |
29 | |||
30 | 1 | Rafael Bailon-Ruiz | |
31 | 3 | Rafael Bailon-Ruiz | The python logging guide recommends adding the empty handler be default to prevent "No handlers could be found for logger X.Y.Z" messages from appearing. |
32 | |||
33 | <pre><code class="python"> |
||
34 | import logging |
||
35 | logging.getLogger(__name__).addHandler(logging.NullHandler()) |
||
36 | </code></pre> |
||
37 | |||
38 | Django configures handlers by default so there is no risk for CAMS unless libraries are used independently. |
||
39 | |||
40 | 6 | Rafael Bailon-Ruiz | h3. Setup the log level |
41 | |||
42 | Environment variables control the log level by setting them to one of <code class="shell">DEBUG</code>, <code class="shell">INFO</code>, <code class="shell">WARNING</code>, <code class="shell">ERROR</code> : |
||
43 | |||
44 | * <code class="shell">DJANGO_LOG_LEVEL</code> django related loggers |
||
45 | * <code class="shell">CAMS_LOG_LEVEL</code> general log level (cams libraries and external) |
||
46 | |||
47 | Detailed configuration options are found in the django settings for the gui project (<code class="shell">settings.py</code>) |
||
48 | |||
49 | 1 | Rafael Bailon-Ruiz | h2. See also |
50 | |||
51 | "Configuring Logging for a Library":https://docs.python.org/3/howto/logging.html#library-config |
||
52 | "Good logging practice in Python":https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/ |