mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
feat: configure logfire telemetry (#12)
Co-authored-by: phernandez <phernandez@basicmachines.co>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
import logfire
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.exception_handlers import http_exception_handler
|
||||
from loguru import logger
|
||||
@@ -10,11 +11,13 @@ import basic_memory
|
||||
from basic_memory import db
|
||||
from basic_memory.config import config as app_config
|
||||
from basic_memory.api.routers import knowledge, search, memory, resource
|
||||
from basic_memory.utils import setup_logging
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI): # pragma: no cover
|
||||
"""Lifecycle manager for the FastAPI app."""
|
||||
setup_logging(log_file=".basic-memory/basic-memory.log")
|
||||
logger.info(f"Starting Basic Memory API {basic_memory.__version__}")
|
||||
await db.run_migrations(app_config)
|
||||
yield
|
||||
@@ -30,6 +33,10 @@ app = FastAPI(
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
if app_config != "test":
|
||||
logfire.instrument_fastapi(app)
|
||||
|
||||
|
||||
# Include routers
|
||||
app.include_router(knowledge.router)
|
||||
app.include_router(search.router)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Main CLI entry point for basic-memory.""" # pragma: no cover
|
||||
|
||||
from basic_memory.cli.app import app # pragma: no cover
|
||||
from basic_memory.utils import setup_logging # pragma: no cover
|
||||
|
||||
# Register commands
|
||||
from basic_memory.cli.commands import ( # noqa: F401 # pragma: no cover
|
||||
@@ -16,8 +15,5 @@ from basic_memory.cli.commands import ( # noqa: F401 # pragma: no cover
|
||||
)
|
||||
|
||||
|
||||
# Set up logging when module is imported
|
||||
setup_logging(log_file=".basic-memory/basic-memory-cli.log") # pragma: no cover
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
app()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Configuration management for basic-memory."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import Field, field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
@@ -8,10 +9,14 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
DATABASE_NAME = "memory.db"
|
||||
DATA_DIR_NAME = ".basic-memory"
|
||||
|
||||
Environment = Literal["test", "dev", "prod"]
|
||||
|
||||
|
||||
class ProjectConfig(BaseSettings):
|
||||
"""Configuration for a specific basic-memory project."""
|
||||
|
||||
env: Environment = Field(default="dev", description="Environment name")
|
||||
|
||||
# Default to ~/basic-memory but allow override with env var: BASIC_MEMORY_HOME
|
||||
home: Path = Field(
|
||||
default_factory=lambda: Path.home() / "basic-memory",
|
||||
|
||||
@@ -9,8 +9,11 @@ from typing import Optional, Union
|
||||
from loguru import logger
|
||||
from unidecode import unidecode
|
||||
|
||||
import basic_memory
|
||||
from basic_memory.config import config
|
||||
|
||||
import logfire
|
||||
|
||||
|
||||
def generate_permalink(file_path: Union[Path, str]) -> str:
|
||||
"""Generate a stable permalink from a file path.
|
||||
@@ -61,19 +64,45 @@ def generate_permalink(file_path: Union[Path, str]) -> str:
|
||||
return "/".join(clean_segments)
|
||||
|
||||
|
||||
def setup_logging(home_dir: Path = config.home, log_file: Optional[str] = None) -> None:
|
||||
def setup_logging(
|
||||
home_dir: Path = config.home, log_file: Optional[str] = None
|
||||
) -> None: # pragma: no cover
|
||||
"""
|
||||
Configure logging for the application.
|
||||
:param home_dir: the root directory for the application
|
||||
:param log_file: the name of the log file to write to
|
||||
:param app: the fastapi application instance
|
||||
"""
|
||||
|
||||
# Remove default handler and any existing handlers
|
||||
logger.remove()
|
||||
|
||||
# Add file handler
|
||||
if log_file:
|
||||
# Add file handler if we are not running tests
|
||||
if log_file and config.env != "test":
|
||||
# enable pydantic logfire
|
||||
logfire.configure(
|
||||
code_source=logfire.CodeSource(
|
||||
repository="https://github.com/basicmachines-co/basic-memory",
|
||||
revision=basic_memory.__version__,
|
||||
root_path="/src/basic_memory",
|
||||
),
|
||||
environment=config.env,
|
||||
)
|
||||
logger.configure(handlers=[logfire.loguru_handler()])
|
||||
|
||||
# instrument code spans
|
||||
logfire.instrument_sqlite3()
|
||||
logfire.instrument_pydantic()
|
||||
|
||||
from basic_memory.db import _engine as engine
|
||||
|
||||
if engine:
|
||||
logfire.instrument_sqlalchemy(engine=engine)
|
||||
|
||||
# setup logger
|
||||
log_path = home_dir / log_file
|
||||
logger.add(
|
||||
str(log_path), # loguru expects a string path
|
||||
str(log_path),
|
||||
level=config.log_level,
|
||||
rotation="100 MB",
|
||||
retention="10 days",
|
||||
@@ -85,3 +114,5 @@ def setup_logging(home_dir: Path = config.home, log_file: Optional[str] = None)
|
||||
|
||||
# Add stderr handler
|
||||
logger.add(sys.stderr, level=config.log_level, backtrace=True, diagnose=True, colorize=True)
|
||||
|
||||
logger.info(f"ENV: '{config.env}' Log level: '{config.log_level}' Logging to {log_file}")
|
||||
|
||||
Reference in New Issue
Block a user