.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/basic/example_logging.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_basic_example_logging.py: ======= Logging ======= This example demonstrates BAM Engine's logging system. Learn how to: - Configure global log levels - Set per-event log levels - Use the custom TRACE level for verbose debugging - Create loggers in your custom code Proper logging configuration helps with debugging, performance analysis, and understanding simulation behavior. .. GENERATED FROM PYTHON SOURCE LINES 18-23 Default Logging Behavior ------------------------ By default, BAM Engine logs at INFO level. This provides a good balance between information and noise. .. GENERATED FROM PYTHON SOURCE LINES 23-35 .. code-block:: Python import bamengine as bam from bamengine import logging print("Default log level is INFO") print("Running a short simulation with default logging...") sim = bam.Simulation.init(n_firms=50, n_households=250, seed=42) sim.step() print(f"Simulation complete (1 period). Period: {sim.t}") .. rst-class:: sphx-glr-script-out .. code-block:: none Default log level is INFO Running a short simulation with default logging... Simulation complete (1 period). Period: 1 .. GENERATED FROM PYTHON SOURCE LINES 36-47 Log Levels Overview ------------------- BAM Engine supports standard Python log levels plus a custom TRACE level: - CRITICAL (50): Critical errors that may cause failure - ERROR (40): Errors that affect operation - WARNING (30): Warnings about potential issues - INFO (20): General information (default) - DEBUG (10): Detailed debugging information - TRACE (5): Very verbose output for deep debugging .. GENERATED FROM PYTHON SOURCE LINES 47-56 .. code-block:: Python print("\nAvailable log levels:") print(f" CRITICAL: {logging.CRITICAL}") print(f" ERROR: {logging.ERROR}") print(f" WARNING: {logging.WARNING}") print(f" INFO: {logging.INFO}") print(f" DEBUG: {logging.DEBUG}") print(f" TRACE: {logging.TRACE}") .. rst-class:: sphx-glr-script-out .. code-block:: none Available log levels: CRITICAL: 50 ERROR: 40 WARNING: 30 INFO: 20 DEBUG: 10 TRACE: 5 .. GENERATED FROM PYTHON SOURCE LINES 57-61 Setting Global Log Level ------------------------ Configure logging via the ``log_level`` parameter at initialization. .. GENERATED FROM PYTHON SOURCE LINES 61-86 .. code-block:: Python # Set to WARNING to reduce output (only warnings and above) sim_quiet = bam.Simulation.init( n_firms=50, n_households=250, seed=42, log_level="WARNING", ) print("\nRunning with WARNING level (quiet mode)...") sim_quiet.step() print("Done (you should see fewer log messages)") # Set to DEBUG for more detail sim_debug = bam.Simulation.init( n_firms=50, n_households=250, seed=42, log_level="DEBUG", ) print("\nRunning with DEBUG level (verbose mode)...") sim_debug.step() print("Done (you should see more log messages)") .. rst-class:: sphx-glr-script-out .. code-block:: none Running with WARNING level (quiet mode)... Done (you should see fewer log messages) Running with DEBUG level (verbose mode)... Done (you should see more log messages) .. GENERATED FROM PYTHON SOURCE LINES 87-92 Per-Event Log Levels -------------------- Fine-tune logging by setting different levels for specific events. This is useful when debugging a particular part of the simulation. .. GENERATED FROM PYTHON SOURCE LINES 92-111 .. code-block:: Python # Only show detailed output for labor market events log_config = { "default_level": "WARNING", # Base level (quiet) "events": { "labor_market_round": "DEBUG", # Verbose for this event }, } sim_selective = bam.Simulation.init( n_firms=50, n_households=250, seed=42, logging=log_config, ) print("\nRunning with selective logging (labor market events only)...") sim_selective.step() .. rst-class:: sphx-glr-script-out .. code-block:: none Running with selective logging (labor market events only)... .. GENERATED FROM PYTHON SOURCE LINES 112-117 Using TRACE Level ----------------- TRACE (level 5) provides the most verbose output. Use it for deep debugging when you need to understand exactly what's happening. .. GENERATED FROM PYTHON SOURCE LINES 117-135 .. code-block:: Python # TRACE level - very verbose! sim_trace = bam.Simulation.init( n_firms=20, # Small simulation n_households=100, seed=42, logging={ "default_level": "INFO", "events": { "firms_decide_desired_production": "TRACE", }, }, ) print("\nRunning with TRACE level for production planning...") sim_trace.step() print("Check the output for very detailed production planning info") .. rst-class:: sphx-glr-script-out .. code-block:: none Running with TRACE level for production planning... Check the output for very detailed production planning info .. GENERATED FROM PYTHON SOURCE LINES 136-140 Creating Custom Loggers ----------------------- When writing custom events or extensions, create your own loggers. .. GENERATED FROM PYTHON SOURCE LINES 140-154 .. code-block:: Python # Get a logger for your module logger = logging.getLogger("my_custom_module") # Log at different levels logger.info("This is an info message") logger.debug("This is a debug message (may not show at INFO level)") logger.warning("This is a warning") # The custom TRACE method logger.trace("This is a trace message (very verbose)") print("\n(Custom logger messages shown above if level allows)") .. rst-class:: sphx-glr-script-out .. code-block:: none (Custom logger messages shown above if level allows) .. GENERATED FROM PYTHON SOURCE LINES 155-160 Conditional Logging ------------------- For performance-sensitive code, check if logging is enabled before computing expensive debug information. .. GENERATED FROM PYTHON SOURCE LINES 160-184 .. code-block:: Python def expensive_computation(): """Simulate an expensive debugging calculation.""" rng = bam.make_rng() arr = bam.ops.uniform(rng, 0, 1, 1000000) return bam.ops.mean(arr) # Create a logger perf_logger = logging.getLogger("performance_example") perf_logger.setLevel(logging.DEBUG) # Good practice: check before expensive operations if perf_logger.isEnabledFor(logging.DEBUG): result = expensive_computation() perf_logger.debug(f"Expensive result: {result:.6f}") # This is more efficient than: # perf_logger.debug(f"Expensive result: {expensive_computation()}") # Because expensive_computation() would run even if DEBUG is disabled print("\nConditional logging demonstrated (check code for pattern)") .. rst-class:: sphx-glr-script-out .. code-block:: none Conditional logging demonstrated (check code for pattern) .. GENERATED FROM PYTHON SOURCE LINES 185-190 Silencing Verbose Events ------------------------ Some events run many times per period (like market matching rounds). Silence them to focus on other parts of the simulation. .. GENERATED FROM PYTHON SOURCE LINES 190-213 .. code-block:: Python # Silence repetitive events quiet_config = { "default_level": "INFO", "events": { # Market matching events run multiple times per period "labor_market_round": "WARNING", "credit_market_round": "WARNING", "goods_market_round": "WARNING", }, } sim_focused = bam.Simulation.init( n_firms=50, n_households=250, seed=42, logging=quiet_config, ) print("\nRunning with market matching events silenced...") sim_focused.step() print("Done (market matching events suppressed)") .. rst-class:: sphx-glr-script-out .. code-block:: none Running with market matching events silenced... Done (market matching events suppressed) .. GENERATED FROM PYTHON SOURCE LINES 214-218 Logging in Custom Events ------------------------ When creating custom events, use the built-in logger pattern. .. GENERATED FROM PYTHON SOURCE LINES 218-256 .. code-block:: Python from bamengine import event, ops @event class TaxCollectionEvent: """Custom event that collects taxes from firms.""" def execute(self, sim): # Get a logger for this event logger = logging.getLogger("bamengine.events.tax_collection") logger.info("Collecting taxes from firms...") # Access firm data borr = sim.get_role("Borrower") # Calculate tax (10% of net worth) tax_rate = 0.10 positive_nw = ops.maximum(borr.net_worth, 0.0) tax_amount = ops.multiply(positive_nw, tax_rate) # Log details at debug level total_tax = ops.sum(tax_amount) logger.debug(f"Total tax collected: {total_tax:.2f}") # Very detailed logging at trace level if logger.isEnabledFor(logging.TRACE): logger.trace(f"Individual tax amounts: {tax_amount[:5]}... (first 5)") # Apply tax (reduce net worth) borr.net_worth[:] = borr.net_worth - tax_amount logger.info(f"Tax collection complete. Total: {total_tax:.2f}") print("\nCustom TaxCollectionEvent defined (see code for logging pattern)") .. rst-class:: sphx-glr-script-out .. code-block:: none Custom TaxCollectionEvent defined (see code for logging pattern) .. GENERATED FROM PYTHON SOURCE LINES 257-277 YAML Logging Configuration -------------------------- Logging can also be configured in YAML config files: .. code-block:: yaml # In your config.yml file logging: default_level: INFO events: labor_market_round: WARNING credit_market_round: DEBUG firms_plan_price: TRACE Then load it: .. code-block:: python sim = bam.Simulation.init(config="config.yml") .. GENERATED FROM PYTHON SOURCE LINES 277-291 .. code-block:: Python print( """ YAML logging configuration example: logging: default_level: INFO events: labor_market_round: WARNING credit_market_round: DEBUG firms_plan_price: TRACE """ ) .. rst-class:: sphx-glr-script-out .. code-block:: none YAML logging configuration example: logging: default_level: INFO events: labor_market_round: WARNING credit_market_round: DEBUG firms_plan_price: TRACE .. GENERATED FROM PYTHON SOURCE LINES 292-301 Key Takeaways ------------- - Default level is INFO (balanced output) - Use WARNING or ERROR for quiet runs - Use DEBUG or TRACE for debugging - Configure per-event levels to focus on specific areas - Use ``isEnabledFor()`` before expensive debug computations - Custom events should use ``logging.getLogger()`` .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.152 seconds) .. _sphx_glr_download_auto_examples_basic_example_logging.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_logging.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_logging.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_logging.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_