tools.logger.define_logging()   C
last analyzed

Complexity

Conditions 8

Size

Total Lines 118
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 45
nop 10
dl 0
loc 118
rs 6.9333
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# -*- coding: utf-8
2
3
"""Helpers to log your modeling process with oemof.
4
5
This file is part of project oemof (github.com/oemof/oemof). It's copyrighted
6
by the contributors recorded in the version control history of the file,
7
available from its original location oemof/oemof/tools/logger.py
8
9
SPDX-License-Identifier: MIT
10
"""
11
12
import os
13
import sys
14
from logging import INFO
15
from logging import WARNING
16
from logging import Formatter
17
from logging import StreamHandler
18
from logging import debug
19
from logging import getLogger
20
from logging import handlers
21
from logging import info
22
23
24
def define_logging(
25
    logpath=None,
26
    logfile="oemof.log",
27
    file_format=None,
28
    screen_format=None,
29
    file_datefmt=None,
30
    screen_datefmt=None,
31
    screen_level=INFO,
32
    file_level=WARNING,
33
    log_path=True,
34
    timed_rotating=None,
35
):
36
    r"""Initialise customisable logger.
37
38
    Parameters
39
    ----------
40
    logfile : str
41
        Name of the log file, default: oemof.log
42
    logpath : str
43
        The path for log files. By default a ".oemof' folder is created in your
44
        home directory with subfolder called 'log_files'.
45
    file_format : str
46
        Format of the file output.
47
        Default: "%(asctime)s - %(levelname)s - %(module)s - %(message)s"
48
    screen_format : str
49
        Format of the screen output.
50
        Default: "%(asctime)s-%(levelname)s-%(message)s"
51
    file_datefmt : str
52
        Format of the datetime in the file output. Default: None
53
    screen_datefmt : str
54
        Format of the datetime in the screen output. Default: "%H:%M:%S"
55
    screen_level : int
56
        Level of logging to stdout. Default: 20 (logging.INFO)
57
    file_level : int
58
        Level of logging to file. Default: 30 (logging.WARNING)
59
    log_path : boolean
60
        If True the used file path is logged while initialising the logger.
61
    timed_rotating : dict
62
        Option to pass parameters to the TimedRotatingFileHandler.
63
64
65
    Returns
66
    -------
67
    str : Place where the log file is stored.
68
69
    Notes
70
    -----
71
    By default the INFO level is printed on the screen and the DEBUG level
72
    in a file, but you can easily configure the logger.
73
    Every module that wants to create logging messages has to import the
74
    logging module. The oemof logger module has to be imported once to
75
    initialise it.
76
77
    Examples
78
    --------
79
    To define the default logger you have to import the python logging
80
    library and this function. The first logging message should be the
81
    path where the log file is saved to.
82
83
    >>> import logging
84
    >>> from oemof.tools import logger
85
    >>> mypath = logger.define_logging(
86
    ...     log_path=True, timed_rotating={'backupCount': 4},
87
    ...     screen_level=logging.ERROR, screen_datefmt = "no_date")
88
    >>> mypath[-9:]
89
    'oemof.log'
90
    >>> logging.debug("Hallo")
91
    """
92
93
    if logpath is None:
94
        logpath = extend_basic_path("log_files")
95
96
    # Fetch minimal logging level
97
    if screen_level > file_level:
98
        min_level = file_level
99
    else:
100
        min_level = screen_level
101
102
    file = os.path.join(logpath, logfile)
103
104
    log = getLogger("")
105
106
    # Remove existing handlers to avoid interference.
107
    log.handlers = []
108
    log.setLevel(min_level)
109
110
    if file_format is None:
111
        file_format = "%(asctime)s - %(levelname)s - %(module)s - %(message)s"
112
    file_formatter = Formatter(file_format, file_datefmt)
113
114
    if screen_format is None:
115
        screen_format = "%(asctime)s-%(levelname)s-%(message)s"
116
    if screen_datefmt is None:
117
        screen_datefmt = "%H:%M:%S"
118
    screen_formatter = Formatter(screen_format, screen_datefmt)
119
120
    tmp_formatter = Formatter("%(message)s")
121
122
    ch = StreamHandler(sys.stdout)
123
    ch.setFormatter(screen_formatter)
124
    ch.setLevel(screen_level)
125
    log.addHandler(ch)
126
127
    timed_rotating_p = {"when": "midnight", "backupCount": 10}
128
129
    if timed_rotating is not None:
130
        timed_rotating_p.update(timed_rotating)
131
132
    fh = handlers.TimedRotatingFileHandler(file, **timed_rotating_p)
133
    fh.setFormatter(tmp_formatter)
134
    fh.setLevel(file_level)
135
    log.addHandler(fh)
136
137
    debug("******************************************************")
138
    fh.setFormatter(file_formatter)
139
    if log_path:
140
        info("Path for logging: {0}".format(file))
141
    return file
142
143
144
def extend_basic_path(subfolder):
145
    """Returns a path based on the basic oemof path and creates it if
146
    necessary. The subfolder is the name of the path extension.
147
    """
148
    extended_path = os.path.join(get_basic_path(), subfolder)
149
    if not os.path.isdir(extended_path):
150
        os.mkdir(extended_path)
151
    return extended_path
152
153
154
def get_basic_path():
155
    """Returns the basic oemof path and creates it if necessary.
156
    The basic path is the '.oemof' folder in the $HOME directory.
157
    """
158
    basicpath = os.path.join(os.path.expanduser("~"), ".oemof")
159
    if not os.path.isdir(basicpath):
160
        os.mkdir(basicpath)
161
    return basicpath
162