From device to searchable text: how I work with the Unified Log – Thesis Friday #30

Key finding

– On the busy device I tested, the entries that hold unlock traces were gone within about a day. Secure the log the same day.

– A logarchive is a folder. Hash every file in it, save the list, and hash the list too.

– `log show` hides info and debug entries unless you ask for them, so an empty result can still hide a trace.

– iLEAPP finds what someone has already described. When it stays quiet, search the raw log yourself.

Part of the Anchored Log Reconstruction series. This is how I do it myself, written for people who are just starting out.

The Unified Log records what happens on an Apple device down to the microsecond, and it forgets quickly. On the busy device I tested, the entries that hold unlock traces were gone within about a day. That is why I work in a fixed order: secure the log, check it, and only then look.

In every command below I use one archive name, devicename_version.logarchive. I name an archive after the device and the iOS version, for example iphone14_26.6.logarchive. Swap in your own.

Secure the log

I pick one route and note which one I used. On a Mac I use log collect, which needs a trusted connection and the device passcode:

mkdir -p ~/logs && cd ~/logs
sudo log collect --device --output ~/logs/devicename_version.logarchive

Without a Mac you can use UFADE, a free Python tool. Its README says the “Collect Unified Logs” option saves the log as a logarchive. A sysdiagnose is quicker, but Christian Peter’s research reports that it holds less log than a direct collection. I prefer the direct route when I have the choice.

Check what I have

Before I analyse anything I write down the device, the iOS version and the time I secured the log. Then I hash the archive. A logarchive is a folder and shasum only hashes files, so I hash every file inside, save that list, and hash the list as well. I do this before opening the folder in Finder, which would add a .DS_Store file.

cd ~/logs/devicename_version.logarchive
find . -type f ! -name .DS_Store -print0 | xargs -0 shasum -a 256 | LC_ALL=C sort -k2 > ../devicename_version.sha256
cd ..
shasum -a 256 devicename_version.sha256

The last line gives one hash for the whole archive. I note it and keep the list next to it. Verifying later takes one command, and every line has to say OK:

cd ~/logs/devicename_version.logarchive
shasum -a 256 -c ../devicename_version.sha256

Then I check that the trace I need is still in there. I search for a marker line from my own reference action. As an example, this finds the kernel lines that record an APFS volume being unlocked:

log show --archive ~/logs/devicename_version.logarchive --info --debug --style compact \
  --predicate 'composedMessage CONTAINS "handle_async_keybag_unlock"' | head -n 5

I switch on --info and --debug because log show hides both levels by default. Without them, an empty result can mean the line exists but isn’t displayed. If nothing comes back with both on, the trace is gone. That is a result, and it’s where I stop.

Look inside

iLEAPP is the easiest start, because it already knows many traces. Next I open the logarchive itself in Consolation3, which puts a log show browser in a window. I can pick a time range and filter without typing commands, and I read the raw log instead of someone’s interpretation of it.

For free searching I export a window to a text file and open it in any good text editor, like Notepad++, BBEdit or VS Code. Ctrl-F is enough.

log show --archive ~/logs/devicename_version.logarchive --info --debug \
  --start "2026-10-01 09:00:00" --end "2026-10-01 10:00:00" > ~/logs/devicename_version_window.txt

I always give a start and an end time. --last is relative to now, and on an old archive it gave me zero events. For larger volumes I’m starting to use Elastic. I’ve only just begun, so I won’t say more about it here.

Known and unknown traces

iLEAPP is good at known traces. Someone described them and the tool looks for them. If your trace isn’t on that list the tool stays quiet, and quiet doesn’t mean absent.

For an unknown trace I start from something I did myself. I perform one action on a test device and write down the exact time, secure the log the same day and run the checks above. Then I open the log around that moment and read the lines around my action. Whatever I conclude is a guess until I repeat the action once and the same lines return.

That is ALR in small. I write down the time, and the clock I read it from, before I open the log, because the log can’t check its own clock. I cut a window around that moment and ignore the rest until I have a reason to look. When a tool reports something, I look for the raw line behind it. When the archive is empty, my marker is missing or two tools disagree, I stop and find out why before I write anything down. For that I do reference research: one known action on a test device, secured the same day, to see what that action leaves behind.

Try it yourself

Take a test device without personal data, unlock it and write down the exact time. Secure the log the same day, do the checks including the hash and the marker search, and look for your unlock in the log.

This is my first-line workflow, not a complete method, and the retention finding comes from the devices I tested. Numbers from different tools don’t always match, so I note which tool and settings produced each one. Latest releases as of 2 October 2026: iLEAPP v2026.4.3, UFADE 1.0.4 and Consolation3.

© 2026 Tim Korver — Thesis Friday. Licensed under CC BY-NC-ND 4.0. Method: Anchored Log Reconstruction (ALR). Commercial or training use requires written permission. See Copyright and Use.

Monthly digest of new posts. Double opt-in, unsubscribe anytime. Privacy