Skip to content

Commit 69a886c

Browse files
committed
refactor(logging[infra]): add structured logging infrastructure to all modules
why: Enable structured logging with `extra` context for filtering, testing, and aggregation. Library modules need NullHandler per Python best practices. what: - Add `logging.getLogger(__name__)` to every module - Add NullHandler in library `__init__.py` - Add TmuxpLoggerAdapter with process() override for Python <3.13 compat - Simplify tmuxp_echo to pure print wrapper (decoupled from logging) - Add setup_log_file() for centralized --log-file handler setup - Fix setup_logger to target "tmuxp" logger, skip NullHandler check - Change default CLI log level from INFO to WARNING - Fix timestamp format bug: %H:%m:%S -> %H:%M:%S - Add future annotations and fix import ordering in _compat.py
1 parent 54aadae commit 69a886c

17 files changed

Lines changed: 242 additions & 47 deletions

File tree

src/tmuxp/__about__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
from __future__ import annotations
44

5+
import logging
6+
7+
logger = logging.getLogger(__name__)
8+
59
__title__ = "tmuxp"
610
__package_name__ = "tmuxp"
711
__version__ = "1.65.0"

src/tmuxp/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
from __future__ import annotations
88

9+
import logging
10+
911
from . import cli, util
1012
from .__about__ import (
1113
__author__,
@@ -17,3 +19,6 @@
1719
__title__,
1820
__version__,
1921
)
22+
23+
logger = logging.getLogger(__name__)
24+
logger.addHandler(logging.NullHandler())

src/tmuxp/_compat.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
# flake8: NOQA
1+
from __future__ import annotations
2+
3+
import logging
24
import sys
35

6+
logger = logging.getLogger(__name__)
7+
48
PY3 = sys.version_info[0] == 3
59
PYMINOR = sys.version_info[1]
610
PYPATCH = sys.version_info[2]
711

8-
_identity = lambda x: x
12+
13+
def _identity(x: object) -> object:
14+
"""Return *x* unchanged — used as a no-op decorator."""
15+
return x
16+
917

1018
if PY3 and PYMINOR >= 7:
11-
breakpoint = breakpoint
19+
breakpoint = breakpoint # noqa: A001
1220
else:
1321
import pdb
1422

15-
breakpoint = pdb.set_trace
23+
breakpoint = pdb.set_trace # noqa: A001
1624

1725

1826
implements_to_string = _identity

src/tmuxp/_internal/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
"""Internal APIs for tmuxp."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
7+
logger = logging.getLogger(__name__)

src/tmuxp/_internal/private_path.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
from __future__ import annotations
88

9+
import logging
910
import os
1011
import pathlib
1112
import typing as t
1213

14+
logger = logging.getLogger(__name__)
15+
1316
if t.TYPE_CHECKING:
1417
PrivatePathBase = pathlib.Path
1518
else:

src/tmuxp/_internal/types.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212

1313
from __future__ import annotations
1414

15+
import logging
1516
import typing as t
1617
from typing import TypedDict
1718

19+
logger = logging.getLogger(__name__)
20+
1821
if t.TYPE_CHECKING:
1922
import sys
2023

src/tmuxp/cli/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ def create_parser() -> argparse.ArgumentParser:
181181
"--log-level",
182182
action="store",
183183
metavar="log-level",
184-
default="info",
184+
default="warning",
185185
choices=["debug", "info", "warning", "error", "critical"],
186-
help='log level (debug, info, warning, error, critical) (default "info")',
186+
help='log level (debug, info, warning, error, critical) (default "warning")',
187187
)
188188
parser.add_argument(
189189
"--color",
@@ -297,7 +297,7 @@ def cli(_args: list[str] | None = None) -> None:
297297
parser = create_parser()
298298
args = parser.parse_args(_args, namespace=ns)
299299

300-
setup_logger(logger=logger, level=args.log_level.upper())
300+
setup_logger(level=args.log_level.upper())
301301

302302
if args.subparser_name is None:
303303
parser.print_help()

src/tmuxp/cli/_colors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
from __future__ import annotations
1111

12+
import logging
13+
1214
from tmuxp._internal.colors import (
1315
ColorMode,
1416
Colors,
@@ -20,6 +22,8 @@
2022
unstyle,
2123
)
2224

25+
logger = logging.getLogger(__name__)
26+
2327
__all__ = [
2428
"ColorMode",
2529
"Colors",

src/tmuxp/cli/_formatter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
from __future__ import annotations
1414

1515
import argparse
16+
import logging
1617
import re
1718
import typing as t
1819

20+
logger = logging.getLogger(__name__)
21+
1922
# Options that expect a value (set externally or via --option=value)
2023
OPTIONS_EXPECTING_VALUE = frozenset(
2124
{

src/tmuxp/cli/load.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from ._colors import ColorMode, Colors, build_description, get_color_mode
2424
from .utils import prompt_choices, prompt_yes_no, tmuxp_echo
2525

26+
logger = logging.getLogger(__name__)
27+
2628
LOAD_DESCRIPTION = build_description(
2729
"""
2830
Load tmuxp workspace file(s) and create or attach to a tmux session.
@@ -74,6 +76,7 @@ class CLILoadNamespace(argparse.Namespace):
7476
colors: CLIColorsLiteral | None
7577
color: CLIColorModeLiteral
7678
log_file: str | None
79+
log_level: str
7780

7881

7982
def load_plugins(
@@ -590,12 +593,7 @@ def command_load(
590593
cli_colors = Colors(get_color_mode(args.color))
591594

592595
if args.log_file:
593-
logfile_handler = logging.FileHandler(args.log_file)
594-
logfile_handler.setFormatter(log.LogFormatter())
595-
# Add handler to tmuxp root logger to capture all tmuxp log messages
596-
tmuxp_logger = logging.getLogger("tmuxp")
597-
tmuxp_logger.setLevel(logging.INFO) # Ensure logger level allows INFO
598-
tmuxp_logger.addHandler(logfile_handler)
596+
log.setup_log_file(args.log_file, args.log_level)
599597

600598
if args.workspace_files is None or len(args.workspace_files) == 0:
601599
tmuxp_echo(cli_colors.error("Enter at least one config"))

0 commit comments

Comments
 (0)