MetricsReader.java revision f33926abed907faf31093544303ea51723738214
126ca65d42523fca95081d21589f46708987d647cChris Wren/* 226ca65d42523fca95081d21589f46708987d647cChris Wren * Copyright (C) 2017 The Android Open Source Project 326ca65d42523fca95081d21589f46708987d647cChris Wren * 426ca65d42523fca95081d21589f46708987d647cChris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 526ca65d42523fca95081d21589f46708987d647cChris Wren * you may not use this file except in compliance with the License. 626ca65d42523fca95081d21589f46708987d647cChris Wren * You may obtain a copy of the License at 726ca65d42523fca95081d21589f46708987d647cChris Wren * 826ca65d42523fca95081d21589f46708987d647cChris Wren * http://www.apache.org/licenses/LICENSE-2.0 926ca65d42523fca95081d21589f46708987d647cChris Wren * 1026ca65d42523fca95081d21589f46708987d647cChris Wren * Unless required by applicable law or agreed to in writing, software 1126ca65d42523fca95081d21589f46708987d647cChris Wren * distributed under the License is distributed on an "AS IS" BASIS, 1226ca65d42523fca95081d21589f46708987d647cChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1326ca65d42523fca95081d21589f46708987d647cChris Wren * See the License for the specific language governing permissions and 1426ca65d42523fca95081d21589f46708987d647cChris Wren * limitations under the License. 1526ca65d42523fca95081d21589f46708987d647cChris Wren */ 16b62371434c9b63560c78a85123fe9386edac1205Chris Wrenpackage android.metrics; 17b62371434c9b63560c78a85123fe9386edac1205Chris Wren 18b62371434c9b63560c78a85123fe9386edac1205Chris Wrenimport android.annotation.SystemApi; 19f33926abed907faf31093544303ea51723738214Chris Wrenimport android.util.EventLog; 20f33926abed907faf31093544303ea51723738214Chris Wrenimport android.util.EventLog.Event; 21f33926abed907faf31093544303ea51723738214Chris Wrenimport android.util.Log; 2226ca65d42523fca95081d21589f46708987d647cChris Wren 23f33926abed907faf31093544303ea51723738214Chris Wrenimport com.android.internal.logging.MetricsLogger; 2426ca65d42523fca95081d21589f46708987d647cChris Wren 25f33926abed907faf31093544303ea51723738214Chris Wrenimport java.io.IOException; 26f33926abed907faf31093544303ea51723738214Chris Wrenimport java.util.ArrayList; 27f33926abed907faf31093544303ea51723738214Chris Wrenimport java.util.LinkedList; 2826ca65d42523fca95081d21589f46708987d647cChris Wrenimport java.util.Queue; 2926ca65d42523fca95081d21589f46708987d647cChris Wren 3026ca65d42523fca95081d21589f46708987d647cChris Wren/** 3126ca65d42523fca95081d21589f46708987d647cChris Wren * Read platform logs. 32b62371434c9b63560c78a85123fe9386edac1205Chris Wren * @hide 3326ca65d42523fca95081d21589f46708987d647cChris Wren */ 34b62371434c9b63560c78a85123fe9386edac1205Chris Wren@SystemApi 3526ca65d42523fca95081d21589f46708987d647cChris Wrenpublic class MetricsReader { 36f33926abed907faf31093544303ea51723738214Chris Wren private Queue<LogMaker> mEventQueue = new LinkedList<>(); 3726ca65d42523fca95081d21589f46708987d647cChris Wren private long mLastEventMs; 3826ca65d42523fca95081d21589f46708987d647cChris Wren private long mCheckpointMs; 39f33926abed907faf31093544303ea51723738214Chris Wren private int[] LOGTAGS = { MetricsLogger.LOGTAG }; 4026ca65d42523fca95081d21589f46708987d647cChris Wren 41f33926abed907faf31093544303ea51723738214Chris Wren /** 42f33926abed907faf31093544303ea51723738214Chris Wren * Read the available logs into a new session. 4326ca65d42523fca95081d21589f46708987d647cChris Wren * 44f33926abed907faf31093544303ea51723738214Chris Wren * The session will contain events starting from the oldest available 45f33926abed907faf31093544303ea51723738214Chris Wren * log on the system up to the most recent at the time of this call. 46f33926abed907faf31093544303ea51723738214Chris Wren * 47f33926abed907faf31093544303ea51723738214Chris Wren * A call to {@link #checkpoint()} will cause the session to contain 48f33926abed907faf31093544303ea51723738214Chris Wren * only events that occured after that call. 49f33926abed907faf31093544303ea51723738214Chris Wren * 50f33926abed907faf31093544303ea51723738214Chris Wren * This call will not return until the system buffer overflows the 51f33926abed907faf31093544303ea51723738214Chris Wren * specified timestamp. If the specified timestamp is 0, then the 52f33926abed907faf31093544303ea51723738214Chris Wren * call will return immediately since any logs 1970 have already been 53f33926abed907faf31093544303ea51723738214Chris Wren * overwritten (n.b. if the underlying system has the capability to 54f33926abed907faf31093544303ea51723738214Chris Wren * store many decades of system logs, this call may fail in 55f33926abed907faf31093544303ea51723738214Chris Wren * interesting ways.) 56f33926abed907faf31093544303ea51723738214Chris Wren * 57f33926abed907faf31093544303ea51723738214Chris Wren * @param horizonMs block until this timestamp is overwritten, 0 for non-blocking read. 5826ca65d42523fca95081d21589f46708987d647cChris Wren */ 59f33926abed907faf31093544303ea51723738214Chris Wren public void read(long horizonMs) { 60f33926abed907faf31093544303ea51723738214Chris Wren ArrayList<Event> nativeEvents = new ArrayList<>(); 61f33926abed907faf31093544303ea51723738214Chris Wren try { 62f33926abed907faf31093544303ea51723738214Chris Wren EventLog.readEventsOnWrapping(LOGTAGS, horizonMs, nativeEvents); 63f33926abed907faf31093544303ea51723738214Chris Wren } catch (IOException e) { 64f33926abed907faf31093544303ea51723738214Chris Wren e.printStackTrace(); 65f33926abed907faf31093544303ea51723738214Chris Wren } 66f33926abed907faf31093544303ea51723738214Chris Wren mEventQueue.clear(); 67f33926abed907faf31093544303ea51723738214Chris Wren for (EventLog.Event event : nativeEvents) { 68f33926abed907faf31093544303ea51723738214Chris Wren final long eventTimestampMs = event.getTimeNanos() / 1000000; 69f33926abed907faf31093544303ea51723738214Chris Wren if (eventTimestampMs > mCheckpointMs) { 70f33926abed907faf31093544303ea51723738214Chris Wren Object data = event.getData(); 71f33926abed907faf31093544303ea51723738214Chris Wren Object[] objects; 72f33926abed907faf31093544303ea51723738214Chris Wren if (data instanceof Object[]) { 73f33926abed907faf31093544303ea51723738214Chris Wren objects = (Object[]) data; 74f33926abed907faf31093544303ea51723738214Chris Wren } else { 75f33926abed907faf31093544303ea51723738214Chris Wren // wrap scalar objects 76f33926abed907faf31093544303ea51723738214Chris Wren objects = new Object[1]; 77f33926abed907faf31093544303ea51723738214Chris Wren objects[0] = data; 78f33926abed907faf31093544303ea51723738214Chris Wren } 79f33926abed907faf31093544303ea51723738214Chris Wren mEventQueue.add(new LogMaker(objects) 80f33926abed907faf31093544303ea51723738214Chris Wren .setTimestamp(eventTimestampMs)); 81f33926abed907faf31093544303ea51723738214Chris Wren mLastEventMs = eventTimestampMs; 82f33926abed907faf31093544303ea51723738214Chris Wren } 83f33926abed907faf31093544303ea51723738214Chris Wren } 8426ca65d42523fca95081d21589f46708987d647cChris Wren } 8526ca65d42523fca95081d21589f46708987d647cChris Wren 86f33926abed907faf31093544303ea51723738214Chris Wren /** Cause this session to only contain events that occur after this call. */ 8726ca65d42523fca95081d21589f46708987d647cChris Wren public void checkpoint() { 88f33926abed907faf31093544303ea51723738214Chris Wren // read the log to find the most recent event. 8926ca65d42523fca95081d21589f46708987d647cChris Wren read(0L); 90f33926abed907faf31093544303ea51723738214Chris Wren // any queued event is now too old, so drop them. 91f33926abed907faf31093544303ea51723738214Chris Wren mEventQueue.clear(); 9226ca65d42523fca95081d21589f46708987d647cChris Wren mCheckpointMs = mLastEventMs; 9326ca65d42523fca95081d21589f46708987d647cChris Wren } 9426ca65d42523fca95081d21589f46708987d647cChris Wren 95f33926abed907faf31093544303ea51723738214Chris Wren /** 96f33926abed907faf31093544303ea51723738214Chris Wren * Rewind the session to the beginning of time and read all available logs. 97f33926abed907faf31093544303ea51723738214Chris Wren * 98f33926abed907faf31093544303ea51723738214Chris Wren * A prior call to {@link #checkpoint()} will cause the reader to ignore 99f33926abed907faf31093544303ea51723738214Chris Wren * any event with a timestamp before the time of that call. 100f33926abed907faf31093544303ea51723738214Chris Wren * 101f33926abed907faf31093544303ea51723738214Chris Wren * The underlying log buffer is live: between calls to {@link #reset()}, older 102f33926abed907faf31093544303ea51723738214Chris Wren * events may be lost from the beginning of the session, and new events may 103f33926abed907faf31093544303ea51723738214Chris Wren * appear at the end. 104f33926abed907faf31093544303ea51723738214Chris Wren */ 10526ca65d42523fca95081d21589f46708987d647cChris Wren public void reset() { 106f33926abed907faf31093544303ea51723738214Chris Wren read(0l); 10726ca65d42523fca95081d21589f46708987d647cChris Wren } 10826ca65d42523fca95081d21589f46708987d647cChris Wren 10926ca65d42523fca95081d21589f46708987d647cChris Wren /* Does the current log session have another entry? */ 11026ca65d42523fca95081d21589f46708987d647cChris Wren public boolean hasNext() { 111f33926abed907faf31093544303ea51723738214Chris Wren return !mEventQueue.isEmpty(); 11226ca65d42523fca95081d21589f46708987d647cChris Wren } 11326ca65d42523fca95081d21589f46708987d647cChris Wren 114f33926abed907faf31093544303ea51723738214Chris Wren /* Return the next entry in the current log session. */ 115b62371434c9b63560c78a85123fe9386edac1205Chris Wren public LogMaker next() { 116f33926abed907faf31093544303ea51723738214Chris Wren return mEventQueue.poll(); 11726ca65d42523fca95081d21589f46708987d647cChris Wren } 11826ca65d42523fca95081d21589f46708987d647cChris Wren 11926ca65d42523fca95081d21589f46708987d647cChris Wren} 120