Utilities & Logging¶
WebATM.utils¶
WebATM.utils ¶
Utility functions for WebATM.
make_json_serializable ¶
Convert an object to a JSON-serializable format.
Recursively converts numpy arrays and scalars, dictionaries (including
BlueSky's msgpack-serialized numpy arrays, identified by the numpy,
data, type and shape byte keys), lists, tuples, and arbitrary
objects (via vars()) into plain Python types that json.dumps can
handle. Byte dictionary keys are decoded to strings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
The object to convert. May be a numpy array/scalar, dict, list,
tuple, or any object exposing |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A JSON-serializable equivalent of |
Source code in WebATM/utils.py
empty_traffic_data ¶
Return a fresh empty ACDATA payload for clearing all aircraft.
Emitted whenever the map must drop stale traffic (simulation reset, active-node change, or server disconnect). A new dict is returned on each call so callers can cache or mutate it without sharing state.
Returns:
| Type | Description |
|---|---|
dict
|
An |
Source code in WebATM/utils.py
id2str ¶
Convert a BlueSky node/sender ID to its hex-string form.
Node IDs arrive from the network as raw bytes; WebATM keys its tracking maps and Socket.IO payloads by the hex-string form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_id
|
bytes | str | None
|
Raw node/sender identifier. |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Hex string for bytes input, |
Source code in WebATM/utils.py
i2txt ¶
Convert an integer to a zero-padded string of fixed width.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
i
|
int
|
The integer to format. |
required |
n
|
int
|
The total width of the resulting string. |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
Source code in WebATM/utils.py
tim2txt ¶
Convert a time value in seconds to an HH:MM:SS.hh string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float
|
Time in seconds (e.g. simulation time). |
required |
Returns:
| Type | Description |
|---|---|
str
|
The formatted time string with hundredths of a second. |
Source code in WebATM/utils.py
WebATM.logger¶
WebATM.logger ¶
Provide centralized logging configuration for WebATM.
Provides standardized logging similar to TypeScript logging with:
- Different log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
- Automatic filename prefixes: [FileName] log information
- Consistent formatting across all Python modules
FileNameFormatter ¶
Bases: Formatter
Custom formatter that adds a filename prefix to log messages.
format ¶
Format a log record, prefixing the message with its source filename.
Werkzeug (Flask's HTTP server) records are prefixed with [Werkzeug];
all other records use the CamelCased stem of the source file name. The
record is restored afterwards, so a record that passes through several
handlers (e.g. console and file) is prefixed exactly once per output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
record
|
LogRecord
|
The log record to format. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The formatted log message. |
Source code in WebATM/logger.py
configure_logging ¶
configure_logging(
level: int = logging.INFO,
log_file: str | None = None,
include_console: bool = True,
)
Configure global logging settings for WebATM.
Resets the WebATM root logger and attaches console and/or file
handlers using the shared :class:FileNameFormatter. Module loggers from
:func:get_logger delegate their level to this root logger, so calling
this again (e.g. to switch to DEBUG at runtime) takes effect everywhere,
including loggers created before the call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). |
INFO
|
log_file
|
str | None
|
Optional file path to write logs to. |
None
|
include_console
|
bool
|
Whether to include console output. |
True
|
Source code in WebATM/logger.py
get_logger ¶
Get or create a logger for a module.
The returned logger is a child of the WebATM root logger and carries
no level of its own, so it always follows the level set by
:func:configure_logging — including changes made after it was created.
logging.getLogger caches by name, so repeated calls with the same name
return the same instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Optional custom name for the logger. If not provided, uses the calling module's filename. |
None
|
Returns:
| Type | Description |
|---|---|
Logger
|
A configured logger instance. |
Example
logger = get_logger() logger.info("Starting process") 2025-11-06 10:30:45 - INFO - [Main] Starting process
Source code in WebATM/logger.py
WebATM.proxy.perf¶
WebATM.proxy.perf ¶
Opt-in performance instrumentation for the proxy ACDATA hot path.
Serializing every ACDATA frame (make_json_serializable in pure Python) is
the dominant per-frame CPU cost under heavy node load. This module measures it
so you can see whether the single -w 1 worker is saturating, and quantifies
the saving from only serializing frames that are actually emitted.
Disabled by default; set WEBATM_PERF=1 to enable. When off, each record_*
call is a single boolean check, so the hot path pays effectively nothing. A
one-line summary is logged every WEBATM_PERF_INTERVAL seconds (default 5)::
[Perf] acdata 5.0s | recv=250 filtered=200 emit=48 throttled=2 |
serialize avg=3.10ms max=8.40ms | emit avg=0.90ms | datapath cpu=0.4% |
projected pre-opt cpu~=15.8% | max emit gap=140ms
datapath cpu is the wall-clock share this worker spent serializing/emitting
ACDATA; projected pre-opt cpu estimates the old serialize-every-frame cost
(one serialize per received frame) so a single run shows the before/after.
DataPathPerf ¶
Accumulate ACDATA serialize/emit timings and log periodic summaries.
All record_* methods are cheap no-ops unless WEBATM_PERF=1 is set
in the environment, so instrumentation can stay in the hot path.
Attributes:
| Name | Type | Description |
|---|---|---|
enabled |
bool
|
Whether instrumentation is active ( |
interval |
float
|
Seconds between logged summaries
( |
Source code in WebATM/proxy/perf.py
record_received ¶
record_filtered ¶
record_serialize ¶
Accumulate the wall-clock time of one frame serialization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
float
|
Time spent in |
required |
Source code in WebATM/proxy/perf.py
record_emit ¶
Accumulate the wall-clock time of one Socket.IO emit.
Also tracks the maximum gap between consecutive emits, which surfaces stalls in the data path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
float
|
Time spent emitting the serialized frame. |
required |
Source code in WebATM/proxy/perf.py
maybe_log ¶
Log a one-line summary and reset counters when the window elapsed.
Called from the data path after each frame; does nothing until
interval seconds have passed since the last summary.