Skip to content

Commit df786d7

Browse files
committed
Add improved logging
1 parent 853a8cd commit df786d7

File tree

5 files changed

+79
-7
lines changed

5 files changed

+79
-7
lines changed

src/apps/dev_cli.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
# NOTE: This application is intended to be run for development purposes only.
1+
import logging
2+
3+
logging.getLogger("sqlalchemy.engine.Engine").disabled = True
24

35
from completions import CompletionService
46
from infrastructure.db.source_repository import SourceRepository
7+
from config.logger import logger
58

69
if __name__ == "__main__":
710
with SourceRepository() as repository:
@@ -11,4 +14,5 @@
1114
q = input("\nAsk a question (or 'exit'): ")
1215
if q.lower() in {"exit", "quit"}:
1316
break
14-
service.create(q)
17+
answer = service.create(q)
18+
logger.info("dev_cli.answer_displayed", answer=answer)

src/completions/services/completion_service.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22
from infrastructure.ollama import create_completion
33
from infrastructure.db.source_repository import SourceRepository
44
from completions.services.context_generation_service import ContextGenerationService
5+
from config import logger
56

67

78
class CompletionService:
89
def __init__(self, repository: SourceRepository):
910
self.repository = repository
1011

1112
def create(self, query, k=3):
12-
prompt_context = ContextGenerationService(query, self.repository).process(k)
13+
logger.info("completion_service.create", query=query)
1314

14-
print("\n🧠 Answering with context:\n")
15-
print(prompt_context)
16-
print("\n💬 LLM Answer:\n")
15+
prompt_context = ContextGenerationService(query, self.repository).process(k)
16+
logger.info("completion_service.context_generated", query=query)
1717

1818
answer = create_completion(create_prompt(prompt_context, query))
19-
print(answer)
19+
logger.info(
20+
"completion_service.answer_generated",
21+
query=query,
22+
answer=answer[0:10] + "...",
23+
)
24+
return answer

src/completions/services/context_generation_service.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from config import logger
12
from infrastructure.db.source_repository import SourceRepository
23

34

@@ -7,6 +8,13 @@ def __init__(self, query: str, repository: SourceRepository):
78
self.repository = repository
89

910
def process(self, k=3):
11+
logger.info("context_generation_service.process", query=self.query)
12+
1013
chunks = self.repository.get_top_k_chunks_by_similarity(self.query, k)
14+
logger.info(
15+
"context_generation_service.found_context_chunks",
16+
chunk_ids=[chunk.id for chunk in chunks],
17+
)
18+
1119
context = "\n\n".join(chunk.content for chunk in chunks)
1220
return context

src/config/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
OLLAMA_MODEL = "mistral"
33
OLLAMA_URL = "http://localhost:11434"
44
EMBEDDING_MODEL = "all-MiniLM-L6-v2"
5+
6+
from .logger import logger

src/config/logger.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import logging
2+
import json
3+
from typing import Optional, Dict, Any
4+
5+
# ANSI escape codes
6+
LOG_COLORS = {
7+
"DEBUG": "\033[94m", # Blue
8+
"INFO": "\033[92m", # Green
9+
"WARNING": "\033[93m", # Yellow
10+
"ERROR": "\033[91m", # Red
11+
"RESET": "\033[0m", # Reset to default
12+
}
13+
14+
15+
class ColorFormatter(logging.Formatter):
16+
def format(self, record: logging.LogRecord) -> str:
17+
level_color = LOG_COLORS.get(record.levelname, "")
18+
reset = LOG_COLORS["RESET"]
19+
record.msg = f"{level_color}{record.msg}{reset}"
20+
return super().format(record)
21+
22+
23+
class SemanticLogger:
24+
def __init__(self, name: Optional[str] = None):
25+
self.logger = logging.getLogger(name or __name__)
26+
handler = logging.StreamHandler()
27+
28+
formatter = ColorFormatter("%(asctime)s [%(levelname)s] %(message)s")
29+
handler.setFormatter(formatter)
30+
31+
self.logger.setLevel(logging.INFO)
32+
if not self.logger.hasHandlers():
33+
self.logger.addHandler(handler)
34+
35+
def info(self, event: str, **data: Any):
36+
self.logger.info(self._format(event, data))
37+
38+
def warning(self, event: str, **data: Any):
39+
self.logger.warning(self._format(event, data))
40+
41+
def error(self, event: str, **data: Any):
42+
self.logger.error(self._format(event, data))
43+
44+
def debug(self, event: str, **data: Any):
45+
self.logger.debug(self._format(event, data))
46+
47+
def _format(self, event: str, data: Dict[str, Any]) -> str:
48+
structured = {"event": event, **data}
49+
return json.dumps(structured)
50+
51+
52+
# Usage
53+
logger = SemanticLogger()

0 commit comments

Comments
 (0)