Blowhole

A simple tool to write an entry to the unified log in macOS Sierra, High Sierra, Mojave and Catalina.
by EHN & DIJ Oakley

version 9
11 June 2019.

Installation:
————

All users are recommend to use the Installer package provided. This is now notarized for Mojave and Catalina, and may be required in the latter.

blowhole uses the Swift standard frameworks. These are installed at a system level in later versions of Mojave (10.14.4 and later) and in Catalina (10.15). Those using earlier versions of Mojave (10.14.3 and before), Sierra or High Sierra may need to download and install Swift Runtime Support for Command Tools from https://support.apple.com/kb/DL1998

Use:
————

blowhole
-or-
blowhole -[option]
-or-
blowhole -[option] [string]

When run with no arguments, this adds an entry similar to
2017-02-10 13:35:38.415904+0000 0x7de872 Default 0x0 61811 blowhole: [co.eclecticlight.blowhole.general] Blowhole snorted!
to the log. Thus, it has a subsystem of co.eclecticlight.blowhole, and writes the message
Blowhole snorted!

When run with a single option, this behaves the same as above, but the log entry is added at the level specified by the letter supplied as the option:
-b -> .debug (usually invisible in the logs)
-d -> .default (the standard, default level)
-e -> .error
-f -> .fault
-i -> .info (which is often invisible too)

There are now three additional options to support Pseudo-Signposts in Sierra and High Sierra, and Signposts in Mojave:
-B -> creates a [Pseudo-]Signpost of type .begin
-E -> creates a [Pseudo-]Signpost of type .end
-V -> creates a [Pseudo-]Signpost of type .event

When run with two arguments, the first specifies the option as above, and the second is a string, which is written into the log message. For example, pass the string “Hello, World!”, and the log entry written should look like
2017-02-10 13:35:38.415904+0000 0x7de872 Default 0x0 61811 blowhole: [co.eclecticlight.blowhole.general] Blowhole: Hello, World!

There are three special two-argument options:

blowhole -m [integer]
loops through writing the numbers 1 to [integer] as quickly as possible, using a simple
for index in 1...integer
loop. This gives you an estimate of the response time of the log system.

blowhole -M [integer]
loops through writing the numbers 1 to [integer] in Mojave’s Signposts as quickly as possible, using a simple
for index in 1...integer
loop. This gives you an estimate of the response time of the Signpost system. When the -M option is used in macOS prior to 10.14, it doesn’t write Pseudo-Signposts, but behaves as for the -m option instead.

blowhole -s [string]
writes a default level message consisting of just the string passed to it. This is intended to make subsequent analysis via JSON and CSV export from Consolation simpler.

If -m or -s are used without supplying an integer or string, then a single normal message is written to the log at the default level.

blowhole -h
displays usage information.

Signposts and Pseudo-Signposts
—————————————————————————————-

When running in Mojave, use the -B, -E, and -V options to write Signposts to the unified log. To measure latency, use the -M option. These can then be harvested and analysed using my RouteMap.
⚠️ There are bugs in Xcode 10ß5 and ß6 which currently prevent Signposts from being written perfectly. I have now implemented workarounds which work as follows:
blowhole -B
writes a begin Signpost with SignpostName ‘blowhole’ and SignpostID 1, and the fixed eventMessage of ‘blowhole’
blowhole -B “my message”
writes a begin Signpost with SignpostName ‘blowhole’ and SignpostID 1, with the eventMessage of ‘my message’.

When running in Sierra and High Sierra, use the -B, -E, and -V options to write Pseudo-Signposts to the unified log. These can only be fully interpreted, harvested and analysed using my RouteMap, although in all other log browsers the Signpost content remains accessible in the eventMessage field.

To get the most out of Pseudo-Signposts, use calls of the form
blowhole -[B|E|V] “SignpostName ID MessageString”
where SignpostName is a string containing no spaces, to form the Signpost Name, ID is an integer to be used as the Signpost ID, and MessageString is an arbitrary string which will appear in the eventMessage field. For example
blowhole -B “loop 62 entered the recursion loop”
writes a Signpost of type begin with the SignpostName of “loop” and the ID of 62, and the eventMessage field will consist of “entered the recursion loop”.

The log entry resulting from that will be a default level entry, with an eventMessage of
Signpost loop 62 entered the recursion loop
which is then parsed and harvested as a Pseudo-Signpost by RouteMap.

⚠️ Later versions of High Sierra do actually contain support for (real) Signposts, but do not support all the Signpost fields available in Mojave. Because Apple has not provided public access to them, blowhole cannot access them, although RouteMap can and will.

For further details, see https://eclecticlight.co


Provided in this archive are:
blowhole - the signed and hardened command tool which you can copy to /usr/local/bin if you prefer to install manually.
BlowholeInstaller.pkg - this is a notarized package installer. Simply double-click it to open it in Installer and it should install the command tool automatically into /usr/local/bin for you
BlowholeReadme.txt - this file
co.eclecticlight.blowhole.plist - an example Property List file which you can install in the LaunchAgents folder in your Home Library folder (~/Library/LaunchAgents) to run Blowhole automatically every hour.

Change List
———————————

Changes for version 9:
– ported to Swift 5 and Xcode 10.2.1
– added Info.plist, signed, hardened, and Installer package notarized for Mojave & Catalina.

Change for version 8.0:
— added -M option for Mojave Signposts.

Changes for version 7.0:
- worked around interface bugs in Xcode 10ß5 and ß6 for Signposts in macOS 10.14.

Changes for version 6.0:
- added support and commands for Pseudo-Signposts in macOS 10.12 and 10.13
- but Mojave ß6 / Xcode 10ß5 have broken the os_signpost() function, and don’t write Signposts properly for the moment.

Changes for version 5.0:
- added support and commands for Signposts in macOS 10.14
- ported to Swift 4.2 and built with Xcode 10ß3 for compatibility with Mojave, High Sierra, and Sierra.

[version 4.0 was experimental and has not been released.]

Changes for version 3.0:
- ported to Swift 3.2 and built with Xcode 9 for compatibility with both Sierra and High Sierra.
- shows version in usage information.

Change for version 2.0:
- changed from integer messages to strings, thanks to info from Eddy Wong and Volodymyr Gorlov, working around the bug in writing mutable strings from Swift.

Changes for version 1.3:
- this version has been rebuilt so that it works properly in macOS Sierra 10.12.4. Apple apparently introduced undocumented changes to the Swift interface to the log system. Those broke versions 1.2 and earlier of blowhole. This new version should run correctly under 10.12.4 and later.
- added -h option for usage information.
