From 258011a78400da53d20900613147c682b2ba2b3c Mon Sep 17 00:00:00 2001 From: Sanilas-ai Date: Mon, 2 Nov 2026 21:15:05 +0300 Subject: [PATCH] refactor: import the shared seismometer logger from core.logger Add a module-level logger to seismometer.core.logger and import it in each module instead of calling logging.getLogger("seismometer") there. Drop the logger from five modules that defined it but never logged. The seismometer.telemetry loggers are unchanged. Closes #37 Signed-off-by: Sanilas-ai --- changelog/37.misc.rst | 1 + src/seismometer/__init__.py | 2 +- src/seismometer/api/plots.py | 4 +--- src/seismometer/api/reports.py | 4 +--- src/seismometer/api/templates.py | 4 ---- src/seismometer/configuration/model.py | 3 +-- src/seismometer/controls/categorical.py | 4 +--- .../controls/categorical_single_column.py | 4 +--- src/seismometer/controls/cohort_comparison.py | 4 +--- src/seismometer/controls/decorators.py | 4 +--- src/seismometer/controls/explore.py | 3 --- src/seismometer/controls/thresholds.py | 3 --- src/seismometer/core/decorators.py | 3 +-- src/seismometer/core/io.py | 4 ++-- src/seismometer/core/logger.py | 4 ++++ src/seismometer/data/binary_performance.py | 4 +--- src/seismometer/data/loader/event.py | 5 +---- src/seismometer/data/loader/pipeline.py | 4 +--- src/seismometer/data/loader/prediction.py | 4 +--- src/seismometer/data/pandas_helpers.py | 3 +-- src/seismometer/data/performance.py | 5 ++--- src/seismometer/html/template.py | 4 ++-- src/seismometer/plot/mpl/timeseries.py | 3 --- src/seismometer/report/alerting.py | 4 +--- src/seismometer/report/profiling.py | 3 +-- src/seismometer/seismogram.py | 3 +-- src/seismometer/table/analytics_table.py | 4 +--- src/seismometer/table/fairness.py | 3 --- tests/core/test_logger.py | 15 +++++++++++++++ 29 files changed, 44 insertions(+), 71 deletions(-) create mode 100644 changelog/37.misc.rst create mode 100644 tests/core/test_logger.py diff --git a/changelog/37.misc.rst b/changelog/37.misc.rst new file mode 100644 index 00000000..c41ebf25 --- /dev/null +++ b/changelog/37.misc.rst @@ -0,0 +1 @@ +Modules now import the shared ``seismometer`` logger from ``seismometer.core.logger`` instead of each calling ``logging.getLogger("seismometer")``. diff --git a/src/seismometer/__init__.py b/src/seismometer/__init__.py index f6bb50ce..70465c70 100644 --- a/src/seismometer/__init__.py +++ b/src/seismometer/__init__.py @@ -10,12 +10,12 @@ import pandas as pd from seismometer.core.autometrics import initialize_otel_config +from seismometer.core.logger import logger # isort: split from seismometer.api import * __version__ = importlib.metadata.version("seismometer") -logger = logging.getLogger("seismometer") def run_startup( diff --git a/src/seismometer/api/plots.py b/src/seismometer/api/plots.py index d3890f58..58e97342 100644 --- a/src/seismometer/api/plots.py +++ b/src/seismometer/api/plots.py @@ -1,4 +1,3 @@ -import logging from typing import Any, Optional import numpy as np @@ -9,6 +8,7 @@ from seismometer.controls.decorators import disk_cached_html_segment from seismometer.core.autometrics import store_call_parameters from seismometer.core.decorators import export +from seismometer.core.logger import logger from seismometer.data import get_cohort_data, get_cohort_performance_data from seismometer.data import pandas_helpers as pdh from seismometer.data import telemetry @@ -24,8 +24,6 @@ from seismometer.html import template from seismometer.seismogram import Seismogram -logger = logging.getLogger("seismometer") - @export def plot_cohort_hist(): diff --git a/src/seismometer/api/reports.py b/src/seismometer/api/reports.py index e113b1c7..12c4cd79 100644 --- a/src/seismometer/api/reports.py +++ b/src/seismometer/api/reports.py @@ -1,18 +1,16 @@ -import logging from typing import Optional from seismometer.controls.categorical import ExploreCategoricalPlots from seismometer.controls.categorical_single_column import ExploreSingleCategoricalPlots from seismometer.core.autometrics import store_call_parameters from seismometer.core.decorators import export +from seismometer.core.logger import logger from seismometer.data.filter import FilterRule from seismometer.report.profiling import ComparisonReportWrapper, SingleReportWrapper from seismometer.seismogram import Seismogram from seismometer.table.analytics_table import ExploreBinaryModelAnalytics from seismometer.table.fairness import ExploreBinaryModelFairness -logger = logging.getLogger("seismometer") - @export class ExploreFairnessAudit(ExploreBinaryModelFairness): diff --git a/src/seismometer/api/templates.py b/src/seismometer/api/templates.py index 1435a971..9bd2db4a 100644 --- a/src/seismometer/api/templates.py +++ b/src/seismometer/api/templates.py @@ -1,5 +1,3 @@ -import logging - import pandas as pd from IPython.display import HTML from pandas.io.formats.style import Styler @@ -10,8 +8,6 @@ from seismometer.html import template from seismometer.seismogram import Seismogram -logger = logging.getLogger("seismometer") - def _get_info_dict(plot_help: bool) -> dict[str, str | list[str]]: """ diff --git a/src/seismometer/configuration/model.py b/src/seismometer/configuration/model.py index b2975ee6..099cf488 100644 --- a/src/seismometer/configuration/model.py +++ b/src/seismometer/configuration/model.py @@ -1,11 +1,10 @@ -import logging from collections import Counter from pathlib import Path from typing import Any, List, Literal, Optional, Union from pydantic import BaseModel, Field, ValidationInfo, field_validator, model_validator -logger = logging.getLogger("seismometer") +from seismometer.core.logger import logger FileLike = str | Path DirLike = str | Path diff --git a/src/seismometer/controls/categorical.py b/src/seismometer/controls/categorical.py index dbe019b7..fa8c314e 100644 --- a/src/seismometer/controls/categorical.py +++ b/src/seismometer/controls/categorical.py @@ -1,4 +1,3 @@ -import logging from collections import defaultdict from typing import List, Optional, Union @@ -15,6 +14,7 @@ from seismometer.controls.styles import BOX_GRID_LAYOUT, html_title from seismometer.core.autometrics import store_call_parameters from seismometer.core.decorators import export +from seismometer.core.logger import logger from seismometer.data import telemetry from seismometer.data.filter import FilterRule from seismometer.html import template @@ -22,8 +22,6 @@ from seismometer.plot.mpl.likert import likert_plot from seismometer.seismogram import Seismogram -logger = logging.getLogger("seismometer") - """ The maximum number of categories allowed in a categorical column. """ diff --git a/src/seismometer/controls/categorical_single_column.py b/src/seismometer/controls/categorical_single_column.py index 02c31751..fea6036d 100644 --- a/src/seismometer/controls/categorical_single_column.py +++ b/src/seismometer/controls/categorical_single_column.py @@ -1,4 +1,3 @@ -import logging from typing import Optional import traitlets @@ -12,14 +11,13 @@ from seismometer.controls.styles import BOX_GRID_LAYOUT, WIDE_LABEL_STYLE, html_title from seismometer.core.autometrics import store_call_parameters from seismometer.core.decorators import export +from seismometer.core.logger import logger from seismometer.data import telemetry from seismometer.html import template from seismometer.plot.mpl._ux import MAX_CATEGORY_SIZE from seismometer.plot.mpl.likert import likert_plot from seismometer.seismogram import Seismogram -logger = logging.getLogger("seismometer") - class OrdinalCategoricalSinglePlot: def __init__( diff --git a/src/seismometer/controls/cohort_comparison.py b/src/seismometer/controls/cohort_comparison.py index 94cff68a..79834cfc 100644 --- a/src/seismometer/controls/cohort_comparison.py +++ b/src/seismometer/controls/cohort_comparison.py @@ -1,17 +1,15 @@ -import logging from functools import partial from typing import Optional from IPython.display import display from ipywidgets import Box, Button, Output, VBox +from seismometer.core.logger import logger from seismometer.data.filter import filter_rule_from_cohort_dictionary from .selection import MultiSelectionListWidget from .styles import BOX_GRID_LAYOUT, WIDE_BUTTON_LAYOUT -logger = logging.getLogger("seismometer") - GENERATE_REPORT = "Generate Report" GENERATING_REPORT = "Generating Report..." diff --git a/src/seismometer/controls/decorators.py b/src/seismometer/controls/decorators.py index eaac8cea..4a0a68ce 100644 --- a/src/seismometer/controls/decorators.py +++ b/src/seismometer/controls/decorators.py @@ -3,7 +3,6 @@ As for all of the utils subpackage, no other custom sub-packages should be referenced. """ import hashlib -import logging import os import shutil from functools import wraps @@ -15,8 +14,7 @@ from ipywidgets import Widget from seismometer.core.decorators import DiskCachedFunction - -logger = logging.getLogger("seismometer") +from seismometer.core.logger import logger def html_load(filepath) -> HTML: diff --git a/src/seismometer/controls/explore.py b/src/seismometer/controls/explore.py index 6b0373b4..5bc4d95c 100644 --- a/src/seismometer/controls/explore.py +++ b/src/seismometer/controls/explore.py @@ -1,4 +1,3 @@ -import logging import os from functools import wraps from typing import Any, Callable, Literal, Optional @@ -14,8 +13,6 @@ from .styles import BOX_GRID_LAYOUT, WIDE_LABEL_STYLE, html_title from .thresholds import MonotonicProbabilitySliderListWidget -logger = logging.getLogger("seismometer") - # region Model Evaluation Header Controls def _combine_scores_checkbox(per_context): diff --git a/src/seismometer/controls/thresholds.py b/src/seismometer/controls/thresholds.py index 6229d2e4..d66351b8 100644 --- a/src/seismometer/controls/thresholds.py +++ b/src/seismometer/controls/thresholds.py @@ -1,4 +1,3 @@ -import logging import operator from collections.abc import Iterable from typing import Optional @@ -10,8 +9,6 @@ from .styles import WIDE_LABEL_STYLE -logger = logging.getLogger("seismometer") - class ProbabilitySliderListWidget(ValueWidget, VBox): """ diff --git a/src/seismometer/core/decorators.py b/src/seismometer/core/decorators.py index c14ca697..40deca6f 100644 --- a/src/seismometer/core/decorators.py +++ b/src/seismometer/core/decorators.py @@ -4,7 +4,6 @@ """ import builtins import hashlib -import logging import os import shutil import sys @@ -16,7 +15,7 @@ import numpy as np import pandas as pd -logger = logging.getLogger("seismometer") +from seismometer.core.logger import logger def export(orig_fn): diff --git a/src/seismometer/core/io.py b/src/seismometer/core/io.py index fffe4aaf..6595a4ba 100644 --- a/src/seismometer/core/io.py +++ b/src/seismometer/core/io.py @@ -1,6 +1,5 @@ import hashlib import json -import logging import os import re import unicodedata @@ -11,8 +10,9 @@ import nbformat import yaml +from seismometer.core.logger import logger + Pathlike = str | Path -logger = logging.getLogger("seismometer") # region io-accessor functions read_ipynb = partial(nbformat.read, as_version=nbformat.current_nbformat) diff --git a/src/seismometer/core/logger.py b/src/seismometer/core/logger.py index 3de66086..a72d4b1a 100644 --- a/src/seismometer/core/logger.py +++ b/src/seismometer/core/logger.py @@ -4,6 +4,10 @@ logging.basicConfig() +# The package logger. Import it from here rather than calling `logging.getLogger("seismometer")` +# in each module, so every module logs under the same name. +logger = logging.getLogger("seismometer") + def init_logger(name: str = "seismometer") -> None: logger = logging.getLogger(name) diff --git a/src/seismometer/data/binary_performance.py b/src/seismometer/data/binary_performance.py index 3400f14c..5c45f569 100644 --- a/src/seismometer/data/binary_performance.py +++ b/src/seismometer/data/binary_performance.py @@ -1,10 +1,10 @@ import itertools -import logging from typing import Any, List, Optional import numpy as np import pandas as pd +from seismometer.core.logger import logger from seismometer.data import pandas_helpers as pdh from seismometer.data.filter import FilterRule from seismometer.seismogram import Seismogram @@ -12,8 +12,6 @@ from . import BinaryClassifierMetricGenerator from .performance import MONOTONIC_METRICS, THRESHOLD -logger = logging.getLogger("seismometer") - GENERATED_COLUMNS = [ "Positives", "Prevalence", diff --git a/src/seismometer/data/loader/event.py b/src/seismometer/data/loader/event.py index 3fac2867..0b4b3c7f 100644 --- a/src/seismometer/data/loader/event.py +++ b/src/seismometer/data/loader/event.py @@ -1,15 +1,12 @@ -import logging - import pandas as pd import seismometer.data.pandas_helpers as pdh from seismometer.configuration import ConfigProvider from seismometer.configuration.model import Event +from seismometer.core.logger import logger from .pipeline import ConfigOnlyHook -logger = logging.getLogger("seismometer") - def get_data_loader(config: ConfigProvider) -> ConfigOnlyHook: """ diff --git a/src/seismometer/data/loader/pipeline.py b/src/seismometer/data/loader/pipeline.py index 8575998d..915ccfff 100644 --- a/src/seismometer/data/loader/pipeline.py +++ b/src/seismometer/data/loader/pipeline.py @@ -1,11 +1,9 @@ -import logging from typing import Callable, Optional, TypeAlias import pandas as pd from seismometer.configuration import ConfigProvider - -logger = logging.getLogger("seismometer") +from seismometer.core.logger import logger ConfigOnlyHook: TypeAlias = Callable[[ConfigProvider], pd.DataFrame] ConfigOnlyHook.__doc__ = """ diff --git a/src/seismometer/data/loader/prediction.py b/src/seismometer/data/loader/prediction.py index c8fe1cde..e14b71a7 100644 --- a/src/seismometer/data/loader/prediction.py +++ b/src/seismometer/data/loader/prediction.py @@ -1,5 +1,4 @@ import csv -import logging import warnings import numpy as np @@ -8,11 +7,10 @@ import seismometer.data.pandas_helpers as pdh from seismometer.configuration import ConfigProvider, ConfigurationError +from seismometer.core.logger import logger from .pipeline import ConfigOnlyHook -logger = logging.getLogger("seismometer") - def get_data_loader(config: ConfigProvider) -> ConfigOnlyHook: """ diff --git a/src/seismometer/data/pandas_helpers.py b/src/seismometer/data/pandas_helpers.py index 5da66899..0e195024 100644 --- a/src/seismometer/data/pandas_helpers.py +++ b/src/seismometer/data/pandas_helpers.py @@ -7,8 +7,7 @@ from seismometer.configuration import ConfigurationError from seismometer.configuration.model import MergeStrategies - -logger = logging.getLogger("seismometer") +from seismometer.core.logger import logger MAXIMUM_COUNT_CATS = 15 diff --git a/src/seismometer/data/performance.py b/src/seismometer/data/performance.py index 3ccfe187..7d474465 100644 --- a/src/seismometer/data/performance.py +++ b/src/seismometer/data/performance.py @@ -1,4 +1,3 @@ -import logging from numbers import Number from pathlib import Path from typing import Callable, Optional, Tuple, Union @@ -7,11 +6,11 @@ import pandas as pd from sklearn.metrics import auc +from seismometer.core.logger import logger + from .confidence import PRConfidenceParam, ROCConfidenceParam, confidence_dict from .decorators import export -logger = logging.getLogger("seismometer") - DEFAULT_RHO = 1 / 3 PathLike = Union[str, Path] diff --git a/src/seismometer/html/template.py b/src/seismometer/html/template.py index 2e83fa47..b05a66d9 100644 --- a/src/seismometer/html/template.py +++ b/src/seismometer/html/template.py @@ -1,12 +1,12 @@ -import logging from typing import Any from IPython.display import HTML, SVG from jinja2 import Environment, PackageLoader, TemplateNotFound +from seismometer.core.logger import logger + FULL_WIDTH_STYLE = "width: 100%; max-width: 1200px;" -logger = logging.getLogger("seismometer") # Initializing Jinja package_loader = PackageLoader("seismometer", "html/resources") diff --git a/src/seismometer/plot/mpl/timeseries.py b/src/seismometer/plot/mpl/timeseries.py index e37b0e07..57821133 100644 --- a/src/seismometer/plot/mpl/timeseries.py +++ b/src/seismometer/plot/mpl/timeseries.py @@ -1,4 +1,3 @@ -import logging from typing import Optional import matplotlib.pyplot as plt @@ -8,8 +7,6 @@ from .decorators import model_plot -logger = logging.getLogger("seismometer") - @model_plot def compare_series( diff --git a/src/seismometer/report/alerting.py b/src/seismometer/report/alerting.py index 94bcd254..31c5a11e 100644 --- a/src/seismometer/report/alerting.py +++ b/src/seismometer/report/alerting.py @@ -29,17 +29,15 @@ show: true """ -import logging from pathlib import Path from typing import Optional import yaml from pydantic import BaseModel, Field +from seismometer.core.logger import logger from seismometer.plot.mpl._ux import alert_colors -logger = logging.getLogger("seismometer") - class ParsedAlert(BaseModel): name: str diff --git a/src/seismometer/report/profiling.py b/src/seismometer/report/profiling.py index fae2a5bb..d4de1d23 100644 --- a/src/seismometer/report/profiling.py +++ b/src/seismometer/report/profiling.py @@ -1,5 +1,4 @@ import json -import logging import os import re from abc import ABC @@ -14,12 +13,12 @@ import seismometer.report from seismometer.core.io import slugify +from seismometer.core.logger import logger from seismometer.data import telemetry from .alerting import AlertConfigProvider, ParsedAlert, ParsedAlertList PROFILING_CONFIG_PATH = _files(seismometer.report) / "report_config.yml" -logger = logging.getLogger("seismometer") def filter_unsupported_columns(df: DataFrame) -> DataFrame: diff --git a/src/seismometer/seismogram.py b/src/seismometer/seismogram.py index 1279e41e..464a1f87 100644 --- a/src/seismometer/seismogram.py +++ b/src/seismometer/seismogram.py @@ -1,5 +1,4 @@ import json -import logging from functools import lru_cache from typing import Optional @@ -8,6 +7,7 @@ from seismometer.configuration import AggregationStrategies, ConfigProvider, MergeStrategies from seismometer.configuration.model import CohortHierarchy, Metric +from seismometer.core.logger import logger from seismometer.core.patterns import Singleton from seismometer.data import pandas_helpers as pdh from seismometer.data import resolve_cohorts @@ -16,7 +16,6 @@ from seismometer.report.alerting import AlertConfigProvider MAXIMUM_NUM_COHORTS = 25 -logger = logging.getLogger("seismometer") class Seismogram(object, metaclass=Singleton): diff --git a/src/seismometer/table/analytics_table.py b/src/seismometer/table/analytics_table.py index 16b69bc6..323561aa 100644 --- a/src/seismometer/table/analytics_table.py +++ b/src/seismometer/table/analytics_table.py @@ -1,4 +1,3 @@ -import logging from enum import Enum from typing import Any, List, Optional @@ -14,6 +13,7 @@ from seismometer.controls.selection import MultiselectDropdownWidget, MultiSelectionListWidget from seismometer.controls.styles import BOX_GRID_LAYOUT, html_title from seismometer.controls.thresholds import MonotonicProbabilitySliderListWidget +from seismometer.core.logger import logger from seismometer.data import pandas_helpers as pdh from seismometer.data import telemetry from seismometer.data.binary_performance import GENERATED_COLUMNS, generate_analytics_data @@ -23,8 +23,6 @@ from .analytics_table_config import COLORING_CONFIG_DEFAULT, AnalyticsTableConfig -logger = logging.getLogger("seismometer") - # region Analytics Table diff --git a/src/seismometer/table/fairness.py b/src/seismometer/table/fairness.py index 6d2c864f..33bd178d 100644 --- a/src/seismometer/table/fairness.py +++ b/src/seismometer/table/fairness.py @@ -1,4 +1,3 @@ -import logging from enum import Enum from typing import Any, Callable, Optional @@ -17,8 +16,6 @@ from seismometer.data.filter import FilterRule from seismometer.data.performance import BinaryClassifierMetricGenerator, MetricGenerator -logger = logging.getLogger("seismometer") - COUNT = "Count" COHORT = "Cohort" CLASS = "Class" diff --git a/tests/core/test_logger.py b/tests/core/test_logger.py new file mode 100644 index 00000000..7a120a2c --- /dev/null +++ b/tests/core/test_logger.py @@ -0,0 +1,15 @@ +import logging + +from seismometer.core.logger import logger + + +def test_logger_is_the_package_logger(): + assert logger is logging.getLogger("seismometer") + + +def test_modules_share_the_package_logger(): + from seismometer.api import plots + from seismometer.data import pandas_helpers + + assert plots.logger is logger + assert pandas_helpers.logger is logger