LogStatistics.cpp revision ee3b838e13dc2140ac2051c1012d471effd0fd5f
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>
1897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h>
1997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h>
2097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h>
2134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/logger.h>
2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h"
2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
267718778793b106498b931dd708a466cf3a6f6a0fMark SalyzynLogStatistics::LogStatistics() : enable(false) {
2797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
2897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizes[id] = 0;
2997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElements[id] = 0;
3058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        mDroppedElements[id] = 0;
3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizesTotal[id] = 0;
3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElementsTotal[id] = 0;
3334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
3434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
3534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
36720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
37720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
3897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
3981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynchar *pidToName(pid_t pid) {
409a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    char *retval = NULL;
41ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    if (pid == 0) { // special case from auditd/klogd for kernel
42ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        retval = strdup("logd");
4397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    } else {
449a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        char buffer[512];
459a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
469a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        int fd = open(buffer, O_RDONLY);
479a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        if (fd >= 0) {
489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            ssize_t ret = read(fd, buffer, sizeof(buffer));
499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            if (ret > 0) {
509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                buffer[sizeof(buffer)-1] = '\0';
519a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                // frameworks intermediate state
52ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn                if (fast<strcmp>(buffer, "<pre-initialized>")) {
539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                    retval = strdup(buffer);
549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                }
559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            }
569a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            close(fd);
579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        }
589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    }
599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    return retval;
609a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
62720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
63720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
64758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::add(LogBufferElement *element) {
65758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
66758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
6797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] += size;
6897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ++mElements[log_id];
6934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
7097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizesTotal[log_id] += size;
7197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ++mElementsTotal[log_id];
72720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
73ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    if (log_id == LOG_ID_KERNEL) {
74ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        return;
75ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    }
76ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
77758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].add(element->getUid(), element);
78ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
79720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
82720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
83758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.add(element->getPid(), element);
84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.add(element->getTid(), element);
85344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
86758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uint32_t tag = element->getTag();
87344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (tag) {
88083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        if (log_id == LOG_ID_SECURITY) {
89083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            securityTagTable.add(tag, element);
90083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        } else {
91083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            tagTable.add(tag, element);
92083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        }
93344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
9434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
9534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
96758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::subtract(LogBufferElement *element) {
97758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
98758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
9997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] -= size;
10097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    --mElements[log_id];
10158b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    if (element->getDropped()) {
10258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
10358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
10434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
105ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    if (log_id == LOG_ID_KERNEL) {
106ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        return;
107ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    }
108ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
109758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].subtract(element->getUid(), element);
11034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
111720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
112720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
11334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
11434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
115758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.subtract(element->getPid(), element);
116758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.subtract(element->getTid(), element);
117344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
118758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uint32_t tag = element->getTag();
119344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (tag) {
120083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        if (log_id == LOG_ID_SECURITY) {
121083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            securityTagTable.subtract(tag, element);
122083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        } else {
123083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            tagTable.subtract(tag, element);
124083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        }
125344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
126c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn}
127c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
128ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop
129ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly.
130758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::drop(LogBufferElement *element) {
131758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
133ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    mSizes[log_id] -= size;
13458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    ++mDroppedElements[log_id];
135ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
136758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].drop(element->getUid(), element);
137ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
138ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (!enable) {
139ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        return;
140ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
141ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
142758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.drop(element->getPid(), element);
143758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.drop(element->getTid(), element);
144ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn}
145ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
14697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::uidToName(uid_t uid) const {
14897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Local hard coded favourites
14997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (uid == AID_LOGD) {
15097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        return strdup("auditd");
15134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
15234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
15397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Android hard coded
15497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    const struct android_id_info *info = android_ids;
15534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
15697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    for (size_t i = 0; i < android_id_count; ++i) {
15797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (info->aid == uid) {
15897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            return strdup(info->name);
15934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
16097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        ++info;
16134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
16234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
16308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    // Parse /data/system/packages.list
164023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn    uid_t userId = uid % AID_USER;
165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *name = android::uidToName(userId);
166023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn    if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
167023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn        name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
168023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn    }
16908739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    if (name) {
17008739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn        return name;
17108739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    }
172720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
173720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // report uid -> pid(s) -> pidToName if unique
174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
175511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        const PidEntry &entry = it->second;
176720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
177720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (entry.getUid() == uid) {
178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const char *nameTmp = entry.getName();
179720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (nameTmp) {
181720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (!name) {
182758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    name = strdup(nameTmp);
183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                } else if (fast<strcmp>(name, nameTmp)) {
184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    free(const_cast<char *>(name));
185023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn                    name = NULL;
186023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn                    break;
187720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
188720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
189720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
190720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
191720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
19297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // No one
193720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    return name;
19434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
19534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
196758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string UidEntry::formatHeader(const std::string &name, log_id_t id) const {
197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    bool isprune = worstUidEnabledForLogid(id);
198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(android::base::StringPrintf(
199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                          name.c_str(), android_log_id_to_name(id)),
200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Size"),
201c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                      std::string(isprune ? "+/-  Pruned" : ""))
202758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn         + formatLine(std::string("UID   PACKAGE"),
203758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("BYTES"),
204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string(isprune ? "NUM" : ""));
205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
207c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzynstd::string UidEntry::format(const LogStatistics &stat, log_id_t id) const {
208ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    uid_t uid = getUid();
209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name = android::base::StringPrintf("%u", uid);
210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *nameTmp = stat.uidToName(uid);
211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(6 - name.length(), (size_t)1),
214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        free(const_cast<char *>(nameTmp));
216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
221c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    if (worstUidEnabledForLogid(id)) {
222c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalDropped = 0;
223c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin();
224c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                it != stat.uidTable[id].end(); ++it) {
225c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            totalDropped += it->second.getDropped();
226c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
227c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t sizes = stat.sizes(id);
228c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalSize = stat.sizesTotal(id);
229c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalElements = stat.elementsTotal(id);
230c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        float totalVirtualSize = (float)sizes + (float)totalDropped * totalSize
231c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                                / totalElements;
232c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t entrySize = getSizes();
233c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        float virtualEntrySize = entrySize;
234c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        int realPermille = virtualEntrySize * 1000.0 / sizes;
235c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t dropped = getDropped();
236c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        if (dropped) {
237c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            pruned = android::base::StringPrintf("%zu", dropped);
238c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            virtualEntrySize += (float)dropped * totalSize / totalElements;
239c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
240c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
241c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        int permille = (realPermille - virtualPermille) * 1000L
242c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                     / (virtualPermille ?: 1);
243c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        if ((permille < -1) || (1 < permille)) {
244c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            std::string change;
245c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            const char *units = "%";
246c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            const char *prefix = (permille > 0) ? "+" : "";
247c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
248c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if (permille > 999) {
249c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                permille = (permille + 1000) / 100; // Now tenths fold
250c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                units = "X";
251c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                prefix = "";
252c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
253c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if ((-99 < permille) && (permille < 99)) {
254c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                change = android::base::StringPrintf("%s%d.%u%s",
255c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    prefix,
256c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    permille / 10,
257c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    ((permille < 0) ? (-permille % 10) : (permille % 10)),
258c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    units);
259c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            } else {
260c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                change = android::base::StringPrintf("%s%d%s",
261c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    prefix,
262c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    (permille + 5) / 10, units);
263c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
264c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            ssize_t spaces = EntryBaseConstants::pruned_len
265c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                           - 2 - pruned.length() - change.length();
266c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if ((spaces <= 0) && pruned.length()) {
267c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                spaces = 1;
268c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
269c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if (spaces > 0) {
270c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                change += android::base::StringPrintf("%*s", (int)spaces, "");
271c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
272c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            pruned = change + pruned;
273c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
274758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
275758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
276758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
277758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
278758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
279758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
280758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name,
281758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Size"),
282758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Pruned"))
283758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn         + formatLine(std::string("  PID/UID   COMMAND LINE"),
284758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("BYTES"),
285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("NUM"));
286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
288758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
290ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid = getPid();
291ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
292758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *nameTmp = getName();
293758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    } else if ((nameTmp = stat.uidToName(uid))) {
298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
300758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        free(const_cast<char *>(nameTmp));
302758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
303758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
304758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string size = android::base::StringPrintf("%zu",
305758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                                   getSizes());
306758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
308758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    size_t dropped = getDropped();
309758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (dropped) {
310758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        pruned = android::base::StringPrintf("%zu", dropped);
311758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
312758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
313758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
314758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
316758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
317758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name,
318758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Size"),
319758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Pruned"))
320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn         + formatLine(std::string("  TID/UID   COMM"),
321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("BYTES"),
322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("NUM"));
323758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
325758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
326758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
327758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name = android::base::StringPrintf("%5u/%u",
328ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                                   getTid(), uid);
329758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *nameTmp = getName();
330758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
333758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
334758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    } else if ((nameTmp = stat.uidToName(uid))) {
335758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        // if we do not have a PID name, lets punt to try UID name?
336758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
337758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
338758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
339758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        free(const_cast<char *>(nameTmp));
340758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        // We tried, better to not have a name at all, we still
341758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        // have TID/UID by number to report in any case.
342758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
343758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
344758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string size = android::base::StringPrintf("%zu",
345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                                   getSizes());
346758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
347758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
348758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    size_t dropped = getDropped();
349758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (dropped) {
350758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        pruned = android::base::StringPrintf("%zu", dropped);
351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::formatHeader(const std::string &name, log_id_t id) const {
357758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    bool isprune = worstUidEnabledForLogid(id);
358758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name,
359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Size"),
360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string(isprune ? "Prune" : ""))
361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn         + formatLine(std::string("    TAG/UID   TAGNAME"),
362758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("BYTES"),
363758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string(isprune ? "NUM" : ""));
364758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
365758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
366758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const {
367758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name;
368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
369758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (uid == (uid_t)-1) {
370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name = android::base::StringPrintf("%7u",
371758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                           getKey());
372ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
373758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name = android::base::StringPrintf("%7u/%u",
374758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                           getKey(), uid);
375ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
376758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *nameTmp = getName();
377758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
378758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
379758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "%*s%s", (int)std::max(14 - name.length(), (size_t)1),
380758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            "", nameTmp);
381758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
382758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
383758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string size = android::base::StringPrintf("%zu",
384758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                                   getSizes());
385758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
386758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
387758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
388758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
38934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
39034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
391ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzynstd::string LogStatistics::format(uid_t uid, pid_t pid,
392ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                  unsigned int logMask) const {
3939a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    static const unsigned short spaces_total = 19;
39434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
39597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on total logging, current and for all time
39697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
397decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn    std::string output = "size/num";
39834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t oldLength;
39997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    short spaces = 1;
40034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
40197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
40297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
403c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn            continue;
404c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        }
40597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
406c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        if (spaces < 0) {
407c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn            spaces = 0;
408c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        }
409decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn        output += android::base::StringPrintf("%*s%s", spaces, "",
410decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn                                              android_log_id_to_name(id));
41197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
41297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    }
413c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
41497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    spaces = 4;
415758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    output += "\nTotal";
416c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
41797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
41897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
41997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            continue;
42034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
42197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
42297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (spaces < 0) {
42397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            spaces = 0;
424e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        }
425decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn        output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
426decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn                                              sizesTotal(id),
427decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn                                              elementsTotal(id));
42897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
42934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
43034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
43197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    spaces = 6;
432758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    output += "\nNow";
43334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
43497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
43597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
43634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            continue;
43734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
43834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
43997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        size_t els = elements(id);
44034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (els) {
44197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            oldLength = output.length();
442e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (spaces < 0) {
443e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces = 0;
444e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
445decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn            output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
446decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn                                                  sizes(id), els);
44797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            spaces -= output.length() - oldLength;
44834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
44934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        spaces += spaces_total;
45034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
45134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
45297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on Chattiest
4538e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
454758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name;
455758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
45697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Chattiest by application (UID)
45797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
45897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
4598e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            continue;
4608e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
4618e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
462758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name = (uid == AID_ROOT)
463758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            ? "Chattiest UIDs in %s log buffer:"
464758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            : "Logging for your UID in %s log buffer:";
465ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += uidTable[id].format(*this, uid, pid, name, id);
466720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
46797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
468720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (enable) {
469ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = ((uid == AID_ROOT) && !pid)
470ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            ? "Chattiest PIDs:"
471ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            : "Logging for this PID:";
472ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += pidTable.format(*this, uid, pid, name);
473ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest TIDs";
474ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid) {
475ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            name += android::base::StringPrintf(" for PID %d", pid);
476ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
477ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
478ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += tidTable.format(*this, uid, pid, name);
47917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
48017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
481344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
482ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest events log buffer TAGs";
483ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid) {
484ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            name += android::base::StringPrintf(" for PID %d", pid);
485ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
486ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
487ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
488344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
489344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
490083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
491ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest security log buffer TAGs";
492ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid) {
493ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            name += android::base::StringPrintf(" for PID %d", pid);
494ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
495ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
496ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
497083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    }
498083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
49973160acc5cb5236b30327569e6b51dbfe73e4a0fMark Salyzyn    return output;
50034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
5014ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn
502720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
503720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
504720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) {
50597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char buffer[512];
50697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
50797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    FILE *fp = fopen(buffer, "r");
50897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (fp) {
50997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        while (fgets(buffer, sizeof(buffer), fp)) {
51097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            int uid;
511c32afdf913f082235b1e66f5a57678c7f0723129Mark Salyzyn            if (sscanf(buffer, "Uid: %d", &uid) == 1) {
51297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                fclose(fp);
51397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                return uid;
5144ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            }
5154ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        }
51697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        fclose(fp);
5174ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    }
518e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn    return AID_LOGD; // associate this with the logger
5194ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn}
520720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
521720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
522720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
523720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) {
524511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    return pidTable.add(pid)->second.getUid();
525720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
526720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
527720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string
528758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::pidToName(pid_t pid) const {
529758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    // An inconvenient truth ... getName() can alter the object
530758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable);
531758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *name = writablePidTable.add(pid)->second.getName();
53281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    if (!name) {
53381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return NULL;
534720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
53581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    return strdup(name);
536720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
537