551. Setting up the ProcessMetrics module
662. Using both session-based and snapshot monitoring approaches
773. Working with all available metric types
8- 4. Interpreting and displaying the collected metrics
8+ 4. Interpreting and displaying the metrics
995. Proper error handling and best practices
10+ 6. Continuous monitoring with callbacks
1011"""
1112import json
1213import os
@@ -316,7 +317,7 @@ def demo_other_process_monitoring() -> None:
316317 print (f" PID { proc .info ['pid' ]} : { proc .info ['name' ]} " )
317318
318319 # Try to monitor a system process like explorer.exe on Windows
319- target_name = "explorer.exe" if os . name == "nt" else "sshd"
320+ target_name = "explorer.exe"
320321 target_pid = None
321322
322323 for proc in psutil .process_iter (['pid' , 'name' ]):
@@ -340,6 +341,119 @@ def demo_other_process_monitoring() -> None:
340341 print (f"\n Could not find { target_name } process" )
341342
342343
344+ def demo_continuous_monitoring () -> None :
345+ """
346+ Demonstrates how to use continuous monitoring with callbacks.
347+
348+ This approach is ideal for:
349+ - Real-time monitoring dashboards
350+ - System administration panels
351+ - Long-term resource tracking
352+ - Detecting resource spikes or anomalies
353+ """
354+ print ("\n \n " + "=" * 80 )
355+ print ("DEMONSTRATION: CONTINUOUS MONITORING WITH CALLBACKS" )
356+ print ("=" * 80 )
357+
358+ metrics = ProcessMetrics ()
359+ pid = os .getpid () # Monitor the current Python process
360+
361+ # Define the metrics we want to collect
362+ flags = (
363+ ProcessMetrics .METRIC_WORKING_SET |
364+ ProcessMetrics .METRIC_PRIVATE_BYTES |
365+ ProcessMetrics .METRIC_CPU_USAGE |
366+ ProcessMetrics .METRIC_HANDLES |
367+ ProcessMetrics .METRIC_THREADS
368+ )
369+
370+ # Counter for received updates
371+ updates_received = 0
372+
373+ # Callback function that will be called for each metrics update
374+ def metrics_callback (data ):
375+ nonlocal updates_received
376+ updates_received += 1
377+ print (f"\n Update #{ updates_received } received:" )
378+ print (f" PID: { data ['pid' ]} " )
379+
380+ if 'working_set_kb' in data :
381+ print (f" Working Set: { data ['working_set_kb' ]} KB" )
382+ if 'private_kb' in data :
383+ print (f" Private Memory: { data ['private_kb' ]} KB" )
384+ if 'cpu' in data :
385+ print (f" CPU Usage: { data ['cpu' ]} %" )
386+ if 'handles' in data :
387+ print (f" Handles: { data ['handles' ]} " )
388+ if 'threads' in data :
389+ print (f" Threads: { data ['threads' ]} " )
390+
391+ # If we receive 5 updates, simulate some workload
392+ if updates_received == 5 :
393+ print ("\n [Simulating intensive workload during monitoring...]" )
394+ simulate_workload (intensity = 3 )
395+
396+ # Start monitoring with a 1-second interval, run for 10 seconds
397+ interval_ms = 1000 # 1 second between updates
398+ duration_ms = 10000 # Run for 10 seconds total
399+
400+ print (f"Starting continuous monitoring for PID { pid } " )
401+ print (f"Interval: { interval_ms } ms, Duration: { duration_ms } ms" )
402+ print ("Updates will be printed as they are received..." )
403+
404+ # Start the monitoring
405+ success = metrics .start_monitoring (
406+ pid = pid ,
407+ metrics = flags ,
408+ interval_ms = interval_ms ,
409+ duration_ms = duration_ms ,
410+ callback = metrics_callback
411+ )
412+
413+ if not success :
414+ print ("ERROR: Failed to start continuous monitoring!" )
415+ return
416+
417+ # Wait until monitoring is complete
418+ print ("Monitoring active. Waiting for completion..." )
419+
420+ # Keep checking if monitoring is still active
421+ while metrics .is_monitoring_active ():
422+ time .sleep (0.5 )
423+
424+ print ("\n Monitoring completed automatically after duration expired." )
425+ print (f"Received { updates_received } updates in total." )
426+
427+ # Demonstrate manual stopping
428+ print ("\n Now demonstrating indefinite monitoring with manual stop..." )
429+ updates_received = 0
430+
431+ # Start indefinite monitoring (duration = -1)
432+ success = metrics .start_monitoring (
433+ pid = pid ,
434+ metrics = flags ,
435+ interval_ms = interval_ms ,
436+ duration_ms = - 1 , # Run indefinitely
437+ callback = metrics_callback
438+ )
439+
440+ if not success :
441+ print ("ERROR: Failed to start indefinite monitoring!" )
442+ return
443+
444+ print ("Indefinite monitoring started. Will stop after 5 seconds..." )
445+
446+ # Let it run for 5 seconds then stop manually
447+ time .sleep (5 )
448+
449+ # Stop monitoring
450+ if metrics .stop_monitoring ():
451+ print ("\n Monitoring stopped manually." )
452+ print (f"Received { updates_received } updates before stopping." )
453+ else :
454+ print ("\n Failed to stop monitoring or monitoring was already stopped." )
455+
456+
343457def main ():
344458 """Main function to demonstrate all ProcessMetrics capabilities."""
345459 print ("=" * 80 )
@@ -353,6 +467,7 @@ def main():
353467 demo_snapshot_monitoring ()
354468 demo_selective_metrics ()
355469 demo_other_process_monitoring ()
470+ demo_continuous_monitoring () # Added the new continuous monitoring demo
356471
357472 print ("\n " + "=" * 80 )
358473 print ("DEMONSTRATION COMPLETE" )
0 commit comments