summaryrefslogtreecommitdiff
path: root/perfstatsd/perfstatsd.cpp
blob: 6a16e47016773af736691b4cae045cc899cbe302 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "perfstatsd"

#include <perfstatsd.h>

using namespace android::pixel::perfstatsd;

Perfstatsd::Perfstatsd(void) {
    mRefreshPeriod = DEFAULT_DATA_COLLECT_PERIOD;

    std::unique_ptr<StatsType> cpuUsage(new CpuUsage);
    cpuUsage->setBufferSize(CPU_USAGE_BUFFER_SIZE);
    mStats.emplace_back(std::move(cpuUsage));

    std::unique_ptr<StatsType> ioUsage(new IoUsage);
    ioUsage->setBufferSize(IO_USAGE_BUFFER_SIZE);
    mStats.emplace_back(std::move(ioUsage));
}

void Perfstatsd::refresh(void) {
    for (auto const &stats : mStats) {
        stats->refresh();
    }
    return;
}

void Perfstatsd::getHistory(std::string *ret) {
    std::priority_queue<StatsData, std::vector<StatsData>, StatsdataCompare> mergedQueue;
    for (auto const &stats : mStats) {
        stats->dump(&mergedQueue);
    }

    while (!mergedQueue.empty()) {
        StatsData data = mergedQueue.top();
        auto raw_time = data.getTime();
        auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(raw_time);
        auto d = raw_time - seconds;
        auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(d);
        std::string content = data.getData();

        time_t t = std::chrono::system_clock::to_time_t(raw_time);
        char buff[20];
        strftime(buff, sizeof(buff), "%m-%d %H:%M:%S", localtime(&t));

        ret->append(std::string(buff) + ".");
        ret->append(std::to_string(milliseconds.count()) + "\n");
        ret->append(content + "\n");
        mergedQueue.pop();
    }

    if (ret->size() > 400_KiB)
        LOG_TO(SYSTEM, WARNING) << "Data might be too large. size: " << ret->size() << " bytes\n"
                                << *ret;
}

void Perfstatsd::setOptions(const std::string &key, const std::string &value) {
    if (key == PERFSTATSD_PERIOD) {
        uint32_t val = 0;
        if (!base::ParseUint(value, &val) || val < 1) {
            LOG_TO(SYSTEM, ERROR) << "Invalid value. Minimum refresh period is 1 second";
        } else {
            mRefreshPeriod = val;
            LOG_TO(SYSTEM, INFO) << "set period to " << value << " seconds";
        }
        return;
    }

    for (auto const &stats : mStats) {
        stats->setOptions(std::forward<const std::string>(key),
                          std::forward<const std::string>(value));
    }
    return;
}