Skip to content

Commit 1623770

Browse files
mschmickingclaude
andcommitted
docs(logs): explain why the stream can look empty, and split out automation
Reported as 'logs prints the banner and nothing else'. Traced with a raw websocket probe: the subscription is accepted, frames do arrive, and the command prints them — verified by running iob-sync logs while opening a second connection, which Admin logs at info and which appeared immediately. The stream was not broken; the house was quiet. Reading the instance objects showed javascript.1/2/3 all at loglevel=info, and the adapter's 'script recompiled / started / stopped' messages are debug-level, so they were never emitted. A push therefore looks silent even when it worked. --level made that worse by implying it could reveal them. It only narrows what the server already sends, so it now says so when debug or silly is requested, and points at the instance log level in Admin. README gains an 'If logs shows nothing' section with a way to prove the stream is alive, and the --json deep dive moves to docs/AUTOMATION.md with a short pointer, plus a Docs index. All anchors and relative links checked; the only broken one is the screenshot placeholder, which is deliberate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 3b9724b commit 1623770

3 files changed

Lines changed: 75 additions & 24 deletions

File tree

README.md

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ The five commands worth knowing on day one:
6262
- [Safety model](#safety-model)
6363
- [Authentication](#authentication)
6464
- [Scripting and automation](#scripting-and-automation)
65+
- [Docs](#docs)
6566
- [Known limitations](#known-limitations)
6667
- [Development](#development)
6768

@@ -203,6 +204,21 @@ iob-sync logs garage # only lines mentioning "garage"
203204
iob-sync logs --level error # only failures
204205
```
205206

207+
#### If `logs` shows nothing
208+
209+
It is streaming; there is simply nothing to show. Two things surprise people:
210+
211+
- **`--level` only narrows what the server already sends.** An ioBroker adapter emits
212+
nothing below _its own_ configured log level, so asking for `--level debug` while
213+
`javascript.0` runs at `info` produces silence. Raise it in **Admin → Instances →
214+
your javascript instance → log level**.
215+
- **"script recompiled / started / stopped" messages are debug-level**, so at the default
216+
`info` they are never emitted at all — a `push` looks silent even though it worked.
217+
Your own `log()` calls are info and do appear.
218+
219+
To prove the stream is alive, run `iob-sync logs` and open a second terminal running any
220+
`iob-sync` command: Admin logs every connection at info, so a line appears immediately.
221+
206222
## Commands
207223

208224
**Sync**
@@ -306,35 +322,16 @@ Connect to the **admin adapter** port (usually 8081), not the socket.io adapter
306322

307323
## Scripting and automation
308324

309-
Human output is for reading; `--json` is for everything else. It emits
310-
[NDJSON](https://ndjson.org) on stdout — one JSON object per line, each tagged with a
311-
`type`. Human text is suppressed and warnings/errors stay on stderr, so **stdout stays
312-
parseable even when a command fails**.
313-
314-
What that is actually for:
325+
`--json` puts [NDJSON](https://ndjson.org) on stdout — one JSON object per line, each
326+
tagged with a `type`. Human text is suppressed and warnings/errors stay on stderr, so
327+
**stdout stays parseable even when a command fails**.
315328

316329
```bash
317330
# Fail a CI job if anything drifted from git
318331
test -z "$(iob-sync --json status | jq -rc 'select(.state != "in-sync")')"
319-
320-
# Alert if a script got disabled behind your back
321-
iob-sync --json list | jq -r 'select(.enabled | not) | .id'
322-
323-
# Nightly backup, reporting where the snapshot went
324-
iob-sync --json backup | jq -r .snapshot
325-
326-
# Follow only errors, as structured events
327-
iob-sync --json logs --level error
328332
```
329333

330-
It is also what makes the tool usable by a coding agent: an agent editing your scripts
331-
can read `status`, push, and then watch `logs` for a compile failure, without
332-
screen-scraping a table meant for a terminal.
333-
334-
Records carry underlying values rather than display strings — `enabled` is a boolean, not
335-
`"✓"`; `engine` is the full instance id, not `js.2`; and `--json status` includes the
336-
in-sync scripts the human view collapses into a count. NDJSON rather than one array
337-
because `logs` and `watch` never end; use `jq -s .` if you want a single document.
334+
See **[docs/AUTOMATION.md](docs/AUTOMATION.md)** for the record shapes and more examples.
338335

339336
## Known limitations
340337

@@ -400,6 +397,13 @@ Every test runs against an in-process fake Admin server (`test/fake-server.ts`);
400397
touches a real instance. `AGENTS.md` documents the architecture, the wire protocol, and
401398
the safety invariants any change has to preserve — read it before changing sync logic.
402399

400+
## Docs
401+
402+
- **[docs/AUTOMATION.md](docs/AUTOMATION.md)**`--json` record shapes, CI and agent usage
403+
- **[docs/GOING-PUBLIC.md](docs/GOING-PUBLIC.md)** — release checklist (maintainers)
404+
- **[AGENTS.md](AGENTS.md)** — architecture, wire protocol, safety invariants
405+
- **[CHANGELOG.md](CHANGELOG.md)**
406+
403407
## License
404408

405409
MIT — see [LICENSE](LICENSE).

docs/AUTOMATION.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Scripting and automation
2+
3+
Machine-readable output, and what it is for. See the
4+
[README](../README.md) for everything else.
5+
6+
Human output is for reading; `--json` is for everything else. It emits
7+
[NDJSON](https://ndjson.org) on stdout — one JSON object per line, each tagged with a
8+
`type`. Human text is suppressed and warnings/errors stay on stderr, so **stdout stays
9+
parseable even when a command fails**.
10+
11+
What that is actually for:
12+
13+
```bash
14+
# Fail a CI job if anything drifted from git
15+
test -z "$(iob-sync --json status | jq -rc 'select(.state != "in-sync")')"
16+
17+
# Alert if a script got disabled behind your back
18+
iob-sync --json list | jq -r 'select(.enabled | not) | .id'
19+
20+
# Nightly backup, reporting where the snapshot went
21+
iob-sync --json backup | jq -r .snapshot
22+
23+
# Follow only errors, as structured events
24+
iob-sync --json logs --level error
25+
```
26+
27+
It is also what makes the tool usable by a coding agent: an agent editing your scripts
28+
can read `status`, push, and then watch `logs` for a compile failure, without
29+
screen-scraping a table meant for a terminal.
30+
31+
Records carry underlying values rather than display strings — `enabled` is a boolean, not
32+
`"✓"`; `engine` is the full instance id, not `js.2`; and `--json status` includes the
33+
in-sync scripts the human view collapses into a count. NDJSON rather than one array
34+
because `logs` and `watch` never end; use `jq -s .` if you want a single document.

src/commands/logs.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,24 @@ export async function logs(ctx: CommandContext, opts: LogsOptions = {}): Promise
7474

7575
// Announced before subscribing, not after: the server logs our own connection, so
7676
// a line can arrive while `subscribe` is still in flight and print above the banner.
77+
const level = parseLevel(opts.level);
7778
ctx.log.info(
7879
`Streaming logs from ${ctx.config.url}${opts.pattern ? ` matching "${opts.pattern}"` : ''} ` +
79-
`at level ${parseLevel(opts.level)} and above.`,
80+
`at level ${level} and above.`,
8081
);
8182

83+
// This filter only narrows what the server already sends. An adapter emits nothing
84+
// below its own configured log level, so asking for debug here while javascript.2
85+
// runs at info yields silence — and the flag makes it look like the tool is broken
86+
// rather than that the messages were never sent.
87+
if (level === 'debug' || level === 'silly') {
88+
ctx.log.info(
89+
`Note: ${level} lines only appear if the adapter itself is set to ${level} ` +
90+
'(ioBroker Admin → Instances → the javascript instance → log level). ' +
91+
'Script recompile/start/stop messages are debug-level.',
92+
);
93+
}
94+
8295
await ctx.socket.subscribeLog((entry) => {
8396
if (severityRank(entry.severity) < minRank) return;
8497
if (!matches(entry, opts.pattern)) return;

0 commit comments

Comments
 (0)