ISEPOS-2280 Added base loggers scripts #1

Open
ymlesni wants to merge 8 commits from ymlesni/shared-snippets:feature/ISEPOS-2280-mechanizm-raportowania-informacji-z-aplikacji-do-pliku-z-logami into main
3 changed files with 277 additions and 0 deletions
Showing only changes of commit 9c654357c8 - Show all commits

View File

@ -0,0 +1,111 @@
%
% -----------------
% Copyright © 2024 ACK Cyfronet AGH, Poland.
% -----------------
%
% BASE_LOGGER A singleton logger class for logging messages to a file.
%
% This class implements a simple logging mechanism with different log levels
% (TRACE, DEBUG, INFO, WARNING, ERROR) and writes log entries to a file.
% It follows the Singleton pattern to ensure that only one instance of the logger
% exists throughout the application.
%
% Properties:
% fid - (private) The file identifier for the log file. This is used to write logs.
%
% Methods:
%
% getInstance() - Retrieves the singleton instance of the logger.
%
% trace(message) - Logs a message with TRACE level.
% @param message The message to log.
%
% debug(message) - Logs a message with DEBUG level.
% @param message The message to log.
%
% info(message) - Logs a message with INFO level.
% @param message The message to log.
%
% warning(message) - Logs a message with WARNING level.
% @param message The message to log.
%
% error(message) - Logs a message with ERROR level.
% @param message The message to log.
%
% delete() - Destructor method that closes the file identifier when the logger is deleted.
%
% Example usage:
% logger = base_logger.getInstance();
% logger.info('This is an info message');
% logger.error('This is an error message');
%
% See also: fopen, fclose, dbstack, fprintf
classdef base_logger < handle
properties(Access=private)
fid;
end
methods(Static, Access = public)
function obj = getInstance()
persistent instance;
if isempty(instance)
instance = base_logger();
end
obj = instance;
end
end
methods(Access=private)
function this = base_logger()
this.fid = fopen(getenv("DEFAULT_LOG_PATH"), 'a');
if this.fid == -1
error('Failed to open log file: application.log');
end
end
function log(this, level, message)
current_time = datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss');
stack = dbstack('-completenames');
if length(stack) > 2
script_name = stack(3).name;
else
script_name = 'Unknown';
end
if this.fid ~= -1
fprintf(this.fid, '%s %s %s %s\n', char(current_time), level, script_name, message);
else
error('File identifier is invalid. Cannot write to log.');
end
end
end
methods(Access=public)
function trace(this, message)
this.log("TRACE", message);
end
function debug(this, message)
this.log("DEBUG", message);
end
function info(this, message)
this.log("INFO", message);
end
function warning(this, message)
this.log("WARNING", message);
end
function error(this, message)
this.log("ERROR", message);
end
function delete(this)
if this.fid ~= -1
fclose(this.fid);
end
end
end
end

View File

@ -0,0 +1,111 @@
%
% -----------------
% Copyright © 2024 ACK Cyfronet AGH, Poland.
% -----------------
%
% BASE_LOGGER A singleton logger class for logging messages to a file.
%
% This class implements a simple logging mechanism with different log levels
% (TRACE, DEBUG, INFO, WARNING, ERROR) and writes log entries to a file.
% It follows the Singleton pattern to ensure that only one instance of the logger
% exists throughout the application.
%
% Properties:
% fid - (private) The file identifier for the log file. This is used to write logs.
%
% Methods:
%
% getInstance() - Retrieves the singleton instance of the logger.
%
% trace(message) - Logs a message with TRACE level.
% @param message The message to log.
%
% debug(message) - Logs a message with DEBUG level.
% @param message The message to log.
%
% info(message) - Logs a message with INFO level.
% @param message The message to log.
%
% warning(message) - Logs a message with WARNING level.
% @param message The message to log.
%
% error(message) - Logs a message with ERROR level.
% @param message The message to log.
%
% delete() - Destructor method that closes the file identifier when the logger is deleted.
%
% Example usage:
% logger = base_logger.getInstance();
% logger.info('This is an info message');
% logger.error('This is an error message');
%
% See also: fopen, fclose, dbstack, fprintf
classdef base_logger < handle
properties(Access=private)
fid;
end
methods(Static, Access = public)
function obj = getInstance()
persistent instance;
if isempty(instance)
instance = base_logger();
end
obj = instance;
end
end
methods(Access=private)
function this = base_logger()
this.fid = fopen(getenv("DEFAULT_LOG_PATH"), 'a');
if this.fid == -1
error('Failed to open log file: application.log');
end
end
function log(this, level, message)
current_time = strftime('%Y-%m-%d %H:%M:%S', localtime(time()));
stack = dbstack('-completenames');
if length(stack) > 2
script_name = stack(3).name;
else
script_name = 'Unknown';
end
if this.fid ~= -1
fprintf(this.fid, '%s %s %s %s\n', char(current_time), level, script_name, message);
else
error('File identifier is invalid. Cannot write to log.');
end
end
end
methods(Access=public)
function trace(this, message)
this.log("TRACE", message);
end
function debug(this, message)
this.log("DEBUG", message);
end
function info(this, message)
this.log("INFO", message);
end
function warning(this, message)
this.log("WARNING", message);
end
function error(this, message)
this.log("ERROR", message);
end
function delete(this)
if this.fid ~= -1
fclose(this.fid);
end
end
end
end

View File

@ -0,0 +1,55 @@
#
# -----------------
# Copyright © 2024 ACK Cyfronet AGH, Poland.
# -----------------
#
import os
import logging
def getDefaultLogger(name):
"""
Retrieves or creates a logger with the specified name and sets it up with a file handler.
The logger is configured to write log messages to the file path specified by the
'DEFAULT_LOG_PATH' environment variable. It uses the 'INFO' level as the default
logging level and writes log entries in the following format:
'YYYY-MM-DD HH:MM:SS,ms LEVEL logger_name message'
If the logger does not already have handlers, a file handler is created, and the
logging output is appended to the file. The log format includes the timestamp with
milliseconds, log level, logger name, and the log message.
Parameters:
-----------
name : str
The name of the logger. This can be the name of the module or any identifier
that you want to associate with the logger.
Returns:
--------
logger : logging.Logger
A logger instance with the specified name. The logger is configured with a
file handler that writes to the file specified by the 'DEFAULT_LOG_PATH'
environment variable.
Raises:
-------
KeyError:
If the 'DEFAULT_LOG_PATH' environment variable is not set.
Review

Here, again, the name of the variable should be updated. But I thought also that instead of throwing an error, we might use some default file name, to allow users to run the app also outside of the platform. But, I would set the default log file name to something different than "application.log", so that we know that we could notice if something is wrong with setting the environment variable.

Here, again, the name of the variable should be updated. But I thought also that instead of throwing an error, we might use some default file name, to allow users to run the app also outside of the platform. But, I would set the default log file name to something different than "application.log", so that we know that we could notice if something is wrong with setting the environment variable.
Example:
--------
logger = getDefaultLogger(__name__)
logger.info("This is an info message.")
"""
logger = logging.getLogger(name)
if not logger.hasHandlers():
file_handler = logging.FileHandler(os.environ['DEFAULT_LOG_PATH'], mode='a')
formatter = logging.Formatter('%(asctime)s,%(msecs)d %(levelname)s %(name)s %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.setLevel(logging.INFO)
return logger