Skip to content

Commit

Permalink
Merge pull request #332 from Sema4AI/setup-logging
Browse files Browse the repository at this point in the history
Use structlog and enable persisting logs in JSONL format
  • Loading branch information
nfcampos authored May 7, 2024
2 parents d209845 + 6be55d9 commit 3b2f20a
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ package-lock.json
*.temp

# Log files
*.log
*.log*
logs/
npm-debug.log*
yarn-debug.log*
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ COPY ./backend .
# Copy the frontend build
COPY --from=builder /frontend/dist ./ui

ENTRYPOINT [ "uvicorn", "app.server:app", "--host", "0.0.0.0" ]
ENTRYPOINT [ "uvicorn", "app.server:app", "--host", "0.0.0.0", "--log-config", "log_config.json" ]
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ COPY . .

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --start-interval=1s --retries=3 CMD [ "curl", "-f", "http://localhost:8000/health" ]

ENTRYPOINT [ "uvicorn", "app.server:app", "--host", "0.0.0.0" ]
ENTRYPOINT [ "uvicorn", "app.server:app", "--host", "0.0.0.0", "--log-config", "log_config.json" ]
2 changes: 1 addition & 1 deletion backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ build_ui:
TEST_FILE ?= tests/unit_tests/

start:
poetry run uvicorn app.server:app --reload --port 8100
poetry run uvicorn app.server:app --reload --port 8100 --log-config log_config.json

migrate:
migrate -database postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):$(POSTGRES_PORT)/$(POSTGRES_DB)?sslmode=disable -path ./migrations up
Expand Down
18 changes: 18 additions & 0 deletions backend/app/lifespan.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import asyncpg
import orjson
import structlog
from fastapi import FastAPI

_pg_pool = None
Expand All @@ -26,6 +27,23 @@ async def _init_connection(conn) -> None:

@asynccontextmanager
async def lifespan(app: FastAPI):
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.stdlib.render_to_log_kwargs,
],
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)

global _pg_pool

_pg_pool = await asyncpg.create_pool(
Expand Down
4 changes: 2 additions & 2 deletions backend/app/llms.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import logging
import os
from functools import lru_cache
from urllib.parse import urlparse

import boto3
import httpx
import structlog
from langchain_anthropic import ChatAnthropic
from langchain_community.chat_models import BedrockChat, ChatFireworks
from langchain_community.chat_models.ollama import ChatOllama
from langchain_google_vertexai import ChatVertexAI
from langchain_openai import AzureChatOpenAI, ChatOpenAI

logger = logging.getLogger(__name__)
logger = structlog.get_logger(__name__)


@lru_cache(maxsize=4)
Expand Down
4 changes: 2 additions & 2 deletions backend/app/server.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging
import os
from pathlib import Path

import orjson
import structlog
from fastapi import FastAPI, Form, UploadFile
from fastapi.exceptions import HTTPException
from fastapi.staticfiles import StaticFiles
Expand All @@ -13,7 +13,7 @@
from app.lifespan import lifespan
from app.upload import convert_ingestion_input_to_blob, ingest_runnable

logger = logging.getLogger(__name__)
logger = structlog.get_logger(__name__)

app = FastAPI(title="OpenGPTs API", lifespan=lifespan)

Expand Down
4 changes: 2 additions & 2 deletions backend/app/stream.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import logging
from typing import Any, AsyncIterator, Dict, Optional, Sequence, Union

import orjson
import structlog
from langchain_core.messages import AnyMessage, BaseMessage, message_chunk_to_message
from langchain_core.runnables import Runnable, RunnableConfig
from langserve.serialization import WellKnownLCSerializer

logger = logging.getLogger(__name__)
logger = structlog.get_logger(__name__)

MessagesStream = AsyncIterator[Union[list[AnyMessage], str]]

Expand Down
70 changes: 70 additions & 0 deletions backend/log_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"default": {
"()": "uvicorn.logging.DefaultFormatter",
"fmt": "%(asctime)s - %(name)s - %(levelprefix)s %(message)s"
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": "%(asctime)s - %(name)s - %(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s"
},
"json": {
"()": "pythonjsonlogger.jsonlogger.JsonFormatter"
}
},
"handlers": {
"default": {
"formatter": "default",
"class": "logging.StreamHandler",
"stream": "ext://sys.stderr"
},
"access": {
"formatter": "access",
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout"
},
"file": {
"formatter": "json",
"class": "logging.handlers.RotatingFileHandler",
"filename": "./app.log",
"mode": "a+",
"maxBytes": 10000000,
"backupCount": 1
}
},
"root": {
"handlers": [
"default",
"file"
],
"level": "INFO"
},
"loggers": {
"app": {
"handlers": [
"default",
"file"
],
"level": "INFO",
"propagate": false
},
"uvicorn": {
"handlers": [
"default",
"file"
],
"level": "INFO",
"propagate": false
},
"uvicorn.access": {
"handlers": [
"access",
"file"
],
"level": "INFO",
"propagate": false
}
}
}
37 changes: 35 additions & 2 deletions backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ asyncpg = "^0.29.0"
langchain-core = "^0.1.44"
pyjwt = {extras = ["crypto"], version = "^2.8.0"}
langchain-anthropic = "^0.1.8"
structlog = "^24.1.0"
python-json-logger = "^2.0.7"

[tool.poetry.group.dev.dependencies]
uvicorn = "^0.23.2"
Expand Down

0 comments on commit 3b2f20a

Please sign in to comment.