Better logger
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import logging
|
||||
import traceback
|
||||
from dataclasses import dataclass
|
||||
from datetime import UTC
|
||||
@@ -6,6 +5,7 @@ from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from alpine_bits_python.db import Customer, Reservation
|
||||
from alpine_bits_python.logging_config import get_logger
|
||||
from alpine_bits_python.schemas import (
|
||||
CommentData,
|
||||
CommentListItemData,
|
||||
@@ -25,8 +25,7 @@ from .generated.alpinebits import (
|
||||
UniqueIdType2,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
_LOGGER.setLevel(logging.INFO)
|
||||
_LOGGER = get_logger(__name__)
|
||||
|
||||
# Define type aliases for the two Customer types
|
||||
NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer # noqa: E501
|
||||
|
||||
@@ -7,7 +7,6 @@ handshaking functionality with configurable supported actions and capabilities.
|
||||
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from abc import ABC
|
||||
from dataclasses import dataclass
|
||||
@@ -24,6 +23,7 @@ from alpine_bits_python.alpine_bits_helpers import (
|
||||
create_res_notif_push_message,
|
||||
create_res_retrieve_response,
|
||||
)
|
||||
from alpine_bits_python.logging_config import get_logger
|
||||
|
||||
from .db import AckedRequest, Customer, Reservation
|
||||
from .generated.alpinebits import (
|
||||
@@ -36,8 +36,7 @@ from .generated.alpinebits import (
|
||||
)
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
_LOGGER = get_logger(__name__)
|
||||
|
||||
|
||||
class HttpStatusCode(IntEnum):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import asyncio
|
||||
import gzip
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import urllib.parse
|
||||
from collections import defaultdict
|
||||
@@ -31,6 +30,7 @@ from .config_loader import load_config
|
||||
from .db import Base, get_database_url
|
||||
from .db import Customer as DBCustomer
|
||||
from .db import Reservation as DBReservation
|
||||
from .logging_config import get_logger, setup_logging
|
||||
from .rate_limit import (
|
||||
BURST_RATE_LIMIT,
|
||||
DEFAULT_RATE_LIMIT,
|
||||
@@ -40,9 +40,8 @@ from .rate_limit import (
|
||||
webhook_limiter,
|
||||
)
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
# Configure logging - will be reconfigured during lifespan with actual config
|
||||
_LOGGER = get_logger(__name__)
|
||||
|
||||
# HTTP Basic auth for AlpineBits
|
||||
security_basic = HTTPBasic()
|
||||
@@ -168,6 +167,10 @@ async def lifespan(app: FastAPI):
|
||||
_LOGGER.exception("Failed to load config: ")
|
||||
config = {}
|
||||
|
||||
# Setup logging from config
|
||||
setup_logging(config)
|
||||
_LOGGER.info("Application startup initiated")
|
||||
|
||||
DATABASE_URL = get_database_url(config)
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import logging
|
||||
import os
|
||||
import secrets
|
||||
|
||||
@@ -10,8 +9,9 @@ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
from alpine_bits_python.logging_config import get_logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger = get_logger(__name__)
|
||||
|
||||
# Security scheme
|
||||
security = HTTPBearer()
|
||||
|
||||
87
src/alpine_bits_python/logging_config.py
Normal file
87
src/alpine_bits_python/logging_config.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""Centralized logging configuration for AlpineBits application.
|
||||
|
||||
This module sets up logging based on config and provides a function to get
|
||||
loggers from anywhere in the application.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def setup_logging(config: dict | None = None):
|
||||
"""Configure logging based on application config.
|
||||
|
||||
Args:
|
||||
config: Application configuration dict with optional 'logger' section
|
||||
|
||||
Logger config format:
|
||||
logger:
|
||||
level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||
file: "alpinebits.log" # Optional, logs to console if not provided
|
||||
|
||||
"""
|
||||
if config is None:
|
||||
config = {}
|
||||
|
||||
logger_config = config.get("logger", {})
|
||||
level = logger_config.get("level", "INFO").upper()
|
||||
log_file = logger_config.get("file")
|
||||
|
||||
# Convert string level to logging constant
|
||||
numeric_level = getattr(logging, level, logging.INFO)
|
||||
|
||||
# Create formatter with timestamp
|
||||
formatter = logging.Formatter(
|
||||
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
|
||||
# Get root logger
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(numeric_level)
|
||||
|
||||
# Remove existing handlers to avoid duplicates
|
||||
root_logger.handlers.clear()
|
||||
|
||||
# Console handler (always add this)
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setLevel(numeric_level)
|
||||
console_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
# File handler (optional)
|
||||
if log_file:
|
||||
log_path = Path(log_file)
|
||||
|
||||
# Create logs directory if it doesn't exist
|
||||
if log_path.parent != Path():
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file_handler = logging.FileHandler(log_file, encoding="utf-8")
|
||||
file_handler.setLevel(numeric_level)
|
||||
file_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(file_handler)
|
||||
|
||||
root_logger.info("Logging to file: %s", log_file)
|
||||
|
||||
root_logger.info("Logging configured at %s level", level)
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""Get a logger instance for the given module name.
|
||||
|
||||
Usage:
|
||||
from alpine_bits_python.logging_config import get_logger
|
||||
|
||||
_LOGGER = get_logger(__name__)
|
||||
_LOGGER.info("Something happened")
|
||||
|
||||
Args:
|
||||
name: Usually __name__ from the calling module
|
||||
|
||||
Returns:
|
||||
Configured logger instance
|
||||
|
||||
"""
|
||||
return logging.getLogger(name)
|
||||
Reference in New Issue
Block a user