Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

125 logging file handling should be consistent #126

Merged
merged 2 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[tool.poetry]
name = "streamsight"
version = "0.2.11"
version = "1.0.0"
description = "A toolkit for offline evaluation of Recommender Systems."
authors = ["Ng Tze Kean <[email protected]>"]
readme = "README.md"
repository = "https://github.com/HiIAmTzeKean/Streamsight"
documentation = "https://hiiamtzekean.github.io/Streamsight/"
keywords = ["recsys", "toolkit", "streamsight", "evaluation"]
keywords = ["recsys", "toolkit", "practical evaluation", "global timeline"]

[tool.poetry.dependencies]
python = "3.12.5"
Expand All @@ -22,6 +22,7 @@ progressbar = "^2.5"
typing-extensions = "^4.12.2"
deprecation = "^2.1.0"
sphinxcontrib-pdfembed = {git = "https://github.com/SuperKogito/sphinxcontrib-pdfembed"}
pyfiglet = "^1.0.2"

[tool.poetry.group.dev.dependencies]
pytest = "^8.3.2"
Expand All @@ -33,6 +34,7 @@ setuptools = "^73.0.0"
sphinx = "7.4.7"
sphinx-rtd-theme = "^2.0.0"
ipywidgets = "^8.1.5"
pyfiglet = "^1.0.2"

[build-system]
requires = ["poetry-core"]
Expand Down
14 changes: 5 additions & 9 deletions streamsight/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@
import logging
import logging.config

from streamsight.utils import (
prepare_logger,
log_level,
log_level_by_name,
suppress_warnings,
suppress_specific_warnings,
)
from streamsight.utils import (log_level, log_level_by_name, prepare_logger,
suppress_specific_warnings, suppress_warnings)

LOGGING_CONFIG = "LOGGING_CONFIG.yaml"
LOGGING_CONFIG_FILENAME = "LOGGING_CONFIG.yaml"

prepare_logger(LOGGING_CONFIG)
prepare_logger(LOGGING_CONFIG_FILENAME)

logger = logging.getLogger(__name__)
logger.info("streamsight package loaded.")
26 changes: 17 additions & 9 deletions streamsight/utils/directory_tools.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import os
from typing import Final

import yaml

LOG_FILE: Final[str] = "streamsight.log"


def safe_dir(path):
"""Check if directory is safe

Check if the directory exists, if not create it.

:param path: The path to the directory.
Expand All @@ -15,27 +18,32 @@ def safe_dir(path):
os.makedirs(path)


def create_config_yaml(path: str):
def create_config_yaml(config_filename: str):
"""
Create a configuration file for the logger.

Writes a default configuration file for the logger in YAML format.
The configuration file specifies the format of the log messages,
the output stream, and the log level.

:param path: The name of the file to be created.
:type path: str
"""
# Get the current working directory
current_directory = os.getcwd()

# Define the default log file path in the current directory
log_file_path = os.path.join(current_directory, "logs/streamsight.log")
yaml_file_path = os.path.join(current_directory, config_filename)

default_config = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"detailed": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
},
"simple": {
"format": "%(levelname)s - %(message)s"
},
"simple": {"format": "%(levelname)s - %(message)s"},
},
"handlers": {
"console": {
Expand All @@ -48,7 +56,7 @@ def create_config_yaml(path: str):
"class": "logging.FileHandler",
"level": "DEBUG",
"formatter": "detailed",
"filename": "logs/streamsight.log",
"filename": log_file_path,
},
},
"loggers": {
Expand All @@ -65,5 +73,5 @@ def create_config_yaml(path: str):
}

# Write the YAML content
with open(path, "w") as file:
with open(yaml_file_path, "w") as file:
yaml.dump(default_config, file, default_flow_style=False)
28 changes: 20 additions & 8 deletions streamsight/utils/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import os
from typing import Union

import pyfiglet

import numpy as np
import progressbar
import yaml
Expand Down Expand Up @@ -117,31 +119,41 @@ def __call__(self, block_num, block_size, total_size):
self.pbar.finish()


def prepare_logger(path: str) -> dict:
def prepare_logger(log_config_filename: str) -> dict:
"""Prepare the logger.

Prepare the logger by reading the configuration file and setting up the logger.
If the configuration file does not exist, it will be created.

:param path: Path to the configuration file.
:type path: str
:param log_config_filename: Name of configuration file.
:type log_config_filename: str
:return: Configuration dictionary.
:rtype: dict
"""
if not os.path.exists(path):
create_config_yaml(path)
if not os.path.exists(log_config_filename):
create_config_yaml(log_config_filename)

try:
with open(path, "r") as stream:
with open(log_config_filename, "r") as stream:
config = yaml.load(stream, Loader=yaml.FullLoader)
except FileNotFoundError:
raise FileNotFoundError(f"Configuration file not found at {path}.")
raise FileNotFoundError(f"Configuration file not found at {log_config_filename}.")
except yaml.YAMLError as e:
raise ValueError(f"Error parsing YAML configuration: {e}")

dir_name = os.path.dirname(config["handlers"]["file"]["filename"])
# Get the log file path from the configuration
log_file = config["handlers"]["file"]["filename"]

# Ensure the log file directory exists
dir_name = os.path.dirname(log_file)
safe_dir(dir_name)

# Write ASCII art to the log file
with open(log_file, "w") as log:
ascii_art = pyfiglet.figlet_format("streamsight")
log.write(ascii_art)
log.write("\n")

logging.config.dictConfig(config)
logging.captureWarnings(True)
return config
Expand Down