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 20b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn#include <ctype.h> 21720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <stdlib.h> 2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <sys/types.h> 2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 24501c373916e292764400dbae735f44b33378400fMark Salyzyn#include <algorithm> // std::max 25b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn#include <memory> 26501c373916e292764400dbae735f44b33378400fMark Salyzyn#include <string> // std::string 27511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn#include <unordered_map> 28511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 294f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h> 30501c373916e292764400dbae735f44b33378400fMark Salyzyn#include <android/log.h> 31758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <private/android_filesystem_config.h> 3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 3397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h" 345ac5c6b19364b5b3061a59db796b2357c95c3b64Mark Salyzyn#include "LogUtils.h" 3534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 3634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \ 37501c373916e292764400dbae735f44b33378400fMark Salyzyn for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t)((i) + 1)) 3834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 39758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynclass LogStatistics; 40758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 41720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry> 42511338dd575572d567c04d69eaea60627b6c3452Mark Salyzynclass LogHashtable { 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 60501c373916e292764400dbae735f44b33378400fMark Salyzyn public: 61501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t size() const { 62501c373916e292764400dbae735f44b33378400fMark Salyzyn return map.size(); 63501c373916e292764400dbae735f44b33378400fMark Salyzyn } 64b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn 656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn // Estimate unordered_map memory usage. 666d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t sizeOf() const { 676d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn return sizeof(*this) + 68b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) + 696d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead); 706d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 716d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 72511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn typedef typename std::unordered_map<TKey, TEntry>::iterator iterator; 73501c373916e292764400dbae735f44b33378400fMark Salyzyn typedef 74501c373916e292764400dbae735f44b33378400fMark Salyzyn typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator; 75511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 76501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const TEntry* []> sort(uid_t uid, pid_t pid, 77ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn size_t len) const { 78758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!len) { 79501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const TEntry* []> sorted(NULL); 80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 82720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 83501c373916e292764400dbae735f44b33378400fMark Salyzyn const TEntry** retval = new const TEntry*[len]; 84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memset(retval, 0, sizeof(*retval) * len); 85720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 86501c373916e292764400dbae735f44b33378400fMark Salyzyn for (const_iterator it = map.begin(); it != map.end(); ++it) { 87501c373916e292764400dbae735f44b33378400fMark Salyzyn const TEntry& entry = it->second; 88ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 89ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if ((uid != AID_ROOT) && (uid != entry.getUid())) { 90ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn continue; 91ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 92ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid && entry.getPid() && (pid != entry.getPid())) { 93ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn continue; 94ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 95ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 96758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t sizes = entry.getSizes(); 97758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t index = len - 1; 98501c373916e292764400dbae735f44b33378400fMark Salyzyn while ((!retval[index] || (sizes > retval[index]->getSizes())) && 99501c373916e292764400dbae735f44b33378400fMark Salyzyn (--index >= 0)) 100720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ; 101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (++index < (ssize_t)len) { 102758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t num = len - index - 1; 103758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (num) { 104758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memmove(&retval[index + 1], &retval[index], 105758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn num * sizeof(retval[0])); 106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 107758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn retval[index] = &entry; 108720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 109720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 110501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const TEntry* []> sorted(retval); 111720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 112720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 113720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 114501c373916e292764400dbae735f44b33378400fMark Salyzyn inline iterator add(TKey key, LogBufferElement* element) { 115511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 116511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 117758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(element))).first; 118511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 119758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.add(element); 12081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 121511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 12281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 12381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator add(TKey key) { 125511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 126511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 127511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(key))).first; 128511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 129511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it->second.add(key); 13081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 131511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 13281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 13381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 134501c373916e292764400dbae735f44b33378400fMark Salyzyn void subtract(TKey key, LogBufferElement* element) { 135511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 136758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if ((it != map.end()) && it->second.subtract(element)) { 137511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn map.erase(it); 13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 13981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 14081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 141501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void drop(TKey key, LogBufferElement* element) { 142511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 143511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it != map.end()) { 144758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.drop(element); 14581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 14681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 14781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 148501c373916e292764400dbae735f44b33378400fMark Salyzyn inline iterator begin() { 149501c373916e292764400dbae735f44b33378400fMark Salyzyn return map.begin(); 150501c373916e292764400dbae735f44b33378400fMark Salyzyn } 151501c373916e292764400dbae735f44b33378400fMark Salyzyn inline const_iterator begin() const { 152501c373916e292764400dbae735f44b33378400fMark Salyzyn return map.begin(); 153501c373916e292764400dbae735f44b33378400fMark Salyzyn } 154501c373916e292764400dbae735f44b33378400fMark Salyzyn inline iterator end() { 155501c373916e292764400dbae735f44b33378400fMark Salyzyn return map.end(); 156501c373916e292764400dbae735f44b33378400fMark Salyzyn } 157501c373916e292764400dbae735f44b33378400fMark Salyzyn inline const_iterator end() const { 158501c373916e292764400dbae735f44b33378400fMark Salyzyn return map.end(); 159501c373916e292764400dbae735f44b33378400fMark Salyzyn } 160758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 161501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string format(const LogStatistics& stat, uid_t uid, pid_t pid, 162501c373916e292764400dbae735f44b33378400fMark Salyzyn const std::string& name = std::string(""), 163501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t id = LOG_ID_MAX) const { 164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static const size_t maximum_sorted_entries = 32; 165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string output; 166501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const TEntry* []> sorted = 167501c373916e292764400dbae735f44b33378400fMark Salyzyn sort(uid, pid, maximum_sorted_entries); 168758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!sorted.get()) { 169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool headerPrinted = false; 172758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for (size_t index = 0; index < maximum_sorted_entries; ++index) { 173501c373916e292764400dbae735f44b33378400fMark Salyzyn const TEntry* entry = sorted[index]; 174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!entry) { 175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) { 178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!headerPrinted) { 181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += "\n\n"; 182758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->formatHeader(name, id); 183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn headerPrinted = true; 184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->format(stat, id); 186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 189720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 190720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants { 192501c373916e292764400dbae735f44b33378400fMark Salyzynstatic constexpr size_t pruned_len = 14; 193501c373916e292764400dbae735f44b33378400fMark Salyzynstatic constexpr size_t total_len = 80; 194758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 195758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 19681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase { 19797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t size; 19834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 199501c373916e292764400dbae735f44b33378400fMark Salyzyn EntryBase() : size(0) { 200501c373916e292764400dbae735f44b33378400fMark Salyzyn } 201501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit EntryBase(LogBufferElement* element) : size(element->getMsgLen()) { 202501c373916e292764400dbae735f44b33378400fMark Salyzyn } 20334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 204501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t getSizes() const { 205501c373916e292764400dbae735f44b33378400fMark Salyzyn return size; 206501c373916e292764400dbae735f44b33378400fMark Salyzyn } 20781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 208501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 209501c373916e292764400dbae735f44b33378400fMark Salyzyn size += element->getMsgLen(); 210501c373916e292764400dbae735f44b33378400fMark Salyzyn } 211501c373916e292764400dbae735f44b33378400fMark Salyzyn inline bool subtract(LogBufferElement* element) { 212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size -= element->getMsgLen(); 213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return !size; 214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 216501c373916e292764400dbae735f44b33378400fMark Salyzyn static std::string formatLine(const std::string& name, 217501c373916e292764400dbae735f44b33378400fMark Salyzyn const std::string& size, 218501c373916e292764400dbae735f44b33378400fMark Salyzyn const std::string& pruned) { 219501c373916e292764400dbae735f44b33378400fMark Salyzyn ssize_t drop_len = 220501c373916e292764400dbae735f44b33378400fMark Salyzyn std::max(pruned.length() + 1, EntryBaseConstants::pruned_len); 221501c373916e292764400dbae735f44b33378400fMark Salyzyn ssize_t size_len = 222501c373916e292764400dbae735f44b33378400fMark Salyzyn std::max(size.length() + 1, EntryBaseConstants::total_len - 223501c373916e292764400dbae735f44b33378400fMark Salyzyn name.length() - drop_len - 1); 224501c373916e292764400dbae735f44b33378400fMark Salyzyn 225501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string ret = android::base::StringPrintf( 226501c373916e292764400dbae735f44b33378400fMark Salyzyn "%s%*s%*s", name.c_str(), (int)size_len, size.c_str(), 227501c373916e292764400dbae735f44b33378400fMark Salyzyn (int)drop_len, pruned.c_str()); 228b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn // remove any trailing spaces 229b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn size_t pos = ret.size(); 230b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn size_t len = 0; 231b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn while (pos && isspace(ret[--pos])) ++len; 232b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn if (len) ret.erase(pos + 1, len); 233b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn return ret + "\n"; 234758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 23581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 23681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 23781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase { 23881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn size_t dropped; 23981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 240501c373916e292764400dbae735f44b33378400fMark Salyzyn EntryBaseDropped() : dropped(0) { 241501c373916e292764400dbae735f44b33378400fMark Salyzyn } 242501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit EntryBaseDropped(LogBufferElement* element) 243501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBase(element), dropped(element->getDropped()) { 244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 24581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 246501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t getDropped() const { 247501c373916e292764400dbae735f44b33378400fMark Salyzyn return dropped; 248501c373916e292764400dbae735f44b33378400fMark Salyzyn } 249ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 250501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 251758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped += element->getDropped(); 252758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::add(element); 25381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 254501c373916e292764400dbae735f44b33378400fMark Salyzyn inline bool subtract(LogBufferElement* element) { 255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped -= element->getDropped(); 256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return EntryBase::subtract(element) && !dropped; 25781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 258501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void drop(LogBufferElement* element) { 25981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn dropped += 1; 260758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::subtract(element); 26181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 26281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 26381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 26481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped { 26581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn const uid_t uid; 266ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 26781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 268501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit UidEntry(LogBufferElement* element) 269501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 270501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element->getUid()), 271501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element->getPid()) { 272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 27381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 274501c373916e292764400dbae735f44b33378400fMark Salyzyn inline const uid_t& getKey() const { 275501c373916e292764400dbae735f44b33378400fMark Salyzyn return uid; 276501c373916e292764400dbae735f44b33378400fMark Salyzyn } 277501c373916e292764400dbae735f44b33378400fMark Salyzyn inline const uid_t& getUid() const { 278501c373916e292764400dbae735f44b33378400fMark Salyzyn return getKey(); 279501c373916e292764400dbae735f44b33378400fMark Salyzyn } 280501c373916e292764400dbae735f44b33378400fMark Salyzyn inline const pid_t& getPid() const { 281501c373916e292764400dbae735f44b33378400fMark Salyzyn return pid; 282501c373916e292764400dbae735f44b33378400fMark Salyzyn } 283ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn 284501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 285ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid != element->getPid()) { 286ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = -1; 287ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 288a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn EntryBaseDropped::add(element); 289ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 290758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 291501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string formatHeader(const std::string& name, log_id_t id) const; 292501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string format(const LogStatistics& stat, log_id_t id) const; 29334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 29434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 29581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android { 29681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid); 29781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn} 29881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 29981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped { 300720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const pid_t pid; 301720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn uid_t uid; 302501c373916e292764400dbae735f44b33378400fMark Salyzyn char* name; 303720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 304501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit PidEntry(pid_t pid) 305501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(), 306501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(pid), 307501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(android::pidToUid(pid)), 308501c373916e292764400dbae735f44b33378400fMark Salyzyn name(android::pidToName(pid)) { 309501c373916e292764400dbae735f44b33378400fMark Salyzyn } 310501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit PidEntry(LogBufferElement* element) 311501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 312501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element->getPid()), 313501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element->getUid()), 314501c373916e292764400dbae735f44b33378400fMark Salyzyn name(android::pidToName(pid)) { 315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 316501c373916e292764400dbae735f44b33378400fMark Salyzyn PidEntry(const PidEntry& element) 317501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 318501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element.pid), 319501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element.uid), 320501c373916e292764400dbae735f44b33378400fMark Salyzyn name(element.name ? strdup(element.name) : NULL) { 321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 322501c373916e292764400dbae735f44b33378400fMark Salyzyn ~PidEntry() { 323501c373916e292764400dbae735f44b33378400fMark Salyzyn free(name); 324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 325720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 326501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getKey() const { 327501c373916e292764400dbae735f44b33378400fMark Salyzyn return pid; 328501c373916e292764400dbae735f44b33378400fMark Salyzyn } 329501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getPid() const { 330501c373916e292764400dbae735f44b33378400fMark Salyzyn return getKey(); 331501c373916e292764400dbae735f44b33378400fMark Salyzyn } 332501c373916e292764400dbae735f44b33378400fMark Salyzyn const uid_t& getUid() const { 333501c373916e292764400dbae735f44b33378400fMark Salyzyn return uid; 334501c373916e292764400dbae735f44b33378400fMark Salyzyn } 335501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* getName() const { 336501c373916e292764400dbae735f44b33378400fMark Salyzyn return name; 337501c373916e292764400dbae735f44b33378400fMark Salyzyn } 33881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 339758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t newPid) { 3400eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (name && !fastcmp<strncmp>(name, "zygote", 6)) { 341aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn free(name); 342aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn name = NULL; 343aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn } 34481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(newPid); 34681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 34781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 34881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 349501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 350758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (getUid() != incomingUid) { 352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 35381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn free(name); 354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(element->getPid()); 35581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } else { 356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getPid()); 35781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 358758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 35981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 361501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string formatHeader(const std::string& name, log_id_t id) const; 362501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string format(const LogStatistics& stat, log_id_t id) const; 363344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn}; 364344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 36517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped { 36617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const pid_t tid; 367ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 36817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn uid_t uid; 369501c373916e292764400dbae735f44b33378400fMark Salyzyn char* name; 370501c373916e292764400dbae735f44b33378400fMark Salyzyn 371501c373916e292764400dbae735f44b33378400fMark Salyzyn TidEntry(pid_t tid, pid_t pid) 372501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(), 373501c373916e292764400dbae735f44b33378400fMark Salyzyn tid(tid), 374501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(pid), 375501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(android::pidToUid(tid)), 376501c373916e292764400dbae735f44b33378400fMark Salyzyn name(android::tidToName(tid)) { 377501c373916e292764400dbae735f44b33378400fMark Salyzyn } 378501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit TidEntry(LogBufferElement* element) 379501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 380501c373916e292764400dbae735f44b33378400fMark Salyzyn tid(element->getTid()), 381501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element->getPid()), 382501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element->getUid()), 383501c373916e292764400dbae735f44b33378400fMark Salyzyn name(android::tidToName(tid)) { 384501c373916e292764400dbae735f44b33378400fMark Salyzyn } 385501c373916e292764400dbae735f44b33378400fMark Salyzyn TidEntry(const TidEntry& element) 386501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 387501c373916e292764400dbae735f44b33378400fMark Salyzyn tid(element.tid), 388501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element.pid), 389501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element.uid), 390501c373916e292764400dbae735f44b33378400fMark Salyzyn name(element.name ? strdup(element.name) : NULL) { 391501c373916e292764400dbae735f44b33378400fMark Salyzyn } 392501c373916e292764400dbae735f44b33378400fMark Salyzyn ~TidEntry() { 393501c373916e292764400dbae735f44b33378400fMark Salyzyn free(name); 394501c373916e292764400dbae735f44b33378400fMark Salyzyn } 395501c373916e292764400dbae735f44b33378400fMark Salyzyn 396501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getKey() const { 397501c373916e292764400dbae735f44b33378400fMark Salyzyn return tid; 398501c373916e292764400dbae735f44b33378400fMark Salyzyn } 399501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getTid() const { 400501c373916e292764400dbae735f44b33378400fMark Salyzyn return getKey(); 401501c373916e292764400dbae735f44b33378400fMark Salyzyn } 402501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getPid() const { 403501c373916e292764400dbae735f44b33378400fMark Salyzyn return pid; 404501c373916e292764400dbae735f44b33378400fMark Salyzyn } 405501c373916e292764400dbae735f44b33378400fMark Salyzyn const uid_t& getUid() const { 406501c373916e292764400dbae735f44b33378400fMark Salyzyn return uid; 407501c373916e292764400dbae735f44b33378400fMark Salyzyn } 408501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* getName() const { 409501c373916e292764400dbae735f44b33378400fMark Salyzyn return name; 410501c373916e292764400dbae735f44b33378400fMark Salyzyn } 41117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 412758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t incomingTid) { 4130eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (name && !fastcmp<strncmp>(name, "zygote", 6)) { 41417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 41517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn name = NULL; 41617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 41717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn if (!name) { 418758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(incomingTid); 41917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 42017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 42117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 422501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 423758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 424ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t incomingPid = element->getPid(); 425ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if ((getUid() != incomingUid) || (getPid() != incomingPid)) { 426758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 427ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = incomingPid; 42817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 429758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(element->getTid()); 43017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } else { 431758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getTid()); 43217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 433758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 43417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 435758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 436501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string formatHeader(const std::string& name, log_id_t id) const; 437501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string format(const LogStatistics& stat, log_id_t id) const; 43817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn}; 43917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 4406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynstruct TagEntry : public EntryBaseDropped { 441344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uint32_t tag; 442ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid; 443344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid_t uid; 444344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 445501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit TagEntry(LogBufferElement* element) 446501c373916e292764400dbae735f44b33378400fMark Salyzyn : EntryBaseDropped(element), 447501c373916e292764400dbae735f44b33378400fMark Salyzyn tag(element->getTag()), 448501c373916e292764400dbae735f44b33378400fMark Salyzyn pid(element->getPid()), 449501c373916e292764400dbae735f44b33378400fMark Salyzyn uid(element->getUid()) { 450758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 451344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 452501c373916e292764400dbae735f44b33378400fMark Salyzyn const uint32_t& getKey() const { 453501c373916e292764400dbae735f44b33378400fMark Salyzyn return tag; 454501c373916e292764400dbae735f44b33378400fMark Salyzyn } 455501c373916e292764400dbae735f44b33378400fMark Salyzyn const pid_t& getPid() const { 456501c373916e292764400dbae735f44b33378400fMark Salyzyn return pid; 457501c373916e292764400dbae735f44b33378400fMark Salyzyn } 458501c373916e292764400dbae735f44b33378400fMark Salyzyn const uid_t& getUid() const { 459501c373916e292764400dbae735f44b33378400fMark Salyzyn return uid; 460501c373916e292764400dbae735f44b33378400fMark Salyzyn } 461501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* getName() const { 462501c373916e292764400dbae735f44b33378400fMark Salyzyn return android::tagToName(tag); 463501c373916e292764400dbae735f44b33378400fMark Salyzyn } 46481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 465501c373916e292764400dbae735f44b33378400fMark Salyzyn inline void add(LogBufferElement* element) { 466ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (uid != element->getUid()) { 467344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid = -1; 468344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 469ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn if (pid != element->getPid()) { 470ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid = -1; 471ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn } 472a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn EntryBaseDropped::add(element); 473344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 474758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 475501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string formatHeader(const std::string& name, log_id_t id) const; 476501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string format(const LogStatistics& stat, log_id_t id) const; 477720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 478720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 4796a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyntemplate <typename TEntry> 4806a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynclass LogFindWorst { 481501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const TEntry* []> sorted; 4826a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 483501c373916e292764400dbae735f44b33378400fMark Salyzyn public: 484501c373916e292764400dbae735f44b33378400fMark Salyzyn explicit LogFindWorst(std::unique_ptr<const TEntry* []>&& sorted) 485501c373916e292764400dbae735f44b33378400fMark Salyzyn : sorted(std::move(sorted)) { 486501c373916e292764400dbae735f44b33378400fMark Salyzyn } 4876a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 488501c373916e292764400dbae735f44b33378400fMark Salyzyn void findWorst(int& worst, size_t& worst_sizes, size_t& second_worst_sizes, 489501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t threshold) { 4906a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (sorted.get() && sorted[0] && sorted[1]) { 4916a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst_sizes = sorted[0]->getSizes(); 4926a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if ((worst_sizes > threshold) 4936a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn // Allow time horizon to extend roughly tenfold, assume 4946a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn // average entry length is 100 characters. 495501c373916e292764400dbae735f44b33378400fMark Salyzyn && (worst_sizes > (10 * sorted[0]->getDropped()))) { 4966a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst = sorted[0]->getKey(); 4976a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn second_worst_sizes = sorted[1]->getSizes(); 4986a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (second_worst_sizes < threshold) { 4996a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn second_worst_sizes = threshold; 5006a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5016a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5026a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5036a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5046a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 505501c373916e292764400dbae735f44b33378400fMark Salyzyn void findWorst(int& worst, size_t worst_sizes, size_t& second_worst_sizes) { 5066a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (sorted.get() && sorted[0] && sorted[1]) { 5076a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn worst = sorted[0]->getKey(); 508501c373916e292764400dbae735f44b33378400fMark Salyzyn second_worst_sizes = 509501c373916e292764400dbae735f44b33378400fMark Salyzyn worst_sizes - sorted[0]->getSizes() + sorted[1]->getSizes(); 5106a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5116a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 5126a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn}; 5136a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 51434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics 51534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics { 516c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn friend UidEntry; 517c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn 51834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mSizes[LOG_ID_MAX]; 51934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mElements[LOG_ID_MAX]; 52058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t mDroppedElements[LOG_ID_MAX]; 52197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mSizesTotal[LOG_ID_MAX]; 52297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mElementsTotal[LOG_ID_MAX]; 5233296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn static size_t SizesTotal; 524720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn bool enable; 52534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 52697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // uid to size list 527720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<uid_t, UidEntry> uidTable_t; 52897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn uidTable_t uidTable[LOG_ID_MAX]; 529e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 530bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn // pid of system to size list 531bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t; 532bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable_t pidSystemTable[LOG_ID_MAX]; 533bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 534720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // pid to uid list 535720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<pid_t, PidEntry> pidTable_t; 536720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn pidTable_t pidTable; 537720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 53817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn // tid to uid list 53917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn typedef LogHashtable<pid_t, TidEntry> tidTable_t; 54017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn tidTable_t tidTable; 54117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 542344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn // tag list 543344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn typedef LogHashtable<uint32_t, TagEntry> tagTable_t; 544344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn tagTable_t tagTable; 545344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 546083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn // security tag list 547083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable_t securityTagTable; 548083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn 5496d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t sizeOf() const { 5506d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() + 551b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn tagTable.sizeOf() + securityTagTable.sizeOf() + 552b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (pidTable.size() * sizeof(pidTable_t::iterator)) + 553b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn (tagTable.size() * sizeof(tagTable_t::iterator)); 554501c373916e292764400dbae735f44b33378400fMark Salyzyn for (auto it : pidTable) { 5556d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn const char* name = it.second.getName(); 5566d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (name) size += strlen(name) + 1; 5576d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 558501c373916e292764400dbae735f44b33378400fMark Salyzyn for (auto it : tidTable) { 5596d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn const char* name = it.second.getName(); 5606d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn if (name) size += strlen(name) + 1; 5616d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5626d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn log_id_for_each(id) { 5636d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size += uidTable[id].sizeOf(); 564b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn size += uidTable[id].size() * sizeof(uidTable_t::iterator); 5656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn size += pidSystemTable[id].sizeOf(); 566501c373916e292764400dbae735f44b33378400fMark Salyzyn size += 567501c373916e292764400dbae735f44b33378400fMark Salyzyn pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator); 5686d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5696d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn return size; 5706d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn } 5716d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn 572501c373916e292764400dbae735f44b33378400fMark Salyzyn public: 57334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn LogStatistics(); 57434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 575501c373916e292764400dbae735f44b33378400fMark Salyzyn void enableStatistics() { 576501c373916e292764400dbae735f44b33378400fMark Salyzyn enable = true; 577501c373916e292764400dbae735f44b33378400fMark Salyzyn } 57834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 579501c373916e292764400dbae735f44b33378400fMark Salyzyn void add(LogBufferElement* entry); 580501c373916e292764400dbae735f44b33378400fMark Salyzyn void subtract(LogBufferElement* entry); 581ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn // entry->setDropped(1) must follow this call 582501c373916e292764400dbae735f44b33378400fMark Salyzyn void drop(LogBufferElement* entry); 583aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn // Correct for coalescing two entries referencing dropped content 584501c373916e292764400dbae735f44b33378400fMark Salyzyn void erase(LogBufferElement* element) { 58558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn log_id_t log_id = element->getLogId(); 58658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mElements[log_id]; 58758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mDroppedElements[log_id]; 58858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 589e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 5906a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { 5916a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); 5926a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 593501c373916e292764400dbae735f44b33378400fMark Salyzyn LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, 594501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id id) { 5956a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); 596758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 5976a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { 5986a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len)); 599bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 60034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 60134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn // fast track current value by id only 602501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t sizes(log_id_t id) const { 603501c373916e292764400dbae735f44b33378400fMark Salyzyn return mSizes[id]; 604501c373916e292764400dbae735f44b33378400fMark Salyzyn } 605501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t elements(log_id_t id) const { 606501c373916e292764400dbae735f44b33378400fMark Salyzyn return mElements[id]; 607501c373916e292764400dbae735f44b33378400fMark Salyzyn } 60858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t realElements(log_id_t id) const { 60958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn return mElements[id] - mDroppedElements[id]; 61058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 611501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t sizesTotal(log_id_t id) const { 612501c373916e292764400dbae735f44b33378400fMark Salyzyn return mSizesTotal[id]; 613501c373916e292764400dbae735f44b33378400fMark Salyzyn } 614501c373916e292764400dbae735f44b33378400fMark Salyzyn size_t elementsTotal(log_id_t id) const { 615501c373916e292764400dbae735f44b33378400fMark Salyzyn return mElementsTotal[id]; 616501c373916e292764400dbae735f44b33378400fMark Salyzyn } 617501c373916e292764400dbae735f44b33378400fMark Salyzyn static size_t sizesTotal() { 618501c373916e292764400dbae735f44b33378400fMark Salyzyn return SizesTotal; 619501c373916e292764400dbae735f44b33378400fMark Salyzyn } 62034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 621ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::string format(uid_t uid, pid_t pid, unsigned int logMask) const; 6229a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 623ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn // helper (must be locked directly or implicitly by mLogElementsLock) 624501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* pidToName(pid_t pid) const; 6254ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn uid_t pidToUid(pid_t pid); 626501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* uidToName(uid_t uid) const; 62734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 62834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 629501c373916e292764400dbae735f44b33378400fMark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__ 630