LogStatistics.cpp revision f31ae3d666f6e723a7dde6734c6d8395f8bcdc11
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 303296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzynsize_t LogStatistics::SizesTotal; 313296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn 327718778793b106498b931dd708a466cf3a6f6a0fMark SalyzynLogStatistics::LogStatistics() : enable(false) { 3397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 3497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[id] = 0; 3597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElements[id] = 0; 3658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn mDroppedElements[id] = 0; 3797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[id] = 0; 3897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElementsTotal[id] = 0; 3934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 4034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 4134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 42720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 43720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 44501c373916e292764400dbae735f44b33378400fMark Salyzynsize_t sizesTotal() { 45501c373916e292764400dbae735f44b33378400fMark Salyzyn return LogStatistics::sizesTotal(); 46501c373916e292764400dbae735f44b33378400fMark Salyzyn} 473296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn 4897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 49501c373916e292764400dbae735f44b33378400fMark Salyzynchar* pidToName(pid_t pid) { 50501c373916e292764400dbae735f44b33378400fMark Salyzyn char* retval = NULL; 51501c373916e292764400dbae735f44b33378400fMark Salyzyn if (pid == 0) { // special case from auditd/klogd for kernel 52ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn retval = strdup("logd"); 5397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } else { 549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char buffer[512]; 559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); 569a03863e88da99ba010342c874252089dd771f7fMark Salyzyn int fd = open(buffer, O_RDONLY); 579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (fd >= 0) { 589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn ssize_t ret = read(fd, buffer, sizeof(buffer)); 599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (ret > 0) { 60501c373916e292764400dbae735f44b33378400fMark Salyzyn buffer[sizeof(buffer) - 1] = '\0'; 619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn // frameworks intermediate state 620eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { 639a03863e88da99ba010342c874252089dd771f7fMark Salyzyn retval = strdup(buffer); 649a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 659a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 669a03863e88da99ba010342c874252089dd771f7fMark Salyzyn close(fd); 679a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 689a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 699a03863e88da99ba010342c874252089dd771f7fMark Salyzyn return retval; 709a03863e88da99ba010342c874252089dd771f7fMark Salyzyn} 71720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 72720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 73501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::add(LogBufferElement* element) { 74758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 75758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 7697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] += size; 7797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElements[log_id]; 7834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 79a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn if (element->getDropped()) { 80a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn ++mDroppedElements[log_id]; 81a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn } else { 82a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // When caller adding a chatty entry, they will have already 83a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // called add() and subtract() for each entry as they are 84a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // evaluated and trimmed, thus recording size and number of 85a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // elements, but we must recognize the manufactured dropped 86a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn // entry as not contributing to the lifetime totals. 87a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn mSizesTotal[log_id] += size; 883296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn SizesTotal += size; 89a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn ++mElementsTotal[log_id]; 90a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn } 91720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 92ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 93ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 94ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 95ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 96758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].add(element->getUid(), element); 97bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 98bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].add(element->getPid(), element); 99bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 100ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 101720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 102720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 103720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 105758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.add(element->getPid(), element); 106758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.add(element->getTid(), element); 107344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 108758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 109344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 110083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (log_id == LOG_ID_SECURITY) { 111083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn securityTagTable.add(tag, element); 112083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } else { 113083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable.add(tag, element); 114083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 115344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 11634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 11734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 118501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::subtract(LogBufferElement* element) { 119758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 120758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 12197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] -= size; 12297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn --mElements[log_id]; 12358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn if (element->getDropped()) { 12458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn --mDroppedElements[log_id]; 12558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn } 12634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 127ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 128ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 129ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 130ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 131758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].subtract(element->getUid(), element); 132bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 133bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].subtract(element->getPid(), element); 134bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 13534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 136720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 137720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 13834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 13934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 140758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.subtract(element->getPid(), element); 141758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.subtract(element->getTid(), element); 142344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 143758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 144344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 145083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (log_id == LOG_ID_SECURITY) { 146083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn securityTagTable.subtract(tag, element); 147083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } else { 148083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn tagTable.subtract(tag, element); 149083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 150344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 151c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn} 152c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 153ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop 154ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly. 155501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::drop(LogBufferElement* element) { 156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 158ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn mSizes[log_id] -= size; 15958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn ++mDroppedElements[log_id]; 160ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].drop(element->getUid(), element); 162bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (element->getUid() == AID_SYSTEM) { 163bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn pidSystemTable[log_id].drop(element->getPid(), element); 164bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 165ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 166ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (!enable) { 167ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn return; 168ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 169ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.drop(element->getPid(), element); 171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.drop(element->getTid(), element); 1726a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn 1736a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn uint32_t tag = element->getTag(); 1746a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (tag) { 1756a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (log_id == LOG_ID_SECURITY) { 1766a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn securityTagTable.drop(tag, element); 1776a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } else { 1786a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn tagTable.drop(tag, element); 1796a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 1806a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 181ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn} 182ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 18397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 184501c373916e292764400dbae735f44b33378400fMark Salyzynconst char* LogStatistics::uidToName(uid_t uid) const { 18597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Local hard coded favourites 18697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (uid == AID_LOGD) { 18797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup("auditd"); 18834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 18934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 190b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // Android system 191b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (uid < AID_APP) { 192b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // in bionic, thread safe as long as we copy the results 193501c373916e292764400dbae735f44b33378400fMark Salyzyn struct passwd* pwd = getpwuid(uid); 194b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (pwd) { 195b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn return strdup(pwd->pw_name); 19634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 19734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 19834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 19908739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn // Parse /data/system/packages.list 200dff44709cf462a3af7eb5770c90e3ada492295b7Jeff Sharkey uid_t userId = uid % AID_USER_OFFSET; 201501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* name = android::uidToName(userId); 202023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { 203023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); 204023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn } 20508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (name) { 20608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn return name; 20708739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 208720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 209b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn // Android application 210b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (uid >= AID_APP) { 211501c373916e292764400dbae735f44b33378400fMark Salyzyn struct passwd* pwd = getpwuid(uid); 212b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn if (pwd) { 213b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn return strdup(pwd->pw_name); 214b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn } 215b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn } 216b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn 217720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // report uid -> pid(s) -> pidToName if unique 218501c373916e292764400dbae735f44b33378400fMark Salyzyn for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); 219501c373916e292764400dbae735f44b33378400fMark Salyzyn ++it) { 220501c373916e292764400dbae735f44b33378400fMark Salyzyn const PidEntry& entry = it->second; 221720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 222720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (entry.getUid() == uid) { 223501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* nameTmp = entry.getName(); 224720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 225758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 226720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!name) { 227758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = strdup(nameTmp); 2280eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn } else if (fastcmp<strcmp>(name, nameTmp)) { 229501c373916e292764400dbae735f44b33378400fMark Salyzyn free(const_cast<char*>(name)); 230023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = NULL; 231023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn break; 232720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 233720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 234720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 235720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 236720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 23797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // No one 238720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return name; 23934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 24034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 241501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string UidEntry::formatHeader(const std::string& name, log_id_t id) const { 242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 243501c373916e292764400dbae735f44b33378400fMark Salyzyn return formatLine(android::base::StringPrintf(name.c_str(), 244501c373916e292764400dbae735f44b33378400fMark Salyzyn android_log_id_to_name(id)), 245758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 246501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string(isprune ? "+/- Pruned" : "")) + 247501c373916e292764400dbae735f44b33378400fMark Salyzyn formatLine(std::string("UID PACKAGE"), std::string("BYTES"), 248758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "NUM" : "")); 249758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 250758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 251f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn// Helper to truncate name, if too long, and add name dressings 252f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzynstatic void formatTmp(const LogStatistics& stat, const char* nameTmp, uid_t uid, 253f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn std::string& name, std::string& size, size_t nameLen) { 254f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn const char* allocNameTmp = nullptr; 255f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn if (!nameTmp) nameTmp = allocNameTmp = stat.uidToName(uid); 256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 257f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn size_t lenSpace = std::max(nameLen - name.length(), (size_t)1); 258f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn size_t len = EntryBaseConstants::total_len - 259f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn EntryBaseConstants::pruned_len - size.length() - 260f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn name.length() - lenSpace - 2; 261f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn size_t lenNameTmp = strlen(nameTmp); 262f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn while ((len < lenNameTmp) && (lenSpace > 1)) { 263f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn ++len; 264f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn --lenSpace; 265f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn } 266f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn name += android::base::StringPrintf("%*s", (int)lenSpace, ""); 267f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn if (len < lenNameTmp) { 268f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn name += "..."; 269f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn nameTmp += lenNameTmp - std::max(len - 3, (size_t)1); 270f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn } 271f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn name += nameTmp; 272f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn free(const_cast<char*>(allocNameTmp)); 273758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 274f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn} 275758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 276f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzynstd::string UidEntry::format(const LogStatistics& stat, log_id_t id) const { 277f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn uid_t uid = getUid(); 278f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn std::string name = android::base::StringPrintf("%u", uid); 279758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 280758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 281f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn formatTmp(stat, nullptr, uid, name, size, 6); 282f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn 283758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 284c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (worstUidEnabledForLogid(id)) { 285c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalDropped = 0; 286501c373916e292764400dbae735f44b33378400fMark Salyzyn for (LogStatistics::uidTable_t::const_iterator it = 287501c373916e292764400dbae735f44b33378400fMark Salyzyn stat.uidTable[id].begin(); 288501c373916e292764400dbae735f44b33378400fMark Salyzyn it != stat.uidTable[id].end(); ++it) { 289c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn totalDropped += it->second.getDropped(); 290c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 291c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t sizes = stat.sizes(id); 292c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalSize = stat.sizesTotal(id); 293c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t totalElements = stat.elementsTotal(id); 294501c373916e292764400dbae735f44b33378400fMark Salyzyn float totalVirtualSize = 295501c373916e292764400dbae735f44b33378400fMark Salyzyn (float)sizes + (float)totalDropped * totalSize / totalElements; 296c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t entrySize = getSizes(); 297c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn float virtualEntrySize = entrySize; 298c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn int realPermille = virtualEntrySize * 1000.0 / sizes; 299c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn size_t dropped = getDropped(); 300c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (dropped) { 301c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 302c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn virtualEntrySize += (float)dropped * totalSize / totalElements; 303c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 304c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; 305501c373916e292764400dbae735f44b33378400fMark Salyzyn int permille = 306501c373916e292764400dbae735f44b33378400fMark Salyzyn (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1); 307c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((permille < -1) || (1 < permille)) { 308c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn std::string change; 309501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* units = "%"; 310501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* prefix = (permille > 0) ? "+" : ""; 311c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn 312c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if (permille > 999) { 313501c373916e292764400dbae735f44b33378400fMark Salyzyn permille = (permille + 1000) / 100; // Now tenths fold 314c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn units = "X"; 315c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn prefix = ""; 316c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 317c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((-99 < permille) && (permille < 99)) { 318501c373916e292764400dbae735f44b33378400fMark Salyzyn change = android::base::StringPrintf( 319501c373916e292764400dbae735f44b33378400fMark Salyzyn "%s%d.%u%s", prefix, permille / 10, 320c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn ((permille < 0) ? (-permille % 10) : (permille % 10)), 321c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn units); 322c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } else { 323501c373916e292764400dbae735f44b33378400fMark Salyzyn change = android::base::StringPrintf( 324501c373916e292764400dbae735f44b33378400fMark Salyzyn "%s%d%s", prefix, (permille + 5) / 10, units); 325c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 326501c373916e292764400dbae735f44b33378400fMark Salyzyn ssize_t spaces = EntryBaseConstants::pruned_len - 2 - 327501c373916e292764400dbae735f44b33378400fMark Salyzyn pruned.length() - change.length(); 328c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn if ((spaces <= 0) && pruned.length()) { 329c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn spaces = 1; 330c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 331d966e226809bd446bb33651b71d7934887787c1dMark Salyzyn if (spaces > 0) { 332c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn change += android::base::StringPrintf("%*s", (int)spaces, ""); 333c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 334c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn pruned = change + pruned; 335c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn } 336758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 337758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 338bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string output = formatLine(name, size, pruned); 339bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 340bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (uid != AID_SYSTEM) { 341bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 342bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 343bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 344bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn static const size_t maximum_sorted_entries = 32; 345501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<const PidEntry* []> sorted = 346501c373916e292764400dbae735f44b33378400fMark Salyzyn stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); 347bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 348bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (!sorted.get()) { 349bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 350bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 351bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string byPid; 352bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn size_t index; 353bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn bool hasDropped = false; 354bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn for (index = 0; index < maximum_sorted_entries; ++index) { 355501c373916e292764400dbae735f44b33378400fMark Salyzyn const PidEntry* entry = sorted[index]; 356bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (!entry) { 357bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn break; 358bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 359bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (entry->getSizes() <= (getSizes() / 100)) { 360bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn break; 361bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 362bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn if (entry->getDropped()) { 363bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn hasDropped = true; 364bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 365bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn byPid += entry->format(stat, id); 366bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 367501c373916e292764400dbae735f44b33378400fMark Salyzyn if (index > 1) { // print this only if interesting 368bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn std::string ditto("\" "); 369501c373916e292764400dbae735f44b33378400fMark Salyzyn output += formatLine(std::string(" PID/UID COMMAND LINE"), ditto, 370501c373916e292764400dbae735f44b33378400fMark Salyzyn hasDropped ? ditto : std::string("")); 371bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn output += byPid; 372bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn } 373bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn 374bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn return output; 375758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 376758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 377501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string PidEntry::formatHeader(const std::string& name, 378501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t /* id */) const { 379501c373916e292764400dbae735f44b33378400fMark Salyzyn return formatLine(name, std::string("Size"), std::string("Pruned")) + 380501c373916e292764400dbae735f44b33378400fMark Salyzyn formatLine(std::string(" PID/UID COMMAND LINE"), 381501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string("BYTES"), std::string("NUM")); 382758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 383758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 384501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string PidEntry::format(const LogStatistics& stat, 385501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t /* id */) const { 386758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 387ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn pid_t pid = getPid(); 388ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", pid, uid); 389501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 390758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 391f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn formatTmp(stat, getName(), uid, name, size, 12); 392f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn 393758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 394758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 395758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 396758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 397758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 398758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 399758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 400758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 401758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 402501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TidEntry::formatHeader(const std::string& name, 403501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t /* id */) const { 404501c373916e292764400dbae735f44b33378400fMark Salyzyn return formatLine(name, std::string("Size"), std::string("Pruned")) + 405501c373916e292764400dbae735f44b33378400fMark Salyzyn formatLine(std::string(" TID/UID COMM"), std::string("BYTES"), 406758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("NUM")); 407758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 408758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 409501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TidEntry::format(const LogStatistics& stat, 410501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t /* id */) const { 411758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 412501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid); 413501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 414758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 415f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn formatTmp(stat, getName(), uid, name, size, 12); 416f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn 417758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 418758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 419758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 420758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 421758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 422758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 423758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 424758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 425758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 426501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TagEntry::formatHeader(const std::string& name, log_id_t id) const { 427758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 428501c373916e292764400dbae735f44b33378400fMark Salyzyn return formatLine(name, std::string("Size"), 429501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string(isprune ? "Prune" : "")) + 430501c373916e292764400dbae735f44b33378400fMark Salyzyn formatLine(std::string(" TAG/UID TAGNAME"), 431501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string("BYTES"), std::string(isprune ? "NUM" : "")); 432758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 433758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 434501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TagEntry::format(const LogStatistics& /* stat */, 435501c373916e292764400dbae735f44b33378400fMark Salyzyn log_id_t /* id */) const { 436758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 437758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 438758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (uid == (uid_t)-1) { 439501c373916e292764400dbae735f44b33378400fMark Salyzyn name = android::base::StringPrintf("%7u", getKey()); 440ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } else { 441501c373916e292764400dbae735f44b33378400fMark Salyzyn name = android::base::StringPrintf("%7u/%u", getKey(), uid); 442ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 443501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* nameTmp = getName(); 444758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 445758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 446501c373916e292764400dbae735f44b33378400fMark Salyzyn "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp); 447758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 448758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 449501c373916e292764400dbae735f44b33378400fMark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 450758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 451758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 4526a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn size_t dropped = getDropped(); 4536a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn if (dropped) { 4546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 4556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn } 456758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 457758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 45834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 45934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 460ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzynstd::string LogStatistics::format(uid_t uid, pid_t pid, 461ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn unsigned int logMask) const { 4629a03863e88da99ba010342c874252089dd771f7fMark Salyzyn static const unsigned short spaces_total = 19; 46334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 46497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on total logging, current and for all time 46597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 466decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn std::string output = "size/num"; 46734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t oldLength; 46897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn short spaces = 1; 46934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 47097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 4719af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 47297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 4739af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 474decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn output += android::base::StringPrintf("%*s%s", spaces, "", 475decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn android_log_id_to_name(id)); 47697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 47797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } 4789af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 4799af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*sTotal", spaces, ""); 480c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 4819af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char TotalStr[] = "\nTotal"; 4829af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(TotalStr); 4839af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += TotalStr; 484c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 4859af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t totalSize = 0; 4869af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t totalEls = 0; 48797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 4889af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 48997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 4909af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 4919af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizesTotal(id); 4929af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 4939af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t els = elementsTotal(id); 4949af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls += els; 495501c373916e292764400dbae735f44b33378400fMark Salyzyn output += 496501c373916e292764400dbae735f44b33378400fMark Salyzyn android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); 49797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 49834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 4999af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 500501c373916e292764400dbae735f44b33378400fMark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, 501501c373916e292764400dbae735f44b33378400fMark Salyzyn totalEls); 50234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 5039af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char NowStr[] = "\nNow"; 5049af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(NowStr); 5059af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += NowStr; 50634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 5079af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize = 0; 5089af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls = 0; 50997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 5109af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 5119af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5129af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t els = elements(id); 5139af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (els) { 5149af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn oldLength = output.length(); 5159af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5169af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizes(id); 5179af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 5189af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalEls += els; 519501c373916e292764400dbae735f44b33378400fMark Salyzyn output += 520501c373916e292764400dbae735f44b33378400fMark Salyzyn android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); 5219af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces -= output.length() - oldLength; 52234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 5239af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces += spaces_total; 5249af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn } 5259af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 526501c373916e292764400dbae735f44b33378400fMark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, 527501c373916e292764400dbae735f44b33378400fMark Salyzyn totalEls); 5289af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5299af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const char OverheadStr[] = "\nOverhead"; 5309af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn spaces = 10 - strlen(OverheadStr); 5319af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += OverheadStr; 5329af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn 5339af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize = 0; 5349af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn log_id_for_each(id) { 5359af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 53634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 53797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t els = elements(id); 53834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (els) { 53997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 5409af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5419af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn // estimate the std::list overhead. 5429af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn static const size_t overhead = 5439af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & 544501c373916e292764400dbae735f44b33378400fMark Salyzyn -sizeof(uint64_t)) + 5459af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn sizeof(std::list<LogBufferElement*>); 5469af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn size_t szs = sizes(id) + els * overhead; 5479af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn totalSize += szs; 5489af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu", spaces, "", szs); 54997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces -= output.length() - oldLength; 55034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 55134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn spaces += spaces_total; 55234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 5536d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn totalSize += sizeOf(); 5549af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (spaces < 0) spaces = 0; 5559af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize); 55634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 55797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on Chattiest 5588e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 559758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 560758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 56197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Chattiest by application (UID) 56297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 5639af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (!(logMask & (1 << id))) continue; 5648e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 565501c373916e292764400dbae735f44b33378400fMark Salyzyn name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:" 566501c373916e292764400dbae735f44b33378400fMark Salyzyn : "Logging for your UID in %s log buffer:"; 567ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += uidTable[id].format(*this, uid, pid, name, id); 568720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 56997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 570720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (enable) { 571501c373916e292764400dbae735f44b33378400fMark Salyzyn name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:" 572501c373916e292764400dbae735f44b33378400fMark Salyzyn : "Logging for this PID:"; 573ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += pidTable.format(*this, uid, pid, name); 574ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest TIDs"; 5759af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 576ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 577ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += tidTable.format(*this, uid, pid, name); 57817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 57917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 580344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (enable && (logMask & (1 << LOG_ID_EVENTS))) { 581ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest events log buffer TAGs"; 5829af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 583ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 584ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS); 585344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 586344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 587083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (enable && (logMask & (1 << LOG_ID_SECURITY))) { 588ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name = "Chattiest security log buffer TAGs"; 5899af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn if (pid) name += android::base::StringPrintf(" for PID %d", pid); 590ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn name += ":"; 591501c373916e292764400dbae735f44b33378400fMark Salyzyn output += 592501c373916e292764400dbae735f44b33378400fMark Salyzyn securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); 593083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 594083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn 59573160acc5cb5236b30327569e6b51dbfe73e4a0fMark Salyzyn return output; 59634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 5974ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn 598720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 599720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 600720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) { 60197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn char buffer[512]; 60297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); 603501c373916e292764400dbae735f44b33378400fMark Salyzyn FILE* fp = fopen(buffer, "r"); 60497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (fp) { 60597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn while (fgets(buffer, sizeof(buffer), fp)) { 60697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn int uid; 607c32afdf913f082235b1e66f5a57678c7f0723129Mark Salyzyn if (sscanf(buffer, "Uid: %d", &uid) == 1) { 60897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 60997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return uid; 6104ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 6114ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 61297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 6134ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 614501c373916e292764400dbae735f44b33378400fMark Salyzyn return AID_LOGD; // associate this with the logger 6154ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn} 616720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 617720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 618720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) { 619511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return pidTable.add(pid)->second.getUid(); 620720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 621720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 622720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string 623501c373916e292764400dbae735f44b33378400fMark Salyzynconst char* LogStatistics::pidToName(pid_t pid) const { 624758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // An inconvenient truth ... getName() can alter the object 625501c373916e292764400dbae735f44b33378400fMark Salyzyn pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable); 626501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* name = writablePidTable.add(pid)->second.getName(); 62781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 62881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return NULL; 629720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 63081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return strdup(name); 631720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 632