LogStatistics.h revision 3296291cffd13af13ea9e60a8ac1138101cf8e4c
134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn/* 234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Copyright (C) 2014 The Android Open Source Project 334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * you may not use this file except in compliance with the License. 634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * You may obtain a copy of the License at 734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 1034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 1134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 1234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * See the License for the specific language governing permissions and 1434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * limitations under the License. 1534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn */ 1634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 1734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#ifndef _LOGD_LOG_STATISTICS_H__ 1834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define _LOGD_LOG_STATISTICS_H__ 1934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 20720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <memory> 21720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <stdlib.h> 2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <sys/types.h> 2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 24758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <algorithm> // std::max 25758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <string> // std::string 26511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn#include <unordered_map> 27511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 280dd4431072cce3c62876b728cb20aa5b77b11a8dMark Salyzyn#include <android/log.h> 294f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h> 30758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <private/android_filesystem_config.h> 3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h" 335ac5c6b19364b5b3061a59db796b2357c95c3b64Mark Salyzyn#include "LogUtils.h" 3434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 3534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \ 36f0f94fe49b04c2d2bf0a0a44a7afb9118607b351Chih-Hung Hsieh for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t) ((i) + 1)) 3734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 38758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynclass LogStatistics; 39758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry> 41511338dd575572d567c04d69eaea60627b6c3452Mark Salyzynclass LogHashtable { 42511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 43511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn std::unordered_map<TKey, TEntry> map; 44511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 456d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t bucket_size() const { 466d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t count = 0; 476d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn for (size_t idx = 0; idx < map.bucket_count(); ++idx) { 486d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t bucket_size = map.bucket_size(idx); 496d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (bucket_size == 0) bucket_size = 1; 506d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn count += bucket_size; 516d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 526d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn float load_factor = map.max_load_factor(); 536d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (load_factor < 1.0) return count; 546d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn return count * load_factor; 556d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 566d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 576d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn static const size_t unordered_map_per_entry_overhead = sizeof(void*); 586d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn static const size_t unordered_map_bucket_overhead = sizeof(void*); 596d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 60720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic: 61511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 62b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn size_t size() const { return map.size(); } 63b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn 646d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn // Estimate unordered_map memory usage. 656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t sizeOf() const { 666d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn return sizeof(*this) + 67b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) + 686d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead); 696d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 706d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 71511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn typedef typename std::unordered_map<TKey, TEntry>::iterator iterator; 72758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator; 73511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 74ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid, 75ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn size_t len) const { 76758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!len) { 77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const TEntry *[]> sorted(NULL); 78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 79720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 81758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const TEntry **retval = new const TEntry* [len]; 82758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memset(retval, 0, sizeof(*retval) * len); 83720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for(const_iterator it = map.begin(); it != map.end(); ++it) { 85511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn const TEntry &entry = it->second; 86ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 87ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if ((uid != AID_ROOT) && (uid != entry.getUid())) { 88ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn continue; 89ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 90ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid && entry.getPid() && (pid != entry.getPid())) { 91ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn continue; 92ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 93ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 94758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t sizes = entry.getSizes(); 95758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t index = len - 1; 96758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn while ((!retval[index] || (sizes > retval[index]->getSizes())) 97758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn && (--index >= 0)) 98720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ; 99758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (++index < (ssize_t)len) { 100758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t num = len - index - 1; 101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (num) { 102758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memmove(&retval[index + 1], &retval[index], 103758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn num * sizeof(retval[0])); 104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 105758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn retval[index] = &entry; 106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 107720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 108720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const TEntry *[]> sorted(retval); 109720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 110720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 111720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 112758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline iterator add(TKey key, LogBufferElement *element) { 113511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 114511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 115758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(element))).first; 116511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 117758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.add(element); 11881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 119511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 12081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 12181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 122511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator add(TKey key) { 123511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 125511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(key))).first; 126511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 127511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it->second.add(key); 12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 129511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 13081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 13181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn void subtract(TKey key, LogBufferElement *element) { 133511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if ((it != map.end()) && it->second.subtract(element)) { 135511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn map.erase(it); 13681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 13781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 139758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void drop(TKey key, LogBufferElement *element) { 140511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 141511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it != map.end()) { 142758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.drop(element); 14381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 14481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 14581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 146511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator begin() { return map.begin(); } 147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline const_iterator begin() const { return map.begin(); } 148511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator end() { return map.end(); } 149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline const_iterator end() const { return map.end(); } 150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format( 152758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const LogStatistics &stat, 153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid, 154ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid, 155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &name = std::string(""), 156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t id = LOG_ID_MAX) const { 157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static const size_t maximum_sorted_entries = 32; 158758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string output; 159ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid, 160ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn maximum_sorted_entries); 161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!sorted.get()) { 162758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 163758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool headerPrinted = false; 165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for (size_t index = 0; index < maximum_sorted_entries; ++index) { 166758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const TEntry *entry = sorted[index]; 167758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!entry) { 168758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) { 171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 172758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!headerPrinted) { 174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += "\n\n"; 175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->formatHeader(name, id); 176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn headerPrinted = true; 177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->format(stat, id); 179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 1826d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 183720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 184720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants { 186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static constexpr size_t pruned_len = 14; 187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static constexpr size_t total_len = 80; 188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 19081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase { 19197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t size; 19234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 19381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn EntryBase():size(0) { } 1949e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit EntryBase(LogBufferElement *element):size(element->getMsgLen()) { } 19534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 19697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t getSizes() const { return size; } 19781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { size += element->getMsgLen(); } 199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline bool subtract(LogBufferElement *element) { 200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size -= element->getMsgLen(); 201758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return !size; 202758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 203758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static std::string formatLine( 205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &name, 206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &size, 207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &pruned) { 208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t drop_len = std::max(pruned.length() + 1, 209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseConstants::pruned_len); 210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t size_len = std::max(size.length() + 1, 211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseConstants::total_len 212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn - name.length() - drop_len - 1); 213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (pruned.length()) { 215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return android::base::StringPrintf("%s%*s%*s\n", name.c_str(), 216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)size_len, size.c_str(), 217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)drop_len, pruned.c_str()); 218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else { 219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return android::base::StringPrintf("%s%*s\n", name.c_str(), 220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)size_len, size.c_str()); 221758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 222758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 22381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 22481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 22581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase { 22681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn size_t dropped; 22781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 22881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn EntryBaseDropped():dropped(0) { } 2299e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit EntryBaseDropped(LogBufferElement *element): 230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase(element), 2316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn dropped(element->getDropped()) { 232758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 23381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 234ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn size_t getDropped() const { return dropped; } 235ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 236758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 237758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped += element->getDropped(); 238758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::add(element); 23981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 240758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline bool subtract(LogBufferElement *element) { 241758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped -= element->getDropped(); 242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return EntryBase::subtract(element) && !dropped; 24381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void drop(LogBufferElement *element) { 24581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn dropped += 1; 246758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::subtract(element); 24781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 24881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 24981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 25081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped { 25181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn const uid_t uid; 252ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 25381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 2549e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit UidEntry(LogBufferElement *element): 255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 256ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn uid(element->getUid()), 257ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid(element->getPid()) { 258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 25981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 26081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn inline const uid_t&getKey() const { return uid; } 261ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn inline const uid_t&getUid() const { return getKey(); } 262ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn inline const pid_t&getPid() const { return pid; } 263ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 264ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn inline void add(LogBufferElement *element) { 265ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid != element->getPid()) { 266ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = -1; 267ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 268a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn EntryBaseDropped::add(element); 269ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 271758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 27334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 27434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 27581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android { 27681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid); 27781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn} 27881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 27981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped { 280720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const pid_t pid; 281720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn uid_t uid; 282720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn char *name; 283720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 2849e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit PidEntry(pid_t pid): 285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(), 286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(pid), 287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(android::pidToUid(pid)), 288758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::pidToName(pid)) { 289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 2909e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit PidEntry(LogBufferElement *element): 291758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 292758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(element->getPid()), 293758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()), 294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::pidToName(pid)) { 295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn PidEntry(const PidEntry &element): 297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(element.pid), 299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element.uid), 300758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(element.name ? strdup(element.name) : NULL) { 301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 302720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ~PidEntry() { free(name); } 303720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 304720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const pid_t&getKey() const { return pid; } 305ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn const pid_t&getPid() const { return getKey(); } 306720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const uid_t&getUid() const { return uid; } 307720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const char*getName() const { return name; } 30881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 309758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t newPid) { 3100eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (name && !fastcmp<strncmp>(name, "zygote", 6)) { 311aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn free(name); 312aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn name = NULL; 313aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn } 31481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(newPid); 31681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 31781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 31881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 319758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (getUid() != incomingUid) { 322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 32381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn free(name); 324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(element->getPid()); 32581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } else { 326758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getPid()); 32781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 328758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 32981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 330758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 333344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn}; 334344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 33517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped { 33617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const pid_t tid; 337ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 33817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn uid_t uid; 33917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn char *name; 34017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 341ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn TidEntry(pid_t tid, pid_t pid): 342758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(), 343758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(tid), 344ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid(pid), 345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(android::pidToUid(tid)), 346758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::tidToName(tid)) { 347758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 3489e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit TidEntry(LogBufferElement *element): 349758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 350758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(element->getTid()), 351ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid(element->getPid()), 352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()), 353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::tidToName(tid)) { 354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn TidEntry(const TidEntry &element): 356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 357758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(element.tid), 358ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid(element.pid), 359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element.uid), 360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(element.name ? strdup(element.name) : NULL) { 361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 36217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn ~TidEntry() { free(name); } 36317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 36417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const pid_t&getKey() const { return tid; } 365ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn const pid_t&getTid() const { return getKey(); } 366ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn const pid_t&getPid() const { return pid; } 36717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const uid_t&getUid() const { return uid; } 36817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const char*getName() const { return name; } 36917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t incomingTid) { 3710eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (name && !fastcmp<strncmp>(name, "zygote", 6)) { 37217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 37317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn name = NULL; 37417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 37517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn if (!name) { 376758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(incomingTid); 37717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 37817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 37917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 380758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 381758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 382ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t incomingPid = element->getPid(); 383ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if ((getUid() != incomingUid) || (getPid() != incomingPid)) { 384758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 385ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = incomingPid; 38617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 387758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(element->getTid()); 38817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } else { 389758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getTid()); 39017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 391758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 39217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 393758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 394758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 395758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 39617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn}; 39717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 3986a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynstruct TagEntry : public EntryBaseDropped { 399344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uint32_t tag; 400ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 401344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid_t uid; 402344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 4039e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit TagEntry(LogBufferElement *element): 4046a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn EntryBaseDropped(element), 405758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tag(element->getTag()), 406ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid(element->getPid()), 407758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()) { 408758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 409344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 410344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uint32_t&getKey() const { return tag; } 411ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn const pid_t&getPid() const { return pid; } 412344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uid_t&getUid() const { return uid; } 413807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn const char*getName(size_t &len) const { return android::tagToName(&len, tag); } 41481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 415758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 416ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (uid != element->getUid()) { 417344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid = -1; 418344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 419ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid != element->getPid()) { 420ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = -1; 421ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 422a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn EntryBaseDropped::add(element); 423344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 424758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 425758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 426758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 427720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 428720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 4296a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyntemplate <typename TEntry> 4306a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynclass LogFindWorst { 4316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn std::unique_ptr<const TEntry *[]> sorted; 4326a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 4336a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynpublic: 4346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 4359e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh explicit LogFindWorst(std::unique_ptr<const TEntry *[]> &&sorted) : sorted(std::move(sorted)) { } 4366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 4376a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn void findWorst(int &worst, 4386a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn size_t &worst_sizes, size_t &second_worst_sizes, 4396a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn size_t threshold) { 4406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (sorted.get() && sorted[0] && sorted[1]) { 4416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst_sizes = sorted[0]->getSizes(); 4426a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if ((worst_sizes > threshold) 4436a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn // Allow time horizon to extend roughly tenfold, assume 4446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn // average entry length is 100 characters. 4456a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn && (worst_sizes > (10 * sorted[0]->getDropped()))) { 4466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst = sorted[0]->getKey(); 4476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn second_worst_sizes = sorted[1]->getSizes(); 4486a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (second_worst_sizes < threshold) { 4496a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn second_worst_sizes = threshold; 4506a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4516a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4526a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4536a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 4556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn void findWorst(int &worst, 4566a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn size_t worst_sizes, size_t &second_worst_sizes) { 4576a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (sorted.get() && sorted[0] && sorted[1]) { 4586a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst = sorted[0]->getKey(); 4596a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn second_worst_sizes = worst_sizes 4606a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn - sorted[0]->getSizes() 4616a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn + sorted[1]->getSizes(); 4626a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4636a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 4646a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn}; 4656a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 46634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics 46734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics { 468c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn friend UidEntry; 469c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn 47034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mSizes[LOG_ID_MAX]; 47134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mElements[LOG_ID_MAX]; 47258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t mDroppedElements[LOG_ID_MAX]; 47397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mSizesTotal[LOG_ID_MAX]; 47497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mElementsTotal[LOG_ID_MAX]; 4753296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn static size_t SizesTotal; 476720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn bool enable; 47734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 47897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // uid to size list 479720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<uid_t, UidEntry> uidTable_t; 48097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn uidTable_t uidTable[LOG_ID_MAX]; 481e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 482bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn // pid of system to size list 483bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t; 484bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable_t pidSystemTable[LOG_ID_MAX]; 485bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 486720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // pid to uid list 487720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<pid_t, PidEntry> pidTable_t; 488720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn pidTable_t pidTable; 489720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 49017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn // tid to uid list 49117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn typedef LogHashtable<pid_t, TidEntry> tidTable_t; 49217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn tidTable_t tidTable; 49317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 494344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn // tag list 495344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn typedef LogHashtable<uint32_t, TagEntry> tagTable_t; 496344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn tagTable_t tagTable; 497344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 498083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn // security tag list 499083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable_t securityTagTable; 500083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn 5016d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t sizeOf() const { 5026d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() + 503b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn tagTable.sizeOf() + securityTagTable.sizeOf() + 504b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (pidTable.size() * sizeof(pidTable_t::iterator)) + 505b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (tagTable.size() * sizeof(tagTable_t::iterator)); 5066d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn for(auto it : pidTable) { 5076d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn const char* name = it.second.getName(); 5086d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (name) size += strlen(name) + 1; 5096d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5106d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn for(auto it : tidTable) { 5116d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn const char* name = it.second.getName(); 5126d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (name) size += strlen(name) + 1; 5136d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5146d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn log_id_for_each(id) { 5156d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size += uidTable[id].sizeOf(); 516b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn size += uidTable[id].size() * sizeof(uidTable_t::iterator); 5176d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size += pidSystemTable[id].sizeOf(); 518b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn size += pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator); 5196d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5206d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn return size; 5216d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5226d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 52334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic: 5246d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 52534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn LogStatistics(); 52634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 527720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn void enableStatistics() { enable = true; } 52834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 52997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn void add(LogBufferElement *entry); 53097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn void subtract(LogBufferElement *entry); 531ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn // entry->setDropped(1) must follow this call 532ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn void drop(LogBufferElement *entry); 533aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn // Correct for coalescing two entries referencing dropped content 53458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn void erase(LogBufferElement *element) { 53558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn log_id_t log_id = element->getLogId(); 53658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mElements[log_id]; 53758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mDroppedElements[log_id]; 53858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 539e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 5406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { 5416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); 5426a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5436a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { 5446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); 545758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 5466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { 5476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len)); 548bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 54934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 55034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn // fast track current value by id only 55134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t sizes(log_id_t id) const { return mSizes[id]; } 55234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t elements(log_id_t id) const { return mElements[id]; } 55358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t realElements(log_id_t id) const { 55458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn return mElements[id] - mDroppedElements[id]; 55558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 55697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; } 55797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; } 5583296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn static size_t sizesTotal() { return SizesTotal; } 55934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 560ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::string format(uid_t uid, pid_t pid, unsigned int logMask) const; 5619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 562ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn // helper (must be locked directly or implicitly by mLogElementsLock) 563758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *pidToName(pid_t pid) const; 5644ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn uid_t pidToUid(pid_t pid); 565758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *uidToName(uid_t uid) const; 56634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 56734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 56834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__ 569