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

Commit 67462296 authored by Yao Chen's avatar Yao Chen Committed by Android (Google) Code Review
Browse files

Merge "Add StatsdStats in statsd's dumpsys"

parents 1ae3cf14 f5acabe9
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) {
 */
void StatsService::dump_impl(FILE* out) {
    mConfigManager->Dump(out);
    StatsdStats::getInstance().dumpStats(out);
}

/**
@@ -296,9 +297,8 @@ void StatsService::print_cmd_help(FILE* out) {
    fprintf(out, "  NAME          The name of the configuration\n");
    fprintf(out, "\n");
    fprintf(out, "\n");
    fprintf(out, "usage: adb shell cmd stats print-stats [reset]\n");
    fprintf(out, "usage: adb shell cmd stats print-stats\n");
    fprintf(out, "  Prints some basic stats.\n");
    fprintf(out, "  reset: 1 to reset the statsd stats. default=0.\n");
}

status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) {
@@ -487,14 +487,8 @@ status_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) {
        fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
                mProcessor->GetMetricsSize(key));
    }
    fprintf(out, "Detailed statsd stats in logcat...\n");
    StatsdStats& statsdStats = StatsdStats::getInstance();
    bool reset = false;
    if (args.size() > 1) {
        reset = strtol(args[1].string(), NULL, 10);
    }
    vector<uint8_t> output;
    statsdStats.dumpStats(&output, reset);
    statsdStats.dumpStats(out);
    return NO_ERROR;
}

+112 −62
Original line number Diff line number Diff line
@@ -355,73 +355,135 @@ void StatsdStats::addSubStatsToConfigLocked(const ConfigKey& key,
    }
}

void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
void StatsdStats::dumpStats(FILE* out) const {
    lock_guard<std::mutex> lock(mLock);

    if (DEBUG) {
    time_t t = mStartTimeSec;
    struct tm* tm = localtime(&t);
    char timeBuffer[80];
        strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
        VLOG("=================StatsdStats dump begins====================");
        VLOG("Stats collection start second: %s", timeBuffer);
    }
    ProtoOutputStream proto;
    proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
    proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr));

    VLOG("%lu Config in icebox: ", (unsigned long)mIceBox.size());
    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
    fprintf(out, "Stats collection start second: %s\n", timeBuffer);
    fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
    for (const auto& configStats : mIceBox) {
        const int numBytes = configStats.ByteSize();
        vector<char> buffer(numBytes);
        configStats.SerializeToArray(&buffer[0], numBytes);
        proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0],
                    buffer.size());

        // surround the whole block with DEBUG, so that compiler can strip out the code
        // in production.
        if (DEBUG) {
            VLOG("*****ICEBOX*****");
            VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                 "#matcher=%d, #alert=%d,  #valid=%d",
        fprintf(out,
                "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                "#matcher=%d, #alert=%d,  valid=%d\n",
                configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(),
                configStats.deletion_time_sec(), configStats.metric_count(),
                configStats.condition_count(), configStats.matcher_count(),
                configStats.alert_count(), configStats.is_valid());

        for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) {
                VLOG("\tbroadcast time: %d", broadcastTime);
            fprintf(out, "\tbroadcast time: %d\n", broadcastTime);
        }

        for (const auto& dataDropTime : configStats.data_drop_time_sec()) {
                VLOG("\tdata drop time: %d", dataDropTime);
            fprintf(out, "\tdata drop time: %d\n", dataDropTime);
        }
    }
    }

    fprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
    for (auto& pair : mConfigStats) {
        auto& key = pair.first;
        auto& configStats = pair.second;
        if (DEBUG) {
            VLOG("********Active Configs***********");
            VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                 "#matcher=%d, #alert=%d,  #valid=%d",

        fprintf(out,
                "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                "#matcher=%d, #alert=%d,  valid=%d\n",
                configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(),
                configStats.deletion_time_sec(), configStats.metric_count(),
                configStats.condition_count(), configStats.matcher_count(),
                configStats.alert_count(), configStats.is_valid());
        for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) {
                VLOG("\tbroadcast time: %d", broadcastTime);
            fprintf(out, "\tbroadcast time: %d\n", broadcastTime);
        }

        for (const auto& dataDropTime : configStats.data_drop_time_sec()) {
                VLOG("\tdata drop time: %d", dataDropTime);
            fprintf(out, "\tdata drop time: %d\n", dataDropTime);
        }

        for (const auto& dumpTime : configStats.dump_report_time_sec()) {
                VLOG("\tdump report time: %d", dumpTime);
            fprintf(out, "\tdump report time: %d\n", dumpTime);
        }

        // Add matcher stats
        auto matcherIt = mMatcherStats.find(key);
        if (matcherIt != mMatcherStats.end()) {
            const auto& matcherStats = matcherIt->second;
            for (const auto& stats : matcherStats) {
                fprintf(out, "matcher %lld matched %d times\n", (long long)stats.first,
                        stats.second);
            }
        }
        // Add condition stats
        auto conditionIt = mConditionStats.find(key);
        if (conditionIt != mConditionStats.end()) {
            const auto& conditionStats = conditionIt->second;
            for (const auto& stats : conditionStats) {
                fprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
                        stats.second);
            }
        }
        // Add metrics stats
        auto metricIt = mMetricsStats.find(key);
        if (metricIt != mMetricsStats.end()) {
            const auto& conditionStats = metricIt->second;
            for (const auto& stats : conditionStats) {
                fprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
                        stats.second);
            }
        }
        // Add anomaly detection alert stats
        auto alertIt = mAlertStats.find(key);
        if (alertIt != mAlertStats.end()) {
            const auto& alertStats = alertIt->second;
            for (const auto& stats : alertStats) {
                fprintf(out, "alert %lld declared %d times\n", (long long)stats.first,
                        stats.second);
            }
        }
    }
    fprintf(out, "********Pushed Atom stats***********\n");
    const size_t atomCounts = mPushedAtomStats.size();
    for (size_t i = 2; i < atomCounts; i++) {
        if (mPushedAtomStats[i] > 0) {
            fprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]);
        }
    }

    fprintf(out, "********Pulled Atom stats***********\n");
    for (const auto& pair : mPulledAtomStats) {
        fprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull,
             (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec);
    }

    if (mAnomalyAlarmRegisteredStats > 0) {
        fprintf(out, "********AnomalyAlarmStats stats***********\n");
        fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
    }

    fprintf(out,
            "UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes "
            "lost=%d\n",
            mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(),
            mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes());
}

void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
    lock_guard<std::mutex> lock(mLock);

    ProtoOutputStream proto;
    proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
    proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr));

    for (const auto& configStats : mIceBox) {
        const int numBytes = configStats.ByteSize();
        vector<char> buffer(numBytes);
        configStats.SerializeToArray(&buffer[0], numBytes);
        proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0],
                    buffer.size());
    }

    for (auto& pair : mConfigStats) {
        auto& configStats = pair.second;
        addSubStatsToConfigLocked(pair.first, configStats);

        const int numBytes = configStats.ByteSize();
@@ -437,7 +499,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
        configStats.clear_alert_stats();
    }

    VLOG("********Pushed Atom stats***********");
    const size_t atomCounts = mPushedAtomStats.size();
    for (size_t i = 2; i < atomCounts; i++) {
        if (mPushedAtomStats[i] > 0) {
@@ -446,34 +507,24 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]);
            proto.end(token);

            VLOG("Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]);
        }
    }

    VLOG("********Pulled Atom stats***********");
    for (const auto& pair : mPulledAtomStats) {
        android::os::statsd::writePullerStatsToStream(pair, &proto);
        VLOG("Atom %d->%ld, %ld, %ld\n", (int) pair.first, (long) pair.second.totalPull, (long) pair.second.totalPullFromCache, (long) pair.second.minPullIntervalSec);
    }

    if (mAnomalyAlarmRegisteredStats > 0) {
        VLOG("********AnomalyAlarmStats stats***********");
        long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
                    mAnomalyAlarmRegisteredStats);
        proto.end(token);
        VLOG("Anomaly alarm registrations: %d", mAnomalyAlarmRegisteredStats);
    }

    const int numBytes = mUidMapStats.ByteSize();
    vector<char> buffer(numBytes);
    mUidMapStats.SerializeToArray(&buffer[0], numBytes);
    proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size());
    VLOG("UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes "
         "lost=%d",
         mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(),
         mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes());

    output->clear();
    size_t bufferSize = proto.size();
@@ -493,7 +544,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
    }

    VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize);
    VLOG("=================StatsdStats dump ends====================");
}

}  // namespace statsd
+5 −0
Original line number Diff line number Diff line
@@ -189,6 +189,11 @@ public:
     */
    void dumpStats(std::vector<uint8_t>* buffer, bool reset);

    /**
     * Output statsd stats in human readable format to [out] file.
     */
    void dumpStats(FILE* out) const;

    typedef struct {
        long totalPull;
        long totalPullFromCache;