How Mojave changes the unified log

I hope you haven’t had to look in Mojave’s log yet, at least not in anger, but when you do you’ll get quite a surprise. Yes, it’s still a ‘unified log’ of the type introduced in Sierra, but it has moved on in many important respects. This article explains what has changed, and how that affects you if you want to use or access the log in Mojave.

Log file layout and internals

Unified log files continued to be stored in /var/db/diagnostics, but the folders within that have changed. High Sierra added a folder named HighVolume, which is presumably used to store log files captured during periods of intense log activity, although I haven’t seen any in that folder yet. That is retained in Mojave, and another new folder is added: Signpost. That contains tracev3 log files containing Signpost entries, which are fully implemented in Mojave.

logstructure

Apple’s log file format, tracev3, is proprietary and compressed, and remains completely undocumented. However, it appears that older versions of macOS cannot read either the tracev3 log files or logarchives generated in Mojave. I have tried various combinations, and as far as I can see at the moment, log files and logarchives written in Mojave can only be read by tools running in Mojave, whether using the log command, Apple’s Console, or my Consolation and other free tools available from here.

I suspect that this is also true for logs written by iOS 12, tvOS 12, and watchOS 5, and is an important point for anyone wanting to analyse logs captured on another system, perhaps in forensic work: to ensure full compatibility, you will now need to perform all log analysis on a Mac running Mojave.

Log content

Apple has progressively increased the number of fields available for use within log entries, from 16 in Sierra, to 22 in High Sierra 10.13.6, to 27 in Mojave.

Sierra’s fields are:

  • timestamp – a format date and timestamp string;
  • machTimestamp – the number of Mach system clock ticks, which is effectively elapsed nanoseconds;
  • messageType – e.g. Default, Info;
  • category – a string qualifier, e.g. ‘signposts’;
  • subsystem – e.g. com.apple.kext;
  • processUniqueID;
  • threadID;
  • traceID;
  • senderProgramCounter;
  • processID;
  • eventMessage – the message for that log entry;
  • processImagePath;
  • processImageUUID;
  • senderImagePath;
  • senderImageUUID;
  • timezoneName.

To those, High Sierra 10.13.6 added:

  • eventType – the type of event, e.g. logEvent, which can now include signpostEvent;
  • activityIdentifier – a numeric ID for an activity;
  • parentActivityIdentifier – a numeric ID for the parent activity;
  • creatorActivityID – a numeric ID for the creator activity;
  • signpostID – a numeric ID for a Signpost;
  • source – appears invariably set to null.

Mojave 10.14 now adds:

  • signpostName – a string name for a Signpost;
  • signpostType – the Signpost type – begin, end, or event;
  • signpostScope – a scope string, such as ‘process’;
  • formatString – this gives the format string used to convert variable content into a string for output, e.g. “vm_page_bootstrap: %d free pages and %d wired pages\n” or “%{public}@”;
  • backtrace – this consists of imageOffset and imageUUID structured into a ‘frame’.

mojapps11

Apple’s own processes now use subsystem names much more often than they did in Sierra, for example.

Most of the new fields are to provide for improved event and Signpost logging. If you use the current version of my log browser Consolation, all the fields available for viewing are listed in a window accessed through Help menu. The list provided depends on the version of macOS on which you are running Consolation.

formatString is unusual, as I can see no good reason for wanting to write out the string used to format a log eventMessage into that log entry, except to ensure that the log is not leaking information which should be protected as private. This occurred in High Sierra, when passwords used to encrypt APFS volumes were inadvertently written to the log in plain text. I therefore suspect that this has been introduced by Apple to enable such errors to be detected more easily.

The backtrace field currently appears to be of little use outside Apple. As far as I can tell, none of the public macOS calls to write log entries include such backtrace information, so it can only be written by using Apple’s private interfaces. Because the field has a complex structure, it is currently ignored by Consolation.

mojapps10

The log command

If you use the log command to examine logs, most of its verbs and options remain the same as in High Sierra. One notable point is with Signposts: by default, these are not included in log show output. If you want them included, then you will need to provide the option
--signpost
in the log show command. Although you might think that Signpost information is of little use when using the log for diagnostics or in forensic examination, Mojave itself uses Signposts quite extensively, and they can be of value in the context of other log activity.

Although some consideration is made of the newly-added fields, as far as I can tell at present they haven’t been brought within the scope of predicate filters. So, for example, you can specify
eventType == signpostEvent
to narrow the filter down to Signpost entries only, but you cannot (yet, I think) use
signpostName contains[c] "chars"
However, this may well change during the lifetime of Mojave.

Writing to the log

Public interfaces for writing to the log have only changed to support Signposts. These are very simple to use, for example in Swift 4.2:
self.myLog = OSLog(subsystem: "co.eclecticlight.Whither", category: "Signpost")
let mySpid = OSSignpostID(log: self.myLog!)
os_signpost(.begin, log: self.myLog!, name: "timingCheckMain", signpostID: mySpid, "%{public}@", "\(i)")

You can find full information about how to use Signposts from within Xcode and in scripting and other systems in my Signpost Kit, available from Downloads above.

signpost44

Better, or just a bigger haystack?

Apple is at last starting to segregate its unified log, which may seem contradictory, but will prove a valuable step forward. In Sierra, no matter what a process in macOS or elsewhere wanted to use the log for, the great majority of log entries ended up in the same log files, leading to extreme congestion and delays when filtering entries. The only exceptions to that were the most ephemeral of log entries, which continue to be stored in files in the Special folder.

With Signposts saved separately, and easily eliminated when searching for non-performance entries, the log show command should be easier to use, quicker to return results, and those results should be better-targeted. Instead of looking in one large haystack for your needle, you should find it simple to choose between two rather smaller haystacks.

It remains a shame, though, that Apple’s Console app hasn’t improved much, and still lacks the power that the unified log deserves.