Skip to content

Commit c84bda9

Browse files
committed
Add local and cloud logger
1 parent a66d94a commit c84bda9

File tree

3 files changed

+50
-16
lines changed

3 files changed

+50
-16
lines changed

api/src/middleware/request_context_middleware.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from middleware.request_context import RequestContext, _request_context
66
from utils.logger import HttpRequest, API_ACCESS_LOG
7+
from shared.common.logging_utils import Logger
78

89

910
class RequestContextMiddleware:
@@ -12,7 +13,8 @@ class RequestContextMiddleware:
1213
"""
1314

1415
def __init__(self, app: ASGIApp) -> None:
15-
self.logger = logging.getLogger(API_ACCESS_LOG)
16+
# self.logger = logging.getLogger(API_ACCESS_LOG)
17+
self.logger = Logger(API_ACCESS_LOG).get_logger()
1618
self.app = app
1719

1820
@staticmethod
@@ -38,10 +40,12 @@ def create_http_request(
3840
"""
3941
request_method = scope["method"]
4042
request_path = scope["path"]
43+
query_string = scope.get("query_string", b"").decode("utf-8")
4144
protocol = scope["scheme"].upper() + "/" + str(scope["http_version"])
4245
return HttpRequest(
4346
requestMethod=request_method,
4447
requestUrl=f"{request_context.protocol}://{request_context.host}{request_path}",
48+
queryString=query_string,
4549
remoteIp=request_context.client_host,
4650
protocol=protocol,
4751
status=status_code,
Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import logging
22
import os
3+
from google.cloud.logging.handlers import CloudLoggingHandler
4+
import google.cloud.logging
35

46

57
def get_env_logging_level():
@@ -9,27 +11,54 @@ def get_env_logging_level():
911
return os.getenv("LOGGING_LEVEL", "INFO")
1012

1113

14+
def is_local_env():
15+
return os.getenv("K_SERVICE") is None
16+
17+
1218
class Logger:
1319
"""
14-
Util class for logging information, errors or warnings
20+
GCP-friendly logger: structured JSON output, works locally or in production.
1521
"""
1622

17-
def __init__(self, name):
18-
"""
19-
Initialize the logger
20-
"""
21-
formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s")
22-
23-
console_handler = logging.StreamHandler()
24-
console_handler.setFormatter(formatter)
25-
23+
def __init__(self, name: str):
2624
self.logger = logging.getLogger(name)
27-
self.logger.addHandler(console_handler)
2825
self.logger.setLevel(get_env_logging_level())
26+
self.logger.handlers.clear()
27+
28+
# formatter = jsonlogger.JsonFormatter(
29+
# '%(asctime)s %(levelname)s %(name)s %(message)s'
30+
# )
31+
32+
if is_local_env():
33+
handler = logging.StreamHandler()
34+
else:
35+
try:
36+
client = google.cloud.logging.Client()
37+
handler = CloudLoggingHandler(client)
38+
except Exception as e:
39+
# fallback to stdout if cloud client fails
40+
self.logger.error(f"GCP logging failed, using fallback: {e}")
41+
handler = logging.StreamHandler()
42+
43+
# handler.setFormatter(formatter)
44+
self.logger.addHandler(handler)
45+
46+
# Also configure SQLAlchemy to use this logger
47+
self.setup_sqlalchemy_logger(handler)
48+
49+
def setup_sqlalchemy_logger(self, handler):
50+
sqlalchemy_loggers = [
51+
"sqlalchemy.engine",
52+
# "sqlalchemy.pool",
53+
# "sqlalchemy.dialects.postgresql",
54+
"sqlalchemy.engine.Engine"
55+
]
56+
for logger_name in sqlalchemy_loggers:
57+
logger = logging.getLogger(logger_name)
58+
logger.setLevel(get_env_logging_level())
59+
logger.handlers.clear()
60+
logger.addHandler(handler)
61+
logger.propagate = False
2962

3063
def get_logger(self):
31-
"""
32-
Get the logger instance
33-
:return: the logger instance
34-
"""
3564
return self.logger

api/src/utils/logger.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class HttpRequest:
2929
serverIp: str
3030
latency: float
3131
protocol: str
32+
queryString: str
3233

3334

3435
@dataclass

0 commit comments

Comments
 (0)