Skip to content

Commit 2ab0a48

Browse files
committed
Add --debug argument to CLI to make the THING LOGGER level configurable between debug and info. Unit test also added.
1 parent 517dc8e commit 2ab0a48

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

src/labthings_fastapi/logs.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ def emit(self, record: logging.LogRecord) -> None:
7979
pass # If there's no destination for a particular log, ignore it.
8080

8181

82-
def configure_thing_logger() -> None:
82+
def configure_thing_logger(level: int | None = None) -> None:
8383
"""Set up the logger for thing instances.
8484
85-
We always set the logger for thing instances to level INFO, as this
86-
is currently used to relay progress to the client.
85+
We always set the logger for thing instances to level INFO by default,
86+
as this is currently used to relay progress to the client.
8787
8888
This function will collect logs on a per-invocation
8989
basis by adding a `.DequeByInvocationIDHandler` to the log. Only one
@@ -93,8 +93,15 @@ def configure_thing_logger() -> None:
9393
a filter to add invocation ID is not possible. Instead, we attach a filter to
9494
the handler, which filters all the records that propagate to it (i.e. anything
9595
that starts with ``labthings_fastapi.things``).
96+
97+
:param level: the logging level to use. If not specified, we use the
98+
current level, or INFO if no level has been set.
9699
"""
97-
THING_LOGGER.setLevel(logging.INFO)
100+
if level is not None:
101+
THING_LOGGER.setLevel(level)
102+
elif THING_LOGGER.level == logging.NOTSET:
103+
THING_LOGGER.setLevel(logging.INFO)
104+
98105
if not any(
99106
isinstance(h, DequeByInvocationIDHandler) for h in THING_LOGGER.handlers
100107
):

src/labthings_fastapi/server/cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"""
2020

2121
from argparse import ArgumentParser, Namespace
22+
import logging
2223
import sys
2324
from typing import Literal, Optional, overload
2425

@@ -28,6 +29,7 @@
2829
from . import ThingServer
2930
from . import fallback
3031
from .config_model import ThingServerConfig, ThingImportFailure
32+
from ..logs import configure_thing_logger
3133

3234

3335
def get_default_parser() -> ArgumentParser:
@@ -56,6 +58,11 @@ def get_default_parser() -> ArgumentParser:
5658
default=5000,
5759
help="Bind socket to this port. If 0, an available port will be picked.",
5860
)
61+
parser.add_argument(
62+
"--debug",
63+
action="store_true",
64+
help="Enable debug logging.",
65+
)
5966
return parser
6067

6168

@@ -149,6 +156,9 @@ def serve_from_cli(
149156
option is not specified.
150157
"""
151158
args = parse_args(argv)
159+
if args.debug:
160+
configure_thing_logger(logging.DEBUG)
161+
152162
try:
153163
config, server = None, None
154164
config = config_from_args(args)

tests/test_cli_debug.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import logging
2+
from labthings_fastapi.server.cli import serve_from_cli
3+
from labthings_fastapi.logs import THING_LOGGER
4+
5+
def test_cli_debug_flag():
6+
"""
7+
Test that using the --debug flag sets the logger level to DEBUG,
8+
and that not using it leaves the logger level at INFO.
9+
"""
10+
# Reset logger level to NOTSET
11+
THING_LOGGER.setLevel(logging.NOTSET)
12+
13+
# Run without --debug
14+
# We use dry_run=True to avoid starting uvicorn
15+
# We need a dummy config
16+
dummy_json = '{"things": {}}'
17+
serve_from_cli(["--json", dummy_json], dry_run=True)
18+
19+
assert THING_LOGGER.level == logging.INFO
20+
21+
# Reset logger level
22+
THING_LOGGER.setLevel(logging.NOTSET)
23+
24+
# Run with --debug
25+
serve_from_cli(["--json", dummy_json, "--debug"], dry_run=True)
26+
27+
assert THING_LOGGER.level == logging.DEBUG

0 commit comments

Comments
 (0)