LogStatistics.cpp revision 81b3eabc49736b89c4f99940f79785074955eaa5
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 1797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <algorithm> // std::max 189a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#include <fcntl.h> 1997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h> 2097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h> 2197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h> 2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/logger.h> 2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <private/android_filesystem_config.h> 2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <utils/String8.h> 2634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 2734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h" 2834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 29720f6d1d55d936d98cc9752e96f479e03e6d5009Mark SalyzynLogStatistics::LogStatistics() 30720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn : enable(false) { 3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[id] = 0; 3397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElements[id] = 0; 3497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[id] = 0; 3597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElementsTotal[id] = 0; 3634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 3734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 3834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 39720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 4197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 4281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynchar *pidToName(pid_t pid) { 439a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char *retval = NULL; 44df5aa61f05ccbef441cf8b024d4bbc1b717451f9Mark Salyzyn if (pid == 0) { // special case from auditd for kernel 45df5aa61f05ccbef441cf8b024d4bbc1b717451f9Mark Salyzyn retval = strdup("logd.auditd"); 4697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } else { 479a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char buffer[512]; 489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); 499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn int fd = open(buffer, O_RDONLY); 509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (fd >= 0) { 519a03863e88da99ba010342c874252089dd771f7fMark Salyzyn ssize_t ret = read(fd, buffer, sizeof(buffer)); 529a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (ret > 0) { 539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn buffer[sizeof(buffer)-1] = '\0'; 549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn // frameworks intermediate state 559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (strcmp(buffer, "<pre-initialized>")) { 569a03863e88da99ba010342c874252089dd771f7fMark Salyzyn retval = strdup(buffer); 579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn close(fd); 609a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 629a03863e88da99ba010342c874252089dd771f7fMark Salyzyn return retval; 639a03863e88da99ba010342c874252089dd771f7fMark Salyzyn} 649a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 65720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 66720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 6797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::add(LogBufferElement *e) { 6897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_t log_id = e->getLogId(); 6997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn unsigned short size = e->getMsgLen(); 7097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] += size; 7197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElements[log_id]; 7234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 7381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn uidTable[log_id].add(e->getUid(), e); 74c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 7597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[log_id] += size; 7697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElementsTotal[log_id]; 77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 79720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 8281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn pidTable.add(e->getPid(), e); 8334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 8434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 8597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::subtract(LogBufferElement *e) { 8697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_t log_id = e->getLogId(); 8797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn unsigned short size = e->getMsgLen(); 8897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] -= size; 8997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn --mElements[log_id]; 9034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 9181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn uidTable[log_id].subtract(e->getUid(), e); 9234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 93720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 94720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 9534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 9634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 9781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn pidTable.subtract(e->getPid(), e); 98c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn} 99c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 100ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop 101ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly. 102ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzynvoid LogStatistics::drop(LogBufferElement *e) { 103ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn log_id_t log_id = e->getLogId(); 104ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn unsigned short size = e->getMsgLen(); 105ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn mSizes[log_id] -= size; 106ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 10781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn uidTable[log_id].drop(e->getUid(), e); 108ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 109ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (!enable) { 110ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn return; 111ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 112ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 11381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn pidTable.drop(e->getPid(), e); 114ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn} 115ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 11697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 11797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynchar *LogStatistics::uidToName(uid_t uid) { 11897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Local hard coded favourites 11997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (uid == AID_LOGD) { 12097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup("auditd"); 12134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 12234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 12397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Android hard coded 12497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn const struct android_id_info *info = android_ids; 12534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 12697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn for (size_t i = 0; i < android_id_count; ++i) { 12797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (info->aid == uid) { 12897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup(info->name); 12934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 13097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++info; 13134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 13234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 13308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn // Parse /data/system/packages.list 13408739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn char *name = android::uidToName(uid); 13508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (name) { 13608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn return name; 13708739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 138720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 139720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // report uid -> pid(s) -> pidToName if unique 140720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ssize_t index = -1; 141720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn while ((index = pidTable.next(index)) != -1) { 142720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const PidEntry &entry = pidTable.entryAt(index); 143720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 144720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (entry.getUid() == uid) { 145720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const char *n = entry.getName(); 146720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 147720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (n) { 148720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!name) { 149720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn name = strdup(n); 150720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } else if (strcmp(name, n)) { 151720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn free(name); 152720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return NULL; 153720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 154720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 155720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 156720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 157720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 15897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // No one 159720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return name; 16034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 16134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 16297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynstatic void format_line(android::String8 &output, 163ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 &name, android::String8 &size, android::String8 &pruned) { 164ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn static const size_t pruned_len = 6; 165ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn static const size_t total_len = 70 + pruned_len; 166ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 167ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn ssize_t drop_len = std::max(pruned.length() + 1, pruned_len); 168ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn ssize_t size_len = std::max(size.length() + 1, 169ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn total_len - name.length() - drop_len - 1); 170ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 171ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (pruned.length()) { 172ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn output.appendFormat("%s%*s%*s\n", name.string(), 173ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn (int)size_len, size.string(), 174ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn (int)drop_len, pruned.string()); 175ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } else { 176ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn output.appendFormat("%s%*s\n", name.string(), 177ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn (int)size_len, size.string()); 178ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 17934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 18034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 18197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) { 1829a03863e88da99ba010342c874252089dd771f7fMark Salyzyn static const unsigned short spaces_total = 19; 18334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 18434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (*buf) { 185239605ef64d34ced82c97870e3f3f5c4145be58cGreg Hackmann free(*buf); 18634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *buf = NULL; 18734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 18834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 18997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on total logging, current and for all time 19097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 19197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn android::String8 output("size/num"); 19234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t oldLength; 19397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn short spaces = 1; 19434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 19597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 19697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 197c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn continue; 198c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn } 19997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 200c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn if (spaces < 0) { 201c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn spaces = 0; 202c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn } 20397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id)); 20497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 20597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } 206c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 20797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 4; 20897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn output.appendFormat("\nTotal"); 209c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 21097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 21197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 21297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn continue; 21334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 21497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 21597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (spaces < 0) { 21697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 0; 217e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn } 21897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn output.appendFormat("%*s%zu/%zu", spaces, "", 21997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn sizesTotal(id), elementsTotal(id)); 22097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 22134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 22234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 22397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 6; 22497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn output.appendFormat("\nNow"); 22534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 22697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 22797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 22834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn continue; 22934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 23034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 23197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t els = elements(id); 23234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (els) { 23397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 234e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn if (spaces < 0) { 235e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn spaces = 0; 236e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn } 23797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els); 23897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces -= output.length() - oldLength; 23934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 24034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn spaces += spaces_total; 24134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 24234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 24397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on Chattiest 2448e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 24597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Chattiest by application (UID) 246720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn static const size_t maximum_sorted_entries = 32; 24797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 24897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 2498e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn continue; 2508e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn } 2518e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 252720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn bool headerPrinted = false; 253720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id); 254720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ssize_t index = -1; 255720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) { 25697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn const UidEntry *entry = sorted[index]; 25797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn uid_t u = entry->getKey(); 25897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if ((uid != AID_ROOT) && (u != uid)) { 25934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn continue; 26034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 26134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 262720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!headerPrinted) { 2635720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn output.appendFormat("\n\n"); 2645720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn android::String8 name(""); 26597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (uid == AID_ROOT) { 2665720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.appendFormat( 2675720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn "Chattiest UIDs in %s log buffer:", 26897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn android_log_id_to_name(id)); 26997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } else { 2705720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.appendFormat( 2715720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn "Logging for your UID in %s log buffer:", 27297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn android_log_id_to_name(id)); 273e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn } 274ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 size("Size"); 275ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 pruned("Pruned"); 276ae769238391f7f9fa5c03a436d5f1fd73130e6bdMark Salyzyn if (!worstUidEnabledForLogid(id)) { 277ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn pruned.setTo(""); 278ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 279ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn format_line(output, name, size, pruned); 2805720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn 2815720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.setTo("UID PACKAGE"); 2825720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn size.setTo("BYTES"); 2835720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn pruned.setTo("LINES"); 2845720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn if (!worstUidEnabledForLogid(id)) { 2855720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn pruned.setTo(""); 2865720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn } 2875720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn format_line(output, name, size, pruned); 2885720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn 289720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn headerPrinted = true; 29034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 29134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 29297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn android::String8 name(""); 29397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn name.appendFormat("%u", u); 29497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn char *n = uidToName(u); 29597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (n) { 29697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n); 29797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn free(n); 29834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 29934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 30097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn android::String8 size(""); 301720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn size.appendFormat("%zu", entry->getSizes()); 30234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 303ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 pruned(""); 304ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn size_t dropped = entry->getDropped(); 305ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (dropped) { 306ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn pruned.appendFormat("%zu", dropped); 307ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 308ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 309ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn format_line(output, name, size, pruned); 31034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 311720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 31297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 313720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (enable) { 31481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn // Pid table 315720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn bool headerPrinted = false; 316720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries); 317720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn ssize_t index = -1; 318720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) { 319720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const PidEntry *entry = sorted[index]; 320720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn uid_t u = entry->getUid(); 321720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if ((uid != AID_ROOT) && (u != uid)) { 322720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn continue; 323720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 324720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 325720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!headerPrinted) { 3265720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn output.appendFormat("\n\n"); 3275720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn android::String8 name(""); 328720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (uid == AID_ROOT) { 3295720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.appendFormat("Chattiest PIDs:"); 330720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } else { 3315720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.appendFormat("Logging for this PID:"); 332720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 333720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn android::String8 size("Size"); 334ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 pruned("Pruned"); 335ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn format_line(output, name, size, pruned); 3365720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn 3375720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn name.setTo(" PID/UID COMMAND LINE"); 3385720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn size.setTo("BYTES"); 3395720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn pruned.setTo("LINES"); 3405720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn format_line(output, name, size, pruned); 3415720d2c168f17afb57eefb6ed762a120a24c8ecbMark Salyzyn 342720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn headerPrinted = true; 343720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 344720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 345720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn android::String8 name(""); 346720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn name.appendFormat("%5u/%u", entry->getKey(), u); 347720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn const char *n = entry->getName(); 348720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (n) { 349720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n); 350720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } else { 351720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn char *un = uidToName(u); 352720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (un) { 353720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un); 354720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn free(un); 355720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 356720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 357720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 358720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn android::String8 size(""); 359720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn size.appendFormat("%zu", entry->getSizes()); 360720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 361ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn android::String8 pruned(""); 362ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn size_t dropped = entry->getDropped(); 363ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (dropped) { 364ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn pruned.appendFormat("%zu", dropped); 365ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 366ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 367ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn format_line(output, name, size, pruned); 368720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 36934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 37034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 37197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn *buf = strdup(output.string()); 37234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 3734ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn 374720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 375720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 376720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) { 37797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn char buffer[512]; 37897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); 37997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn FILE *fp = fopen(buffer, "r"); 38097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (fp) { 38197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn while (fgets(buffer, sizeof(buffer), fp)) { 38297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn int uid; 383c32afdf913f082235b1e66f5a57678c7f0723129Mark Salyzyn if (sscanf(buffer, "Uid: %d", &uid) == 1) { 38497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 38597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return uid; 3864ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 3874ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 38897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 3894ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 390e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn return AID_LOGD; // associate this with the logger 3914ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn} 392720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 393720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 394720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 395720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) { 39681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return pidTable.entryAt(pidTable.add(pid)).getUid(); 397720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 398720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 399720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string 400720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynchar *LogStatistics::pidToName(pid_t pid) { 40181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn const char *name = pidTable.entryAt(pidTable.add(pid)).getName(); 40281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 40381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return NULL; 404720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 40581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return strdup(name); 406720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 407