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