Skip to content

Commit df3f292

Browse files
Merge pull request #54 from DUNE-DAQ/emmuhamm/manual-handlers-refactor
Major refactor of handlers
2 parents 7b81745 + 8cb6d43 commit df3f292

13 files changed

Lines changed: 1323 additions & 672 deletions

File tree

src/daqpytools/apps/logging_demonstrator.py

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77

88
from daqpytools.logging.exceptions import LoggerSetupError
99
from daqpytools.logging.formatter import CONTEXT_SETTINGS
10+
from daqpytools.logging.handlerconf import LogHandlerConf
1011
from daqpytools.logging.handlers import (
1112
HandlerType,
12-
LogHandlerConf,
13+
add_handler,
1314
)
1415
from daqpytools.logging.levels import logging_log_level_keys
15-
from daqpytools.logging.logger import get_daq_logger
16+
from daqpytools.logging.logger import get_daq_logger, setup_daq_ers_logger
1617
from daqpytools.logging.utils import get_width
1718

1819

@@ -163,7 +164,7 @@ def test_handlertypes(main_logger: logging.Logger) -> None:
163164
main_logger (logging.Logger): A logger to print messages with
164165
"""
165166
#* Test choosing which handler to use individually
166-
main_logger.debug("Default go to tty / rich / file when added")
167+
main_logger.debug("Default go to whatever handlers were initialised with")
167168
main_logger.critical("Should only go to tty",
168169
extra={"handlers": [HandlerType.Rich]}
169170
)
@@ -225,6 +226,78 @@ def test_handlerconf(main_logger: logging.Logger) -> None:
225226
extra=handlerconf.ERS
226227
)
227228

229+
230+
def test_fallback_handlers(log_level: str) -> None:
231+
"""Demonstrate fallback handler behavior for a logger.
232+
233+
Args:
234+
log_level (str): Log level used to initialize the demo logger.
235+
236+
Returns:
237+
None
238+
"""
239+
fallback_log: logging.Logger = get_daq_logger(
240+
logger_name="fallback_logger",
241+
log_level=log_level,
242+
stream_handlers=False,
243+
rich_handler=True,
244+
)
245+
246+
fallback_log.info("Rich Only")
247+
248+
add_handler(
249+
fallback_log,
250+
HandlerType.Lstdout,
251+
True
252+
)
253+
254+
add_handler(
255+
fallback_log,
256+
HandlerType.Lstderr,
257+
True,
258+
fallback_handler = {HandlerType.Unknown}
259+
)
260+
261+
fallback_log.critical("Rich + stdout only")
262+
fallback_log.critical(
263+
"Rich + stdout + stderr",
264+
extra={"handlers": [HandlerType.Rich, HandlerType.Stream]},
265+
)
266+
267+
268+
def test_ers_handler_configuration(log_level: str) -> None:
269+
"""Demonstrate ERS-driven handler configuration for a logger.
270+
271+
Args:
272+
log_level (str): Log level used to initialize the demo logger.
273+
274+
Returns:
275+
None
276+
"""
277+
# Injecting specific
278+
os.environ["DUNEDAQ_ERS_WARNING"] = "rich"
279+
os.environ["DUNEDAQ_ERS_INFO"] = "lstdout"
280+
os.environ["DUNEDAQ_ERS_FATAL"] = "lstderr,rich"
281+
os.environ["DUNEDAQ_ERS_ERROR"] = "rich"
282+
283+
ers_logger: logging.Logger = get_daq_logger(
284+
logger_name="ers_logger",
285+
log_level=log_level,
286+
stream_handlers=False,
287+
rich_handler=True,
288+
)
289+
ers_logger.info("Just rich is added")
290+
291+
# Sets up the logger with all the relevant handlers
292+
setup_daq_ers_logger(ers_logger, "session_temp")
293+
ers_logger.info("ERS configured, but should still only be rich")
294+
295+
ers_hc = LogHandlerConf(init_ers=True)
296+
ers_logger.info("ERS Info lstdout ", extra=ers_hc.ERS)
297+
ers_logger.warning("ERS error lstdout", extra=ers_hc.ERS)
298+
ers_logger.critical("ERS critical lstderr + rich", extra=ers_hc.ERS)
299+
300+
228301
class AllOptionsCommand(click.Command):
229302
"""Parse the arguments passed and validate they are acceptable, otherwise print the
230303
relevant options.
@@ -294,11 +367,19 @@ def parse_args(self, ctx: click.Context, args: list[str]) -> None:
294367
),
295368
)
296369
@click.option(
297-
"-e",
370+
"-ep",
298371
"--ersprotobufstream",
299-
is_flag=True,
372+
type=str,
373+
help=(
374+
"Set up an ERS protobuf handler, and publish to ERS via protobuf."
375+
)
376+
)
377+
@click.option(
378+
"-eh",
379+
"--ershandlers",
380+
is_flag=True,
300381
help=(
301-
"Set up an ERS handler, and publish to ERS"
382+
"Demonstrate automatic logger configuration with ers variables."
302383
)
303384
)
304385
@click.option(
@@ -357,18 +438,29 @@ def parse_args(self, ctx: click.Context, args: list[str]) -> None:
357438
"logger handlers assigned to the given logger instance"
358439
),
359440
)
441+
@click.option(
442+
"-fh",
443+
"--fallback-handlers",
444+
is_flag=True,
445+
help=(
446+
"If true, demonstrates the use of fallback handlers."
447+
),
448+
)
360449
def main(
361450
log_level: str,
362451
rich_handler: bool,
363452
file_handler_path: str,
364453
stream_handlers: bool,
365454
child_logger: bool,
366455
disable_logger_inheritance: bool,
367-
ersprotobufstream: bool,
456+
ersprotobufstream: str,
368457
handlertypes:bool,
369458
handlerconf:bool,
370459
throttle: bool,
371-
suppress_basic: bool
460+
suppress_basic: bool,
461+
fallback_handlers: bool,
462+
ershandlers: bool,
463+
372464
) -> None:
373465
"""Demonstrate use of the daq_logging class with daqpyutils_logging_demonstrator.
374466
Note - if you are seeing output logs without any explicit handlers assigned, this is
@@ -384,7 +476,8 @@ def main(
384476
disable_logger_inheritance (bool): If true, disable logger inheritance so each
385477
logger instance only uses the logger handlers assigned to the given logger
386478
instance.
387-
ersprotobufstream (bool): If true, sets up an ERS protobuf handler. Error msg
479+
ersprotobufstream (str): Sets up an ERS protobuf handler with supplied
480+
session name. Error msg
388481
are demonstrated in the HandlerType demonstration, requiring handlerconf
389482
to be set to true. The topic for these tests is session_tester.
390483
handlertypes (bool): If true, demonstrates the advanced feature of HandlerTypes.
@@ -393,6 +486,8 @@ def main(
393486
throttle (bool): If true, demonstrates the throttling feature. Requires Rich.
394487
suppress_basic (bool): If true, supresses basic functionality.
395488
Useful to only test the advanced features of logging
489+
fallback_handlers (bool): If true, demonstrates fallback handler behavior.
490+
ershandlers (bool): If true, demonstrates ERS-based handler setup.
396491
397492
Returns:
398493
None
@@ -408,7 +503,8 @@ def main(
408503
rich_handler=rich_handler,
409504
file_handler_path=file_handler_path,
410505
stream_handlers=stream_handlers,
411-
ers_kafka_handler=ersprotobufstream,
506+
ers_kafka_session=ersprotobufstream,
507+
ers_app_name="Custom App Name", # Can be none!
412508
throttle=throttle
413509
)
414510

@@ -431,7 +527,10 @@ def main(
431527
test_handlertypes(main_logger)
432528
if handlerconf:
433529
test_handlerconf(main_logger)
434-
530+
if fallback_handlers:
531+
test_fallback_handlers(log_level)
532+
if ershandlers:
533+
test_ers_handler_configuration(log_level)
435534

436535
if __name__ == "__main__":
437536
main()

src/daqpytools/logging/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from daqpytools.logging.handlerconf import HandlerType, LogHandlerConf
2+
from daqpytools.logging.handlers import add_handler
3+
from daqpytools.logging.levels import logging_log_levels
4+
from daqpytools.logging.logger import (
5+
get_daq_logger,
6+
setup_daq_ers_logger,
7+
setup_root_logger,
8+
)
9+
10+
__all__ = [
11+
"HandlerType",
12+
"LogHandlerConf",
13+
"add_handler",
14+
"get_daq_logger",
15+
"logging_log_levels",
16+
"setup_daq_ers_logger",
17+
"setup_root_logger",
18+
]

src/daqpytools/logging/exceptions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ def __init__(self, ers_log_level:str) -> None:
4444
super().__init__(err_msg)
4545

4646

47+
class ERSInitError(Exception):
48+
"""Custom error for ERS Init."""
49+
50+
def __init__(self, address:str, topic:str) -> None:
51+
"""C'tor."""
52+
err_msg = (
53+
"The Kafka broker cannot be initialised using "
54+
f"{address=} and {topic=}"
55+
)
56+
super().__init__(err_msg)
57+
58+
4759

4860
class ProtobufFormatError(Exception):
4961
"""Custom error for Protobuf URL formatting issues."""

0 commit comments

Comments
 (0)