From 1bb92a9157a2deb0c8440c4647bb43f12667a620 Mon Sep 17 00:00:00 2001 From: Markus Rosenstihl Date: Mon, 13 Jul 2026 22:59:54 +0200 Subject: [PATCH] switch all prints to logging module --- src/damaris/gui/DamarisGUI.py | 258 +++++++++++++++------------------- 1 file changed, 117 insertions(+), 141 deletions(-) diff --git a/src/damaris/gui/DamarisGUI.py b/src/damaris/gui/DamarisGUI.py index 89ae3b8..ba409c1 100644 --- a/src/damaris/gui/DamarisGUI.py +++ b/src/damaris/gui/DamarisGUI.py @@ -70,36 +70,9 @@ debug = False # version info from damaris import __version__ - -class logstream: - gui_log = None - text_log = sys.__stdout__ - - def write( self, message ): - # default for stdout and stderr - if self.gui_log is not None: - self.gui_log( message ) - if debug or self.gui_log is None: - self.text_log.write( message ) - self.text_log.flush( ) - def __call__( self, message ): - self.write( message ) - def flush(self): - pass - def __del__( self ): - pass - -global log -log = logstream( ) -sys.stdout = log -sys.stderr = log - -ExperimentHandling.log = log -ResultHandling.log = log -ResultReader.log = log -ExperimentWriter.log = log -BackendDriver.log = log -DataPool.log = log +# Unified logging +import logging +logger = logging.getLogger("damaris.gui") class LockFile: @@ -109,17 +82,17 @@ class LockFile: self.conn = sqlite3.connect(self.file) self.cursor = self.conn.cursor() self.id = None - print("Connected to db..") + logger.debug("Connected to db..") def add_experiment(self): - print("Add experiment..") + logger.debug("Add experiment..") self.id = str(uuid.uuid4()) self.cursor.execute("INSERT INTO damaris VALUES (?, ?)",(self.id, "started")) self.conn.commit() return self.id def del_experiment(self, id): - print("Delete experiment..") + logger.debug("Delete experiment..") self.cursor.execute('DELETE FROM damaris WHERE uuid=?', (id,)) self.conn.commit() return True @@ -166,6 +139,13 @@ class DamarisGUI: self.log = LogWindow( self.xml_gui , self) + # Initialize unified logging with GUI output + from damaris.gui import setup_logging + self._logger = setup_logging( + level=logging.DEBUG if debug else logging.INFO, + gui_callback=self.log, + ) + self.sw = ScriptWidgets( self.xml_gui, self ) self.toolbar_init( ) @@ -503,23 +483,23 @@ class DamarisGUI: def start_experiment( self, widget, data=None ): import time overall_start = time.time() - print(f"DEBUG: start_experiment called at {overall_start}") + logger.debug("start_experiment called at %s", overall_start) # something running? if self.si is not None or self.state != DamarisGUI.Edit_State: - print("Experiment is still running or cleaning up!") + logger.error("Experiment is still running or cleaning up!") return # get config values: config_start = time.time() actual_config = self.config.get( ) - print(f"DEBUG: Config load took {time.time() - config_start:.3f}s") + logger.debug("Config load took %.3fs", time.time() - config_start) # get scripts and start script interface gui_start = time.time() self.sw.disable_editing( ) exp_script, res_script = self.sw.get_scripts( ) - print(f"DEBUG: GUI operations took {time.time() - gui_start:.3f}s") + logger.debug("GUI operations took %.3fs", time.time() - gui_start) if not actual_config[ "start_result_script" ]: res_script = "" if not actual_config[ "start_experiment_script" ]: @@ -529,7 +509,7 @@ class DamarisGUI: backend = "" if (backend == "" and exp_script == "" and res_script == ""): - print("nothing to do...so doing nothing!") + logger.info("Nothing to do...so doing nothing!") self.sw.enable_editing( ) return @@ -547,11 +527,11 @@ class DamarisGUI: ln = 0 if type( lo ) is not int: lo = 0 - print("Experiment Script: %s at line %d, col %d:" % (e.__class__.__name__, ln, lo)) + logger.error("Experiment Script: %s at line %d, col %d", e.__class__.__name__, ln, lo) if e.text != "": - print(e.text.rstrip()) - print(" "*(e.offset-1)+"^") - print(e) + logger.error(e.text.rstrip()) + logger.error(" "*(e.offset-1)+"^") + logger.error("%s", e) res_code = None if res_script != "": @@ -565,14 +545,14 @@ class DamarisGUI: ln = 0 if type( lo ) is not int: lo = 0 - print("Result script: %s at line %d, col %d:" % (e.__class__.__name__, ln, lo)) + logger.error("Result script: %s at line %d, col %d", e.__class__.__name__, ln, lo) if e.text != "": - print("\"%s\"" % e.text) - # print " "*(e.offset+1)+"^" # nice idea, but needs monospaced fonts + logger.error("\"%s\"", e.text) + # logger.error(" "*(e.offset+1)+"^" # nice idea, but needs monospaced fonts pass - print(e) + logger.error("%s", e) - print(f"DEBUG: Script compilation took {time.time() - compile_start:.3f}s") + logger.debug("Script compilation took %.3fs", time.time() - compile_start) # detect error if (exp_script != "" and exp_code is None) or \ @@ -605,10 +585,10 @@ class DamarisGUI: pass # Use observe_data_pool(None) which is now optimized with fast TreeStore replacement - print(f"DEBUG: Data pool cleanup ({listener_count} listeners, {data_items} items)") + logger.debug("Data pool cleanup (%d listeners, %d items)", listener_count, data_items) self.monitor.observe_data_pool( None ) - - print(f"DEBUG: Data cleanup took {time.time() - data_cleanup_start:.3f}s") + + logger.debug("Data cleanup took %.3fs", time.time() - data_cleanup_start) # set the text mark for hdf logging if self.log.textbuffer.get_mark( "lastdumped" ) is None: @@ -619,14 +599,12 @@ class DamarisGUI: interval = 0.1 self.stop_experiment_flag.clear() - # Add timing debug info - import time start_time = time.time() - print(f"DEBUG: Starting experiment at {start_time}") + logger.debug("Starting experiment at %s", start_time) self.id = self.lockfile.add_experiment() - print(f"DEBUG: Lock file operation took {time.time() - start_time:.3f}s") - + logger.debug("Lock file operation took %.3fs", time.time() - start_time) + # Add more timing points lock_wait_start = time.time() while not self.lockfile.am_i_next(): @@ -639,9 +617,9 @@ class DamarisGUI: loop_run = 0 loop_run += interval - print(f"DEBUG: Lock wait took {time.time() - lock_wait_start:.3f}s") + logger.debug("Lock wait took %.3fs", time.time() - lock_wait_start) - if self.stop_experiment_flag.isSet(): + if self.stop_experiment_flag.is_set(): #Experiment has been stopped, clean up and leave self.experiment_script_statusbar_label.set_text("Experiment stopped") self.state = DamarisGUI.Edit_State @@ -665,7 +643,7 @@ class DamarisGUI: self.spool_dir, clear_jobs=actual_config[ "del_jobs_after_execution" ], clear_results=actual_config[ "del_results_after_processing" ] ) - print(f"DEBUG: ScriptInterface creation took {time.time() - script_interface_start:.3f}s") + logger.debug("ScriptInterface creation took %.3fs", time.time() - script_interface_start) self.data = self.si.data # run frontend and script engines @@ -673,18 +651,18 @@ class DamarisGUI: # Start temperature monitoring if configured (before scripts start) temp_start = time.time() self.start_temperature_monitoring(actual_config) - print(f"DEBUG: Temperature monitoring startup took {time.time() - temp_start:.3f}s") - + logger.debug("Temperature monitoring startup took %.3fs", time.time() - temp_start) + scripts_start = time.time() self.si.runScripts( ) - print(f"DEBUG: Script execution startup took {time.time() - scripts_start:.3f}s") + logger.debug("Script execution startup took %.3fs", time.time() - scripts_start) except Exception as e: - #print "ToDo evaluate exception",str(e), "at",traceback.extract_tb(sys.exc_info()[2])[-1][1:3] - #print "Full traceback:" + #logger.debug("ToDo evaluate exception %s at %s", str(e), traceback.extract_tb(sys.exc_info()[2])[-1][1:3]) + #logger.debug("Full traceback:") traceback_file = io.StringIO( ) traceback.print_tb( sys.exc_info( )[ 2 ], None, traceback_file ) self.main_notebook.set_current_page( DamarisGUI.Log_Display ) - print("Error while executing scripts: %s\n" % str( e ) + traceback_file.getvalue( )) + logger.error("Error while executing scripts: %s", str( e ) + traceback_file.getvalue( )) traceback_file = None self.data = None @@ -692,14 +670,14 @@ class DamarisGUI: still_running = [_f for _f in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if _f] for r in still_running: r.quit_flag.set( ) - print("waiting for threads stoping...", end=' ') + logger.info("Waiting for threads to stop...") still_running = [x for x in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if x is not None and x.is_alive( )] for t in still_running: while t.is_alive(): while gtk.events_pending(): gtk.main_iteration_do(False) t.join( 0.05 ) - print("done") + logger.info("Threads stopped") # cleanup self.si = None @@ -786,17 +764,18 @@ class DamarisGUI: if not self.si.exp_handling.is_alive( ): self.si.exp_handling.join( ) if self.si.exp_handling.raised_exception: - print("experiment script failed at line %d (function %s): %s" % (self.si.exp_handling.location[ 0 ], - self.si.exp_handling.location[ 1 ], - self.si.exp_handling.raised_exception)) - print("Full traceback", self.si.exp_handling.traceback) + logger.error("Experiment script failed at line %d (function %s): %s", + self.si.exp_handling.location[ 0 ], + self.si.exp_handling.location[ 1 ], + self.si.exp_handling.raised_exception) + logger.error("Full traceback: %s", self.si.exp_handling.traceback) e_text = "Experiment Script Failed (%d)" % e else: e_text = "Experiment Script Finished (%d)" % e - print("experiment script finished") + logger.info("Experiment script finished") self.si.exp_handling = None else: - #print self.si.back_driver.get_messages() + # Backend messages are now handled by FileTailerHandler e_text = "Experiment Script Running (%d)" % e e_text += experimenttimetext @@ -804,10 +783,11 @@ class DamarisGUI: if not self.si.res_handling.is_alive( ): self.si.res_handling.join( ) if self.si.res_handling.raised_exception: - print("result script failed at line %d (function %s): %s" % (self.si.res_handling.location[ 0 ], - self.si.res_handling.location[ 1 ], - self.si.res_handling.raised_exception)) - print("Full traceback", self.si.res_handling.traceback) + logger.error("Result script failed at line %d (function %s): %s", + self.si.res_handling.location[ 0 ], + self.si.res_handling.location[ 1 ], + self.si.res_handling.raised_exception) + logger.error("Full traceback: %s", self.si.res_handling.traceback) r_text = "Result Script Failed (%d)" % r else: r_text = "Result Script Finished (%d)" % r @@ -831,16 +811,16 @@ class DamarisGUI: if self.dump_thread is not None: if self.dump_thread.is_alive( ): - sys.stdout.write( "." ) + sys.stderr.write( "." ) self.dump_dots += 1 if self.dump_dots > 80: - print() + sys.stderr.write("\n") self.dump_dots = 0 else: self.dump_thread.join( ) self.dump_thread = None dump_size = os.stat( self.dump_filename ).st_size / 1e6 - print("done (%.1f s, %.1f MB)" % (time.time( ) - self.dump_start_time, dump_size)) + logger.info("Done (%.1f s, %.1f MB)", time.time( ) - self.dump_start_time, dump_size) gdk.threads_enter( ) if e_text: @@ -856,12 +836,12 @@ class DamarisGUI: # Stop temperature monitoring when experiment finishes self.stop_temperature_monitoring() if self.save_thread is None and self.dump_filename != "": - print("all subprocesses ended, saving data pool") + logger.info("All subprocesses ended, saving data pool") # Disable run button during data saving to prevent UI confusion gdk.threads_enter() self.toolbar_run_button.set_sensitive(False) gdk.threads_leave() - + # thread to save data... self.save_thread = threading.Thread( target=self.dump_states, name="dump states" ) self.save_thread.start( ) @@ -875,21 +855,21 @@ class DamarisGUI: self.toolbar_stop_button.set_sensitive( False ) gdk.threads_leave( ) if len( still_running ) != 0: - print("subprocess(es) still running: " + ', '.join( [s.getName( ) for s in still_running] )) + logger.warning("Subprocess(es) still running: %s", ', '.join( [s.getName( ) for s in still_running] )) return True else: if self.save_thread is not None: if self.save_thread.is_alive( ): - sys.stdout.write( "." ) + sys.stderr.write( "." ) self.dump_dots += 1 if self.dump_dots > 80: - print() + sys.stderr.write("\n") self.dump_dots = 0 return True self.save_thread.join( ) self.save_thread = None dump_size = os.stat( self.dump_filename ).st_size / 1e6 - print("done (%.1f s, %.1f MB)" % (time.time( ) - self.dump_start_time, dump_size)) + logger.info("Done (%.1f s, %.1f MB)", time.time( ) - self.dump_start_time, dump_size) # keep data to display but throw away everything else self.si = None @@ -910,7 +890,7 @@ class DamarisGUI: dump_interval = self.dump_timeinterval if self.dump_timeinterval > 0 else 2.0 if self.dump_thread is None and self.dump_filename != "" and \ self.last_dumped + dump_interval < time.time( ): - print("dumping data pool") + logger.info("Dumping data pool") self.dump_start_time = time.time( ) self.dump_dots = 0 # thread to save data... @@ -945,13 +925,13 @@ class DamarisGUI: try: self.dump_filename = actual_config.get( "data_pool_name" ) % extensions_dict except ValueError: - print("invalid formating character in '" + actual_config.get( "data_pool_name" ) + "'") + logger.error("Invalid formatting character in '%s'", actual_config.get( "data_pool_name" )) self.dump_filename = "DAMARIS_data_pool.h5" - print("reseting dumpfile to " + self.dump_filename) + logger.info("Resetting dumpfile to %s", self.dump_filename) del extensions_dict if os.path.split( self.dump_filename )[ 1 ] == "" or os.path.isdir( self.dump_filename ): - print("The dump filename is a directory, using filename 'DAMARIS_data_pool.h5'") + logger.warning("Dump filename is a directory, using filename 'DAMARIS_data_pool.h5'") self.dump_filename += os.sep + "DAMARIS_data_pool.h5" # compression @@ -968,7 +948,7 @@ class DamarisGUI: try: self.dump_timeinterval = int( 60 * float( actual_config[ "data_pool_write_interval" ] ) ) except ValueError as e: - print("configuration provides non-number for dump interval: " + str( e )) + logger.warning("Configuration provides non-number for dump interval: %s", str( e )) # if existent, move away old files if os.path.isfile( self.dump_filename ): @@ -990,15 +970,15 @@ class DamarisGUI: last_backup -= 1 os.rename( self.dump_filename, dump_filename_pattern % 0 ) if cummulated_size > (1 << 30): - print("Warning: the cumulated backups size of '%s' is %d MByte" % (self.dump_filename, - cummulated_size / (1 << 20))) + logger.warning("The cumulated backups size of '%s' is %d MByte", self.dump_filename, + cummulated_size / (1 << 20)) # init is finnished now # now it's time to create the hdf file dump_file = None if not os.path.isfile( self.dump_filename ): if not init: - print("dump file \"%s\" vanished unexpectedly, creating new one" % self.dump_filename) + logger.warning("Dump file \"%s\" vanished unexpectedly, creating new one", self.dump_filename) # have a look to the path and create necessary directories dir_stack = [ ] dir_trunk = os.path.dirname( os.path.abspath( self.dump_filename ) ) @@ -1012,8 +992,7 @@ class DamarisGUI: continue os.mkdir( dir_trunk ) except OSError as e: - print(e) - print("could not create dump directory '%s', so hdf5 dumps disabled" % dir_trunk) + logger.error("Could not create dump directory '%s', so hdf5 dumps disabled: %s", dir_trunk, e) self.dump_filename = "" self.dump_timeinterval = 0 return True @@ -1056,7 +1035,7 @@ class DamarisGUI: if dump_file is None: # exit! - print("could not create dump directory '%s', so hdf5 dumps disabled" % dir_trunk) + logger.error("Could not create dump directory '%s', so hdf5 dumps disabled", dir_trunk) self.dump_filename = "" self.dump_timeinterval = 0 return True @@ -1200,24 +1179,24 @@ class DamarisGUI: temp_baudrate = config.get("temperature_baudrate", 19200) if not temp_device: - print("Temperature monitoring: No device configured for Eurotherm") + logger.warning("Temperature monitoring: No device configured for Eurotherm") return - + self.temp_controller = create_controller( "eurotherm", temp_device, baudrate=temp_baudrate ) - print(f"Temperature monitoring started with Eurotherm on {temp_device} (interval: {temp_interval}s)") - + logger.info("Temperature monitoring started with Eurotherm on %s (interval: %ss)", temp_device, temp_interval) + elif controller_type == "simulated": # Simulated controller doesn't need device configuration # Use default parameters: 290K base, 10K amplitude, 60s period, 5% noise, 10% missing self.temp_controller = create_controller("simulated") - print(f"Temperature monitoring started with simulated controller (interval: {temp_interval}s)") - + logger.info("Temperature monitoring started with simulated controller (interval: %ss)", temp_interval) + else: - print(f"Temperature monitoring: Unknown controller type: {controller_type}") + logger.warning("Temperature monitoring: Unknown controller type: %s", controller_type) return - + # Create and start monitor thread self.temp_monitor = TemperatureMonitor( controller=self.temp_controller, @@ -1226,9 +1205,9 @@ class DamarisGUI: data_key="temperature" ) self.temp_monitor.start() - + except Exception as e: - print(f"Failed to start temperature monitoring: {e}") + logger.error("Failed to start temperature monitoring: %s", e) import traceback traceback.print_exc() self.temp_controller = None @@ -1241,17 +1220,17 @@ class DamarisGUI: if self.temp_monitor is not None: try: self.temp_monitor.stop() - print("Temperature monitoring stopped") + logger.info("Temperature monitoring stopped") except Exception as e: - print(f"Error stopping temperature monitoring: {e}") + logger.error("Error stopping temperature monitoring: %s", e) finally: self.temp_monitor = None - + if self.temp_controller is not None: try: self.temp_controller.close() except Exception as e: - print(f"Error closing temperature controller: {e}") + logger.error("Error closing temperature controller: %s", e) finally: self.temp_controller = None @@ -1282,7 +1261,7 @@ class DamarisGUI: if not self.doc_browser.is_alive( ): self.doc_browser.join( ) if self.doc_browser.my_webbrowser is not None: - print("new browser tab") + logger.debug("New browser tab") self.doc_browser.my_webbrowser.open_new_tab( self.doc_urls[ requested_doc ] ) else: del self.doc_browser @@ -1292,7 +1271,7 @@ class DamarisGUI: self.doc_browser = start_browser( self.doc_urls[ requested_doc ] ) self.doc_browser.start( ) else: - print("missing docs for '%s'" % (requested_doc)) + logger.warning("Missing docs for '%s'", requested_doc) show_manual = show_doc_menu @@ -1316,11 +1295,11 @@ class start_browser( threading.Thread ): # this is what it should be everywhere! self.my_webbrowser = webbrowser.get( ) if self.my_webbrowser is not None: - print("starting web browser (module webbrowser)") + logger.info("Starting web browser (module webbrowser)") self.my_webbrowser.open( self.start_url ) return True # last resort - print("starting web browser (webbrowser.py)") + logger.info("Starting web browser (webbrowser.py)") self.my_webbrowser_process = os.spawnl( os.P_NOWAIT, sys.executable, os.path.basename( sys.executable ), @@ -1343,8 +1322,6 @@ class LogWindow: font_desc = pango.FontDescription("Monospace 10") self.textview.modify_font(font_desc) self.textbuffer = self.textview.get_buffer( ) - self.logstream = log - self.logstream.gui_log = self self.last_timetag = None self( "Started in directory %s\n" % os.getcwd( ) ) @@ -1374,8 +1351,7 @@ class LogWindow: return False def __del__( self ): - self.logstream.gui_log = None - self.logstream = None + pass class ScriptWidgets: @@ -1642,8 +1618,8 @@ get_ylabel set_ylabel""" ln = 0 if type( lo ) is not int: lo = 0 - print("Syntax Error:\n%s in %s at line %d, offset %d" % ( - str( se ), se.filename, ln, lo) + "\n(ToDo: Dialog)") + logger.error("Syntax Error:\n%s in %s at line %d, offset %d", + str( se ), se.filename, ln, lo) if ln > 0 and ln <= tb.get_line_count( ): new_place = tb.get_iter_at_line_offset( ln - 1, 0 ) if lo > 0 and lo <= new_place.get_chars_in_line( ): @@ -1651,7 +1627,7 @@ get_ylabel set_ylabel""" tb.place_cursor( new_place ) tv.scroll_to_iter( new_place, 0.2, False, 0, 0 ) except Exception as e: - print("Compilation Error:\n" + str( e ) + "\n(ToDo: Dialog)") + logger.error("Compilation Error:\n%s", str( e )) def notebook_page_switched( self, notebook, page, pagenumber ): self.set_toolbuttons_status( ) @@ -1669,7 +1645,7 @@ get_ylabel set_ylabel""" newline = self.data_handling_line_indicator.get_value_as_int( ) - 1 newcol = column_indicator.get_value_as_int( ) - 1 else: - print("unknown line/column selector") + logger.error("Unknown line/column selector") return False textbuffer = textview.get_buffer( ) @@ -2475,13 +2451,13 @@ pygobject version %(pygobject)s elif isinstance( model, gtk.TreeStore ): model.append( None, [ libname ] ) else: - print("cannot append compression lib name to %s" % model.__class__.__name__) + logger.warning("Cannot append compression lib name to %s", model.__class__.__name__) # debug message if debug: - print("DAMARIS", __version__) - print(components_text % components_versions) + logger.debug("DAMARIS %s", __version__) + logger.debug(components_text % components_versions) # set no compression as default... self.config_data_pool_complib.set_active( 0 ) @@ -2497,7 +2473,7 @@ pygobject version %(pygobject)s if os.access( self.system_default_filename, os.R_OK ): self.load_config( self.system_default_filename ) else: - print("can not read system defaults from %s, ask your instrument responsible if required" % self.system_default_filename) + logger.warning("Can not read system defaults from %s, ask your instrument responsible if required", self.system_default_filename) self.config_from_system = self.get( ) self.load_config( ) @@ -2620,7 +2596,7 @@ pygobject version %(pygobject)s iter = model.iter_next( iter ) # if this compression method is not supported, warn and do nothing if iter is None: - print("compression method %s is not supported" % config[ "data_pool_complib" ]) + logger.warning("Compression method %s is not supported", config[ "data_pool_complib" ]) def on_adc_bit_depth_changed(self, widget): ADC_Result.default_bit_depth = widget.get_value_as_int() @@ -2784,7 +2760,7 @@ pygobject version %(pygobject)s readfile = open( filename, "rb" ) except Exception as e: if debug: - print("Could not open %s: %s" % (filename, str( e ))) + logger.debug("Could not open %s: %s", filename, str( e )) return # parser functions @@ -2836,7 +2812,7 @@ pygobject version %(pygobject)s if not os.path.isdir( dirs ): os.makedirs( dirs ) - print("save config to: "+filename) + logger.info("Save config to: %s", filename) configfile = open( filename, "w" ) configfile.write( "\n" ) @@ -2845,10 +2821,10 @@ pygobject version %(pygobject)s if k in self.config_from_system \ and self.config_from_system[ k ] == v: if debug: - print("Ignoring for write, because system value for %r is %r equal to %r" % \ - (k, self.config_from_system[ k ], v)) + logger.debug("Ignoring for write, because system value for %r is %r equal to %r", + k, self.config_from_system[ k ], v) continue - print(k,v, type(v)) + logger.debug("Config key: %s = %r (%s)", k, v, type(v).__name__) val = "" typename = "" if type( v ) is bool: @@ -3097,11 +3073,11 @@ class MonitorWidgets: pwd = namelist[ : ] iter = self.source_list_find( namelist ) if iter is None or len( namelist ) > 0: - print("source_list_remove: WARNING: Not found") + logger.warning("source_list_remove: Not found") return model = self.display_source_treestore if model.iter_has_child( iter ): - print("source_list_remove: WARNING: Request to delete a tree") + logger.warning("source_list_remove: Request to delete a tree") return while True: parent = model.iter_parent( iter ) @@ -3186,7 +3162,7 @@ class MonitorWidgets: if event.subject.startswith( "__" ): return if debug and self.update_counter < 0: - print("negative event count!", self.update_counter) + logger.debug("Negative event count: %d", self.update_counter) # Throttling removed as it blocks data production thread. # GUI updates are already decoupled via idle_add. @@ -3232,10 +3208,10 @@ class MonitorWidgets: do fast work selecting important events """ if debug and self.update_counter < 0: - print("negative event count!", self.update_counter) + logger.debug("Negative event count: %d", self.update_counter) if self.update_counter > 5: if debug: - print("sleeping to find time for graphics updates") + logger.debug("Sleeping to find time for graphics updates") threading.Event( ).wait( 0.05 ) while self.update_counter > 15: threading.Event( ).wait( 0.05 ) @@ -3264,7 +3240,7 @@ class MonitorWidgets: if self.displayed_data[ 1 ] is new_data_struct: # update display only if self.update_counter > 10: - print("update queue too long (%d>10): skipping one update" % self.update_counter) + logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter) else: gdk.threads_enter( ) try: @@ -3282,7 +3258,7 @@ class MonitorWidgets: new_data_struct.register_listener( self.datastructures_listener ) self.displayed_data[ 1 ] = new_data_struct if self.update_counter > 10: - print("update queue too long (%d>10): skipping one update" % self.update_counter) + logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter) else: gdk.threads_enter( ) try: @@ -3323,7 +3299,7 @@ class MonitorWidgets: self.update_counter_lock.release( ) # print "update display", self.update_counter if self.update_counter > 10: - print("update queue too long (%d>10): skipping one update" % self.update_counter) + logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter) return if self.displayed_data[ 0 ] is None or subject != self.displayed_data[ 0 ]: return @@ -3751,7 +3727,7 @@ class MonitorWidgets: moving_average = data_slice = None if max_points_to_display > 0 and len( xdata ) > max_points_to_display: - print("decimating data to %d points by moving average (prevent crash of matplotlib)" % max_points_to_display) + logger.warning("Decimating data to %d points by moving average (prevent crash of matplotlib)", max_points_to_display) n = numpy.ceil( len( xdata ) / max_points_to_display ) moving_average = numpy.ones( n, dtype="float" ) / n data_slice = numpy.array( numpy.floor( numpy.arange( max_points_to_display, dtype="float" ) \