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#include <thread> 162498b56bSopenharmony_ci#include <algorithm> 172498b56bSopenharmony_ci 182498b56bSopenharmony_ci#include <log_utils.h> 192498b56bSopenharmony_ci#include <properties.h> 202498b56bSopenharmony_ci 212498b56bSopenharmony_ci#include "log_stats.h" 222498b56bSopenharmony_ci 232498b56bSopenharmony_cinamespace OHOS { 242498b56bSopenharmony_cinamespace HiviewDFX { 252498b56bSopenharmony_ciusing namespace std; 262498b56bSopenharmony_ci 272498b56bSopenharmony_ciLogStats::LogStats() 282498b56bSopenharmony_ci{ 292498b56bSopenharmony_ci Reset(); 302498b56bSopenharmony_ci enable = IsStatsEnable(); 312498b56bSopenharmony_ci tagEnable = IsTagStatsEnable(); 322498b56bSopenharmony_ci} 332498b56bSopenharmony_ciLogStats::~LogStats() {} 342498b56bSopenharmony_ci 352498b56bSopenharmony_cistatic inline int idxLvl(uint16_t lvl) 362498b56bSopenharmony_ci{ 372498b56bSopenharmony_ci return static_cast<int>(lvl) - LevelBase; 382498b56bSopenharmony_ci} 392498b56bSopenharmony_ci 402498b56bSopenharmony_cistatic void UpdateStats(StatsEntry &entry, const StatsInfo &info) 412498b56bSopenharmony_ci{ 422498b56bSopenharmony_ci LogTimeStamp ts_mono(info.mono_sec, info.tv_nsec); 432498b56bSopenharmony_ci static LogTimeStamp ts_audit_period(1, 0); // Audit period : one second 442498b56bSopenharmony_ci ts_mono -= entry.monoTimeLast; 452498b56bSopenharmony_ci if (ts_mono > ts_audit_period) { 462498b56bSopenharmony_ci entry.monoTimeLast -= entry.monoTimeAuditStart; 472498b56bSopenharmony_ci float secs = entry.monoTimeLast.FloatSecs(); 482498b56bSopenharmony_ci if (secs < 1.0f) { 492498b56bSopenharmony_ci secs = 1.0f; 502498b56bSopenharmony_ci } 512498b56bSopenharmony_ci float freq = entry.tmpLines / secs; 522498b56bSopenharmony_ci if (freq > entry.freqMax) { 532498b56bSopenharmony_ci entry.freqMax = freq; 542498b56bSopenharmony_ci entry.realTimeFreqMax = entry.realTimeLast; 552498b56bSopenharmony_ci } 562498b56bSopenharmony_ci entry.tmpLines = 0; 572498b56bSopenharmony_ci float throughput = entry.tmpLen / secs; 582498b56bSopenharmony_ci if (throughput > entry.throughputMax) { 592498b56bSopenharmony_ci entry.throughputMax = throughput; 602498b56bSopenharmony_ci entry.realTimeThroughputMax = entry.realTimeLast; 612498b56bSopenharmony_ci } 622498b56bSopenharmony_ci entry.tmpLen = 0; 632498b56bSopenharmony_ci entry.monoTimeAuditStart.SetTimeStamp(info.mono_sec, info.tv_nsec); 642498b56bSopenharmony_ci } 652498b56bSopenharmony_ci 662498b56bSopenharmony_ci int lvl = idxLvl(info.level); 672498b56bSopenharmony_ci entry.lines[lvl]++; 682498b56bSopenharmony_ci entry.len[lvl] += info.len; 692498b56bSopenharmony_ci entry.dropped += info.dropped; 702498b56bSopenharmony_ci entry.tmpLines++; 712498b56bSopenharmony_ci entry.tmpLen += info.len; 722498b56bSopenharmony_ci entry.monoTimeLast.SetTimeStamp(info.mono_sec, info.tv_nsec); 732498b56bSopenharmony_ci entry.realTimeLast.SetTimeStamp(info.tv_sec, info.tv_nsec); 742498b56bSopenharmony_ci} 752498b56bSopenharmony_ci 762498b56bSopenharmony_cistatic void ResetStatsEntry(StatsEntry &entry) 772498b56bSopenharmony_ci{ 782498b56bSopenharmony_ci entry.dropped = 0; 792498b56bSopenharmony_ci entry.tmpLines = 0; 802498b56bSopenharmony_ci entry.freqMax = 0; 812498b56bSopenharmony_ci entry.realTimeFreqMax.SetTimeStamp(0, 0); 822498b56bSopenharmony_ci entry.tmpLen = 0; 832498b56bSopenharmony_ci entry.throughputMax = 0; 842498b56bSopenharmony_ci entry.realTimeThroughputMax.SetTimeStamp(0, 0); 852498b56bSopenharmony_ci entry.monoTimeLast.SetTimeStamp(0, 0); 862498b56bSopenharmony_ci entry.monoTimeAuditStart.SetTimeStamp(0, 0); 872498b56bSopenharmony_ci for (uint32_t &i : entry.lines) { 882498b56bSopenharmony_ci i = 0; 892498b56bSopenharmony_ci } 902498b56bSopenharmony_ci for (uint64_t &i : entry.len) { 912498b56bSopenharmony_ci i = 0; 922498b56bSopenharmony_ci } 932498b56bSopenharmony_ci} 942498b56bSopenharmony_ci 952498b56bSopenharmony_cistatic void StatsInfo2NewStatsEntry(const StatsInfo &info, StatsEntry &entry) 962498b56bSopenharmony_ci{ 972498b56bSopenharmony_ci entry.dropped = info.dropped; 982498b56bSopenharmony_ci entry.tmpLines = 1; 992498b56bSopenharmony_ci entry.freqMax = 0; 1002498b56bSopenharmony_ci entry.realTimeFreqMax.SetTimeStamp(info.tv_sec, info.tv_nsec); 1012498b56bSopenharmony_ci entry.tmpLen = info.len; 1022498b56bSopenharmony_ci entry.throughputMax = 0; 1032498b56bSopenharmony_ci entry.realTimeThroughputMax.SetTimeStamp(info.tv_sec, info.tv_nsec); 1042498b56bSopenharmony_ci entry.realTimeLast.SetTimeStamp(info.tv_sec, info.tv_nsec); 1052498b56bSopenharmony_ci entry.monoTimeLast.SetTimeStamp(info.mono_sec, info.tv_nsec); 1062498b56bSopenharmony_ci entry.monoTimeAuditStart.SetTimeStamp(info.mono_sec, info.tv_nsec); 1072498b56bSopenharmony_ci for (uint32_t &i : entry.lines) { 1082498b56bSopenharmony_ci i = 0; 1092498b56bSopenharmony_ci } 1102498b56bSopenharmony_ci for (uint64_t &i : entry.len) { 1112498b56bSopenharmony_ci i = 0; 1122498b56bSopenharmony_ci } 1132498b56bSopenharmony_ci int lvl = idxLvl(info.level); 1142498b56bSopenharmony_ci entry.lines[lvl] = 1; 1152498b56bSopenharmony_ci entry.len[lvl] = info.len; 1162498b56bSopenharmony_ci} 1172498b56bSopenharmony_ci 1182498b56bSopenharmony_civoid LogStats::UpdateTagTable(TagTable& tt, const StatsInfo &info) 1192498b56bSopenharmony_ci{ 1202498b56bSopenharmony_ci if (!tagEnable) { 1212498b56bSopenharmony_ci return; 1222498b56bSopenharmony_ci } 1232498b56bSopenharmony_ci auto itt = tt.find(info.tag); 1242498b56bSopenharmony_ci if (itt != tt.end()) { 1252498b56bSopenharmony_ci UpdateStats(itt->second, info); 1262498b56bSopenharmony_ci } else { 1272498b56bSopenharmony_ci TagStatsEntry entry; 1282498b56bSopenharmony_ci StatsInfo2NewStatsEntry(info, entry); 1292498b56bSopenharmony_ci (void)tt.emplace(info.tag, entry); 1302498b56bSopenharmony_ci } 1312498b56bSopenharmony_ci} 1322498b56bSopenharmony_ci 1332498b56bSopenharmony_civoid LogStats::UpdateDomainTable(const StatsInfo &info) 1342498b56bSopenharmony_ci{ 1352498b56bSopenharmony_ci DomainTable& t = domainStats[info.type]; 1362498b56bSopenharmony_ci auto it = t.find(info.domain); 1372498b56bSopenharmony_ci if (it != t.end()) { 1382498b56bSopenharmony_ci UpdateStats(it->second.stats, info); 1392498b56bSopenharmony_ci } else { 1402498b56bSopenharmony_ci DomainStatsEntry entry; 1412498b56bSopenharmony_ci StatsInfo2NewStatsEntry(info, entry.stats); 1422498b56bSopenharmony_ci auto result = t.emplace(info.domain, entry); 1432498b56bSopenharmony_ci if (!result.second) { 1442498b56bSopenharmony_ci cerr << "Add entry to DomainTable error" << endl; 1452498b56bSopenharmony_ci return; 1462498b56bSopenharmony_ci } 1472498b56bSopenharmony_ci it = result.first; 1482498b56bSopenharmony_ci } 1492498b56bSopenharmony_ci UpdateTagTable(it->second.tagStats, info); 1502498b56bSopenharmony_ci} 1512498b56bSopenharmony_ci 1522498b56bSopenharmony_civoid LogStats::UpdatePidTable(const StatsInfo &info) 1532498b56bSopenharmony_ci{ 1542498b56bSopenharmony_ci PidTable& t = pidStats; 1552498b56bSopenharmony_ci auto it = t.find(info.pid); 1562498b56bSopenharmony_ci if (it != t.end()) { 1572498b56bSopenharmony_ci UpdateStats(it->second.statsAll, info); 1582498b56bSopenharmony_ci UpdateStats(it->second.stats[info.type], info); 1592498b56bSopenharmony_ci } else { 1602498b56bSopenharmony_ci PidStatsEntry entry; 1612498b56bSopenharmony_ci StatsInfo2NewStatsEntry(info, entry.statsAll); 1622498b56bSopenharmony_ci for (StatsEntry &e : entry.stats) { 1632498b56bSopenharmony_ci ResetStatsEntry(e); 1642498b56bSopenharmony_ci } 1652498b56bSopenharmony_ci entry.stats[info.type] = entry.statsAll; 1662498b56bSopenharmony_ci entry.name = GetNameByPid(info.pid); 1672498b56bSopenharmony_ci auto result = t.emplace(info.pid, entry); 1682498b56bSopenharmony_ci if (!result.second) { 1692498b56bSopenharmony_ci cerr << "Add entry to PidTable error" << endl; 1702498b56bSopenharmony_ci return; 1712498b56bSopenharmony_ci } 1722498b56bSopenharmony_ci it = result.first; 1732498b56bSopenharmony_ci } 1742498b56bSopenharmony_ci UpdateTagTable(it->second.tagStats, info); 1752498b56bSopenharmony_ci} 1762498b56bSopenharmony_ci 1772498b56bSopenharmony_civoid LogStats::Count(const StatsInfo &info) 1782498b56bSopenharmony_ci{ 1792498b56bSopenharmony_ci if (enable) { 1802498b56bSopenharmony_ci std::scoped_lock lk(lock); 1812498b56bSopenharmony_ci int index = idxLvl(info.level); 1822498b56bSopenharmony_ci totalLines[index]++; 1832498b56bSopenharmony_ci totalLens[index] += info.len; 1842498b56bSopenharmony_ci UpdateDomainTable(info); 1852498b56bSopenharmony_ci UpdatePidTable(info); 1862498b56bSopenharmony_ci } 1872498b56bSopenharmony_ci} 1882498b56bSopenharmony_ci 1892498b56bSopenharmony_civoid LogStats::Reset() 1902498b56bSopenharmony_ci{ 1912498b56bSopenharmony_ci std::scoped_lock lk(lock); 1922498b56bSopenharmony_ci for (auto &t : domainStats) { 1932498b56bSopenharmony_ci t.clear(); 1942498b56bSopenharmony_ci } 1952498b56bSopenharmony_ci pidStats.clear(); 1962498b56bSopenharmony_ci tsBegin = LogTimeStamp(CLOCK_REALTIME); 1972498b56bSopenharmony_ci monoBegin = LogTimeStamp(CLOCK_MONOTONIC); 1982498b56bSopenharmony_ci for (int i = 0; i < LevelNum; i++) { 1992498b56bSopenharmony_ci totalLines[i] = 0; 2002498b56bSopenharmony_ci totalLens[i] = 0; 2012498b56bSopenharmony_ci } 2022498b56bSopenharmony_ci} 2032498b56bSopenharmony_ci 2042498b56bSopenharmony_ciconst LogTypeDomainTable& LogStats::GetDomainTable() const 2052498b56bSopenharmony_ci{ 2062498b56bSopenharmony_ci return domainStats; 2072498b56bSopenharmony_ci} 2082498b56bSopenharmony_ci 2092498b56bSopenharmony_ciconst PidTable& LogStats::GetPidTable() const 2102498b56bSopenharmony_ci{ 2112498b56bSopenharmony_ci return pidStats; 2122498b56bSopenharmony_ci} 2132498b56bSopenharmony_ci 2142498b56bSopenharmony_ciconst LogTimeStamp& LogStats::GetBeginTs() const 2152498b56bSopenharmony_ci{ 2162498b56bSopenharmony_ci return tsBegin; 2172498b56bSopenharmony_ci} 2182498b56bSopenharmony_ci 2192498b56bSopenharmony_ciconst LogTimeStamp& LogStats::GetBeginMono() const 2202498b56bSopenharmony_ci{ 2212498b56bSopenharmony_ci return monoBegin; 2222498b56bSopenharmony_ci} 2232498b56bSopenharmony_ci 2242498b56bSopenharmony_civoid LogStats::GetTotalLines(uint32_t (&in_lines)[LevelNum]) const 2252498b56bSopenharmony_ci{ 2262498b56bSopenharmony_ci std::copy(totalLines, totalLines + LevelNum, in_lines); 2272498b56bSopenharmony_ci} 2282498b56bSopenharmony_ci 2292498b56bSopenharmony_civoid LogStats::GetTotalLens(uint64_t (&in_lens)[LevelNum]) const 2302498b56bSopenharmony_ci{ 2312498b56bSopenharmony_ci std::copy(totalLens, totalLens + LevelNum, in_lens); 2322498b56bSopenharmony_ci} 2332498b56bSopenharmony_ci 2342498b56bSopenharmony_cibool LogStats::IsEnable() const 2352498b56bSopenharmony_ci{ 2362498b56bSopenharmony_ci return enable; 2372498b56bSopenharmony_ci} 2382498b56bSopenharmony_ci 2392498b56bSopenharmony_cibool LogStats::IsTagEnable() const 2402498b56bSopenharmony_ci{ 2412498b56bSopenharmony_ci return tagEnable; 2422498b56bSopenharmony_ci} 2432498b56bSopenharmony_ci 2442498b56bSopenharmony_cistd::unique_lock<std::mutex> LogStats::GetLock() 2452498b56bSopenharmony_ci{ 2462498b56bSopenharmony_ci std::unique_lock<std::mutex> lk(lock); 2472498b56bSopenharmony_ci return lk; 2482498b56bSopenharmony_ci} 2492498b56bSopenharmony_ci 2502498b56bSopenharmony_civoid LogStats::Print() 2512498b56bSopenharmony_ci{ 2522498b56bSopenharmony_ci cout << "Domain Table:" << endl; 2532498b56bSopenharmony_ci int i = 0; 2542498b56bSopenharmony_ci for (auto &t : domainStats) { 2552498b56bSopenharmony_ci i++; 2562498b56bSopenharmony_ci if (t.size() == 0) { 2572498b56bSopenharmony_ci continue; 2582498b56bSopenharmony_ci } 2592498b56bSopenharmony_ci cout << " Log type:" << (i - 1) << endl; 2602498b56bSopenharmony_ci for (auto &it : t) { 2612498b56bSopenharmony_ci cout << " Domain: 0x" << std::hex << it.first << std::dec << endl; 2622498b56bSopenharmony_ci cout << " "; 2632498b56bSopenharmony_ci it.second.stats.Print(); 2642498b56bSopenharmony_ci for (auto &itt : it.second.tagStats) { 2652498b56bSopenharmony_ci cout << " Tag: " << itt.first << endl; 2662498b56bSopenharmony_ci cout << " "; 2672498b56bSopenharmony_ci itt.second.Print(); 2682498b56bSopenharmony_ci } 2692498b56bSopenharmony_ci } 2702498b56bSopenharmony_ci } 2712498b56bSopenharmony_ci cout << "Pid Table:" << endl; 2722498b56bSopenharmony_ci for (auto &t : pidStats) { 2732498b56bSopenharmony_ci cout << " Proc: " << t.second.name << "(" << t.first << ")" << endl; 2742498b56bSopenharmony_ci cout << " "; 2752498b56bSopenharmony_ci t.second.statsAll.Print(); 2762498b56bSopenharmony_ci int i = 0; 2772498b56bSopenharmony_ci for (auto &s : t.second.stats) { 2782498b56bSopenharmony_ci i++; 2792498b56bSopenharmony_ci if (s.GetTotalLines() == 0) { 2802498b56bSopenharmony_ci continue; 2812498b56bSopenharmony_ci } 2822498b56bSopenharmony_ci cout << " Log Type: " << (i - 1) << endl; 2832498b56bSopenharmony_ci cout << " "; 2842498b56bSopenharmony_ci s.Print(); 2852498b56bSopenharmony_ci } 2862498b56bSopenharmony_ci for (auto &itt : t.second.tagStats) { 2872498b56bSopenharmony_ci cout << " Tag: " << itt.first << endl; 2882498b56bSopenharmony_ci cout << " "; 2892498b56bSopenharmony_ci itt.second.Print(); 2902498b56bSopenharmony_ci } 2912498b56bSopenharmony_ci } 2922498b56bSopenharmony_ci} 2932498b56bSopenharmony_ci} // namespace HiviewDFX 2942498b56bSopenharmony_ci} // namespace OHOS