Skip to content

Commit 8a0b094

Browse files
authored
fix: Standardize logging across the app and improve metric handling
fix: Standardize logging across the app and improve metric handling
2 parents 3379570 + 275cfe0 commit 8a0b094

17 files changed

Lines changed: 101 additions & 67 deletions

src/sample_python_app/app/lifecycle.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,17 @@
55

66
import socket
77

8+
from loguru import logger
89
from prometheus_client import start_http_server
910

10-
from sample_python_app.core.logging import setup_logger
11-
12-
logger = setup_logger("normal")
13-
1411

1512
def start_metrics_server(port: int) -> None:
1613
"""Start the Prometheus metrics server on the specified port."""
1714
if _port_in_use(port):
18-
logger.error(f"Port {port} already in use; metrics disabled")
15+
logger.error("Port {} already in use; metrics disabled", port)
1916
return
2017

21-
logger.info(f"Starting Prometheus metrics on 0.0.0.0:{port}")
18+
logger.info("Starting Prometheus metrics on 0.0.0.0:{}", port)
2219
start_http_server(port, addr="0.0.0.0")
2320

2421

src/sample_python_app/app/runner.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@
66
import time
77
from datetime import date
88

9+
from loguru import logger
10+
911
from sample_python_app.core import (
1012
FETCH_COUNTER,
1113
FETCH_DURATION,
12-
setup_logger,
1314
weather_settings,
1415
)
1516
from sample_python_app.exceptions import AppError
1617
from sample_python_app.services import (
18+
CustomHTTPClient,
1719
fetch_astronomical_data_from_api,
1820
fetch_hourly_forecast_from_api,
21+
set_next_hour_forecast_temperature,
1922
)
20-
from sample_python_app.services.http_client import CustomHTTPClient
2123
from sample_python_app.ui import display_astronomical_data
2224

23-
logger = setup_logger("normal")
24-
2525

2626
class AstroFetcher:
2727
"""Fetches astronomical data and displays only once per day.
@@ -40,16 +40,17 @@ def fetch(self, *, exit_on_error: bool = True) -> None:
4040
lat = weather_settings.LOCATION.latitude
4141
lon = weather_settings.LOCATION.longitude
4242

43-
logger.info("Using latitude=%s longitude=%s", lat, lon)
43+
logger.info("Using latitude={} longitude={}", lat, lon)
4444

4545
start = time.time()
4646

4747
try:
4848
astro = fetch_astronomical_data_from_api(lat, lon, client=self.client)
4949
forecast = fetch_hourly_forecast_from_api(lat, lon, client=self.client)
50+
set_next_hour_forecast_temperature(forecast, location=f"{lat},{lon}")
5051
FETCH_COUNTER.inc()
5152
except AppError as exc:
52-
logger.error("Weather fetch failed: %s", exc)
53+
logger.error("Weather fetch failed: {}", exc)
5354
if exit_on_error:
5455
raise SystemExit(1) from None
5556
return

src/sample_python_app/app/scheduler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
from loguru import logger
99

1010
from sample_python_app.app.runner import fetcher
11-
from sample_python_app.core.logging import setup_logger
1211

1312

1413
def start_scheduler(test_mode: bool = False) -> None:
1514
"""Start the scheduler to fetch astronomical data every 24 hours."""
16-
setup_logger("normal")
1715
scheduler_logger = logger.bind(component="scheduler")
1816

1917
if test_mode:

src/sample_python_app/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
FETCH_COUNTER,
77
FETCH_DURATION,
88
FETCH_ERRORS,
9+
FORECAST_NEXT_HOUR_TEMPERATURE,
910
HTTP_REQUEST_DURATION,
1011
HTTP_REQUEST_EXCEPTIONS,
1112
HTTP_REQUESTS,
@@ -22,4 +23,5 @@
2223
"HTTP_REQUESTS",
2324
"HTTP_REQUEST_EXCEPTIONS",
2425
"HTTP_REQUEST_DURATION",
26+
"FORECAST_NEXT_HOUR_TEMPERATURE",
2527
]

src/sample_python_app/core/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Settings(BaseSettings):
3030
TIMEZONE: str = "America/Chicago"
3131
PROMETHEUS_METRICS_PORT: int = 8000
3232
GF_SECURITY_ADMIN_PASSWORD: SecretStr = SecretStr("admin")
33+
LOG_LEVEL: str = "INFO"
3334

3435
model_config = SettingsConfigDict(
3536
env_file=".env",

src/sample_python_app/core/logging.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,41 @@
1212
)
1313

1414

15-
def setup_logger(mode="normal"):
15+
def setup_logger(level: str = "INFO"):
1616
"""Configure and return a Loguru logger instance.
1717
1818
Args:
19-
mode (str, optional): Logging mode. "normal" for console and file logging,
20-
"silent" for file logging only. Defaults to "normal".
19+
level (str, optional): Logging level for file outputs (e.g., "INFO", "DEBUG",
20+
"ERROR"). Defaults to "INFO".
2121
2222
Returns:
2323
logger: Configured Loguru logger instance.
2424
2525
"""
2626
logger.remove()
27-
if mode == "silent":
28-
# Log errors to the console even in silent mode
29-
logger.add(sys.stdout, format=log_format, level="ERROR")
27+
if level.upper() == "SILENT":
28+
# Only add file handler at ERROR level (or could be level, but no stdout)
3029
logger.add(
3130
"app.log",
3231
format=log_format,
33-
level="DEBUG",
32+
level="ERROR",
3433
rotation="1 MB",
3534
retention="10 days",
3635
compression="zip",
3736
)
38-
elif mode == "debug":
39-
logger.add(sys.stdout, format=log_format, level="DEBUG")
37+
else:
4038
logger.add(
41-
"app.log",
39+
sys.stdout,
4240
format=log_format,
43-
level="DEBUG",
44-
rotation="1 MB",
45-
retention="10 days",
46-
compression="zip",
41+
level=level,
42+
backtrace=True,
43+
diagnose=True,
44+
enqueue=True,
4745
)
48-
else:
49-
logger.add(sys.stdout, format=log_format, level="INFO")
5046
logger.add(
5147
"app.log",
5248
format=log_format,
53-
level="DEBUG",
49+
level=level,
5450
rotation="1 MB",
5551
retention="10 days",
5652
compression="zip",

src/sample_python_app/core/metrics.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Prometheus metrics for astronomical data fetches."""
22

3-
from prometheus_client import Counter, Histogram, start_http_server
3+
from prometheus_client import Counter, Gauge, Histogram, start_http_server
44

55
FETCH_COUNTER = Counter(
66
"fetch_all_total",
@@ -29,12 +29,19 @@
2929
"HTTP request latency in seconds",
3030
["method", "host", "path"],
3131
)
32+
FORECAST_NEXT_HOUR_TEMPERATURE = Gauge(
33+
"forecast_next_hour_temperature",
34+
"Forecast temperature for 1 hour from now (°F)",
35+
["location"],
36+
)
37+
3238
__all__ = [
3339
"FETCH_COUNTER",
3440
"FETCH_ERRORS",
3541
"FETCH_DURATION",
3642
"HTTP_REQUESTS",
3743
"HTTP_REQUEST_EXCEPTIONS",
3844
"HTTP_REQUEST_DURATION",
45+
"FORECAST_NEXT_HOUR_TEMPERATURE",
3946
"start_http_server",
4047
]

src/sample_python_app/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"""
55

66
from sample_python_app.app import start_metrics_server, start_scheduler
7-
from sample_python_app.core import settings
7+
from sample_python_app.core import settings, setup_logger
8+
9+
setup_logger(settings.LOG_LEVEL)
810

911

1012
def run_app() -> None:

src/sample_python_app/scripts.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
import sys
1010
from pathlib import Path
1111

12+
from loguru import logger
13+
1214
from sample_python_app.core.logging import setup_logger
1315

1416
ROOT = Path(__file__).resolve().parents[2]
1517

18+
setup_logger("DEBUG")
19+
1620

1721
def _run(cmd: list[str]) -> None:
18-
logger = setup_logger("normal")
1922
logger.info(f"Running: {' '.join(cmd)}")
2023
subprocess.check_call(cmd, cwd=str(ROOT))
2124

@@ -33,5 +36,4 @@ def run_checks() -> None:
3336
_run([py, "-m", "ruff", "check", ".", "--exit-zero"])
3437
_run([py, "-m", "coverage", "run", "-m", "pytest"])
3538

36-
logger = setup_logger("normal")
3739
logger.info("All checks completed.")

src/sample_python_app/services/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
fetch_astronomical_data_from_api,
55
fetch_hourly_forecast_by_grid,
66
fetch_hourly_forecast_from_api,
7+
set_next_hour_forecast_temperature,
78
)
9+
from sample_python_app.services.http_client import CustomHTTPClient
810

911
__all__ = [
1012
"fetch_astronomical_data_from_api",
1113
"fetch_hourly_forecast_from_api",
1214
"fetch_hourly_forecast_by_grid",
15+
"set_next_hour_forecast_temperature",
16+
"CustomHTTPClient",
1317
]

0 commit comments

Comments
 (0)