Skip to content

Logging

Rod Christiansen edited this page Oct 8, 2026 · 3 revisions

Logging

Where the client writes, how the files rotate, and what the lines look like.

Everything lives under /Library/Managed Reports/logs.

File Written by Rotation
reportmate.log managedreportsrunner Rolled on the first write of a new local day; 30 rolled files kept
reportmate-appusage.log reportmate-appusage Same rules
reportmate-postflight.log The Munki postflight wrapper and ReportMate's postflight script Same rules, implemented in shell
launchd-<label>.log (for example launchd-com.github.reportmate.hourly.log) launchd, capturing each daemon's stdout and stderr Not rotated; truncated at the next client start if over 1 MiB

The privileged helper writes no file. It logs to the unified log under the subsystem com.github.reportmate.helper, category xpc, including every accepted or rejected connection and refused preference write.

log show --last 1h --predicate 'subsystem == "com.github.reportmate.helper"'

Rolled files are named <stem>-YYYY-MM-DD.log, dated by the last write of the file being rolled — not by the day it was rolled.

Line format

[2026-01-15 09:30:12] INFO  Starting collection for module: security
[2026-01-15 09:30:44] WARN  management step 'mdm_info' failed, continuing: timed out
[2026-01-15 09:30:51] ERROR Transmission failed: HTTP error 401: unauthorized

Local time, then a level padded to five characters, then the message. swift-log's eight levels are collapsed to four: trace and debug become DEBUG, info and notice become INFO, warning becomes WARN, error and critical become ERROR.

The file is the log

The console only carries what -v asks for; the file always carries INFO and above, and -vvv lowers it to DEBUG. That split is deliberate — under launchd the console goes to the launchd-*.log capture files, which nothing rotates.

Several processes can share one log file safely: appends use O_APPEND, and the roll re-checks the file on disk before renaming, so a sibling that already rolled it is not undone. If two processes roll the same day, the second merges its content into the existing rolled file rather than clobbering it.

If /Library/Managed Reports/logs cannot be created or written — running unprivileged, for instance — the log falls back to ~/Library/Logs/ReportMate/<name>.log with the same rules.

launchd capture files

launchd-<label>.log exists so a crash leaves a trace, not as a log. Nothing rotates it, so any file over 1 MiB is truncated at the next client start. The postinstall also deletes legacy unrotated files such as reportmate-hourly.log, reportmate-daily.log and munki-postflight.log (and their .error.log twins) if they are present.

Reading them

The Logs tab of Managed Reports Runner.app lists every .log file in /Library/Managed Reports/logs in reverse name order, and colours each line by level. The same files can be read from a shell.

The last run of the collector.

sudo tail -100 "/Library/Managed Reports/logs/reportmate.log"

Everything a module logged today.

sudo grep "module: security" "/Library/Managed Reports/logs/reportmate.log"

What Munki triggered after its last run.

sudo tail -50 "/Library/Managed Reports/logs/reportmate-postflight.log"

Anything a daemon printed outside the client's own logging.

sudo tail -50 "/Library/Managed Reports/logs/launchd-com.github.reportmate.hourly.log"

The payload itself

To see exactly what was sent, read the newest cache directory rather than turning up logging.

sudo cat "/Library/Managed Reports/cache/$(sudo ls -t '/Library/Managed Reports/cache' | head -1)/event.json"

-vvv also prints the whole payload to the console between === COLLECTED DATA PAYLOAD === markers.

Clone this wiki locally