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

Ticket 23 configure bluesky logging #40

Merged
merged 18 commits into from
Oct 28, 2024
7 changes: 7 additions & 0 deletions doc/logging/logger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Bluesky logger

To invoke the bluesky logger, import as `from ibex_bluesky_core.logger import logger` and use it at the desired level:
`logger.blueskylogger.warning("Message to be logged")`
The logger utilizes a `TimedRotatingFileHandler` defined in the `logging.conf` file that rolls over the log at midnight.

The default logging level is defined at `INFO`. This means that events of lesser severity will not be logged. To change the default level, change level attribute of logger_blueskycore in the `logging.conf`
27 changes: 27 additions & 0 deletions src/ibex_bluesky_core/logger/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Bluesky specific logging utility."""

import logging
import logging.config
import os
from pathlib import Path

"""Logger for bluesky. Loads the configured log handler and also attaches to default bluesky logger
To use me
1. you need to import me --> from ibex_bluesky_core.logger import logger
2. Use me at the level you want --> logger.blueskylogger.info("Some useful message")
3. To change the log level check the logging.conf file"""

BLUESKY_LOGGER = "bluesky"
DEFAULT_LOGGER = "blueskylogs.log"
LOG_FOLDER = os.path.join("C:\\", "instrument", "var", "logs", BLUESKY_LOGGER)

# Find the log directory, if already set in the environment, else use the default
log_location = os.environ.get("BLUESKY_LOGS", LOG_FOLDER)
# Create the log directory if it doesn't already exist
os.makedirs(log_location, exist_ok=True)

filepath = Path(__file__).resolve().parent
# disable_existing_loggers ensures all loggers have same configuration as below
logging.config.fileConfig(os.path.join(filepath, "logging.conf"), disable_existing_loggers=False)

blueskylogger = logging.getLogger("blueskycore")
31 changes: 31 additions & 0 deletions src/ibex_bluesky_core/logger/logging.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[loggers]
keys=root,blueskycore

[handlers]
keys=timedRotatingFileHandler

[formatters]
keys=simpleFormatter,debugFormatter

[logger_root]
level=INFO
handlers=timedRotatingFileHandler

[logger_blueskycore]
level=INFO
qualname=blueskycore
propagate=0
handlers=timedRotatingFileHandler

[handler_timedRotatingFileHandler]
class=logging.handlers.TimedRotatingFileHandler
level=INFO
formatter=debugFormatter
#args=set the file name to blueskylogs.log and the log folder as set in the environment variable; if not set, set to default - \instrument\var\logs\bluesky
args=(os.path.join(os.environ.get("BLUESKY_LOGS", os.path.join("C:\\", "instrument", "var", "logs", "bluesky")),'blueskylogs.log'), "midnight")

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

[formatter_debugFormatter]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
25 changes: 25 additions & 0 deletions tests/logger/test_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
from logging.handlers import TimedRotatingFileHandler

from ibex_bluesky_core.logger import logger

LOG_MESSAGE = "Logging something to "
LOG_FILE_NAME = "blueskylogs.log"


def test_GIVEN_logging_is_requested_THEN_handler_is_added():
this_function_name = sys._getframe().f_code.co_name
message = LOG_MESSAGE + this_function_name
# Log invocation.
logger.blueskylogger.info(message)

loghandler = None
for handler in logger.blueskylogger.handlers:
if isinstance(handler, TimedRotatingFileHandler):
loghandler = handler

assert isinstance(loghandler, TimedRotatingFileHandler)
assert loghandler is not None
assert loghandler.name == "timedRotatingFileHandler"
assert loghandler.baseFilename.endswith(LOG_FILE_NAME)
assert loghandler is not None