12498b56bSopenharmony_ci/*
22498b56bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42498b56bSopenharmony_ci * you may not use this file except in compliance with the License.
52498b56bSopenharmony_ci * You may obtain a copy of the License at
62498b56bSopenharmony_ci *
72498b56bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82498b56bSopenharmony_ci *
92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122498b56bSopenharmony_ci * See the License for the specific language governing permissions and
132498b56bSopenharmony_ci * limitations under the License.
142498b56bSopenharmony_ci */
152498b56bSopenharmony_ci#ifndef LOG_STATS_H
162498b56bSopenharmony_ci#define LOG_STATS_H
172498b56bSopenharmony_ci#include <unordered_map>
182498b56bSopenharmony_ci#include <optional>
192498b56bSopenharmony_ci#include <mutex>
202498b56bSopenharmony_ci
212498b56bSopenharmony_ci#include <log_timestamp.h>
222498b56bSopenharmony_ci#include <hilog_cmd.h>
232498b56bSopenharmony_ci#include <hilog_common.h>
242498b56bSopenharmony_ci#include <hilog/log.h>
252498b56bSopenharmony_ci
262498b56bSopenharmony_cinamespace OHOS {
272498b56bSopenharmony_cinamespace HiviewDFX {
282498b56bSopenharmony_cienum class StatsType {
292498b56bSopenharmony_ci    STATS_MASTER,
302498b56bSopenharmony_ci    STATS_DOMAIN,
312498b56bSopenharmony_ci    STATS_PID,
322498b56bSopenharmony_ci    STATS_TAG,
332498b56bSopenharmony_ci};
342498b56bSopenharmony_ci
352498b56bSopenharmony_cistruct StatsInfo {
362498b56bSopenharmony_ci    uint16_t level;
372498b56bSopenharmony_ci    uint16_t type;
382498b56bSopenharmony_ci    uint16_t len;
392498b56bSopenharmony_ci    uint16_t dropped;
402498b56bSopenharmony_ci    uint32_t domain;
412498b56bSopenharmony_ci    uint32_t pid;
422498b56bSopenharmony_ci    uint32_t tv_sec;
432498b56bSopenharmony_ci    uint32_t tv_nsec;
442498b56bSopenharmony_ci    uint32_t mono_sec;
452498b56bSopenharmony_ci    std::string tag;
462498b56bSopenharmony_ci};
472498b56bSopenharmony_ci
482498b56bSopenharmony_cistruct StatsEntry {
492498b56bSopenharmony_ci    uint32_t lines[LevelNum];
502498b56bSopenharmony_ci    uint64_t len[LevelNum];
512498b56bSopenharmony_ci    uint32_t dropped;
522498b56bSopenharmony_ci    uint32_t tmpLines;
532498b56bSopenharmony_ci    float freqMax; // lines per second, average value
542498b56bSopenharmony_ci    LogTimeStamp realTimeFreqMax;
552498b56bSopenharmony_ci    uint32_t tmpLen;
562498b56bSopenharmony_ci    float throughputMax; // length per second, average value
572498b56bSopenharmony_ci    LogTimeStamp realTimeThroughputMax;
582498b56bSopenharmony_ci    LogTimeStamp realTimeLast;
592498b56bSopenharmony_ci    LogTimeStamp monoTimeLast;
602498b56bSopenharmony_ci    LogTimeStamp monoTimeAuditStart;
612498b56bSopenharmony_ci
622498b56bSopenharmony_ci    float GetFreqMax() const
632498b56bSopenharmony_ci    {
642498b56bSopenharmony_ci        // this 0 is a initialized 0, so no need comapre to epsilon(0.000001)
652498b56bSopenharmony_ci        if (freqMax == 0) {
662498b56bSopenharmony_ci            LogTimeStamp tmp = monoTimeLast;
672498b56bSopenharmony_ci            tmp -= monoTimeAuditStart;
682498b56bSopenharmony_ci            float secs = tmp.FloatSecs();
692498b56bSopenharmony_ci            if (secs > 1) {
702498b56bSopenharmony_ci                return tmpLines / secs;
712498b56bSopenharmony_ci            } else {
722498b56bSopenharmony_ci                return tmpLines;
732498b56bSopenharmony_ci            }
742498b56bSopenharmony_ci        }
752498b56bSopenharmony_ci        return freqMax;
762498b56bSopenharmony_ci    }
772498b56bSopenharmony_ci
782498b56bSopenharmony_ci    float GetThroughputMax() const
792498b56bSopenharmony_ci    {
802498b56bSopenharmony_ci        // this 0 is a initialized 0, so no need comapre to epsilon(0.000001)
812498b56bSopenharmony_ci        if (throughputMax == 0) {
822498b56bSopenharmony_ci            LogTimeStamp tmp = monoTimeLast;
832498b56bSopenharmony_ci            tmp -= monoTimeAuditStart;
842498b56bSopenharmony_ci            float secs = tmp.FloatSecs();
852498b56bSopenharmony_ci            if (secs > 1) {
862498b56bSopenharmony_ci                return tmpLen / secs;
872498b56bSopenharmony_ci            } else {
882498b56bSopenharmony_ci                return tmpLen;
892498b56bSopenharmony_ci            }
902498b56bSopenharmony_ci        }
912498b56bSopenharmony_ci        return throughputMax;
922498b56bSopenharmony_ci    }
932498b56bSopenharmony_ci
942498b56bSopenharmony_ci    uint32_t GetTotalLines() const
952498b56bSopenharmony_ci    {
962498b56bSopenharmony_ci        uint32_t totalLines = 0;
972498b56bSopenharmony_ci        for (const uint32_t &i : lines) {
982498b56bSopenharmony_ci            totalLines += i;
992498b56bSopenharmony_ci        }
1002498b56bSopenharmony_ci        return totalLines;
1012498b56bSopenharmony_ci    }
1022498b56bSopenharmony_ci
1032498b56bSopenharmony_ci    uint64_t GetTotalLen() const
1042498b56bSopenharmony_ci    {
1052498b56bSopenharmony_ci        uint64_t totalLen = 0;
1062498b56bSopenharmony_ci        for (const uint64_t &i : len) {
1072498b56bSopenharmony_ci            totalLen += i;
1082498b56bSopenharmony_ci        }
1092498b56bSopenharmony_ci        return totalLen;
1102498b56bSopenharmony_ci    }
1112498b56bSopenharmony_ci
1122498b56bSopenharmony_ci    void Print() const
1132498b56bSopenharmony_ci    {
1142498b56bSopenharmony_ci        const std::string sep = " | ";
1152498b56bSopenharmony_ci        std::cout << "Lines: ";
1162498b56bSopenharmony_ci        std::cout << GetTotalLines() << sep;
1172498b56bSopenharmony_ci        std::cout << "Length: ";
1182498b56bSopenharmony_ci        std::cout << GetTotalLen() << sep;
1192498b56bSopenharmony_ci        std::cout << "Dropped: " << dropped << sep;
1202498b56bSopenharmony_ci        std::cout << "Max freq: " << GetFreqMax() << sep;
1212498b56bSopenharmony_ci        std::cout << "Max freq ts: " << realTimeFreqMax.tv_sec << "." << realTimeFreqMax.tv_nsec << sep;
1222498b56bSopenharmony_ci        std::cout << "Max throughput: " << GetThroughputMax() << sep;
1232498b56bSopenharmony_ci        std::cout << "Max throughput ts: " << realTimeThroughputMax.tv_sec << ".";
1242498b56bSopenharmony_ci        std::cout << realTimeThroughputMax.tv_nsec << sep;
1252498b56bSopenharmony_ci        std::cout << std::endl;
1262498b56bSopenharmony_ci    }
1272498b56bSopenharmony_ci};
1282498b56bSopenharmony_ciusing TagStatsEntry = struct StatsEntry;
1292498b56bSopenharmony_ciusing TagTable = std::unordered_map<std::string, TagStatsEntry>;
1302498b56bSopenharmony_ci
1312498b56bSopenharmony_cistruct DomainStatsEntry {
1322498b56bSopenharmony_ci    StatsEntry stats;
1332498b56bSopenharmony_ci    TagTable tagStats;
1342498b56bSopenharmony_ci};
1352498b56bSopenharmony_ciusing DomainTable = std::unordered_map<uint32_t, DomainStatsEntry>;
1362498b56bSopenharmony_ci
1372498b56bSopenharmony_ciusing LogTypeDomainTable = DomainTable[TypeNum];
1382498b56bSopenharmony_ci
1392498b56bSopenharmony_cistruct PidStatsEntry {
1402498b56bSopenharmony_ci    StatsEntry statsAll;
1412498b56bSopenharmony_ci    StatsEntry stats[TypeNum];
1422498b56bSopenharmony_ci    std::string name;
1432498b56bSopenharmony_ci    TagTable tagStats;
1442498b56bSopenharmony_ci};
1452498b56bSopenharmony_ciusing PidTable = std::unordered_map<uint32_t, PidStatsEntry>;
1462498b56bSopenharmony_ci
1472498b56bSopenharmony_ciclass LogStats {
1482498b56bSopenharmony_cipublic:
1492498b56bSopenharmony_ci    explicit LogStats();
1502498b56bSopenharmony_ci    ~LogStats();
1512498b56bSopenharmony_ci
1522498b56bSopenharmony_ci    void Count(const StatsInfo &info);
1532498b56bSopenharmony_ci    void Reset();
1542498b56bSopenharmony_ci    void Print();
1552498b56bSopenharmony_ci
1562498b56bSopenharmony_ci    const LogTypeDomainTable& GetDomainTable() const;
1572498b56bSopenharmony_ci    const PidTable& GetPidTable() const;
1582498b56bSopenharmony_ci    const LogTimeStamp& GetBeginTs() const;
1592498b56bSopenharmony_ci    const LogTimeStamp& GetBeginMono() const;
1602498b56bSopenharmony_ci    void GetTotalLines(uint32_t (&in_lines)[LevelNum]) const;
1612498b56bSopenharmony_ci    void GetTotalLens(uint64_t (&in_lens)[LevelNum]) const;
1622498b56bSopenharmony_ci    bool IsEnable() const;
1632498b56bSopenharmony_ci    bool IsTagEnable() const;
1642498b56bSopenharmony_ci
1652498b56bSopenharmony_ci    std::unique_lock<std::mutex> GetLock();
1662498b56bSopenharmony_ci
1672498b56bSopenharmony_ciprivate:
1682498b56bSopenharmony_ci    LogTypeDomainTable domainStats;
1692498b56bSopenharmony_ci    PidTable pidStats;
1702498b56bSopenharmony_ci    LogTimeStamp tsBegin;
1712498b56bSopenharmony_ci    LogTimeStamp monoBegin;
1722498b56bSopenharmony_ci    uint32_t totalLines[LevelNum];
1732498b56bSopenharmony_ci    uint64_t totalLens[LevelNum];
1742498b56bSopenharmony_ci    bool enable;
1752498b56bSopenharmony_ci    bool tagEnable;
1762498b56bSopenharmony_ci    std::mutex lock;
1772498b56bSopenharmony_ci
1782498b56bSopenharmony_ci    void UpdateTagTable(TagTable& tt, const StatsInfo &info);
1792498b56bSopenharmony_ci    void UpdateDomainTable(const StatsInfo &info);
1802498b56bSopenharmony_ci    void UpdatePidTable(const StatsInfo &info);
1812498b56bSopenharmony_ci};
1822498b56bSopenharmony_ci} // namespace HiviewDFX
1832498b56bSopenharmony_ci} // namespace OHOS
1842498b56bSopenharmony_ci#endif // LOG_STATS_H