88from flask import copy_current_request_context , has_request_context
99
1010from ..utilities import TimeoutTracker
11+ from ..schema import LogRecordSchema
12+ from ..deque import Deque
1113
1214_LOG = logging .getLogger (__name__ )
1315
@@ -29,6 +31,7 @@ def __init__(
2931 kwargs = None ,
3032 daemon = True ,
3133 default_stop_timeout : int = 5 ,
34+ log_len : int = 100 ,
3235 ):
3336 threading .Thread .__init__ (
3437 self ,
@@ -76,10 +79,14 @@ def __init__(
7679 self ._end_time = None # Task end time
7780
7881 # Public state properties
79- self .input : dict = {} # Input arguments. TODO: Automate this. Currently manual via Action.dispatch_request
82+ self .input : dict = (
83+ {}
84+ ) # Input arguments. TODO: Automate this. Currently manual via Action.dispatch_request
8085 self .progress : int = None # Percent progress of the task
8186 self .data = {} # Dictionary of custom data added during the task
82- self .log = [] # The log will hold dictionary objects with log information
87+ self .log = Deque (
88+ None , log_len
89+ ) # The log will hold dictionary objects with log information
8390
8491 # Stuff for handling termination
8592 self ._running_lock = (
@@ -106,7 +113,7 @@ def status(self):
106113 Current running status of the thread.
107114
108115 ============== =============================================
109- Status Meaning
116+ Status Meaning
110117 ============== =============================================
111118 ``pending`` Not yet started
112119 ``running`` Currently in-progress
@@ -143,7 +150,7 @@ def update_progress(self, progress: int):
143150 def update_data (self , data : dict ):
144151 """
145152
146- :param data: dict:
153+ :param data: dict:
147154
148155 """
149156 # Store data to be used before task finishes (eg for real-time plotting)
@@ -165,15 +172,15 @@ def _thread_proc(self, f):
165172 """Wraps the target function to handle recording `status` and `return` to `state`.
166173 Happens inside the task thread.
167174
168- :param f:
175+ :param f:
169176
170177 """
171178
172179 def wrapped (* args , ** kwargs ):
173180 """
174181
175- :param *args:
176- :param **kwargs:
182+ :param *args:
183+ :param **kwargs:
177184
178185 """
179186 nonlocal self
@@ -222,7 +229,7 @@ def get(self, block=True, timeout=None):
222229 def _async_raise (self , exc_type ):
223230 """
224231
225- :param exc_type:
232+ :param exc_type:
226233
227234 """
228235 # Should only be called on a started thread, so raise otherwise.
@@ -319,18 +326,20 @@ def stop(self, timeout=None, exception=ActionKilledException):
319326
320327
321328class ThreadLogHandler (logging .Handler ):
322- def __init__ (self , thread = None , dest = None , level = logging .INFO ):
329+ def __init__ (
330+ self , thread = None , dest = None , level = logging .INFO , default_log_len : int = 100
331+ ):
323332 """Set up a log handler that appends messages to a list.
324-
333+
325334 This log handler will first filter by ``thread``, if one is
326335 supplied. This should be a ``threading.Thread`` object.
327336 Only log entries from the specified thread will be
328337 saved.
329-
338+
330339 ``dest`` should specify a list, to which we will append
331340 each log entry as it comes in. If none is specified, a
332341 new list will be created.
333-
342+
334343 NB this log handler does not currently rotate or truncate
335344 the list - so if you use it on a thread that produces a
336345 lot of log messages, you may run into memory problems.
@@ -340,34 +349,28 @@ def __init__(self, thread=None, dest=None, level=logging.INFO):
340349 logging .Handler .__init__ (self )
341350 self .setLevel (level )
342351 self .thread = thread
343- self .dest = dest if dest is not None else []
352+ self .dest = dest if dest is not None else Deque ( None , default_log_len )
344353 self .addFilter (self .check_thread )
345354
346355 def check_thread (self , record ):
347356 """Determine if a thread matches the desired record
348357
349- :param record:
358+ :param record:
350359
351360 """
352361 if self .thread is None :
353362 return 1
354-
355363 if threading .get_ident () == self .thread .ident :
356364 return 1
357365 return 0
358366
359367 def emit (self , record ):
360368 """Do something with a logged message
361369
362- :param record:
370+ :param record:
363371
364372 """
365- record_dict = {"message" : record .getMessage ()}
366- for k in ["created" , "levelname" , "levelno" , "lineno" , "filename" ]:
367- record_dict [k ] = getattr (record , k )
368- self .dest .append (record_dict )
369- # FIXME: make sure this doesn't become a memory disaster!
370- # We probably need to check the size of the list...
373+ self .dest .append (LogRecordSchema ().dump (record ))
371374 # TODO: think about whether any of the keys are security flaws
372375 # (this is why I don't dump the whole logrecord)
373376
0 commit comments