11import logging
2+ import os
23
34from logging .config import dictConfig
45from pathlib import Path
56from sys import stdout
7+ import requests
68
79from memos import settings
10+ from dotenv import load_dotenv
811
12+ # Load environment variables
13+ load_dotenv ()
914
1015selected_log_level = logging .DEBUG if settings .DEBUG else logging .WARNING
1116
@@ -21,6 +26,15 @@ def _setup_logfile() -> Path:
2126 return logfile
2227
2328
29+ class OpenTelemetryHandler (logging .Handler ):
30+ def emit (self , record ):
31+ if record .levelno == logging .INFO or record .levelno == logging .ERROR :
32+ try :
33+ logOpenTelemetry (record .getMessage ())
34+ except Exception as e :
35+ pass
36+
37+
2438LOGGING_CONFIG = {
2539 "version" : 1 ,
2640 "disable_existing_loggers" : False ,
@@ -51,10 +65,14 @@ def _setup_logfile() -> Path:
5165 "backupCount" : 3 ,
5266 "formatter" : "standard" ,
5367 },
68+ "opentelemetry" : {
69+ "level" : "INFO" ,
70+ "class" : "memos.log.OpenTelemetryHandler" ,
71+ },
5472 },
5573 "root" : { # Root logger handles all logs
5674 "level" : logging .DEBUG if settings .DEBUG else logging .INFO ,
57- "handlers" : ["console" , "file" ],
75+ "handlers" : ["console" , "file" , "opentelemetry" ],
5876 },
5977 "loggers" : {
6078 "memos" : {
@@ -76,3 +94,29 @@ def get_logger(name: str | None = None) -> logging.Logger:
7694 if name :
7795 return parent_logger .getChild (name )
7896 return parent_logger
97+
98+
99+ def logOpenTelemetry (message : str ):
100+ trace_id = requests .headers .get ("traceId" )
101+
102+ headers = {
103+ "Content-Type" : "application/json" ,
104+ "Authorization" : f"Bearer { os .getenv ('LOGGER_TOKEN' )} "
105+ }
106+
107+ post_content = {
108+ "trace_id" : trace_id ,
109+ "action" : "memos" ,
110+ "message" : message ,
111+ }
112+
113+ logger_url = os .getenv ("LOGGER_URL" )
114+ if not logger_url :
115+ return
116+
117+ requests .post (
118+ url = logger_url ,
119+ headers = headers ,
120+ json = post_content ,
121+ timeout = 5
122+ )
0 commit comments