iOS Diagnostics (Part 2)

Last year I blogged about getting detailed diagnostics from iOS using a proxy. With iOS 8, Apple has significantly improved the detail contained in the diagnostic dump. Gone is the text file and in comes a sqlite database containing about 100 tables. This will make analysing the data much easier. Furthermore, the tables give us a clearer indication of what data might be available. We’re going to use SQL to extract and process the data and see what we can tell. So head over to here and get your data.

I’ve tried to detail some of the things I’ve found below. However, my real motive was to provide a way of finding out what was using draining the battery on my iOS devices. We’ve all had the scenario where we’ve not really used our devices but the battery has mysteriously run down. To this end I put together a quick python hack that generates a report from your diagnostic database. You can find the tool here. I plan to add more sections in the coming months. You can find an example report here taken from my iPhone . In the time period shown the battery had been draining, but I had not been using it. The report shows that I was getting lots of push notifications concerned with the key value store. If I connect my iPhone to the Charles Proxy I can see it’s constantly posting to Presumably in response to a push notification telling it something has changed.

Battery Drain

There are two tables, PLBatteryAgent_EventBackward_Battery, PLBatteryAgent_EventBackward_BatteryUI, populated with detailed battery information. Table PLBatteryAgent_EventBackward_Battery contains the most detail including voltage, battery level, current, cycle count. For 5 days I have nearly 11,000 rows!

We can extract time and level using the following SQL:

SELECT datetime(timestamp, 'unixepoch'), Level from PLBatteryAgent_EventBackward_Battery

We can use this to make a nice graph of how batter level changes over time:



There is wealth of energy diagnostic information kept by iOS. The table PLIOReportAgent_EventBackward_EnergyModel seems to take a snapshot of power usage broken down by CPU, DRAM, GPU, SoC Energy. Much more interesting is the table PLBLMAccountingService_Aggregate_BLMAppEnergyBreakdown which contains, on a per app basis, where the energy is being used. It’s broken down into fields such as: Airdrop, AirplayMirroring , BLMEnergyDisplay, BLMEnergyGPS, BLMEnergyGPU, BLMEnergyPA_accessories, BLMEnergyPA_apsd, BLMEnergyWiFi, BLMEnergyTorch. Samples appear to be on an hourly and daily basis. I would imagine this table is used to populate the energy breakdown you can get in the This really is a treasure trove! For example, you can tell which apps used location in the background. The times are on hour boundaries:

SELECT datetime(timestamp, 'unixepoch') AS TIME, BLMAppName FROM PLBLMAccountingService_Aggregate_BLMAppEnergyBreakdown WHERE BLMEnergy_BackgroundLocation > 0  ORDER BY TIME

These tables are a good place to see which apps and internal processes are using power. Note that some of the columns always seem to be 0. You can see overall energy per app per day:

SELECT datetime(timestamp, ‘unixepoch’) AS TIME, BLMAppName, BLMEnergy FROM PLBLMAccountingService_Aggregate_BLMAppEnergyBreakdown WHERE timeInterval=’3600’ ORDER BY TIME

When the device was sleeping and awake:

SELECT  datetime(timestamp, 'unixepoch') AS Time, * FROM PLSleepWakeAgent_EventForward_PowerState


The are several tables concerned with audio: PLAudioAgent_EventPoint_AudioApp, PLAudioAgent_EventForward_Output, PLAudioAgent_EventForward_Routing, PLAudioAgent_EventPoint_AudioApp. The following SQL shows you when you had headphones connected and broadly what kind of audio was coming out (Audio/Video, Call, Ringtone etc)

SELECT datetime(timestamp, 'unixepoch') AS TIME, OutputCategory FROM  PLAudioAgent_EventForward_Routing WHERE HeadphonesConnected


There are three tables concerned with the camera: PLCameraAgent_EventForward_BackCamera, PLCameraAgent_EventForward_FrontCamera, and PLCameraAgent_EventForward_Torch The following SQL will show you when the back camera was on:

SELECT datetime(timestamp, 'unixepoch') AS TIME FROM  PLCameraAgent_EventForward_BackCamera WHERE State = 1

You can do a similar thing for the front camera and the torch/flash.

Core Location

iOS keeps track of which apps ask for location and how long they use it for, and the desired accuracy. Note the actual location is not recorded! The following SQL will show you the total number of location requests per client.

SELECT Client, COUNT(Client) AS Count FROM PLLocationAgent_EventForward_ClientStatus GROUP BY Client ORDER BY Count DESC

The biggest user for me was which belongs to the process routined. I think routined is the frequent locations service i.e. the one that tells you in notification centre how long it will take to get home. You can see what’s being stored by looking in frequent locations in Settings -> Privacy -> Location -> System -> Frequent Locations.

Push Notifications

It would appear iOS logs when each push notification arrives. This includes the silent background ones too. It includes which push server you were connected to, and whether you were on Wifi on Cellular. There appears to be a priority fields, but I’m not sure what that’s used for. The following SQL will show you the total number of push notifications per app/service (Apple refers to these as topics)

SELECT Topic, COUNT(Topic) AS Count FROM PLXPCAgent_EventPoint_Apsd GROUP BY Topic ORDER BY Count DESC

My biggest hitter was followed by You can break down the data in terms of the number of push notifications in a given period. To see number of push notifications on an hourly basis:

SELECT T, COUNT(T) AS Count FROM (SELECT strftime('%Y-%m-%d %H:00', datetime(timestamp, 'unixepoch')) as T FROM PLXPCAgent_EventPoint_Apsd) GROUP BY T

Application Usage

See when apps are doing some background processing:

SELECT datetime(timestamp, 'unixepoch') AS Time, Identifier, DisplayName from  PLApplicationAgent_EventNone_ApplicationMetaData, PLApplicationAgent_EventNone_ApplicationMetaData_Array_UIBackgroundModes
where PLApplicationAgent_EventNone_ApplicationMetaData_Array_UIBackgroundModes.fk_id = GROUP BY Time, Identifier

See how many times each application has performed different kinds of background activity (e.g. location, audio, fetch etc):

SELECT identifier, value, count(value) as Count from  PLApplicationAgent_EventPoint_Application, PLApplicationAgent_EventNone_ApplicationMetaData_Array_UIBackgroundModes
where PLApplicationAgent_EventNone_ApplicationMetaData_Array_UIBackgroundModes.fk_id =
group by Identifier, value

iOS appears to sample how much processing time each process gets. The sample length seems vary from sample to sample:

SELECT  value, processname, datetime(timestamp, 'unixepoch') AS Start, datetime(timestampEnd, 'unixepoch') AS End  FROM PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval_Dynamic, PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval WHERE PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval.ID = PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval_Dynamic.FK_ID
GROUP BY timestamp, timestampEnd,processname

or see the total processing time for each process:

SELECT  SUM(value) AS TotalTime, processname FROM PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval_Dynamic, PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval WHERE PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval.ID = PLProcessMonitorAgent_EventInterval_ProcessMonitorInterval_Dynamic.FK_ID
GROUP BY processname ORDER BY TotalTime DESC


The table PLBBAgent_EventPoint_TelephonyActivity keeps track of how much signal you have (including the number of bars), whether you are in a call, and if you’re on LTE, 3G, 2G and if airplane mode is active. There is another table, PLBBAgent_EventPoint_TelephonyRegistration which details which operator you are connected too.

The following SQL will show you your signal strength at each recorded time point:

SELECT timestamp, signalstrength from PLBBAgent_EventPoint_TelephonyActivity


The table PLDisplayAgent_EventForward_Display contains detailed recordings of your screen metrics including brightness and how much current is being used. Another table PLDisplayAgent_EventPoint_UserBrightness seems to record when you override the brightness manually.

Power Assertions

Find out the different kinds of power assertions:

SELECT AssertType FROM PLPowerAssertionAgent_EventInterval_Assertion GROUP BY AssertType

I had the following: AssertionStorm, BackgroundTask, EnableIdleSleep, InternalPreventDisplaySleep, NoIdleSleepAssertion, PreventUserIdleDisplaySleep. PreventUserIdleSystemSleep , SystemIsActive

Find assertions relating to background tasks. The assertion will often contain the name of them method being called:

SELECT  datetime(timestamp, 'unixepoch') AS Start,  datetime(timestampEnd, 'unixepoch') AS End, timestampEnd - timestamp AS time, * FROM PLPowerAssertionAgent_EventInterval_Assertion WHERE  AssertName LIKE '%BKNewProcess%' ORDER BY start


There appears to be some tables concerned with internal UIKit stuff: PLXPCAgent_EventForward_UIKitActivity, PLXPCAgent_EventForward_UIKitAlert, and PLXPCAgent_EventForward_UIKitKeyboard. The table PLXPCAgent_EventForward_UIKitKeyboard appear to show when the keyboard is shown. It also includes which keyboard was used:

SELECT datetime(timestamp, 'unixepoch') AS TIME, Keyboard-ID FROM  PLXPCAgent_EventForward_UIKitKeyboard WHERE Status = 1


Overall, I think the fact that Apple is collecting these kinds of metrics is a good thing. It will allow them to better understand how customers are using their devices, and thus draining their batteries. I assume that this data is only harvested when you go to the genius bar and they run through the diagnostics app with you. However, I could be wrong and it could be part of the standard Diagnostics and Usage data collections.




Copyright © 2014 - Christopher Lyon Anderson. Powered by Octopress