1+ import builtins
2+ import logging
3+ import os
4+ import atexit
5+ from datetime import datetime
6+ from typing import Any , TextIO
7+ from agents import Span
8+
9+ _original_print = builtins .print
10+
11+ LOGFILE_NAME = "agentops-tmp.log"
12+
13+ ## Instrument loggers and print function to log to a file
14+ def setup_print_logger () -> None :
15+ """
16+ ~Monkeypatches~ *Instruments the built-in print function and configures logging to also log to a file.
17+ Preserves existing logging configuration and console output behavior.
18+ """
19+ log_file = os .path .join (os .getcwd (), LOGFILE_NAME )
20+
21+ file_logger = logging .getLogger ('agentops_file_logger' )
22+ file_logger .setLevel (logging .DEBUG )
23+
24+ file_handler = logging .FileHandler (log_file )
25+ file_handler .setFormatter (logging .Formatter ('%(asctime)s - %(levelname)s - %(message)s' ))
26+ file_handler .setLevel (logging .DEBUG )
27+ file_logger .addHandler (file_handler )
28+
29+ # Ensure the new logger doesn't propagate to root
30+ file_logger .propagate = False
31+
32+ def print_logger (* args : Any , ** kwargs : Any ) -> None :
33+ """
34+ Custom print function that logs to file and console.
35+
36+ Args:
37+ *args: Arguments to print
38+ **kwargs: Keyword arguments to print
39+ """
40+ message = " " .join (str (arg ) for arg in args )
41+ file_logger .info (message )
42+
43+ # print to console using original print
44+ _original_print (* args , ** kwargs )
45+
46+ # replace the built-in print with ours
47+ builtins .print = print_logger
48+
49+ def cleanup ():
50+ """
51+ Cleanup function to be called when the process exits.
52+ Removes the log file and restores the original print function.
53+ """
54+ try :
55+ # Remove our file handler
56+ for handler in file_logger .handlers [:]:
57+ handler .close ()
58+ file_logger .removeHandler (handler )
59+
60+ # Restore the original print function
61+ builtins .print = _original_print
62+ except Exception as e :
63+ # If something goes wrong during cleanup, just print the error
64+ _original_print (f"Error during cleanup: { e } " )
65+
66+ # Register the cleanup function to run when the process exits
67+ atexit .register (cleanup )
68+
69+
70+ def upload_logfile (trace_id : int ) -> None :
71+ """
72+ Upload the log file to the API.
73+ """
74+ from agentops import get_client
75+
76+ log_file = os .path .join (os .getcwd (), LOGFILE_NAME )
77+ if not os .path .exists (log_file ):
78+ return
79+ with open (log_file , "r" ) as f :
80+ log_content = f .read ()
81+
82+ client = get_client ()
83+ client .api .v4 .upload_logfile (log_content , trace_id )
84+
85+ os .remove (log_file )
86+
0 commit comments