Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Changed

- **Per-task overhead** β€” runtime type checks on the per-task path
(`task_callbacks`) run only in debug mode (`RADICAL_ASYNCFLOW_DEBUG` or
`RADICAL_DEBUG`, see *Logging & Debugging* in the best-practice guide);
per-task log messages format lazily; telemetry event arguments are built
only when telemetry is enabled; a decorated call creates its component
directly instead of building a wrapper per call.
- **Log levels** β€” per-task messages (`<uid> is in <state> state`,
`Submitting <n> tasks/blocks`) are logged at DEBUG instead of INFO.
- **`init_default_logger`** sets the logger level to the lowest level of its
handlers instead of `NOTSET`, so records no handler would emit are dropped
before they are built. Configuring the root logger, records of other
libraries below that level are dropped too.

## [0.5.1] - 2026-08-20

### Fixed
Expand Down
25 changes: 23 additions & 2 deletions docs/best_practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,32 @@ await flow.shutdown()
## Logging & Debugging

Enable detailed logs to diagnose issues:
```python
import logging
from radical.asyncflow.logging import init_default_logger

init_default_logger(logging.DEBUG)
```

DEBUG logs show task registration, dependencies, submission and every task
state change; INFO and above show engine lifecycle events and errors.

### Debug mode

Debug mode adds runtime type checks on the per-task engine method
`task_callbacks` (via `typeguard`). They add noticeable per-task overhead,
so they are off by default. Enable them with an environment variable set
before `radical.asyncflow` is imported:

```bash
export RADICAL_LOG_LVL=DEBUG
export RADICAL_ASYNCFLOW_DEBUG=1
```

Logs show task dependencies, execution order, errors.
`RADICAL_DEBUG` is honoured as well; when both are set,
`RADICAL_ASYNCFLOW_DEBUG` decides, so `RADICAL_ASYNCFLOW_DEBUG=0` disables
debug mode in an environment that sets `RADICAL_DEBUG`. The values `1`,
`true`, `yes` and `on` (any case) enable it; any other value disables it.
The test suite runs in debug mode.

---

Expand Down
6 changes: 4 additions & 2 deletions src/radical/asyncflow/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,10 @@ def init_default_logger(

logger.addHandler(struct_handler)

# Set logger level
logger.setLevel(logging.NOTSET)
# Logger level = lowest handler level: records below every handler's
# level are dropped before a LogRecord is built. A handler at NOTSET (0)
# accepts everything; level 1 expresses that without meaning "inherit".
logger.setLevel(min(h.level for h in logger.handlers) or 1)

# Capture warnings
logging.captureWarnings(True)
Expand Down
Loading
Loading