Application usage data on macOS can easily be misinterpreted. Even the native Screen Time service does not do a great job determining which applications were truly ‘in use’ and for how long.
More on this here: Spelunking macOS ScreenTime App Usage with R

With that said, let’s take a quick review of how the macOS Jamf Pro framework collects application usage logs.


Log Collection#

One of the JamfDaemon’s primary responsibilities is monitoring application usage events and capturing statistics.

Key locations:

  • LaunchDaemon:
    /Library/LaunchDaemons/com.jamf.management.daemon.plist
  • Jamf.app application bundle (includes JamfDaemon executable):
    /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon

Previously, application usage data was logged to /Library/Application Support/JAMF/Usage/[capture-date]/[current-user].plist

The basic syntax structure for each tracked application contained key-value pairs for elapsed mins/secs for foremost apps and apps that were loaded and running.

defaults read /Library/Application\ Support/JAMF/Usage/[capture-date]/[current-user].plist
"/Applications/Google Chrome.app" = {
    foremost = 13;
    open = 2460;
    secondsforemost = 832;
    secondsopen = 147643;
    version = "91.0.4472.106";
};

Around Jamf Pro version 10.30.1, the application usage data was moved to:

/Library/Application Support/JAMF/usage_reports

The schema changed to JSON and now only contains a secondsActive key, which seems to collect the same data as the secondsforemost key from the older .plist structure.

cat /Library/Application\ Support/JAMF/usage_reports/2021-09-06 | jq
{
  "appName": "Google Chrome",
  "appPath": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
  "secondsActive": 2259
}

It seems the JamfDaemon is monitoring application lifecycle using an NSWorkspace object, which watches Launch Services (launchservicesd) events. Running /usr/bin/strings on the JamfDaemon app bundle shows some plain text references:

/usr/bin/strings /Library/Application\ Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon | grep -i NSWorkspace

Sample output:

stopping listening for NSWorkspace events
starting to listen for NSWorkspace events
NSWorkspaceApplicationKey
Unable to set currently active process. NSWorkspace reports no frontmostApplication or menuBarOwningApplication
failed to update icon - NSWorkspace unable to set icon
NSWorkspace

Frontmost/foreground app state can be viewed, along with the app’s unique ASN number, by calling /usr/bin/lsappinfo while interactively switching frontmost apps in the macOS GUI. This demonstrates the type of events being watched, such as kLSNotifyBecameFrontmost and LSMenuBarOwnerASN.

/usr/bin/lsappinfo listen +becameFrontmost forever

Sample notification:

Notification: kLSNotifyBecameFrontmost time=09/06/2021 19:23:46.696 dataRef={ "LSOtherASN"=ASN:0x0-0x11011:, "LSMenuBarOwnerASN"=ASN:0x0-0xa40a4:, "LSMenuBarOwnerApplicationSeed"=455, "ApplicationType"="Foreground", "LSASN"=ASN:0x0-0xa40a4:, "LSFrontApplicationSeed"=495, "CFBundleIdentifier"="com.apple.TextEdit" } affectedASN="TextEdit" ASN:0x0-0xa40a4:  context=0x0 sessionID=186a8 notificationID=0x7f86c2704d20

lsappinfo can also give insight into the launch time of a specific app:

/usr/bin/lsappinfo info -only kLSLaunchTimeKey TextEdit

Sample output:

"LSLaunchTime"=2021/09/06 14:38:37

Log Submission#

Once the macOS device completes an inventory update, the captured JSON data will be sent to the Jamf Pro server and stored in the following MySQL database table: application_usage_logs.

MySQL database table: application_usage_logs

MySQL database table: application_usage_logs


Log Review#

Checking the device’s inventory record in Jamf Pro will show all captured usage data. See the Jamf Pro Administrator’s Guide.

Device’s inventory record in Jamf Pro

Device’s inventory record in Jamf Pro

Usage data can also be returned by the Jamf Pro Classic API on a per-device basis using the computerapplicationusage endpoint resource.

Log retention in Jamf Pro is set under System Settings > Log Flushing. Depending on database restrictions and performance, it may not be possible to extend the log retention