Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8f0660c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "statsd: parse the new format of stats log"

parents 164d4300 80235403
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -71,10 +71,9 @@ bool CpuTimePerUidFreqPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>
    do {
      timeMs = std::stoull(pch);
      auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_FREQ_PULLED, timestamp);
      auto elemList = ptr->GetAndroidLogEventList();
      *elemList << uid;
      *elemList << idx;
      *elemList << timeMs;
      ptr->write(uid);
      ptr->write(idx);
      ptr->write(timeMs);
      ptr->init();
      data->push_back(ptr);
      VLOG("uid %lld, freq idx %d, sys time %lld", (long long)uid, idx, (long long)timeMs);
+3 −4
Original line number Diff line number Diff line
@@ -66,10 +66,9 @@ bool CpuTimePerUidPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* da
    uint64_t sysTimeMs = std::stoull(pch);

    auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_PULLED, timestamp);
    auto elemList = ptr->GetAndroidLogEventList();
    *elemList << uid;
    *elemList << userTimeMs;
    *elemList << sysTimeMs;
    ptr->write(uid);
    ptr->write(userTimeMs);
    ptr->write(sysTimeMs);
    ptr->init();
    data->push_back(ptr);
    VLOG("uid %lld, user time %lld, sys time %lld", (long long)uid, (long long)userTimeMs, (long long)sysTimeMs);
+14 −17
Original line number Diff line number Diff line
@@ -93,11 +93,10 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven

                    auto statePtr = make_shared<LogEvent>(
                            android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, timestamp);
                    auto elemList = statePtr->GetAndroidLogEventList();
                    *elemList << state.name;
                    *elemList << state.residencyInMsecSinceBoot;
                    *elemList << state.totalTransitions;
                    *elemList << state.supportedOnlyInSuspend;
                    statePtr->write(state.name);
                    statePtr->write(state.residencyInMsecSinceBoot);
                    statePtr->write(state.totalTransitions);
                    statePtr->write(state.supportedOnlyInSuspend);
                    statePtr->init();
                    data->push_back(statePtr);
                    VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
@@ -106,11 +105,10 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven
                    for (auto voter : state.voters) {
                        auto voterPtr =
                                make_shared<LogEvent>(android::util::POWER_STATE_VOTER_PULLED, timestamp);
                        auto elemList = voterPtr->GetAndroidLogEventList();
                        *elemList << state.name;
                        *elemList << voter.name;
                        *elemList << voter.totalTimeInMsecVotedForSinceBoot;
                        *elemList << voter.totalNumberOfTimesVotedSinceBoot;
                        voterPtr->write(state.name);
                        voterPtr->write(voter.name);
                        voterPtr->write(voter.totalTimeInMsecVotedForSinceBoot);
                        voterPtr->write(voter.totalNumberOfTimesVotedSinceBoot);
                        voterPtr->init();
                        data->push_back(voterPtr);
                        VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
@@ -141,13 +139,12 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven
                                const PowerStateSubsystemSleepState& state = subsystem.states[j];
                                auto subsystemStatePtr = make_shared<LogEvent>(
                                        android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, timestamp);
                                auto elemList = subsystemStatePtr->GetAndroidLogEventList();
                                *elemList << subsystem.name;
                                *elemList << state.name;
                                *elemList << state.residencyInMsecSinceBoot;
                                *elemList << state.totalTransitions;
                                *elemList << state.lastEntryTimestampMs;
                                *elemList << state.supportedOnlyInSuspend;
                                subsystemStatePtr->write(subsystem.name);
                                subsystemStatePtr->write(state.name);
                                subsystemStatePtr->write(state.residencyInMsecSinceBoot);
                                subsystemStatePtr->write(state.totalTransitions);
                                subsystemStatePtr->write(state.lastEntryTimestampMs);
                                subsystemStatePtr->write(state.supportedOnlyInSuspend);
                                subsystemStatePtr->init();
                                data->push_back(subsystemStatePtr);
                                VLOG("subsystemstate: %s, %s, %lld, %lld, %lld",
+70 −19
Original line number Diff line number Diff line
@@ -29,21 +29,72 @@ using std::ostringstream;
using std::string;
using android::util::ProtoOutputStream;

// We need to keep a copy of the android_log_event_list owned by this instance so that the char*
// for strings is not cleared before we can read them.
LogEvent::LogEvent(log_msg& msg) : mList(msg) {
    init(msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec, &mList);
LogEvent::LogEvent(log_msg& msg) {
    android_log_context context =
            create_android_log_parser(msg.msg() + sizeof(uint32_t), msg.len() - sizeof(uint32_t));
    mTimestampNs = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
    mContext = NULL;
    init(context);
}

LogEvent::LogEvent(int tag, uint64_t timestampNs) : mList(tag), mTimestampNs(timestampNs) {
LogEvent::LogEvent(int32_t tagId, uint64_t timestampNs) {
    mTimestampNs = timestampNs;
    mTagId = tagId;
    mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
    if (mContext) {
        android_log_write_int32(mContext, tagId);
    }

LogEvent::~LogEvent() {
}

void LogEvent::init() {
    mList.convert_to_reader();
    init(mTimestampNs, &mList);
    if (mContext) {
        const char* buffer;
        size_t len = android_log_write_list_buffer(mContext, &buffer);
        // turns to reader mode
        mContext = create_android_log_parser(buffer, len);
        init(mContext);
    }
}

bool LogEvent::write(int32_t value) {
    if (mContext) {
        return android_log_write_int32(mContext, value) >= 0;
    }
    return false;
}

bool LogEvent::write(uint32_t value) {
    if (mContext) {
        return android_log_write_int32(mContext, value) >= 0;
    }
    return false;
}

bool LogEvent::write(uint64_t value) {
    if (mContext) {
        return android_log_write_int64(mContext, value) >= 0;
    }
    return false;
}

bool LogEvent::write(const string& value) {
    if (mContext) {
        return android_log_write_string8_len(mContext, value.c_str(), value.length()) >= 0;
    }
    return false;
}

bool LogEvent::write(float value) {
    if (mContext) {
        return android_log_write_float32(mContext, value) >= 0;
    }
    return false;
}

LogEvent::~LogEvent() {
    if (mContext) {
        android_log_destroy(&mContext);
    }
}

/**
@@ -51,22 +102,25 @@ void LogEvent::init() {
 * The goal is to do as little preprocessing as possible, because we read a tiny fraction
 * of the elements that are written to the log.
 */
void LogEvent::init(int64_t timestampNs, android_log_event_list* reader) {
    mTimestampNs = timestampNs;
    mTagId = reader->tag();

void LogEvent::init(android_log_context context) {
    mElements.clear();
    android_log_list_element elem;

    // TODO: The log is actually structured inside one list.  This is convenient
    // because we'll be able to use it to put the attribution (WorkSource) block first
    // without doing our own tagging scheme.  Until that change is in, just drop the
    // list-related log elements and the order we get there is our index-keyed data
    // structure.
    int i = 0;
    do {
        elem = android_log_read_next(reader->context());
        elem = android_log_read_next(context);
        switch ((int)elem.type) {
            case EVENT_TYPE_INT:
                // elem at [0] is EVENT_TYPE_LIST, [1] is the tag id. If we add WorkSource, it would
                // be the list starting at [2].
                if (i == 1) {
                    mTagId = elem.data.int32;
                    break;
                }
            case EVENT_TYPE_FLOAT:
            case EVENT_TYPE_STRING:
            case EVENT_TYPE_LONG:
@@ -81,13 +135,10 @@ void LogEvent::init(int64_t timestampNs, android_log_event_list* reader) {
            default:
                break;
        }
        i++;
    } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
}

android_log_event_list* LogEvent::GetAndroidLogEventList() {
    return &mList;
}

int64_t LogEvent::GetLong(size_t key, status_t* err) const {
    if (key < 1 || (key - 1)  >= mElements.size()) {
        *err = BAD_INDEX;
+17 −20
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <android/util/ProtoOutputStream.h>
#include <log/log_event_list.h>
#include <log/log_read.h>
#include <private/android_logger.h>
#include <utils/Errors.h>

#include <memory>
@@ -45,12 +46,9 @@ public:
    explicit LogEvent(log_msg& msg);

    /**
     * Constructs a LogEvent with the specified tag and creates an android_log_event_list in write
     * mode. Obtain this list with the getter. Make sure to call init() before attempting to read
     * any of the values. This constructor is useful for unit-testing since we can't pass in an
     * android_log_event_list since there is no copy constructor or assignment operator available.
     * Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
     */
    explicit LogEvent(int tag, uint64_t timestampNs);
    explicit LogEvent(int32_t tagId, uint64_t timestampNs);

    ~LogEvent();

@@ -75,6 +73,17 @@ public:
    bool GetBool(size_t key, status_t* err) const;
    float GetFloat(size_t key, status_t* err) const;

    /**
     * Write test data to the LogEvent. This can only be used when the LogEvent is constructed
     * using LogEvent(tagId, timestampNs). You need to call init() before you can read from it.
     */
    bool write(uint32_t value);
    bool write(int32_t value);
    bool write(uint64_t value);
    bool write(int64_t value);
    bool write(const string& value);
    bool write(float value);

    /**
     * Return a string representation of this event.
     */
@@ -90,13 +99,6 @@ public:
     */
    KeyValuePair GetKeyValueProto(size_t key) const;

    /**
     * A pointer to the contained log_event_list.
     *
     * @return The android_log_event_list contained within.
     */
    android_log_event_list* GetAndroidLogEventList();

    /**
     * Used with the constructor where tag is passed in. Converts the log_event_list to read mode
     * and prepares the list for reading.
@@ -113,16 +115,11 @@ private:
    /**
     * Parses a log_msg into a LogEvent object.
     */
    void init(const log_msg& msg);

    /**
     * Parses a log_msg into a LogEvent object.
     */
    void init(int64_t timestampNs, android_log_event_list* reader);
    void init(android_log_context context);

    vector<android_log_list_element> mElements;
    // Need a copy of the android_log_event_list so the strings are not cleared.
    android_log_event_list mList;

    android_log_context mContext;

    uint64_t mTimestampNs;

Loading