bci_essentials.utils.logger

Utility for logging within BCI-Essentials.

This module provides a Logger wrapper class that allows for easy configuration of logging settings for the 'bci_essentials' package. The Logger class provides methods to initialize and configure the logger.

It uses the logging module from Python's standard library to handle the logging functionality. The logging levels are the same as the ones in the logging module. They are given here in order of increasing severity. When the logging level is set to a particular level, all messages of that level and higher will be logged.

The logging levels can be accessed as class properties of the Logger class. For example, the Logger.INFO property can be used to set the logging level to INFO.

Logging Levels

DEBUG : Debug level logging. This level outputs detailed information, typically of interest only when diagnosing problems. INFO : Info level logging. Confirmation that things are working as expected. - Default logging level for the 'bci_essentials' package WARNING : Warning level logging. An indication that something unexpected happened, or indicative of some problem in the near future (e.g., 'disk space low'). The software is still working as expected. ERROR : Error level logging. Due to a more serious problem, the software has not been able to perform some function. CRITICAL : Critical level logging. A serious error, indicating that the program itself may be unable to continue running.

Examples

Example 1: Creating a Logger object within the 'bci_essentials' package

The following example shows how to use the Logger class within the 'bci_essentials' package, i.e. within package modules. Modules use module-specific child loggers to log messages. The child loggers inherit from the package logger bci_essentials which is configured in the package __init__.py file.

After importing the Logger class, a child logger is created and inherits the package default log level of Logger.INFO. The name of the logger is set to the name the module it is being used in (e.g. 'bci_essentials.utils.logger') so that log messages can be traced back to the module they originated from.

from bci_essentials.utils.logger import Logger logger = Logger(name=__name__)

Example 2: Creating the Logger object outside of the 'bci_essentials' package

The following example shows how to use the Logger class to create a logger within a User script. After importing the Logger class, the User can create a logger for their script with the default logging level of INFO.

from bci_essentials.utils.logger import Logger user_logger = Logger(name="my_script")

If the user wishes to set a different log level for logs within their script, they can use the setLevel() method.

from bci_essentials.utils.logger import Logger logger = Logger(name="my_script") # A logger for the user script logger.setLevel(Logger.DEBUG)

Example 3: Modifying the logging level of the 'bci_essentials' package in a User script

If a User wishes to modify the logging behaviour of the bci_essentials package in their user script, they can retrieve the package logger and modify its logging level.

from bci_essentials.utils.logger import Logger bessy_logger = Logger(name='bci_essentials') # bci_essentials logger bessy_logger.setLevel(Logger.DEBUG)

A User can still use the Logger class to create an indepenent logger for their script, as shown in Example 2 above, and control the logging behaviour of their user script separately from the logging behaviour of the bci_essentials package.

Example 4: Logging messages

After creating the logger instance, log messages can be recorded in the same way as the logging module, calling methods for debug(), info(), warning(), error(), and critical() messages. The logger instance will automatically log the name of the module it is being used in, along with the logging level and the message.

logger.debug("This is a DEBUG message") logger.info("This is an INFO message") logger.logger.warning("This is a warning message") logger.logger.error("This is an error message") logger.logger.critical("This is a critical message")

This is an example of including a variable in the output at the INFO level:

logger.info("The number of channels is %s", n_channels)

Example 5: Changing the logging level after Logger instantiation

The logging level can be changed after instantiation using the setLevel() method. All messages of that level and higher will be logged going forward (i.e. after the logging level is changed).

Note: See example 3 above for an example of changing the logging level of bci_essentials package in a User script.

Here is an example of changing the logging level to DEBUG:

logger.setLevel(Logger.DEBUG)

Here is an example of changing the logging level to ERROR:

logger.setLevel(Logger.ERROR)

The logger level can be reset to the default level using:

logger.setLevel()

Example 6: Saving logs to a file

The logger can be configured to simultaneously save logs to a file using the start_saving() method. This will save all logs AFTER this function is called. Messages before this function is called will not be saved. The filename can be specified as an argument to the function. If no filename is specified, the default filename will be used, which is the current date and time in the format "YYYYmmdd-HHMS-bci_essentials.log".

Here is an example of saving logs to a file with the default filename:

logger.start_saving()

Here is an example of saving logs to a file with a specified filename:

logger.start_saving(filename="my_log_file.log")

Note: The file saving behaviour is for the logger instance only. If the user wish to save logs from the bci_essentials package, they must retrieve the bci_essentials logger and configure it to save logs to a file. E.g.

bessy_logger = Logger(name='bci_essentials') # bci_essentials logger bessy_logger.start_saving()

  1"""Utility for logging within BCI-Essentials.
  2
  3This module provides a `Logger` wrapper class that allows for easy
  4configuration of logging settings for the 'bci_essentials' package.
  5The `Logger` class provides methods to initialize and configure the logger.
  6
  7It uses the `logging` module from Python's standard library to handle
  8the logging functionality. The logging levels are the same as the ones
  9in the `logging` module. They are given here in order of increasing
 10severity. When the logging level is set to a particular level, all
 11messages of that level and higher will be logged.
 12
 13The logging levels can be accessed as class properties of the `Logger`
 14class. For example, the `Logger.INFO` property can be used to set the
 15logging level to INFO.
 16
 17Logging Levels
 18--------------
 19DEBUG :
 20    Debug level logging. This level outputs detailed information,
 21    typically of interest only when diagnosing problems.
 22INFO :
 23    Info level logging. Confirmation that things are working as expected.
 24    - Default logging level for the 'bci_essentials' package
 25WARNING :
 26    Warning level logging. An indication that something unexpected happened,
 27    or indicative of some problem in the near future (e.g., 'disk space low').
 28    The software is still working as expected.
 29ERROR :
 30    Error level logging. Due to a more serious problem, the software has not
 31    been able to perform some function.
 32CRITICAL :
 33    Critical level logging. A serious error, indicating that the program itself
 34    may be unable to continue running.
 35
 36
 37Examples
 38--------
 39
 40Example 1: Creating a Logger object within the 'bci_essentials' package
 41-----------------------------------------------------------------------
 42The following example shows how to use the `Logger` class within the
 43'bci_essentials' package, i.e. within package modules. Modules use
 44module-specific child loggers to log messages. The child loggers inherit
 45from the package logger `bci_essentials` which is configured in the
 46package __init__.py file.
 47
 48After importing the `Logger` class, a child logger is created and inherits
 49the package default log level of `Logger.INFO`. The name of the logger is
 50set to the name the module it is being used in (e.g. 'bci_essentials.utils.logger')
 51so that log messages can be traced back to the module they originated from.
 52    >>> from bci_essentials.utils.logger import Logger
 53    >>> logger = Logger(name=__name__)
 54
 55
 56Example 2: Creating the Logger object outside of the 'bci_essentials' package
 57-----------------------------------------------------------------------------
 58The following example shows how to use the `Logger` class to create a logger
 59within a **User** script. After importing the `Logger` class, the User can
 60create a logger for their script with the default logging level of INFO.
 61    >>> from bci_essentials.utils.logger import Logger
 62    >>> user_logger = Logger(name="my_script")
 63
 64If the user wishes to set a different log level for logs within their script,
 65they can use the `setLevel()` method.
 66    >>> from bci_essentials.utils.logger import Logger
 67    >>> logger = Logger(name="my_script")  # A logger for the user script
 68    >>> logger.setLevel(Logger.DEBUG)
 69
 70
 71Example 3: Modifying the logging level of the 'bci_essentials' package in a User script
 72---------------------------------------------------------------------------------------
 73If a User wishes to modify the logging behaviour of the bci_essentials package in their
 74user script, they can retrieve the package logger and modify its logging level.
 75    >>> from bci_essentials.utils.logger import Logger
 76    >>> bessy_logger = Logger(name='bci_essentials')  # bci_essentials logger
 77    >>> bessy_logger.setLevel(Logger.DEBUG)
 78
 79A User can still use the `Logger` class to create an indepenent logger for their script,
 80as shown in Example 2 above, and control the logging behaviour of their user script
 81separately from the logging behaviour of the bci_essentials package.
 82
 83
 84Example 4: Logging messages
 85---------------------------
 86After creating the logger instance, log messages can be recorded in the
 87same way as the `logging` module, calling methods for debug(), info(),
 88warning(), error(), and critical() messages. The logger instance will
 89automatically log the name of the module it is being used in, along with
 90the logging level and the message.
 91    >>> logger.debug("This is a DEBUG message")
 92    >>> logger.info("This is an INFO message")
 93    >>> logger.logger.warning("This is a warning message")
 94    >>> logger.logger.error("This is an error message")
 95    >>> logger.logger.critical("This is a critical message")
 96
 97This is an example of including a variable in the output at the INFO level:
 98    >>> logger.info("The number of channels is %s", n_channels)
 99
100
101Example 5: Changing the logging level after Logger instantiation
102----------------------------------------------------------------
103The logging level can be changed after instantiation using the `setLevel()`
104method. All messages of that level and higher will be logged going forward
105(i.e. after the logging level is changed).
106
107Note: See example 3 above for an example of changing the logging level of
108bci_essentials package in a User script.
109
110Here is an example of changing the logging level to DEBUG:
111    >>> logger.setLevel(Logger.DEBUG)
112
113Here is an example of changing the logging level to ERROR:
114    >>> logger.setLevel(Logger.ERROR)
115
116The logger level can be reset to the default level using:
117    >>> logger.setLevel()
118
119
120Example 6: Saving logs to a file
121--------------------------------
122The logger can be configured to simultaneously save logs to a file using
123the `start_saving()` method. This will save all logs **AFTER** this
124function is called. *Messages before this function is called will not be
125saved*. The filename can be specified as an argument to the function.
126If no filename is specified, the default filename will be used, which is
127the current date and time in the format "YYYYmmdd-HHMS-bci_essentials.log".
128
129Here is an example of saving logs to a file with the default filename:
130    >>> logger.start_saving()
131
132Here is an example of saving logs to a file with a specified filename:
133    >>> logger.start_saving(filename="my_log_file.log")
134
135Note: The file saving behaviour is for the logger instance only. If the user
136wish to save logs from the bci_essentials package, they must retrieve the
137bci_essentials logger and configure it to save logs to a file. E.g.
138    >>> bessy_logger = Logger(name='bci_essentials')  # bci_essentials logger
139    >>> bessy_logger.start_saving()
140
141"""
142
143import logging
144import datetime
145
146
147class Logger:
148    """
149    A custom logger for the 'bci_essentials' package.
150
151    This class provides an easy-to-use interface for logging within the 'bci_essentials'
152    package. It supports standard logging levels and allows saving log messages to a
153    file.
154
155    Class Properties
156    ----------------
157    DEBUG : logging.Level
158        Debug level logging.
159    INFO : logging.Level
160        Info level logging.
161    WARNING : logging.Level
162        Warning level logging.
163    ERROR : logging.Level
164        Error level logging.
165    CRITICAL : logging.Level
166        Critical level logging.
167
168    """
169
170    # Define logging levels as a Class Property for easy access.
171    # These are the same as the logging levels in the `logging` module.
172    DEBUG = logging.DEBUG
173    INFO = logging.INFO
174    WARNING = logging.WARNING
175    ERROR = logging.ERROR
176    CRITICAL = logging.CRITICAL
177
178    # Setting the default logging level to INFO
179    # Update docstrings on __init__ and setLevel() if this is changed
180    __default_level = INFO
181    # Mapping of logging levels to their string representations
182    __level_names = {
183        logging.DEBUG: "DEBUG",
184        logging.INFO: "INFO",
185        logging.WARNING: "WARNING",
186        logging.ERROR: "ERROR",
187        logging.CRITICAL: "CRITICAL",
188    }
189
190    def __init__(self, name="bci_essentials"):
191        """
192        Initializes and configures the logger.
193
194        Parameters
195        ----------
196        name : str, *optional*
197            Name of the logger.
198            – Default is 'bci_essentials'.
199        """
200
201        self.logger = logging.getLogger(name)
202
203        # Check if this logger already has handlers set up
204        if not self.logger.hasHandlers():
205            self.__configure()
206
207    def __configure(self):
208        """Configures the logger with the default level and format."""
209        # Set log message format
210        formatter = logging.Formatter(
211            fmt="%(asctime)s - %(levelname)s - %(name)s : %(message)s",
212            datefmt="%Y-%m-%d %H:%M:%S",
213        )
214
215        # Set the logging level to the default level
216        self.logger.setLevel(self.__default_level)
217
218        # Create and add a console handler at the default log level
219        console_handler = logging.StreamHandler()
220        console_handler.setFormatter(formatter)
221        console_handler.setLevel(self.__default_level)
222        self.logger.addHandler(console_handler)
223
224    def setLevel(self, level=__default_level):
225        """Sets the logging level for the logger.
226
227        Parameters
228        ----------
229        level : logging.Level
230            Logging level as per python `logging` module. This can be set using
231            the class properties `Logger.DEBUG`, `Logger.INFO`,
232            `Logger.WARNING`, `Logger.ERROR`, and `Logger.CRITICAL`.
233            - Default is `Logger.INFO`.
234
235        """
236        # Inform the user of the new logging level
237        level_name = self.__level_names.get(level, "Unknown Level")
238        self.info(f"Setting logging level to {level_name}")
239
240        # Set the level for the logger
241        self.logger.setLevel(level)
242
243        # Also set the level for all handlers of the logger
244        for handler in self.logger.handlers:
245            handler.setLevel(level)
246
247    def start_saving(self, filename=None):
248        """Enables saving logs to a file.
249
250        Log messages AFTER this function has been called will be saved
251        to a text file using either the specified or default filename.
252
253        **NOTE**: Messages before this function is called will not be saved.
254
255        Parameters
256        ----------
257        filename : str, *optional*
258            Name of the file to log messages to
259            - Default is is "YYYYmmdd-HHMMSS-bci_essentials.log".
260        """
261        if filename is None:
262            filename = (
263                datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
264                + "-bci_essentials.log"
265            )
266        self.info(f"Logging to file: {filename}")
267
268        file_handler = logging.FileHandler(filename)
269        file_formatter = logging.Formatter(
270            "%(asctime)s - %(levelname)s - %(name)s : %(message)s"
271        )
272        file_handler.setFormatter(file_formatter)
273        self.logger.addHandler(file_handler)
274
275    def debug(self, msg, *args, **kwargs):
276        """
277        Logs a DEBUG message.
278
279        Parameters
280        ----------
281        msg : str
282            The log message format string.
283        *args
284            Arguments merged into msg using string formatting.
285        **kwargs
286            Additional keyword arguments.
287
288        Examples
289        --------
290        >>> logger.debug("Debug message with variable: %s", variable_name)
291        """
292        self.logger.debug(msg, *args, **kwargs)
293
294    def info(self, msg, *args, **kwargs):
295        """
296        Logs an INFO message.
297
298        Parameters
299        ----------
300        msg : str
301            The log message format string.
302        *args
303            Arguments merged into msg using string formatting.
304        **kwargs
305            Additional keyword arguments.
306
307        Examples
308        --------
309        >>> logger.info("Info message with variable: %s", variable_name)
310        """
311        self.logger.info(msg, *args, **kwargs)
312
313    def warning(self, msg, *args, **kwargs):
314        """
315        Logs a WARNING message.
316
317        Parameters
318        ----------
319        msg : str
320            The log message format string.
321        *args
322            Arguments merged into msg using string formatting.
323        **kwargs
324            Additional keyword arguments.
325
326        Examples
327        --------
328        >>> logger.warning("Warning message with variable: %s", variable_name)
329        """
330        self.logger.warning(msg, *args, **kwargs)
331
332    def error(self, msg, *args, **kwargs):
333        """
334        Logs an ERROR message.
335
336        Parameters
337        ----------
338        msg : str
339            The log message format string.
340        *args
341            Arguments merged into msg using string formatting.
342        **kwargs
343            Additional keyword arguments.
344
345        Examples
346        --------
347        >>> logger.error("Error message with variable: %s", variable_name)
348        """
349        self.logger.error(msg, *args, **kwargs)
350
351    def critical(self, msg, *args, **kwargs):
352        """
353        Logs a CRITICAL message.
354
355        Parameters
356        ----------
357        msg : str
358            The log message format string.
359        *args
360            Arguments merged into msg using string formatting.
361        **kwargs
362            Additional keyword arguments.
363
364        Examples
365        --------
366        >>> logger.critical("Critical message with variable: %s", variable_name)
367        """
368        self.logger.critical(msg, *args, **kwargs)
class Logger:
148class Logger:
149    """
150    A custom logger for the 'bci_essentials' package.
151
152    This class provides an easy-to-use interface for logging within the 'bci_essentials'
153    package. It supports standard logging levels and allows saving log messages to a
154    file.
155
156    Class Properties
157    ----------------
158    DEBUG : logging.Level
159        Debug level logging.
160    INFO : logging.Level
161        Info level logging.
162    WARNING : logging.Level
163        Warning level logging.
164    ERROR : logging.Level
165        Error level logging.
166    CRITICAL : logging.Level
167        Critical level logging.
168
169    """
170
171    # Define logging levels as a Class Property for easy access.
172    # These are the same as the logging levels in the `logging` module.
173    DEBUG = logging.DEBUG
174    INFO = logging.INFO
175    WARNING = logging.WARNING
176    ERROR = logging.ERROR
177    CRITICAL = logging.CRITICAL
178
179    # Setting the default logging level to INFO
180    # Update docstrings on __init__ and setLevel() if this is changed
181    __default_level = INFO
182    # Mapping of logging levels to their string representations
183    __level_names = {
184        logging.DEBUG: "DEBUG",
185        logging.INFO: "INFO",
186        logging.WARNING: "WARNING",
187        logging.ERROR: "ERROR",
188        logging.CRITICAL: "CRITICAL",
189    }
190
191    def __init__(self, name="bci_essentials"):
192        """
193        Initializes and configures the logger.
194
195        Parameters
196        ----------
197        name : str, *optional*
198            Name of the logger.
199            – Default is 'bci_essentials'.
200        """
201
202        self.logger = logging.getLogger(name)
203
204        # Check if this logger already has handlers set up
205        if not self.logger.hasHandlers():
206            self.__configure()
207
208    def __configure(self):
209        """Configures the logger with the default level and format."""
210        # Set log message format
211        formatter = logging.Formatter(
212            fmt="%(asctime)s - %(levelname)s - %(name)s : %(message)s",
213            datefmt="%Y-%m-%d %H:%M:%S",
214        )
215
216        # Set the logging level to the default level
217        self.logger.setLevel(self.__default_level)
218
219        # Create and add a console handler at the default log level
220        console_handler = logging.StreamHandler()
221        console_handler.setFormatter(formatter)
222        console_handler.setLevel(self.__default_level)
223        self.logger.addHandler(console_handler)
224
225    def setLevel(self, level=__default_level):
226        """Sets the logging level for the logger.
227
228        Parameters
229        ----------
230        level : logging.Level
231            Logging level as per python `logging` module. This can be set using
232            the class properties `Logger.DEBUG`, `Logger.INFO`,
233            `Logger.WARNING`, `Logger.ERROR`, and `Logger.CRITICAL`.
234            - Default is `Logger.INFO`.
235
236        """
237        # Inform the user of the new logging level
238        level_name = self.__level_names.get(level, "Unknown Level")
239        self.info(f"Setting logging level to {level_name}")
240
241        # Set the level for the logger
242        self.logger.setLevel(level)
243
244        # Also set the level for all handlers of the logger
245        for handler in self.logger.handlers:
246            handler.setLevel(level)
247
248    def start_saving(self, filename=None):
249        """Enables saving logs to a file.
250
251        Log messages AFTER this function has been called will be saved
252        to a text file using either the specified or default filename.
253
254        **NOTE**: Messages before this function is called will not be saved.
255
256        Parameters
257        ----------
258        filename : str, *optional*
259            Name of the file to log messages to
260            - Default is is "YYYYmmdd-HHMMSS-bci_essentials.log".
261        """
262        if filename is None:
263            filename = (
264                datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
265                + "-bci_essentials.log"
266            )
267        self.info(f"Logging to file: {filename}")
268
269        file_handler = logging.FileHandler(filename)
270        file_formatter = logging.Formatter(
271            "%(asctime)s - %(levelname)s - %(name)s : %(message)s"
272        )
273        file_handler.setFormatter(file_formatter)
274        self.logger.addHandler(file_handler)
275
276    def debug(self, msg, *args, **kwargs):
277        """
278        Logs a DEBUG message.
279
280        Parameters
281        ----------
282        msg : str
283            The log message format string.
284        *args
285            Arguments merged into msg using string formatting.
286        **kwargs
287            Additional keyword arguments.
288
289        Examples
290        --------
291        >>> logger.debug("Debug message with variable: %s", variable_name)
292        """
293        self.logger.debug(msg, *args, **kwargs)
294
295    def info(self, msg, *args, **kwargs):
296        """
297        Logs an INFO message.
298
299        Parameters
300        ----------
301        msg : str
302            The log message format string.
303        *args
304            Arguments merged into msg using string formatting.
305        **kwargs
306            Additional keyword arguments.
307
308        Examples
309        --------
310        >>> logger.info("Info message with variable: %s", variable_name)
311        """
312        self.logger.info(msg, *args, **kwargs)
313
314    def warning(self, msg, *args, **kwargs):
315        """
316        Logs a WARNING message.
317
318        Parameters
319        ----------
320        msg : str
321            The log message format string.
322        *args
323            Arguments merged into msg using string formatting.
324        **kwargs
325            Additional keyword arguments.
326
327        Examples
328        --------
329        >>> logger.warning("Warning message with variable: %s", variable_name)
330        """
331        self.logger.warning(msg, *args, **kwargs)
332
333    def error(self, msg, *args, **kwargs):
334        """
335        Logs an ERROR message.
336
337        Parameters
338        ----------
339        msg : str
340            The log message format string.
341        *args
342            Arguments merged into msg using string formatting.
343        **kwargs
344            Additional keyword arguments.
345
346        Examples
347        --------
348        >>> logger.error("Error message with variable: %s", variable_name)
349        """
350        self.logger.error(msg, *args, **kwargs)
351
352    def critical(self, msg, *args, **kwargs):
353        """
354        Logs a CRITICAL message.
355
356        Parameters
357        ----------
358        msg : str
359            The log message format string.
360        *args
361            Arguments merged into msg using string formatting.
362        **kwargs
363            Additional keyword arguments.
364
365        Examples
366        --------
367        >>> logger.critical("Critical message with variable: %s", variable_name)
368        """
369        self.logger.critical(msg, *args, **kwargs)

A custom logger for the 'bci_essentials' package.

This class provides an easy-to-use interface for logging within the 'bci_essentials' package. It supports standard logging levels and allows saving log messages to a file.

Class Properties

DEBUG : logging.Level Debug level logging. INFO : logging.Level Info level logging. WARNING : logging.Level Warning level logging. ERROR : logging.Level Error level logging. CRITICAL : logging.Level Critical level logging.

Logger(name='bci_essentials')
191    def __init__(self, name="bci_essentials"):
192        """
193        Initializes and configures the logger.
194
195        Parameters
196        ----------
197        name : str, *optional*
198            Name of the logger.
199            – Default is 'bci_essentials'.
200        """
201
202        self.logger = logging.getLogger(name)
203
204        # Check if this logger already has handlers set up
205        if not self.logger.hasHandlers():
206            self.__configure()

Initializes and configures the logger.

Parameters
  • name (str, optional): Name of the logger. – Default is 'bci_essentials'.
DEBUG = 10
INFO = 20
WARNING = 30
ERROR = 40
CRITICAL = 50
logger
def setLevel(self, level=20):
225    def setLevel(self, level=__default_level):
226        """Sets the logging level for the logger.
227
228        Parameters
229        ----------
230        level : logging.Level
231            Logging level as per python `logging` module. This can be set using
232            the class properties `Logger.DEBUG`, `Logger.INFO`,
233            `Logger.WARNING`, `Logger.ERROR`, and `Logger.CRITICAL`.
234            - Default is `Logger.INFO`.
235
236        """
237        # Inform the user of the new logging level
238        level_name = self.__level_names.get(level, "Unknown Level")
239        self.info(f"Setting logging level to {level_name}")
240
241        # Set the level for the logger
242        self.logger.setLevel(level)
243
244        # Also set the level for all handlers of the logger
245        for handler in self.logger.handlers:
246            handler.setLevel(level)

Sets the logging level for the logger.

Parameters
def start_saving(self, filename=None):
248    def start_saving(self, filename=None):
249        """Enables saving logs to a file.
250
251        Log messages AFTER this function has been called will be saved
252        to a text file using either the specified or default filename.
253
254        **NOTE**: Messages before this function is called will not be saved.
255
256        Parameters
257        ----------
258        filename : str, *optional*
259            Name of the file to log messages to
260            - Default is is "YYYYmmdd-HHMMSS-bci_essentials.log".
261        """
262        if filename is None:
263            filename = (
264                datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
265                + "-bci_essentials.log"
266            )
267        self.info(f"Logging to file: {filename}")
268
269        file_handler = logging.FileHandler(filename)
270        file_formatter = logging.Formatter(
271            "%(asctime)s - %(levelname)s - %(name)s : %(message)s"
272        )
273        file_handler.setFormatter(file_formatter)
274        self.logger.addHandler(file_handler)

Enables saving logs to a file.

Log messages AFTER this function has been called will be saved to a text file using either the specified or default filename.

NOTE: Messages before this function is called will not be saved.

Parameters
  • filename (str, optional): Name of the file to log messages to
    • Default is is "YYYYmmdd-HHMMSS-bci_essentials.log".
def debug(self, msg, *args, **kwargs):
276    def debug(self, msg, *args, **kwargs):
277        """
278        Logs a DEBUG message.
279
280        Parameters
281        ----------
282        msg : str
283            The log message format string.
284        *args
285            Arguments merged into msg using string formatting.
286        **kwargs
287            Additional keyword arguments.
288
289        Examples
290        --------
291        >>> logger.debug("Debug message with variable: %s", variable_name)
292        """
293        self.logger.debug(msg, *args, **kwargs)

Logs a DEBUG message.

Parameters
  • msg (str): The log message format string.
  • *args: Arguments merged into msg using string formatting.
  • **kwargs: Additional keyword arguments.
Examples
>>> logger.debug("Debug message with variable: %s", variable_name)
def info(self, msg, *args, **kwargs):
295    def info(self, msg, *args, **kwargs):
296        """
297        Logs an INFO message.
298
299        Parameters
300        ----------
301        msg : str
302            The log message format string.
303        *args
304            Arguments merged into msg using string formatting.
305        **kwargs
306            Additional keyword arguments.
307
308        Examples
309        --------
310        >>> logger.info("Info message with variable: %s", variable_name)
311        """
312        self.logger.info(msg, *args, **kwargs)

Logs an INFO message.

Parameters
  • msg (str): The log message format string.
  • *args: Arguments merged into msg using string formatting.
  • **kwargs: Additional keyword arguments.
Examples
>>> logger.info("Info message with variable: %s", variable_name)
def warning(self, msg, *args, **kwargs):
314    def warning(self, msg, *args, **kwargs):
315        """
316        Logs a WARNING message.
317
318        Parameters
319        ----------
320        msg : str
321            The log message format string.
322        *args
323            Arguments merged into msg using string formatting.
324        **kwargs
325            Additional keyword arguments.
326
327        Examples
328        --------
329        >>> logger.warning("Warning message with variable: %s", variable_name)
330        """
331        self.logger.warning(msg, *args, **kwargs)

Logs a WARNING message.

Parameters
  • msg (str): The log message format string.
  • *args: Arguments merged into msg using string formatting.
  • **kwargs: Additional keyword arguments.
Examples
>>> logger.warning("Warning message with variable: %s", variable_name)
def error(self, msg, *args, **kwargs):
333    def error(self, msg, *args, **kwargs):
334        """
335        Logs an ERROR message.
336
337        Parameters
338        ----------
339        msg : str
340            The log message format string.
341        *args
342            Arguments merged into msg using string formatting.
343        **kwargs
344            Additional keyword arguments.
345
346        Examples
347        --------
348        >>> logger.error("Error message with variable: %s", variable_name)
349        """
350        self.logger.error(msg, *args, **kwargs)

Logs an ERROR message.

Parameters
  • msg (str): The log message format string.
  • *args: Arguments merged into msg using string formatting.
  • **kwargs: Additional keyword arguments.
Examples
>>> logger.error("Error message with variable: %s", variable_name)
def critical(self, msg, *args, **kwargs):
352    def critical(self, msg, *args, **kwargs):
353        """
354        Logs a CRITICAL message.
355
356        Parameters
357        ----------
358        msg : str
359            The log message format string.
360        *args
361            Arguments merged into msg using string formatting.
362        **kwargs
363            Additional keyword arguments.
364
365        Examples
366        --------
367        >>> logger.critical("Critical message with variable: %s", variable_name)
368        """
369        self.logger.critical(msg, *args, **kwargs)

Logs a CRITICAL message.

Parameters
  • msg (str): The log message format string.
  • *args: Arguments merged into msg using string formatting.
  • **kwargs: Additional keyword arguments.
Examples
>>> logger.critical("Critical message with variable: %s", variable_name)