PreLoginAgents unable to log if built with XCode

Hi,

I'm on MacBook Pro M2, macOS 13.3.1. I'm writing a feature that need to run before login. After some research I found PreLoginAgents sample code: https://developer.apple.com/library/archive/samplecode/PreLoginAgents/Introduction/Intro.html

Followed README, installed pre-built agent and SSH to Macbook, then run:

sudo syslog -c 0 -i
syslog -w

volia! SSH prints agent log, it is working.

But if I build code with XCode, there is no log. I tried following changes with no luck:

  • change LogManager acl log to os_log_info(OS_LOG_DEFAULT, "%s", [str UTF8String]), no log
  • change to syslog(LOG_INFO, "%s", [str UTF8String]), has log!
  • But change min deploy target from 10.9 to 11.0, syslog print no log

What is the proper way to print PreLoginAgents log?

Thanks!

Accepted Reply

Finally I found out why os_log is not working. Add code:

#import <os/log.h>
os_log_t log = os_log_create("com.example.preLoginAgent", "test");
os_log_debug(log, "test log: %{public}s");

Then in SSH terminal, you should run:

log stream --predicate 'subsystem="com.example.preLoginAgent"' --level debug

So what happened here:

  • os_log is not logged in /var/log/system.log, that's why syslog -w won't work.
  • os_log_debug(OS_LOG_DEFAULT, ...) log into default subsystem and it could be difficult to find it in sea of logs (or maybe use grep)
  • use os_log_create to add subsystem for log predicate to found it
  • by default, log stream won't show INFO & DEBUG, so add --level debug or use os_log_error
  • by default, dynamic string will show as <private>, add {public} if you would like to show it

Thanks eskimo for the hint!

Replies

PreLoginAgents hasn’t been updated in… well… almost a decade, and the system log story has moved on since there. I recommend that you switch to use the ‘new’ system log API. For links to docs and hints and tips, see Your Friend the System Log. And for a concrete example, see the Add a First Light Log Point section of Debugging a Network Extension Provider.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Finally I found out why os_log is not working. Add code:

#import <os/log.h>
os_log_t log = os_log_create("com.example.preLoginAgent", "test");
os_log_debug(log, "test log: %{public}s");

Then in SSH terminal, you should run:

log stream --predicate 'subsystem="com.example.preLoginAgent"' --level debug

So what happened here:

  • os_log is not logged in /var/log/system.log, that's why syslog -w won't work.
  • os_log_debug(OS_LOG_DEFAULT, ...) log into default subsystem and it could be difficult to find it in sea of logs (or maybe use grep)
  • use os_log_create to add subsystem for log predicate to found it
  • by default, log stream won't show INFO & DEBUG, so add --level debug or use os_log_error
  • by default, dynamic string will show as <private>, add {public} if you would like to show it

Thanks eskimo for the hint!