LogStatistics.cpp revision d966e226809bd446bb33651b71d7934887787c1d
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 179a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#include <fcntl.h> 18b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn#include <pwd.h> 1997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h> 2097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h> 21b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn#include <sys/types.h> 2297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h> 2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 249af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn#include <list> 259af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 26aeaaf81c2cc8366ac4f66eb3d2fc85f9b8194982Mark Salyzyn#include <android/log.h> 2734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 2834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h" 2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 307718778793b106498b931dd708a466cf3a6f6a0fMark SalyzynLogStatistics::LogStatistics() : enable(false) { 3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[id] = 0; 3397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElements[id] = 0; 3458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn mDroppedElements[id] = 0; 3597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[id] = 0; 3697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElementsTotal[id] = 0; 3734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 3834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 3934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 41720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 4297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 4381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynchar *pidToName(pid_t pid) { 449a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char *retval = NULL; 45ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (pid == 0) { // special case from auditd/klogd for kernel 46ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn retval = strdup("logd"); 4797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } else { 489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char buffer[512]; 499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); 509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn int fd = open(buffer, O_RDONLY); 519a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (fd >= 0) { 529a03863e88da99ba010342c874252089dd771f7fMark Salyzyn ssize_t ret = read(fd, buffer, sizeof(buffer)); 539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (ret > 0) { 549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn buffer[sizeof(buffer)-1] = '\0'; 559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn // frameworks intermediate state 560eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { 579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn retval = strdup(buffer); 589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 609a03863e88da99ba010342c874252089dd771f7fMark Salyzyn close(fd); 619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 629a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 639a03863e88da99ba010342c874252089dd771f7fMark Salyzyn return retval; 649a03863e88da99ba010342c874252089dd771f7fMark Salyzyn} 659a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 66720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 67720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 68758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::add(LogBufferElement *element) { 69758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 70758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 7197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] += size; 7297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElements[log_id]; 7334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 74a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn if (element->getDropped()) { 75a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn ++mDroppedElements[log_id]; 76a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn } else { 77a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // When caller adding a chatty entry, they will have already 78a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // called add() and subtract() for each entry as they are 79a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // evaluated and trimmed, thus recording size and number of 80a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // elements, but we must recognize the manufactured dropped 81a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // entry as not contributing to the lifetime totals. 82a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn mSizesTotal[log_id] += size; 83a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn ++mElementsTotal[log_id]; 84a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn } 85720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 86ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 87ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 88ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 89ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 90758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].add(element->getUid(), element); 91bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 92bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].add(element->getPid(), element); 93bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 94ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 95720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 96720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 97720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 98720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 99758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.add(element->getPid(), element); 100758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.add(element->getTid(), element); 101344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 102758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 103344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 104083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (log_id == LOG_ID_SECURITY) { 105083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn securityTagTable.add(tag, element); 106083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } else { 107083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable.add(tag, element); 108083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 109344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 11034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 11134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 112758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::subtract(LogBufferElement *element) { 113758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 114758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 11597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] -= size; 11697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn --mElements[log_id]; 11758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn if (element->getDropped()) { 11858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mDroppedElements[log_id]; 11958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 12034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 121ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 122ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 123ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 124ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 125758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].subtract(element->getUid(), element); 126bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 127bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].subtract(element->getPid(), element); 128bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 12934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 130720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 131720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 13234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 13334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.subtract(element->getPid(), element); 135758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.subtract(element->getTid(), element); 136344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 137758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 138344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 139083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (log_id == LOG_ID_SECURITY) { 140083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn securityTagTable.subtract(tag, element); 141083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } else { 142083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable.subtract(tag, element); 143083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 144344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 145c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn} 146c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 147ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop 148ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly. 149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::drop(LogBufferElement *element) { 150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 152ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn mSizes[log_id] -= size; 15358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn ++mDroppedElements[log_id]; 154ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].drop(element->getUid(), element); 156bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 157bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].drop(element->getPid(), element); 158bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 159ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 160ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (!enable) { 161ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn return; 162ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 163ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.drop(element->getPid(), element); 165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.drop(element->getTid(), element); 1666a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 1676a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn uint32_t tag = element->getTag(); 1686a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (tag) { 1696a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (log_id == LOG_ID_SECURITY) { 1706a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn securityTagTable.drop(tag, element); 1716a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } else { 1726a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn tagTable.drop(tag, element); 1736a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 1746a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 175ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn} 176ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 17797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::uidToName(uid_t uid) const { 17997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Local hard coded favourites 18097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (uid == AID_LOGD) { 18197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup("auditd"); 18234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 18334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 184b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // Android system 185b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (uid < AID_APP) { 186b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // in bionic, thread safe as long as we copy the results 187b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn struct passwd *pwd = getpwuid(uid); 188b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (pwd) { 189b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn return strdup(pwd->pw_name); 19034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 19134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 19234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 19308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn // Parse /data/system/packages.list 194dff44709cf462a3af7eb5770c90e3ada492295b7Jeff Sharkey uid_t userId = uid % AID_USER_OFFSET; 195758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *name = android::uidToName(userId); 196023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { 197023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); 198023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn } 19908739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (name) { 20008739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn return name; 20108739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 202720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 203b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // Android application 204b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (uid >= AID_APP) { 205b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn struct passwd *pwd = getpwuid(uid); 206b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (pwd) { 207b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn return strdup(pwd->pw_name); 208b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn } 209b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn } 210b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn 211720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // report uid -> pid(s) -> pidToName if unique 212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) { 213511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn const PidEntry &entry = it->second; 214720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 215720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (entry.getUid() == uid) { 216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = entry.getName(); 217720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 219720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!name) { 220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = strdup(nameTmp); 2210eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn } else if (fastcmp<strcmp>(name, nameTmp)) { 222758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(name)); 223023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = NULL; 224023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn break; 225720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 226720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 227720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 228720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 229720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 23097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // No one 231720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return name; 23234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 23334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 234758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string UidEntry::formatHeader(const std::string &name, log_id_t id) const { 235758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 236758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(android::base::StringPrintf( 237758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name.c_str(), android_log_id_to_name(id)), 238758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 239c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn std::string(isprune ? "+/- Pruned" : "")) 240758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string("UID PACKAGE"), 241758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "NUM" : "")); 243758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 245c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzynstd::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { 246ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn uid_t uid = getUid(); 247758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name = android::base::StringPrintf("%u", uid); 248758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = stat.uidToName(uid); 249758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 250758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 251758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(6 - name.length(), (size_t)1), 252758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 253758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 254758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 257758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 259c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (worstUidEnabledForLogid(id)) { 260c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalDropped = 0; 261c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin(); 262c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn it != stat.uidTable[id].end(); ++it) { 263c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn totalDropped += it->second.getDropped(); 264c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 265c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t sizes = stat.sizes(id); 266c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalSize = stat.sizesTotal(id); 267c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalElements = stat.elementsTotal(id); 268c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn float totalVirtualSize = (float)sizes + (float)totalDropped * totalSize 269c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn / totalElements; 270c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t entrySize = getSizes(); 271c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn float virtualEntrySize = entrySize; 272c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn int realPermille = virtualEntrySize * 1000.0 / sizes; 273c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t dropped = getDropped(); 274c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (dropped) { 275c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 276c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn virtualEntrySize += (float)dropped * totalSize / totalElements; 277c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 278c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; 279c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn int permille = (realPermille - virtualPermille) * 1000L 280c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn / (virtualPermille ?: 1); 281c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((permille < -1) || (1 < permille)) { 282c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn std::string change; 283c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn const char *units = "%"; 284c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn const char *prefix = (permille > 0) ? "+" : ""; 285c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn 286c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (permille > 999) { 287c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn permille = (permille + 1000) / 100; // Now tenths fold 288c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn units = "X"; 289c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn prefix = ""; 290c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 291c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((-99 < permille) && (permille < 99)) { 292c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn change = android::base::StringPrintf("%s%d.%u%s", 293c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn prefix, 294c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn permille / 10, 295c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn ((permille < 0) ? (-permille % 10) : (permille % 10)), 296c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn units); 297c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } else { 298c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn change = android::base::StringPrintf("%s%d%s", 299c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn prefix, 300c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn (permille + 5) / 10, units); 301c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 302c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn ssize_t spaces = EntryBaseConstants::pruned_len 303c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn - 2 - pruned.length() - change.length(); 304c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((spaces <= 0) && pruned.length()) { 305c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn spaces = 1; 306c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 307d966e226809bd446bb33651b71d7934887787c1dMark Salyzyn if (spaces > 0) { 308c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn change += android::base::StringPrintf("%*s", (int)spaces, ""); 309c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 310c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn pruned = change + pruned; 311c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 312758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 313758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 314bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string output = formatLine(name, size, pruned); 315bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 316bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (uid != AID_SYSTEM) { 317bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 318bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 319bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 320bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn static const size_t maximum_sorted_entries = 32; 321bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::unique_ptr<const PidEntry *[]> sorted 322bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn = stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); 323bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 324bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (!sorted.get()) { 325bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 326bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 327bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string byPid; 328bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn size_t index; 329bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn bool hasDropped = false; 330bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn for (index = 0; index < maximum_sorted_entries; ++index) { 331bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn const PidEntry *entry = sorted[index]; 332bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (!entry) { 333bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn break; 334bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 335bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (entry->getSizes() <= (getSizes() / 100)) { 336bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn break; 337bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 338bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (entry->getDropped()) { 339bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn hasDropped = true; 340bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 341bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn byPid += entry->format(stat, id); 342bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 343bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (index > 1) { // print this only if interesting 344bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string ditto("\" "); 345bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn output += formatLine(std::string(" PID/UID COMMAND LINE"), 346bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn ditto, hasDropped ? ditto : std::string("")); 347bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn output += byPid; 348bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 349bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 350bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Pruned")) 357758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" PID/UID COMMAND LINE"), 358758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("NUM")); 360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 362758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 363758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 364ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid = getPid(); 365ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", pid, uid); 366758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = getName(); 367758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 369758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 371758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else if ((nameTmp = stat.uidToName(uid))) { 372758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 373758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 374758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 375758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 376758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 377758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 378758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 379758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 380758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 381758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 382758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 383758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 384758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 385758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 386758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 387758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 388758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 389758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 390758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 391758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 392758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 393758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Pruned")) 394758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" TID/UID COMM"), 395758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 396758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("NUM")); 397758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 398758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 399758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 400758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 401758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", 402ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn getTid(), uid); 403758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = getName(); 404758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 405758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 406758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 407758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 408758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else if ((nameTmp = stat.uidToName(uid))) { 409758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // if we do not have a PID name, lets punt to try UID name? 410758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 411758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 412758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 413758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 414758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // We tried, better to not have a name at all, we still 415758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // have TID/UID by number to report in any case. 416758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 417758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 418758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 419758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 420758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 421758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 422758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 423758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 424758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 425758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 426758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 427758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 428758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 429758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 430758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::formatHeader(const std::string &name, log_id_t id) const { 431758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 432758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 433758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 434758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "Prune" : "")) 435758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" TAG/UID TAGNAME"), 436758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 437758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "NUM" : "")); 438758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 439758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 440758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const { 441758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 442758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 443758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (uid == (uid_t)-1) { 444758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::base::StringPrintf("%7u", 445758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey()); 446ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } else { 447758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::base::StringPrintf("%7u/%u", 448758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey(), uid); 449ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 450807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn size_t len = 0; 451807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn const char *nameTmp = getName(len); 452758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 453758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 454807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn "%*s%.*s", (int)std::max(14 - name.length(), (size_t)1), 455807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn "", (int)len, nameTmp); 456758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 457758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 458758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 459758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 460758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 461758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 4626a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn size_t dropped = getDropped(); 4636a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (dropped) { 4646a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 4656a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 466758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 467758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 46834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 46934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 470ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzynstd::string LogStatistics::format(uid_t uid, pid_t pid, 471ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn unsigned int logMask) const { 4729a03863e88da99ba010342c874252089dd771f7fMark Salyzyn static const unsigned short spaces_total = 19; 47334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 47497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on total logging, current and for all time 47597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 476decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn std::string output = "size/num"; 47734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t oldLength; 47897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn short spaces = 1; 47934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 48097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 4819af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 48297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 4839af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 484decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn output += android::base::StringPrintf("%*s%s", spaces, "", 485decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn android_log_id_to_name(id)); 48697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 48797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } 4889af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 4899af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*sTotal", spaces, ""); 490c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 4919af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char TotalStr[] = "\nTotal"; 4929af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(TotalStr); 4939af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += TotalStr; 494c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 4959af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t totalSize = 0; 4969af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t totalEls = 0; 49797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 4989af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 49997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 5009af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5019af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizesTotal(id); 5029af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 5039af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t els = elementsTotal(id); 5049af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls += els; 5059af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); 50697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 50734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 5089af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5099af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); 51034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 5119af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char NowStr[] = "\nNow"; 5129af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(NowStr); 5139af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += NowStr; 51434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 5159af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize = 0; 5169af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls = 0; 51797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 5189af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 5199af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5209af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t els = elements(id); 5219af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (els) { 5229af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn oldLength = output.length(); 5239af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5249af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizes(id); 5259af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 5269af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls += els; 5279af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); 5289af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces -= output.length() - oldLength; 52934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 5309af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces += spaces_total; 5319af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn } 5329af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5339af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); 5349af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5359af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char OverheadStr[] = "\nOverhead"; 5369af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(OverheadStr); 5379af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += OverheadStr; 5389af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5399af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize = 0; 5409af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn log_id_for_each(id) { 5419af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 54234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 54397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t els = elements(id); 54434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (els) { 54597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 5469af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5479af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn // estimate the std::list overhead. 5489af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const size_t overhead = 5499af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & 5509af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn -sizeof(uint64_t)) + 5519af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn sizeof(std::list<LogBufferElement*>); 5529af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizes(id) + els * overhead; 5539af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 5549af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu", spaces, "", szs); 55597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces -= output.length() - oldLength; 55634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 55734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn spaces += spaces_total; 55834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 5596d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn totalSize += sizeOf(); 5609af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5619af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize); 56234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 56397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on Chattiest 5648e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 565758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 566758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 56797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Chattiest by application (UID) 56897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 5699af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 5708e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 571758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = (uid == AID_ROOT) 572758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ? "Chattiest UIDs in %s log buffer:" 573758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn : "Logging for your UID in %s log buffer:"; 574ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += uidTable[id].format(*this, uid, pid, name, id); 575720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 57697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 577720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (enable) { 578ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = ((uid == AID_ROOT) && !pid) 579ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn ? "Chattiest PIDs:" 580ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn : "Logging for this PID:"; 581ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += pidTable.format(*this, uid, pid, name); 582ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest TIDs"; 5839af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 584ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 585ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += tidTable.format(*this, uid, pid, name); 58617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 58717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 588344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (enable && (logMask & (1 << LOG_ID_EVENTS))) { 589ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest events log buffer TAGs"; 5909af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 591ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 592ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS); 593344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 594344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 595083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (enable && (logMask & (1 << LOG_ID_SECURITY))) { 596ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest security log buffer TAGs"; 5979af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 598ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 599ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); 600083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 601083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn 60273160acc5cb5236b30327569e6b51dbfe73e4a0fMark Salyzyn return output; 60334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 6044ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn 605720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 606720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 607720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) { 60897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn char buffer[512]; 60997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); 61097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn FILE *fp = fopen(buffer, "r"); 61197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (fp) { 61297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn while (fgets(buffer, sizeof(buffer), fp)) { 61397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn int uid; 614c32afdf913f082235b1e66f5a57678c7f0723129Mark Salyzyn if (sscanf(buffer, "Uid: %d", &uid) == 1) { 61597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 61697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return uid; 6174ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 6184ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 61997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 6204ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 621e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn return AID_LOGD; // associate this with the logger 6224ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn} 623720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 624720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 625720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 626720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) { 627511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return pidTable.add(pid)->second.getUid(); 628720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 629720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 630720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string 631758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::pidToName(pid_t pid) const { 632758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // An inconvenient truth ... getName() can alter the object 633758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable); 634758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *name = writablePidTable.add(pid)->second.getName(); 63581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 63681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return NULL; 637720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 63881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return strdup(name); 639720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 640