Skip to content

Commit 72a646b

Browse files
committed
Add logging guide and docs navigation
1 parent 857b794 commit 72a646b

5 files changed

Lines changed: 265 additions & 27 deletions

File tree

docs/AGENTS.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
# Documentation
22

3-
- Link to existing docs/API refs instead of re-explaining concepts - reduces duplication
4-
and keeps info in sync - Prevents documentation drift and outdated explanations by
5-
maintaining a single source of truth for each concept
6-
- Link to canonical docs rather than duplicating content - prevents drift and
7-
maintenance burden - Consolidating documentation into existing files with
8-
cross-references keeps information consistent and reduces the effort needed to
9-
update multiple locations when changes occur.
3+
## General
4+
105
- Document only public APIs and user-facing behavior - exclude internals, framework
116
abstractions, and implementation plumbing - Users need actionable documentation on
127
what they can use, not confusing details about internal mechanics they can't control
@@ -17,9 +12,6 @@
1712
comprehensive coverage vs. fragmented mentions - Prevents users from missing
1813
features when they approach from different contexts (CLI vs. API) and allows
1914
features to be documented holistically rather than buried in subsections.
20-
- Avoid `# ruff: noqa` or `# type: ignore` in doc examples - ensures examples stay
21-
correct and runnable - Skip directives hide bugs and type errors in documentation
22-
code that users will copy, leading to broken examples in the wild
2315
- Explicitly mark parameters/features as 'optional' in docs, even when types show it -
2416
reduces cognitive load for readers - Users shouldn't need to parse type signatures
2517
to understand optionality; explicit labels make documentation scannable and
@@ -31,3 +23,21 @@
3123
- Strip boilerplate from docs examples - show only the feature being demonstrated -
3224
Reduces cognitive load and helps readers focus on the specific API or pattern being
3325
taught without distraction from scaffolding code.
26+
27+
## Linking
28+
29+
- Link to existing docs/API refs instead of re-explaining concepts - reduces duplication
30+
and keeps info in sync - Prevents documentation drift and outdated explanations by
31+
maintaining a single source of truth for each concept
32+
- Link to canonical docs rather than duplicating content - prevents drift and
33+
maintenance burden - Consolidating documentation into existing files with
34+
cross-references keeps information consistent and reduces the effort needed to
35+
update multiple locations when changes occur.
36+
37+
## Code Examples
38+
39+
- Avoid `# ruff: noqa` or `# type: ignore` in doc examples - ensures examples stay
40+
correct and runnable - Skip directives hide bugs and type errors in documentation
41+
code that users will copy, leading to broken examples in the wild
42+
- Code file examples should have a title that shows the file name.
43+
- Important lines should be highlighted or annotated with a comment.

docs/source/how_to_guides/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ specific tasks with pytask.
1313
- [Remote Files](remote_files.md)
1414
- [Functional Interface](functional_interface.md)
1515
- [Capture Warnings](capture_warnings.md)
16+
- [Manage Logging](logging.md)
1617
- [How To Influence Build Order](how_to_influence_build_order.md)
1718
- [Hashing Inputs Of Tasks](hashing_inputs_of_tasks.md)
1819
- [Using Task Returns](using_task_returns.md)
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Manage logging
2+
3+
pytask can capture log records emitted during task execution, show them for failing
4+
tasks, stream them live to the terminal, and write them to a file.
5+
6+
If you do not use Python's [`logging`](https://docs.python.org/3/library/logging.html)
7+
module often, think of log records simply as structured status messages such as
8+
"starting download", "loaded 200 rows", or "publishing failed".
9+
10+
This guide focuses on the most common ways to work with logging in pytask.
11+
12+
## Quick start
13+
14+
If you want to... use this:
15+
16+
- see log messages only when a task fails: run `pytask`
17+
- show only logs in failure reports: run `pytask --show-capture=log`
18+
- see logs immediately while tasks run: run `pytask --log-cli --log-cli-level=INFO`
19+
- save logs to a file: run `pytask --log-file=build.log`
20+
- capture more detailed messages such as `INFO` or `DEBUG`: add `--log-level=INFO` or
21+
`--log-level=DEBUG`
22+
23+
## A minimal example
24+
25+
```py title="task_logging.py"
26+
import logging
27+
import sys
28+
29+
30+
logger = logging.getLogger(__name__)
31+
32+
33+
def task_prepare_report():
34+
logger.info("preparing report.txt")
35+
36+
37+
def task_publish_report():
38+
logger.warning("publishing report is about to fail")
39+
print("stdout from publish")
40+
sys.stderr.write("stderr from publish\n")
41+
raise RuntimeError("simulated publish failure")
42+
```
43+
44+
The most common logging levels are:
45+
46+
- `DEBUG`: very detailed information for debugging
47+
- `INFO`: normal progress messages
48+
- `WARNING`: something unexpected happened, but execution can continue
49+
- `ERROR`: a more serious problem
50+
51+
If you are just getting started, `INFO` and `WARNING` are usually the most useful
52+
levels.
53+
54+
Here is what this looks like with live logging enabled and failure output restricted to
55+
captured logs:
56+
57+
```console
58+
$ pytask --log-cli --log-cli-level=INFO --show-capture=log
59+
```
60+
61+
--8<-- "docs/source/_static/md/logging-live.md"
62+
63+
## Show captured logs for failing tasks
64+
65+
Log records emitted with Python's
66+
[`logging`](https://docs.python.org/3/library/logging.html) module are attached to the
67+
report of a failing task in the same way as captured `stdout` and `stderr`.
68+
69+
```py title="task_logging.py"
70+
import logging
71+
72+
73+
logger = logging.getLogger(__name__)
74+
75+
76+
def task_example():
77+
logger.warning("something went wrong")
78+
raise RuntimeError("fail")
79+
```
80+
81+
```console
82+
$ pytask
83+
```
84+
85+
By default, pytask shows captured log output for failing tasks together with the
86+
traceback and any captured `stdout` or `stderr`.
87+
88+
This is useful when a task fails and you want to see what happened right before the
89+
error.
90+
91+
Use `--show-capture` to control which captured output is shown:
92+
93+
```console
94+
$ pytask --show-capture=log
95+
$ pytask --show-capture=all
96+
$ pytask --show-capture=no
97+
```
98+
99+
`--show-capture=log` is useful when you only want log records in the failure report and
100+
want to hide captured `stdout` and `stderr`.
101+
102+
## Control which log records are captured
103+
104+
By default, pytask does not change the logging level. Captured output therefore depends
105+
on your normal logging configuration.
106+
107+
In practice this often means that `WARNING` and `ERROR` messages appear, while `INFO`
108+
and `DEBUG` messages do not, unless you configure logging more explicitly.
109+
110+
Use `--log-level` to set the threshold for captured log records explicitly:
111+
112+
```console
113+
$ pytask --log-level=INFO
114+
$ pytask --log-level=DEBUG
115+
```
116+
117+
As a rule of thumb:
118+
119+
- use `INFO` if you want to see normal progress messages,
120+
- use `DEBUG` only when you need very detailed diagnostics.
121+
122+
This option affects:
123+
124+
- log records attached to failing task reports,
125+
- live logs shown with `--log-cli`,
126+
- exported logs written with `--log-file`.
127+
128+
You can customize the formatting of captured log records with:
129+
130+
```console
131+
$ pytask --log-format="%(asctime)s %(levelname)s %(message)s" \
132+
--log-date-format="%Y-%m-%d %H:%M:%S"
133+
```
134+
135+
## Stream logs live while tasks run
136+
137+
Use `--log-cli` to print log records directly to the terminal during task execution.
138+
139+
```console
140+
$ pytask --log-cli --log-cli-level=INFO
141+
```
142+
143+
This is helpful when tasks take a while and you want immediate feedback instead of
144+
waiting for the final report.
145+
146+
You can customize live logs separately from the captured report output:
147+
148+
```console
149+
$ pytask --log-cli \
150+
--log-cli-level=INFO \
151+
--log-cli-format="%(levelname)s:%(message)s" \
152+
--log-cli-date-format="%H:%M:%S"
153+
```
154+
155+
If `--log-cli-format` or `--log-cli-date-format` are not provided, pytask falls back to
156+
`--log-format` and `--log-date-format`.
157+
158+
## Write logs to a file
159+
160+
Use `--log-file` to export log records from executed tasks to a file.
161+
162+
```console
163+
$ pytask --log-file=build.log
164+
```
165+
166+
This is useful for CI runs, long builds, or when you want to inspect logs after the run
167+
has finished.
168+
169+
The file is overwritten by default. Use `--log-file-mode=a` to append instead.
170+
171+
```console
172+
$ pytask --log-file=build.log --log-file-mode=a
173+
```
174+
175+
You can control the file output independently:
176+
177+
```console
178+
$ pytask --log-file=build.log \
179+
--log-file-level=INFO \
180+
--log-file-format="%(asctime)s %(name)s %(levelname)s %(message)s" \
181+
--log-file-date-format="%Y-%m-%d %H:%M:%S"
182+
```
183+
184+
Relative log file paths are resolved relative to the project root detected by pytask.
185+
186+
## A good beginner setup
187+
188+
If you want a practical setup without spending much time on logging configuration, this
189+
is a good default:
190+
191+
```console
192+
$ pytask --log-cli --log-cli-level=INFO --log-file=build.log --show-capture=log
193+
```
194+
195+
This gives you:
196+
197+
- live progress messages in the terminal,
198+
- a log file you can inspect later,
199+
- only log output in failure reports, without extra `stdout` and `stderr` noise.
200+
201+
## Configure logging defaults in `pyproject.toml`
202+
203+
All logging options can be configured in `pyproject.toml`.
204+
205+
```toml title="pyproject.toml"
206+
[tool.pytask.ini_options]
207+
log_level = "INFO"
208+
log_format = "%(asctime)s %(levelname)s %(message)s"
209+
log_date_format = "%Y-%m-%d %H:%M:%S"
210+
211+
log_cli = true
212+
log_cli_level = "INFO"
213+
log_cli_format = "%(levelname)s:%(message)s"
214+
215+
log_file = "build.log"
216+
log_file_mode = "w"
217+
log_file_level = "INFO"
218+
log_file_format = "%(asctime)s %(name)s %(levelname)s %(message)s"
219+
log_file_date_format = "%Y-%m-%d %H:%M:%S"
220+
```
221+
222+
## Use logging with the programmatic interface
223+
224+
The same options are available via
225+
[`pytask.build`](../api/functional_interfaces.md#build-workflow).
226+
227+
```py title="build.py"
228+
from pytask import build
229+
230+
231+
session = build(
232+
log_level="INFO",
233+
log_cli=True,
234+
log_cli_level="INFO",
235+
log_file="build.log",
236+
log_file_format="%(levelname)s:%(message)s",
237+
)
238+
```

docs/source/tutorials/capturing_output.md

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ By default, capturing is done by intercepting writes to low-level file descripto
2626
allows capturing output from simple `print` statements as well as output from a
2727
subprocess started by a task.
2828

29+
!!! seealso
30+
31+
[Manage logging](../how_to_guides/logging.md) for a dedicated guide to captured logs,
32+
live logs, log files, and logging configuration.
33+
2934
## Setting capturing methods or disabling capturing
3035

3136
There are three ways in which `pytask` can perform capturing:
@@ -49,23 +54,6 @@ $ pytask --capture=tee-sys # combines 'sys' and '-s', capturing sys.stdout/std
4954
# and passing it along to the actual sys.stdout/stderr
5055
```
5156

52-
## Controlling captured log output
53-
54-
Use `--show-capture=log` to only display captured log records for failing tasks or
55-
`--show-capture=all` to display logs together with captured `stdout` and `stderr`.
56-
57-
Use `--log-cli` to stream log records to the terminal while tasks run. You can customize
58-
the live output with `--log-cli-level`, `--log-cli-format`, and `--log-cli-date-format`.
59-
60-
You can also export task logs to a file with `--log-file` and customize the formatting
61-
with `--log-format`, `--log-date-format`, `--log-file-format`, and
62-
`--log-file-date-format`.
63-
64-
The animation below shows the same warning appearing once as a live log line during
65-
execution and again as captured log output in the failure report.
66-
67-
--8<-- "docs/source/_static/md/logging-live.md"
68-
6957
## Using print statements for debugging
7058

7159
One primary benefit of the default capturing of stdout/stderr output is that you can use

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ nav:
4141
- Remote Files: how_to_guides/remote_files.md
4242
- Functional Interface: how_to_guides/functional_interface.md
4343
- Capture Warnings: how_to_guides/capture_warnings.md
44+
- Manage Logging: how_to_guides/logging.md
4445
- How To Influence Build Order: how_to_guides/how_to_influence_build_order.md
4546
- Hashing Inputs Of Tasks: how_to_guides/hashing_inputs_of_tasks.md
4647
- Using Task Returns: how_to_guides/using_task_returns.md

0 commit comments

Comments
 (0)