1515from rich .prompt import Prompt
1616
1717from reflex .constants import LogLevel
18+ from reflex .constants .base import Reflex
19+ from reflex .utils .decorator import once
1820
1921# Console for pretty printing.
2022_console = Console ()
@@ -92,6 +94,51 @@ def print(msg: str, dedupe: bool = False, **kwargs):
9294 _console .print (msg , ** kwargs )
9395
9496
97+ @once
98+ def log_file_console ():
99+ """Create a console that logs to a file.
100+
101+ Returns:
102+ A Console object that logs to a file.
103+ """
104+ from reflex .config import environment
105+
106+ if not (env_log_file := environment .REFLEX_LOG_FILE .get ()):
107+ subseconds = int ((time .time () % 1 ) * 1000 )
108+ timestamp = time .strftime ("%Y-%m-%d_%H-%M-%S" ) + f"_{ subseconds :03d} "
109+ log_file = Reflex .DIR / "logs" / (timestamp + ".log" )
110+ log_file .parent .mkdir (parents = True , exist_ok = True )
111+ else :
112+ log_file = env_log_file
113+ if log_file .exists ():
114+ log_file .unlink ()
115+ log_file .touch ()
116+ return Console (file = log_file .open ("a" , encoding = "utf-8" ))
117+
118+
119+ @once
120+ def should_use_log_file_console () -> bool :
121+ """Check if the log file console should be used.
122+
123+ Returns:
124+ True if the log file console should be used, False otherwise.
125+ """
126+ from reflex .config import environment
127+
128+ return environment .REFLEX_ENABLE_FULL_LOGGING .get ()
129+
130+
131+ def print_to_log_file (msg : str , dedupe : bool = False , ** kwargs ):
132+ """Print a message to the log file.
133+
134+ Args:
135+ msg: The message to print.
136+ dedupe: If True, suppress multiple console logs of print message.
137+ kwargs: Keyword arguments to pass to the print function.
138+ """
139+ log_file_console ().print (msg , ** kwargs )
140+
141+
95142def debug (msg : str , dedupe : bool = False , ** kwargs ):
96143 """Print a debug message.
97144
@@ -110,6 +157,8 @@ def debug(msg: str, dedupe: bool = False, **kwargs):
110157 progress .console .print (msg_ , ** kwargs )
111158 else :
112159 print (msg_ , ** kwargs )
160+ if should_use_log_file_console ():
161+ print_to_log_file (f"[purple]Debug: { msg } [/purple]" , ** kwargs )
113162
114163
115164def info (msg : str , dedupe : bool = False , ** kwargs ):
@@ -126,6 +175,8 @@ def info(msg: str, dedupe: bool = False, **kwargs):
126175 return
127176 _EMITTED_INFO .add (msg )
128177 print (f"[cyan]Info: { msg } [/cyan]" , ** kwargs )
178+ if should_use_log_file_console ():
179+ print_to_log_file (f"[cyan]Info: { msg } [/cyan]" , ** kwargs )
129180
130181
131182def success (msg : str , dedupe : bool = False , ** kwargs ):
@@ -142,6 +193,8 @@ def success(msg: str, dedupe: bool = False, **kwargs):
142193 return
143194 _EMITTED_SUCCESS .add (msg )
144195 print (f"[green]Success: { msg } [/green]" , ** kwargs )
196+ if should_use_log_file_console ():
197+ print_to_log_file (f"[green]Success: { msg } [/green]" , ** kwargs )
145198
146199
147200def log (msg : str , dedupe : bool = False , ** kwargs ):
@@ -158,6 +211,8 @@ def log(msg: str, dedupe: bool = False, **kwargs):
158211 return
159212 _EMITTED_LOGS .add (msg )
160213 _console .log (msg , ** kwargs )
214+ if should_use_log_file_console ():
215+ print_to_log_file (msg , ** kwargs )
161216
162217
163218def rule (title : str , ** kwargs ):
@@ -184,6 +239,8 @@ def warn(msg: str, dedupe: bool = False, **kwargs):
184239 return
185240 _EMIITED_WARNINGS .add (msg )
186241 print (f"[orange1]Warning: { msg } [/orange1]" , ** kwargs )
242+ if should_use_log_file_console ():
243+ print_to_log_file (f"[orange1]Warning: { msg } [/orange1]" , ** kwargs )
187244
188245
189246def _get_first_non_framework_frame () -> FrameType | None :
@@ -248,6 +305,8 @@ def deprecate(
248305 )
249306 if _LOG_LEVEL <= LogLevel .WARNING :
250307 print (f"[yellow]DeprecationWarning: { msg } [/yellow]" , ** kwargs )
308+ if should_use_log_file_console ():
309+ print_to_log_file (f"[yellow]DeprecationWarning: { msg } [/yellow]" , ** kwargs )
251310 if dedupe :
252311 _EMITTED_DEPRECATION_WARNINGS .add (dedupe_key )
253312
@@ -266,6 +325,8 @@ def error(msg: str, dedupe: bool = False, **kwargs):
266325 return
267326 _EMITTED_ERRORS .add (msg )
268327 print (f"[red]{ msg } [/red]" , ** kwargs )
328+ if should_use_log_file_console ():
329+ print_to_log_file (f"[red]{ msg } [/red]" , ** kwargs )
269330
270331
271332def ask (
0 commit comments