This is the first page of a 5 page piece I just finished writing for MacTech. After the last episode of the MacAdmins podcast though, I wanted to go ahead and get some of the information out there. For a much more detailed analysis, check out MacTech!
Apple has a number of different logging APIs. For the past few releases, Apple has tried to capture everything possible in logs, creating what many administrators and developers might consider to be a lot of chatter. As such, an entirely new interface needed to be developed to categorize and filter messages sent into system logs.
The logger command is still used to create entries in system logs. However, if you are then using tail to view /var/log/system.log then you will notice that you no longer see your entry being written. This is because as the logs being created in macOS have gotten more complex, the tools to read and write those logs has gotten more complicated as well.
Let’s take a simple log entry. Below, we’ll write the string “Hello Logs” into the system log. To do so, use the –i option to put the process id of the logger process and –s to write to the system log, as well as to stderr. To make the entry easier we’ll tag it with –t followed by the string of the tag. And finally, we’ll quote the entry we want written into the log. This is basically the simplest form of an entry:
logger -is -t krypted "Hello Logs"
Once written, use the log command to read your spiffy new entries. This isn’t terribly different than how things worked previously. If you’re a developer, you will need to note that all of the legacy APIs you might be using, which include asl_log_message, NSLog, and syslog, have been redirected to the new Unified Logging system, provided you build software for 10.12 (you can still build as before for 10.11, iOS 9, tvOS 10, and watchOS 3 and below). These are replaced with the os_log, os_log_info, os_log_debug, os_log_error, os_log_fault, and os_log_create APIs (which correspond to various levels of logs that are written).
Logs are now stored in the tracev3 formatted files in /var/db/diagnostics, which is a compressed binary format. As with all binary files, you’ll need new tools to read the files. Console has been updated with a new hierarchical capability and the ability to watch activities, subsystems, etc.
The log command provides another means of reading those spiffy new logs. To get started, first check out the man page:
That “Hello Logs” string we used earlier is part of a message that you can easily view using the ‘log show’ command. In the below example, we’ll just run a scan of the last 3 minutes, using the –last option, and then providing a –predicate. We’ll explain those a bit later, but think of it as query parameters – here, we’ll specify to look for “Hello Logs” in eventMessage:
log show --predicate 'eventMessage contains "Hello Logs"' --last 3m
Filtering the log data using “eventMessage CONTAINS “Hello Logs”” shows us that our entry appears as follows:
Timestamp Thread Type Activity PID
2017-03-23 23:51:05.236542-0500 0x4b83bb Default 0x0 88294 logger: Hello Logs
Log – Default: 1, Info: 0, Debug: 0, Error: 0, Fault: 0
Activity – Create: 0, Transition: 0, Actions: 0
krypted March 26th, 2017
Meraki has a syslog option. To configure a Meraki to push logs to a syslog server, open your Meraki Dashboard and click on a device. From there, click on “Alerts & administration”.
At the “Alerts & administration” page scroll down to the Logging section. Click on the “Add a syslog server” link and type the IP address of your syslog servers name or IP. Put the port number into the Port field. Choose what types of events to export. This could be Event Log, Flows or URLs, where:
Note that you can direct each type of traffic to a different syslog server.
krypted April 16th, 2014
When bash scripting, a useful command is logger. The logger command allows you to “make entries in the system log.” When using the logger command, you can write to your own entries to the system log. To show how this command works, we’re going to open two terminal windows, preferably side-by-side. In one window, we’re going to look at the output of the system.log file interactively using the tail command with the -f option
tail -f /private/var/log/system.log
In the other window, we’re going to simply enter the logger command followed by the word frogger:
This will show you an entry similar to the following:
Jun 3 00:34:44 ce.pretendco.com krypted: frogger
Congrats, you’ve successfully written your own log entry into the system log. Now that you’ve done that, go ahead and press the up arrow on your keyboard to see the line again and then hit enter. You’ll then see the same line, with the pid more than likely incremented up by one. The pid is the process id of the logger command you just ran. If you run ps you’ll note that the pid is no longer in use.
Next, we’ll create a text file called froggerlog in our home directory, populating it with just the string: mylogdata. This is meant to emulate having written some data into a log file. We’ll do so using the echo command:
echo mylogdata > froggerlog
Now that we have a file, use the -f option to include the contents of the file into the system.log, specifying the path to the file:
logger -f ~/froggerlog
You will then see something like the following, with your mylogdata string in it:
Jun 3 00:37:24 ce.pretendco.com krypted: mylogdata
Using that structure, you can write data into a file and then later dump that data into the log, so as not to fill up the system.log file with tons of random data as it happens. Or you can write directly into the log as needed. It’s good to have choices.
The -i option is used to include the pid for the logger process in each line. But if you go back and add a second line of data into your log file, and re-run the logger command against that file you’ll notice that the pid is included with each line the same no matter whether you use the -i or not, making the -i unnecessary. You will also note that consecutive rows with the same information simply say — last message repeated 1 time —. This helps to keep log files a bit more trim than they otherwise might be if you have, say, 10,000 lines with the same content:
Jun 3 00:50:57 ce.pretendco.com krypted: mylogdata
Jun 3 00:51:17 ce.pretendco.com krypted: 1234
Jun 3 00:51:17 --- last message repeated 1 time ---
Jun 3 00:51:17 ce.pretendco.com krypted: abc
Now, you might find it difficult to see only the pertinent lines to your script. Use the -t option to tag a line, followed by the tag. For example, let’s add myscript into our lines, continuing to write into the system.log using the froggerlog file from earlier:
logger -t myscript -f ~/froggerlog
Note the output contains the myscript tag in front of the pid, in place of the username you were writing entries as:
Jun 3 00:56:28 ce.pretendco.com myscript: mylogdata
Jun 3 00:56:28 ce.pretendco.com myscript: 1234
Jun 3 00:56:28 --- last message repeated 1 time ---
Jun 3 00:56:28 ce.pretendco.com myscript: abc
Messages can be written at various priorities. To set the priority of your entries, use the -p option. After that enter the priority as an integer, using the following:
For example, to write an alert entry (everyone should see this):
logger -t myscript -f ~/froggerlog -p alert
To write a debug log:
logger -t myscript -f ~/froggerlog -p debug
The alert log is shown but the debug is not. Levels 5-7 are not displayed using a tail of system.log. If you need to verify success or failure of entries, note that logger exits 0 on success but not when an error is encountered. If you’d like to output entries to standard error, you can do so by adding the -s option as well.
krypted June 3rd, 2013
Posted In: Mac OS X