LogStatistics.h revision c723df805a1a3199577cac947cebf2ab53abdb34
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 28758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <base/stringprintf.h> 2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/log.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) \ 3634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 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 45720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic: 46511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 47511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn typedef typename std::unordered_map<TKey, TEntry>::iterator iterator; 48758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator; 49511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn 50758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::unique_ptr<const TEntry *[]> sort(size_t len) const { 51758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!len) { 52720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const TEntry *[]> sorted(NULL); 53720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 54720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 55720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 56758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const TEntry **retval = new const TEntry* [len]; 57758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memset(retval, 0, sizeof(*retval) * len); 58720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 59758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for(const_iterator it = map.begin(); it != map.end(); ++it) { 60511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn const TEntry &entry = it->second; 61758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t sizes = entry.getSizes(); 62758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t index = len - 1; 63758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn while ((!retval[index] || (sizes > retval[index]->getSizes())) 64758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn && (--index >= 0)) 65720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ; 66758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (++index < (ssize_t)len) { 67758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t num = len - index - 1; 68758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (num) { 69758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn memmove(&retval[index + 1], &retval[index], 70758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn num * sizeof(retval[0])); 71720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 72758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn retval[index] = &entry; 73720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 74720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 75720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const TEntry *[]> sorted(retval); 76720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return sorted; 77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 79758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline iterator add(TKey key, LogBufferElement *element) { 80511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 81511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 82758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(element))).first; 83511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.add(element); 8581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 86511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 8781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 8881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 89511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator add(TKey key) { 90511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 91511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it == map.end()) { 92511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it = map.insert(std::make_pair(key, TEntry(key))).first; 93511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn } else { 94511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn it->second.add(key); 9581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 96511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return it; 9781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 9881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 99758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn void subtract(TKey key, LogBufferElement *element) { 100511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if ((it != map.end()) && it->second.subtract(element)) { 102511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn map.erase(it); 10381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 10481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 10581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 106758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void drop(TKey key, LogBufferElement *element) { 107511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn iterator it = map.find(key); 108511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn if (it != map.end()) { 109758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn it->second.drop(element); 11081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 11181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 11281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 113511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator begin() { return map.begin(); } 114758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline const_iterator begin() const { return map.begin(); } 115511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn inline iterator end() { return map.end(); } 116758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline const_iterator end() const { return map.end(); } 117758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 118758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format( 119758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const LogStatistics &stat, 120758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid, 121758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &name = std::string(""), 122758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t id = LOG_ID_MAX) const { 123758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static const size_t maximum_sorted_entries = 32; 124758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string output; 125758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::unique_ptr<const TEntry *[]> sorted = sort(maximum_sorted_entries); 126758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 127758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!sorted.get()) { 128758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 129758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 130758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool headerPrinted = false; 131758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for (size_t index = 0; index < maximum_sorted_entries; ++index) { 132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const TEntry *entry = sorted[index]; 133758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!entry) { 134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 135758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 136758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) { 137758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn break; 138758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 139758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if ((uid != AID_ROOT) && (uid != entry->getUid())) { 140758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn continue; 141758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 142758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (!headerPrinted) { 143758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += "\n\n"; 144758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->formatHeader(name, id); 145758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn headerPrinted = true; 146758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += entry->format(stat, id); 148758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return output; 150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 151720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 152720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants { 154758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static constexpr size_t pruned_len = 14; 155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static constexpr size_t total_len = 80; 156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 15881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase { 15997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t size; 16034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 16181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn EntryBase():size(0) { } 162758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase(LogBufferElement *element):size(element->getMsgLen()) { } 16334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 16497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t getSizes() const { return size; } 16581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 166758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { size += element->getMsgLen(); } 167758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline bool subtract(LogBufferElement *element) { 168758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size -= element->getMsgLen(); 169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return !size; 170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 172758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn static std::string formatLine( 173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &name, 174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &size, 175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const std::string &pruned) { 176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t drop_len = std::max(pruned.length() + 1, 177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseConstants::pruned_len); 178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ssize_t size_len = std::max(size.length() + 1, 179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseConstants::total_len 180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn - name.length() - drop_len - 1); 181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 182758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (pruned.length()) { 183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return android::base::StringPrintf("%s%*s%*s\n", name.c_str(), 184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)size_len, size.c_str(), 185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)drop_len, pruned.c_str()); 186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else { 187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return android::base::StringPrintf("%s%*s\n", name.c_str(), 188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn (int)size_len, size.c_str()); 189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 190758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 19181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 19281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 19381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase { 19481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn size_t dropped; 19581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 19681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn EntryBaseDropped():dropped(0) { } 197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(LogBufferElement *element): 198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase(element), 199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped(element->getDropped()){ 200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 20181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 202ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn size_t getDropped() const { return dropped; } 203ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped += element->getDropped(); 206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::add(element); 20781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline bool subtract(LogBufferElement *element) { 209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn dropped -= element->getDropped(); 210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return EntryBase::subtract(element) && !dropped; 21181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void drop(LogBufferElement *element) { 21381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn dropped += 1; 214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::subtract(element); 21581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 21681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}; 21781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 21881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped { 21981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn const uid_t uid; 22081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 221758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn UidEntry(LogBufferElement *element): 222758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 223758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()) { 224758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 22581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 22681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn inline const uid_t&getKey() const { return uid; } 227758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline const uid_t&getUid() const { return uid; } 228758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 229758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 23134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 23234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 23381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android { 23481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid); 23581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn} 23681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 23781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped { 238720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const pid_t pid; 239720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn uid_t uid; 240720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn char *name; 241720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn PidEntry(pid_t pid): 243758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(), 244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(pid), 245758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(android::pidToUid(pid)), 246758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::pidToName(pid)) { 247758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 248758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn PidEntry(LogBufferElement *element): 249758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 250758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(element->getPid()), 251758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()), 252758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::pidToName(pid)) { 253758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 254758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn PidEntry(const PidEntry &element): 255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pid(element.pid), 257758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element.uid), 258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(element.name ? strdup(element.name) : NULL) { 259758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 260720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ~PidEntry() { free(name); } 261720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 262720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const pid_t&getKey() const { return pid; } 263720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const uid_t&getUid() const { return uid; } 264720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const char*getName() const { return name; } 26581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 266758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t newPid) { 267ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn if (name && !fast<strncmp>(name, "zygote", 6)) { 268aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn free(name); 269aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn name = NULL; 270aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn } 27181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(newPid); 27381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 27481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 27581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 276758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 277758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 278758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (getUid() != incomingUid) { 279758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 28081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn free(name); 281758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::pidToName(element->getPid()); 28281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } else { 283758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getPid()); 28481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 28681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn } 287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 288758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 290344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn}; 291344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 29217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped { 29317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const pid_t tid; 29417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn uid_t uid; 29517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn char *name; 29617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn TidEntry(pid_t tid): 298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(), 299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(tid), 300758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(android::pidToUid(tid)), 301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::tidToName(tid)) { 302758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 303758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn TidEntry(LogBufferElement *element): 304758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 305758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(element->getTid()), 306758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()), 307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(android::tidToName(tid)) { 308758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 309758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn TidEntry(const TidEntry &element): 310758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped(element), 311758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tid(element.tid), 312758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element.uid), 313758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name(element.name ? strdup(element.name) : NULL) { 314758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 31517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn ~TidEntry() { free(name); } 31617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 31717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const pid_t&getKey() const { return tid; } 31817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const uid_t&getUid() const { return uid; } 31917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn const char*getName() const { return name; } 32017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(pid_t incomingTid) { 322ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn if (name && !fast<strncmp>(name, "zygote", 6)) { 32317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 32417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn name = NULL; 32517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 32617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn if (!name) { 327758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(incomingTid); 32817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 32917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 33017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 333758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (getUid() != incomingUid) { 334758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid = incomingUid; 33517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn free(name); 336758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::tidToName(element->getTid()); 33717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } else { 338758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn add(element->getTid()); 33917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 340758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBaseDropped::add(element); 34117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 342758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 343758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 344758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 34517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn}; 34617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 347344bff4391dd434dda501e812f18f524290c5a7cMark Salyzynstruct TagEntry : public EntryBase { 348344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uint32_t tag; 349344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid_t uid; 350344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn TagEntry(LogBufferElement *element): 352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase(element), 353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tag(element->getTag()), 354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid(element->getUid()) { 355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 356344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 357344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uint32_t&getKey() const { return tag; } 358344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const uid_t&getUid() const { return uid; } 359344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn const char*getName() const { return android::tagToName(tag); } 36081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn 361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn inline void add(LogBufferElement *element) { 362758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t incomingUid = element->getUid(); 363758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (uid != incomingUid) { 364344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn uid = -1; 365344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 366758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn EntryBase::add(element); 367344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 369758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string formatHeader(const std::string &name, log_id_t id) const; 370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(const LogStatistics &stat, log_id_t id) const; 371720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}; 372720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 37334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics 37434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics { 375c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn friend UidEntry; 376c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn 37734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mSizes[LOG_ID_MAX]; 37834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t mElements[LOG_ID_MAX]; 37958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t mDroppedElements[LOG_ID_MAX]; 38097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mSizesTotal[LOG_ID_MAX]; 38197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t mElementsTotal[LOG_ID_MAX]; 382720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn bool enable; 38334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 38497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // uid to size list 385720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<uid_t, UidEntry> uidTable_t; 38697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn uidTable_t uidTable[LOG_ID_MAX]; 387e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 388720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // pid to uid list 389720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn typedef LogHashtable<pid_t, PidEntry> pidTable_t; 390720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn pidTable_t pidTable; 391720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 39217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn // tid to uid list 39317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn typedef LogHashtable<pid_t, TidEntry> tidTable_t; 39417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn tidTable_t tidTable; 39517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 396344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn // tag list 397344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn typedef LogHashtable<uint32_t, TagEntry> tagTable_t; 398344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn tagTable_t tagTable; 399344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 40034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic: 40134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn LogStatistics(); 40234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 403720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn void enableStatistics() { enable = true; } 40434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 40597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn void add(LogBufferElement *entry); 40697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn void subtract(LogBufferElement *entry); 407ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn // entry->setDropped(1) must follow this call 408ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn void drop(LogBufferElement *entry); 409aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn // Correct for coalescing two entries referencing dropped content 41058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn void erase(LogBufferElement *element) { 41158b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn log_id_t log_id = element->getLogId(); 41258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mElements[log_id]; 41358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mDroppedElements[log_id]; 41458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 415e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 416758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::unique_ptr<const UidEntry *[]> sort(size_t len, log_id id) { 417758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return uidTable[id].sort(len); 418758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 41934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 42034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn // fast track current value by id only 42134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t sizes(log_id_t id) const { return mSizes[id]; } 42234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t elements(log_id_t id) const { return mElements[id]; } 42358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn size_t realElements(log_id_t id) const { 42458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn return mElements[id] - mDroppedElements[id]; 42558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 42697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; } 42797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; } 42834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 429758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string format(uid_t uid, unsigned int logMask) const; 4309a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 431ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn // helper (must be locked directly or implicitly by mLogElementsLock) 432758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *pidToName(pid_t pid) const; 4334ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn uid_t pidToUid(pid_t pid); 434758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *uidToName(uid_t uid) const; 43534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}; 43634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 43734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__ 438