instruktai-python-logger 0.6.7__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- instruktai_python_logger-0.7.0/LICENSE +21 -0
- instruktai_python_logger-0.7.0/PKG-INFO +194 -0
- instruktai_python_logger-0.7.0/README.md +185 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instrukt_ai_logging/logging.py +10 -262
- instruktai_python_logger-0.7.0/instruktai_python_logger.egg-info/PKG-INFO +194 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instruktai_python_logger.egg-info/SOURCES.txt +2 -6
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/pyproject.toml +2 -6
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/tests/test_configure_logging.py +7 -2
- instruktai_python_logger-0.7.0/tests/test_resolve_log_files.py +64 -0
- instruktai_python_logger-0.6.7/PKG-INFO +0 -129
- instruktai_python_logger-0.6.7/README.md +0 -122
- instruktai_python_logger-0.6.7/instrukt_ai_logging/cli.py +0 -271
- instruktai_python_logger-0.6.7/instrukt_ai_logging/install.py +0 -245
- instruktai_python_logger-0.6.7/instruktai_python_logger.egg-info/PKG-INFO +0 -129
- instruktai_python_logger-0.6.7/instruktai_python_logger.egg-info/entry_points.txt +0 -3
- instruktai_python_logger-0.6.7/tests/test_cli_follow.py +0 -46
- instruktai_python_logger-0.6.7/tests/test_install.py +0 -301
- instruktai_python_logger-0.6.7/tests/test_log_aggregation.py +0 -292
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instrukt_ai_logging/__init__.py +0 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instrukt_ai_logging/py.typed +0 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instruktai_python_logger.egg-info/dependency_links.txt +0 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/instruktai_python_logger.egg-info/top_level.txt +0 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/setup.cfg +0 -0
- {instruktai_python_logger-0.6.7 → instruktai_python_logger-0.7.0}/tests/test_trace_logging.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 InstruktAI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: instruktai-python-logger
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: InstruktAI logging contract for Python services: one-call stdlib logging setup writing the shared logfmt files.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+
# InstruktAI logging
|
|
11
|
+
|
|
12
|
+
One logging contract for InstruktAI services, in three parts:
|
|
13
|
+
|
|
14
|
+
- **`instrukt-ai-logs`** and **`instrukt-ai-log-setup`**: the Rust tool that
|
|
15
|
+
reads and merges an app's logs and wires per-user log rotation.
|
|
16
|
+
- **`instrukt-ai-logging`**: a Rust writer crate (a `tracing` layer).
|
|
17
|
+
- **`instruktai-python-logger`**: the Python writer SDK (module
|
|
18
|
+
`instrukt_ai_logging`, stdlib `logging`).
|
|
19
|
+
|
|
20
|
+
Both writers follow the same contract, [`docs/contract.md`](docs/contract.md):
|
|
21
|
+
the same four env vars, the same single-line logfmt format, the same file
|
|
22
|
+
location. A Rust service and a Python service of one app write identical lines
|
|
23
|
+
into the same directory, and the tool reads both. The executable form of the
|
|
24
|
+
contract is the shared fixture tree under [`conformance/`](conformance/).
|
|
25
|
+
|
|
26
|
+
The contract keeps logs useful from a tail window, for people and for AIs that
|
|
27
|
+
only read the last lines: third-party noise is held back, every event is one
|
|
28
|
+
human-readable line, secrets are redacted and very long values truncated.
|
|
29
|
+
Background in [`docs/design.md`](docs/design.md); release process in
|
|
30
|
+
[`docs/publishing.md`](docs/publishing.md).
|
|
31
|
+
|
|
32
|
+
## Install the tool
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
curl -LsSf https://github.com/InstruktAI/logging/releases/latest/download/instrukt-ai-logs-installer.sh | sh
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This installs both binaries, `instrukt-ai-logs` and `instrukt-ai-log-setup`,
|
|
39
|
+
into `$XDG_BIN_HOME` or `~/.local/bin` (macOS on Apple silicon and Intel, Linux
|
|
40
|
+
x86_64 and aarch64). Rust users can build it instead:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cargo install instrukt-ai-logs
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Up to 0.6.x the two commands came with the Python package. If you installed
|
|
47
|
+
them that way (`uv tool install instruktai-python-logger`, `pipx`, or `pip`),
|
|
48
|
+
remove that install first so the old scripts do not shadow the new binaries,
|
|
49
|
+
for example `uv tool uninstall instruktai-python-logger`. See
|
|
50
|
+
[`CHANGELOG.md`](CHANGELOG.md).
|
|
51
|
+
|
|
52
|
+
## Read logs
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Last 10 minutes (the default)
|
|
56
|
+
instrukt-ai-logs teleclaude
|
|
57
|
+
|
|
58
|
+
# Last 2 hours
|
|
59
|
+
instrukt-ai-logs teleclaude --since 2h
|
|
60
|
+
|
|
61
|
+
# Keep matching lines, then drop matching lines (Python-style regex)
|
|
62
|
+
instrukt-ai-logs teleclaude --since 10m --grep 'logger=teleclaude' --exclude 'level=DEBUG'
|
|
63
|
+
|
|
64
|
+
# Print the window, then follow new lines (tail -f style); Ctrl-C to stop
|
|
65
|
+
instrukt-ai-logs teleclaude --since 10m --follow
|
|
66
|
+
|
|
67
|
+
# Only some per-process files
|
|
68
|
+
instrukt-ai-logs teleclaude --since 1h --logs=cron,docs-watch
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`--since` takes `<n>s`, `<n>m`, `<n>h` or `<n>d`. Without `--logs`, every
|
|
72
|
+
`*.log*` file in the app's directory is merged by timestamp, rotated and
|
|
73
|
+
gzip-compressed archives included. `--logs` (alias `--include`) selects exact
|
|
74
|
+
stems: `--logs=cron` reads `cron.log`, `cron.log.0`, `cron.log.1.gz` and never
|
|
75
|
+
`cron-backup.log`. Follow mode follows each stem's live `<stem>.log`, waits
|
|
76
|
+
for one that does not exist yet, and keeps following across rotation and
|
|
77
|
+
truncation. When nothing matches, a note on stderr names the directory read
|
|
78
|
+
and its newest entry.
|
|
79
|
+
|
|
80
|
+
## Write logs from Python
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install instruktai-python-logger
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```py
|
|
87
|
+
import logging
|
|
88
|
+
from instrukt_ai_logging import configure_logging
|
|
89
|
+
|
|
90
|
+
configure_logging("teleclaude")
|
|
91
|
+
logger = logging.getLogger("teleclaude.core")
|
|
92
|
+
logger.info("job_started", job_id="abc123", user_id=123)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
2026-11-05T09:30:12.345Z level=INFO logger=teleclaude.core msg="job_started" job_id=abc123 user_id=123
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`configure_logging` returns the log file path. `get_logger(name)` returns a
|
|
100
|
+
logger typed for named `**kv` fields; `TRACE` is a level below `DEBUG`.
|
|
101
|
+
`resolve_log_file(app, source=...)` and `resolve_log_files(app, stems=...)`
|
|
102
|
+
locate files without configuring anything.
|
|
103
|
+
|
|
104
|
+
## Write logs from Rust
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
cargo add instrukt-ai-logging tracing
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```rust
|
|
111
|
+
fn main() -> Result<(), instrukt_ai_logging::Error> {
|
|
112
|
+
// $XDG_STATE_HOME/instrukt-ai/teleclaude/teleclaude.log
|
|
113
|
+
let path = instrukt_ai_logging::init("teleclaude", None)?;
|
|
114
|
+
tracing::info!(job_id = "abc123", attempt = 3, "job_started");
|
|
115
|
+
println!("logging to {}", path.display());
|
|
116
|
+
Ok(())
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`init` installs the global subscriber and bridges the `log` crate. The
|
|
121
|
+
`Builder` sets a `source`, `max_message_chars`, extra app prefixes
|
|
122
|
+
(`app_prefix("my_app_core")`), or returns a `Layer` for a subscriber you
|
|
123
|
+
compose yourself. Details in
|
|
124
|
+
[`crates/instrukt-ai-logging/README.md`](crates/instrukt-ai-logging/README.md).
|
|
125
|
+
|
|
126
|
+
## Per-process log files
|
|
127
|
+
|
|
128
|
+
Several processes of one app (a daemon, a watcher, a cron job) can each write
|
|
129
|
+
their own file in the app's directory by passing a source:
|
|
130
|
+
|
|
131
|
+
```py
|
|
132
|
+
configure_logging("teleclaude") # teleclaude.log
|
|
133
|
+
configure_logging("teleclaude", source="docs-watch") # docs-watch.log
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```rust
|
|
137
|
+
instrukt_ai_logging::init("teleclaude", Some("cron"))?; // cron.log
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Pass the bare stem; `.log` is always appended. `instrukt-ai-logs` merges them.
|
|
141
|
+
|
|
142
|
+
## Environment variables
|
|
143
|
+
|
|
144
|
+
Per app, with the app name upper-cased as prefix (here `TELECLAUDE_`):
|
|
145
|
+
|
|
146
|
+
| Variable | Meaning | Default |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `TELECLAUDE_LOG_LEVEL` | threshold for the app's own loggers | `INFO` |
|
|
149
|
+
| `TELECLAUDE_THIRD_PARTY_LOG_LEVEL` | threshold for third-party loggers | `WARNING` |
|
|
150
|
+
| `TELECLAUDE_THIRD_PARTY_LOGGERS` | comma-separated third-party prefixes to spotlight at the third-party level, e.g. `httpcore,telegram`; every other third-party logger then passes at `WARNING`+ | none |
|
|
151
|
+
| `TELECLAUDE_MUTED_LOGGERS` | comma-separated prefixes held at `WARNING`+, e.g. `teleclaude.cli.tui` | none |
|
|
152
|
+
|
|
153
|
+
These four are the whole configuration surface. The longest matching prefix
|
|
154
|
+
decides; the exact rules are in [`docs/contract.md`](docs/contract.md).
|
|
155
|
+
|
|
156
|
+
## Log location
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
$XDG_STATE_HOME/instrukt-ai/{app}/{source or app}.log
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
with `~/.local/state` when `XDG_STATE_HOME` is unset, on macOS and Linux
|
|
163
|
+
alike. There is no override. The location is user-writable, and both writers
|
|
164
|
+
fail at startup when the file cannot be opened: a process that cannot write
|
|
165
|
+
its logs does not start blind.
|
|
166
|
+
|
|
167
|
+
## Rotation
|
|
168
|
+
|
|
169
|
+
Rotation runs entirely as the user. Run once per machine:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
instrukt-ai-log-setup
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It writes a rotation config under `~/.config/instrukt-ai/` and a per-user
|
|
176
|
+
scheduler: a launchd LaunchAgent running `newsyslog` on macOS, a systemd user
|
|
177
|
+
timer running `logrotate` on Linux. Each log rotates at 50 MB and 30 gzipped
|
|
178
|
+
archives are kept. Re-running on a wired machine reports healthy; problems are
|
|
179
|
+
printed and the exit code is 1. The writers never touch rotation; they reopen
|
|
180
|
+
their file when it has been rotated away. No `/etc` configuration and no sudo.
|
|
181
|
+
|
|
182
|
+
## Development
|
|
183
|
+
|
|
184
|
+
`make install` prepares the Python and Rust toolchains; `make install-runtime`
|
|
185
|
+
runs the setup from this checkout. Gates:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
uv run ruff check . && uv run ruff format --check . && uv run pyright && uv run mypy && uv run pytest
|
|
189
|
+
cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# InstruktAI logging
|
|
2
|
+
|
|
3
|
+
One logging contract for InstruktAI services, in three parts:
|
|
4
|
+
|
|
5
|
+
- **`instrukt-ai-logs`** and **`instrukt-ai-log-setup`**: the Rust tool that
|
|
6
|
+
reads and merges an app's logs and wires per-user log rotation.
|
|
7
|
+
- **`instrukt-ai-logging`**: a Rust writer crate (a `tracing` layer).
|
|
8
|
+
- **`instruktai-python-logger`**: the Python writer SDK (module
|
|
9
|
+
`instrukt_ai_logging`, stdlib `logging`).
|
|
10
|
+
|
|
11
|
+
Both writers follow the same contract, [`docs/contract.md`](docs/contract.md):
|
|
12
|
+
the same four env vars, the same single-line logfmt format, the same file
|
|
13
|
+
location. A Rust service and a Python service of one app write identical lines
|
|
14
|
+
into the same directory, and the tool reads both. The executable form of the
|
|
15
|
+
contract is the shared fixture tree under [`conformance/`](conformance/).
|
|
16
|
+
|
|
17
|
+
The contract keeps logs useful from a tail window, for people and for AIs that
|
|
18
|
+
only read the last lines: third-party noise is held back, every event is one
|
|
19
|
+
human-readable line, secrets are redacted and very long values truncated.
|
|
20
|
+
Background in [`docs/design.md`](docs/design.md); release process in
|
|
21
|
+
[`docs/publishing.md`](docs/publishing.md).
|
|
22
|
+
|
|
23
|
+
## Install the tool
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
curl -LsSf https://github.com/InstruktAI/logging/releases/latest/download/instrukt-ai-logs-installer.sh | sh
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This installs both binaries, `instrukt-ai-logs` and `instrukt-ai-log-setup`,
|
|
30
|
+
into `$XDG_BIN_HOME` or `~/.local/bin` (macOS on Apple silicon and Intel, Linux
|
|
31
|
+
x86_64 and aarch64). Rust users can build it instead:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cargo install instrukt-ai-logs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Up to 0.6.x the two commands came with the Python package. If you installed
|
|
38
|
+
them that way (`uv tool install instruktai-python-logger`, `pipx`, or `pip`),
|
|
39
|
+
remove that install first so the old scripts do not shadow the new binaries,
|
|
40
|
+
for example `uv tool uninstall instruktai-python-logger`. See
|
|
41
|
+
[`CHANGELOG.md`](CHANGELOG.md).
|
|
42
|
+
|
|
43
|
+
## Read logs
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Last 10 minutes (the default)
|
|
47
|
+
instrukt-ai-logs teleclaude
|
|
48
|
+
|
|
49
|
+
# Last 2 hours
|
|
50
|
+
instrukt-ai-logs teleclaude --since 2h
|
|
51
|
+
|
|
52
|
+
# Keep matching lines, then drop matching lines (Python-style regex)
|
|
53
|
+
instrukt-ai-logs teleclaude --since 10m --grep 'logger=teleclaude' --exclude 'level=DEBUG'
|
|
54
|
+
|
|
55
|
+
# Print the window, then follow new lines (tail -f style); Ctrl-C to stop
|
|
56
|
+
instrukt-ai-logs teleclaude --since 10m --follow
|
|
57
|
+
|
|
58
|
+
# Only some per-process files
|
|
59
|
+
instrukt-ai-logs teleclaude --since 1h --logs=cron,docs-watch
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`--since` takes `<n>s`, `<n>m`, `<n>h` or `<n>d`. Without `--logs`, every
|
|
63
|
+
`*.log*` file in the app's directory is merged by timestamp, rotated and
|
|
64
|
+
gzip-compressed archives included. `--logs` (alias `--include`) selects exact
|
|
65
|
+
stems: `--logs=cron` reads `cron.log`, `cron.log.0`, `cron.log.1.gz` and never
|
|
66
|
+
`cron-backup.log`. Follow mode follows each stem's live `<stem>.log`, waits
|
|
67
|
+
for one that does not exist yet, and keeps following across rotation and
|
|
68
|
+
truncation. When nothing matches, a note on stderr names the directory read
|
|
69
|
+
and its newest entry.
|
|
70
|
+
|
|
71
|
+
## Write logs from Python
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install instruktai-python-logger
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```py
|
|
78
|
+
import logging
|
|
79
|
+
from instrukt_ai_logging import configure_logging
|
|
80
|
+
|
|
81
|
+
configure_logging("teleclaude")
|
|
82
|
+
logger = logging.getLogger("teleclaude.core")
|
|
83
|
+
logger.info("job_started", job_id="abc123", user_id=123)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
2026-11-05T09:30:12.345Z level=INFO logger=teleclaude.core msg="job_started" job_id=abc123 user_id=123
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`configure_logging` returns the log file path. `get_logger(name)` returns a
|
|
91
|
+
logger typed for named `**kv` fields; `TRACE` is a level below `DEBUG`.
|
|
92
|
+
`resolve_log_file(app, source=...)` and `resolve_log_files(app, stems=...)`
|
|
93
|
+
locate files without configuring anything.
|
|
94
|
+
|
|
95
|
+
## Write logs from Rust
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
cargo add instrukt-ai-logging tracing
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```rust
|
|
102
|
+
fn main() -> Result<(), instrukt_ai_logging::Error> {
|
|
103
|
+
// $XDG_STATE_HOME/instrukt-ai/teleclaude/teleclaude.log
|
|
104
|
+
let path = instrukt_ai_logging::init("teleclaude", None)?;
|
|
105
|
+
tracing::info!(job_id = "abc123", attempt = 3, "job_started");
|
|
106
|
+
println!("logging to {}", path.display());
|
|
107
|
+
Ok(())
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`init` installs the global subscriber and bridges the `log` crate. The
|
|
112
|
+
`Builder` sets a `source`, `max_message_chars`, extra app prefixes
|
|
113
|
+
(`app_prefix("my_app_core")`), or returns a `Layer` for a subscriber you
|
|
114
|
+
compose yourself. Details in
|
|
115
|
+
[`crates/instrukt-ai-logging/README.md`](crates/instrukt-ai-logging/README.md).
|
|
116
|
+
|
|
117
|
+
## Per-process log files
|
|
118
|
+
|
|
119
|
+
Several processes of one app (a daemon, a watcher, a cron job) can each write
|
|
120
|
+
their own file in the app's directory by passing a source:
|
|
121
|
+
|
|
122
|
+
```py
|
|
123
|
+
configure_logging("teleclaude") # teleclaude.log
|
|
124
|
+
configure_logging("teleclaude", source="docs-watch") # docs-watch.log
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```rust
|
|
128
|
+
instrukt_ai_logging::init("teleclaude", Some("cron"))?; // cron.log
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Pass the bare stem; `.log` is always appended. `instrukt-ai-logs` merges them.
|
|
132
|
+
|
|
133
|
+
## Environment variables
|
|
134
|
+
|
|
135
|
+
Per app, with the app name upper-cased as prefix (here `TELECLAUDE_`):
|
|
136
|
+
|
|
137
|
+
| Variable | Meaning | Default |
|
|
138
|
+
| --- | --- | --- |
|
|
139
|
+
| `TELECLAUDE_LOG_LEVEL` | threshold for the app's own loggers | `INFO` |
|
|
140
|
+
| `TELECLAUDE_THIRD_PARTY_LOG_LEVEL` | threshold for third-party loggers | `WARNING` |
|
|
141
|
+
| `TELECLAUDE_THIRD_PARTY_LOGGERS` | comma-separated third-party prefixes to spotlight at the third-party level, e.g. `httpcore,telegram`; every other third-party logger then passes at `WARNING`+ | none |
|
|
142
|
+
| `TELECLAUDE_MUTED_LOGGERS` | comma-separated prefixes held at `WARNING`+, e.g. `teleclaude.cli.tui` | none |
|
|
143
|
+
|
|
144
|
+
These four are the whole configuration surface. The longest matching prefix
|
|
145
|
+
decides; the exact rules are in [`docs/contract.md`](docs/contract.md).
|
|
146
|
+
|
|
147
|
+
## Log location
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
$XDG_STATE_HOME/instrukt-ai/{app}/{source or app}.log
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
with `~/.local/state` when `XDG_STATE_HOME` is unset, on macOS and Linux
|
|
154
|
+
alike. There is no override. The location is user-writable, and both writers
|
|
155
|
+
fail at startup when the file cannot be opened: a process that cannot write
|
|
156
|
+
its logs does not start blind.
|
|
157
|
+
|
|
158
|
+
## Rotation
|
|
159
|
+
|
|
160
|
+
Rotation runs entirely as the user. Run once per machine:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
instrukt-ai-log-setup
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
It writes a rotation config under `~/.config/instrukt-ai/` and a per-user
|
|
167
|
+
scheduler: a launchd LaunchAgent running `newsyslog` on macOS, a systemd user
|
|
168
|
+
timer running `logrotate` on Linux. Each log rotates at 50 MB and 30 gzipped
|
|
169
|
+
archives are kept. Re-running on a wired machine reports healthy; problems are
|
|
170
|
+
printed and the exit code is 1. The writers never touch rotation; they reopen
|
|
171
|
+
their file when it has been rotated away. No `/etc` configuration and no sudo.
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
`make install` prepares the Python and Rust toolchains; `make install-runtime`
|
|
176
|
+
runs the setup from this checkout. Gates:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
uv run ruff check . && uv run ruff format --check . && uv run pyright && uv run mypy && uv run pytest
|
|
180
|
+
cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|