Skip to content

Commit

Permalink
Add optional project_name field to JSON log output
Browse files Browse the repository at this point in the history
  • Loading branch information
drdavella committed Oct 19, 2023
1 parent f9c8b9b commit 2ad1030
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/codemodder/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ def parse_args(argv, codemod_registry):
choices=[OutputFormat.HUMAN, OutputFormat.JSON],
help="the format for the log output",
)
parser.add_argument(
"--project-name",
help="optional descriptive name for the project used in log output",
)
parser.add_argument(
"--path-exclude",
action=CsvListAction,
Expand Down
2 changes: 1 addition & 1 deletion src/codemodder/codemodder.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def run(original_args) -> int:
)
return 1

configure_logger(argv.verbose, argv.log_format)
configure_logger(argv.verbose, argv.log_format, argv.project_name)

log_section("startup")
logger.info("codemodder: python/%s", __VERSION__)
Expand Down
16 changes: 14 additions & 2 deletions src/codemodder/logging.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from enum import Enum
import logging
import sys
from typing import Optional

from pythonjsonlogger import jsonlogger

Expand All @@ -21,13 +22,21 @@ def __str__(self):


class CodemodderJsonFormatter(jsonlogger.JsonFormatter):
project_name: Optional[str]

def __init__(self, *args, project_name: Optional[str] = None, **kwargs):
self.project_name = project_name
super().__init__(*args, **kwargs)

def add_fields(self, log_record, record, message_dict):
super().add_fields(log_record, record, message_dict)
log_record["timestamp"] = log_record.pop("asctime")
log_record.move_to_end("timestamp", last=False)
log_record["level"] = record.levelname.upper()
log_record["file"] = record.filename
log_record["line"] = record.lineno
if self.project_name:
log_record["project-name"] = self.project_name


def log_section(section_name: str):
Expand All @@ -46,7 +55,9 @@ def log_list(level: int, header: str, items: list, predicate=None):
logger.log(level, " - %s", predicate(item) if predicate else item)


def configure_logger(verbose: bool, log_format: OutputFormat):
def configure_logger(
verbose: bool, log_format: OutputFormat, project_name: Optional[str] = None
):
"""
Configure the logger based on the verbosity level.
"""
Expand All @@ -64,7 +75,8 @@ def configure_logger(verbose: bool, log_format: OutputFormat):
handlers.append(stderr_handler)
case OutputFormat.JSON:
formatter = CodemodderJsonFormatter(
"%(asctime) %(level) %(message) %(file) %(line)"
"%(asctime) %(level) %(message) %(file) %(line)",
project_name=project_name,
)
stdout_handler.setFormatter(formatter)

Expand Down
18 changes: 18 additions & 0 deletions tests/test_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pythonjsonlogger import jsonlogger

from codemodder.logging import OutputFormat, configure_logger


def test_json_logger(mocker):
basic_config = mocker.patch("logging.basicConfig")
configure_logger(False, OutputFormat.JSON, "test-project")
assert basic_config.call_count == 1
assert basic_config.call_args[1]["format"] == "%(message)s"
assert isinstance(
basic_config.call_args[1]["handlers"][0].formatter,
jsonlogger.JsonFormatter,
)
assert (
basic_config.call_args[1]["handlers"][0].formatter.project_name
== "test-project"
)

0 comments on commit 2ad1030

Please sign in to comment.