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
17c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn#include <ctype.h>
189a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#include <fcntl.h>
1902dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn#include <inttypes.h>
20b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn#include <pwd.h>
2197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h>
2297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h>
23b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn#include <sys/types.h>
2497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h>
2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
269af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn#include <list>
279af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn
2803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn#include <private/android_logger.h>
2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
3034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h"
3134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
3203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzynstatic const uint64_t hourSec = 60 * 60;
3303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzynstatic const uint64_t monthSec = 31 * 24 * hourSec;
3403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
353296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzynsize_t LogStatistics::SizesTotal;
363296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn
377718778793b106498b931dd708a466cf3a6f6a0fMark SalyzynLogStatistics::LogStatistics() : enable(false) {
3803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_time now(CLOCK_REALTIME);
3997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
4097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizes[id] = 0;
4197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElements[id] = 0;
4258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        mDroppedElements[id] = 0;
4397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizesTotal[id] = 0;
4497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElementsTotal[id] = 0;
4503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mOldest[id] = now;
4603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mNewest[id] = now;
4703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mNewestDropped[id] = now;
4834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
4934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
5034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
51720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
52720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
53501c373916e292764400dbae735f44b33378400fMark Salyzynsize_t sizesTotal() {
54501c373916e292764400dbae735f44b33378400fMark Salyzyn    return LogStatistics::sizesTotal();
55501c373916e292764400dbae735f44b33378400fMark Salyzyn}
563296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn
5797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
58501c373916e292764400dbae735f44b33378400fMark Salyzynchar* pidToName(pid_t pid) {
59501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* retval = NULL;
60501c373916e292764400dbae735f44b33378400fMark Salyzyn    if (pid == 0) {  // special case from auditd/klogd for kernel
61ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        retval = strdup("logd");
6297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    } else {
639a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        char buffer[512];
649a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
659a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        int fd = open(buffer, O_RDONLY);
669a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        if (fd >= 0) {
679a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            ssize_t ret = read(fd, buffer, sizeof(buffer));
689a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            if (ret > 0) {
69501c373916e292764400dbae735f44b33378400fMark Salyzyn                buffer[sizeof(buffer) - 1] = '\0';
709a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                // frameworks intermediate state
710eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn                if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
729a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                    retval = strdup(buffer);
739a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                }
749a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            }
759a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            close(fd);
769a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        }
779a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    }
789a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    return retval;
799a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
8202dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzynvoid LogStatistics::addTotal(LogBufferElement* element) {
8302dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    if (element->getDropped()) return;
8402dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn
8502dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    log_id_t log_id = element->getLogId();
8602dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    unsigned short size = element->getMsgLen();
8702dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    mSizesTotal[log_id] += size;
8802dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    SizesTotal += size;
8902dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    ++mElementsTotal[log_id];
9002dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn}
9102dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn
92501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::add(LogBufferElement* element) {
93758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
94758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
9597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] += size;
9697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ++mElements[log_id];
9734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
9802dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    // When caller adding a chatty entry, they will have already
9902dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    // called add() and subtract() for each entry as they are
10002dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    // evaluated and trimmed, thus recording size and number of
10102dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    // elements, but we must recognize the manufactured dropped
10202dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    // entry as not contributing to the lifetime totals.
103a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn    if (element->getDropped()) {
104a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        ++mDroppedElements[log_id];
105a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn    } else {
106a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        mSizesTotal[log_id] += size;
1073296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn        SizesTotal += size;
108a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        ++mElementsTotal[log_id];
109a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn    }
110720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
11103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_time stamp(element->getRealTime());
11203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (mNewest[log_id] < stamp) {
11303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        // A major time update invalidates the statistics :-(
11403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        log_time diff = stamp - mNewest[log_id];
11503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mNewest[log_id] = stamp;
11603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
11703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (diff.tv_sec > hourSec) {
11803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            // approximate Do-Your-Best fixup
11903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            diff += mOldest[log_id];
12003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
12103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                diff = stamp;
12203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            }
12303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            if (diff <= stamp) {
12403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                mOldest[log_id] = diff;
12503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                if (mNewestDropped[log_id] < diff) {
12603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                    mNewestDropped[log_id] = diff;
12703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                }
12803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            }
12903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        }
13003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
13103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
132ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    if (log_id == LOG_ID_KERNEL) {
133ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        return;
134ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    }
135ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
136758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].add(element->getUid(), element);
137bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    if (element->getUid() == AID_SYSTEM) {
138bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        pidSystemTable[log_id].add(element->getPid(), element);
139bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
140ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
141720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
142720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
143720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
144720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
145758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.add(element->getPid(), element);
146758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.add(element->getTid(), element);
147344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
148758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uint32_t tag = element->getTag();
149344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (tag) {
150083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        if (log_id == LOG_ID_SECURITY) {
151083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            securityTagTable.add(tag, element);
152083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        } else {
153083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            tagTable.add(tag, element);
154083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        }
155344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
156f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
157f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (!element->getDropped()) {
158f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        tagNameTable.add(TagNameKey(element), element);
159f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
16034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
16134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
162501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::subtract(LogBufferElement* element) {
163758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
16597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] -= size;
16697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    --mElements[log_id];
16758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    if (element->getDropped()) {
16858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
16958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
17034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
17103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (mOldest[log_id] < element->getRealTime()) {
17203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mOldest[log_id] = element->getRealTime();
17303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
17403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
175ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    if (log_id == LOG_ID_KERNEL) {
176ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn        return;
177ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn    }
178ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn
179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].subtract(element->getUid(), element);
180bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    if (element->getUid() == AID_SYSTEM) {
181bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        pidSystemTable[log_id].subtract(element->getPid(), element);
182bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
18334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
184720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
185720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
18634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
18734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.subtract(element->getPid(), element);
189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.subtract(element->getTid(), element);
190344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uint32_t tag = element->getTag();
192344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (tag) {
193083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        if (log_id == LOG_ID_SECURITY) {
194083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            securityTagTable.subtract(tag, element);
195083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        } else {
196083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn            tagTable.subtract(tag, element);
197083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn        }
198344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
199f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
200f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (!element->getDropped()) {
201f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        tagNameTable.subtract(TagNameKey(element), element);
202f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
203c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn}
204c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
205ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop
206ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly.
207501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogStatistics::drop(LogBufferElement* element) {
208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    log_id_t log_id = element->getLogId();
209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    unsigned short size = element->getMsgLen();
210ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    mSizes[log_id] -= size;
21158b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    ++mDroppedElements[log_id];
212ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
21303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (mNewestDropped[log_id] < element->getRealTime()) {
21403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        mNewestDropped[log_id] = element->getRealTime();
21503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
21603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uidTable[log_id].drop(element->getUid(), element);
218bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    if (element->getUid() == AID_SYSTEM) {
219bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        pidSystemTable[log_id].drop(element->getPid(), element);
220bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
221ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
222ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (!enable) {
223ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        return;
224ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
225ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
226758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    pidTable.drop(element->getPid(), element);
227758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    tidTable.drop(element->getTid(), element);
2286a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
2296a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    uint32_t tag = element->getTag();
2306a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    if (tag) {
2316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (log_id == LOG_ID_SECURITY) {
2326a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            securityTagTable.drop(tag, element);
2336a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        } else {
2346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            tagTable.drop(tag, element);
2356a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
2366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
237f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
238f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    tagNameTable.subtract(TagNameKey(element), element);
239ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn}
240ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
24197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
2423c501b50b41086cde59a6811f4aa5cd3e736f5f2Mark Salyzyn// Requires parent LogBuffer::wrlock() to be held
243501c373916e292764400dbae735f44b33378400fMark Salyzynconst char* LogStatistics::uidToName(uid_t uid) const {
24497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Local hard coded favourites
24597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (uid == AID_LOGD) {
24697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        return strdup("auditd");
24734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
24834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
249b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn    // Android system
250b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn    if (uid < AID_APP) {
251b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn        // in bionic, thread safe as long as we copy the results
252501c373916e292764400dbae735f44b33378400fMark Salyzyn        struct passwd* pwd = getpwuid(uid);
253b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn        if (pwd) {
254b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn            return strdup(pwd->pw_name);
25534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
25634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
25734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25808739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    // Parse /data/system/packages.list
259dff44709cf462a3af7eb5770c90e3ada492295b7Jeff Sharkey    uid_t userId = uid % AID_USER_OFFSET;
260501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* name = android::uidToName(userId);
261023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn    if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
262023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn        name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
263023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn    }
26408739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    if (name) {
26508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn        return name;
26608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    }
267720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
268b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn    // Android application
269b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn    if (uid >= AID_APP) {
270501c373916e292764400dbae735f44b33378400fMark Salyzyn        struct passwd* pwd = getpwuid(uid);
271b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn        if (pwd) {
272b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn            return strdup(pwd->pw_name);
273b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn        }
274b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn    }
275b8a95bd3c9502d48b203b9f1e5df9b84a5df6281Mark Salyzyn
276720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // report uid -> pid(s) -> pidToName if unique
277501c373916e292764400dbae735f44b33378400fMark Salyzyn    for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end();
278501c373916e292764400dbae735f44b33378400fMark Salyzyn         ++it) {
279501c373916e292764400dbae735f44b33378400fMark Salyzyn        const PidEntry& entry = it->second;
280720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
281720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (entry.getUid() == uid) {
282501c373916e292764400dbae735f44b33378400fMark Salyzyn            const char* nameTmp = entry.getName();
283720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
284758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (nameTmp) {
285720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (!name) {
286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    name = strdup(nameTmp);
2870eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn                } else if (fastcmp<strcmp>(name, nameTmp)) {
288501c373916e292764400dbae735f44b33378400fMark Salyzyn                    free(const_cast<char*>(name));
289023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn                    name = NULL;
290023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn                    break;
291720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
292720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
293720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
294720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
295720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
29697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // No one
297720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    return name;
29834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
29934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
300501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    bool isprune = worstUidEnabledForLogid(id);
302501c373916e292764400dbae735f44b33378400fMark Salyzyn    return formatLine(android::base::StringPrintf(name.c_str(),
303501c373916e292764400dbae735f44b33378400fMark Salyzyn                                                  android_log_id_to_name(id)),
304758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("Size"),
305501c373916e292764400dbae735f44b33378400fMark Salyzyn                      std::string(isprune ? "+/-  Pruned" : "")) +
306501c373916e292764400dbae735f44b33378400fMark Salyzyn           formatLine(std::string("UID   PACKAGE"), std::string("BYTES"),
307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string(isprune ? "NUM" : ""));
308758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
309758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
310f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn// Helper to truncate name, if too long, and add name dressings
311f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzynstatic void formatTmp(const LogStatistics& stat, const char* nameTmp, uid_t uid,
312f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn                      std::string& name, std::string& size, size_t nameLen) {
313f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    const char* allocNameTmp = nullptr;
314f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    if (!nameTmp) nameTmp = allocNameTmp = stat.uidToName(uid);
315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
316f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
317f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        size_t len = EntryBaseConstants::total_len -
318f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn                     EntryBaseConstants::pruned_len - size.length() -
319f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn                     name.length() - lenSpace - 2;
320f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        size_t lenNameTmp = strlen(nameTmp);
321f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        while ((len < lenNameTmp) && (lenSpace > 1)) {
322f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn            ++len;
323f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn            --lenSpace;
324f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        }
325f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        name += android::base::StringPrintf("%*s", (int)lenSpace, "");
326f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        if (len < lenNameTmp) {
327f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn            name += "...";
328f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn            nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
329f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        }
330f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        name += nameTmp;
331f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn        free(const_cast<char*>(allocNameTmp));
332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
333f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn}
334758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
335f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzynstd::string UidEntry::format(const LogStatistics& stat, log_id_t id) const {
336f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    uid_t uid = getUid();
337f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    std::string name = android::base::StringPrintf("%u", uid);
338758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
339758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
340f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    formatTmp(stat, nullptr, uid, name, size, 6);
341f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn
342758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
343c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    if (worstUidEnabledForLogid(id)) {
344c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalDropped = 0;
345501c373916e292764400dbae735f44b33378400fMark Salyzyn        for (LogStatistics::uidTable_t::const_iterator it =
346501c373916e292764400dbae735f44b33378400fMark Salyzyn                 stat.uidTable[id].begin();
347501c373916e292764400dbae735f44b33378400fMark Salyzyn             it != stat.uidTable[id].end(); ++it) {
348c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            totalDropped += it->second.getDropped();
349c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
350c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t sizes = stat.sizes(id);
351c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalSize = stat.sizesTotal(id);
352c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t totalElements = stat.elementsTotal(id);
353501c373916e292764400dbae735f44b33378400fMark Salyzyn        float totalVirtualSize =
354501c373916e292764400dbae735f44b33378400fMark Salyzyn            (float)sizes + (float)totalDropped * totalSize / totalElements;
355c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t entrySize = getSizes();
356c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        float virtualEntrySize = entrySize;
357c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        int realPermille = virtualEntrySize * 1000.0 / sizes;
358c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        size_t dropped = getDropped();
359c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        if (dropped) {
360c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            pruned = android::base::StringPrintf("%zu", dropped);
361c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            virtualEntrySize += (float)dropped * totalSize / totalElements;
362c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
363c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
364501c373916e292764400dbae735f44b33378400fMark Salyzyn        int permille =
365501c373916e292764400dbae735f44b33378400fMark Salyzyn            (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1);
366c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        if ((permille < -1) || (1 < permille)) {
367c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            std::string change;
368501c373916e292764400dbae735f44b33378400fMark Salyzyn            const char* units = "%";
369501c373916e292764400dbae735f44b33378400fMark Salyzyn            const char* prefix = (permille > 0) ? "+" : "";
370c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
371c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if (permille > 999) {
372501c373916e292764400dbae735f44b33378400fMark Salyzyn                permille = (permille + 1000) / 100;  // Now tenths fold
373c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                units = "X";
374c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                prefix = "";
375c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
376c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if ((-99 < permille) && (permille < 99)) {
377501c373916e292764400dbae735f44b33378400fMark Salyzyn                change = android::base::StringPrintf(
378501c373916e292764400dbae735f44b33378400fMark Salyzyn                    "%s%d.%u%s", prefix, permille / 10,
379c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    ((permille < 0) ? (-permille % 10) : (permille % 10)),
380c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                    units);
381c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            } else {
382501c373916e292764400dbae735f44b33378400fMark Salyzyn                change = android::base::StringPrintf(
383501c373916e292764400dbae735f44b33378400fMark Salyzyn                    "%s%d%s", prefix, (permille + 5) / 10, units);
384c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
385501c373916e292764400dbae735f44b33378400fMark Salyzyn            ssize_t spaces = EntryBaseConstants::pruned_len - 2 -
386501c373916e292764400dbae735f44b33378400fMark Salyzyn                             pruned.length() - change.length();
387c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            if ((spaces <= 0) && pruned.length()) {
388c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                spaces = 1;
389c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
390d966e226809bd446bb33651b71d7934887787c1dMark Salyzyn            if (spaces > 0) {
391c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn                change += android::base::StringPrintf("%*s", (int)spaces, "");
392c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            }
393c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn            pruned = change + pruned;
394c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn        }
395758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
396758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
397bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    std::string output = formatLine(name, size, pruned);
398bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
399bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    if (uid != AID_SYSTEM) {
400bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        return output;
401bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
402bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
403bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    static const size_t maximum_sorted_entries = 32;
404501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::unique_ptr<const PidEntry* []> sorted =
405501c373916e292764400dbae735f44b33378400fMark Salyzyn        stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries);
406bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
407bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    if (!sorted.get()) {
408bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        return output;
409bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
410bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    std::string byPid;
411bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    size_t index;
412bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    bool hasDropped = false;
413bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    for (index = 0; index < maximum_sorted_entries; ++index) {
414501c373916e292764400dbae735f44b33378400fMark Salyzyn        const PidEntry* entry = sorted[index];
415bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        if (!entry) {
416bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn            break;
417bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        }
418bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        if (entry->getSizes() <= (getSizes() / 100)) {
419bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn            break;
420bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        }
421bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        if (entry->getDropped()) {
422bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn            hasDropped = true;
423bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        }
424bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        byPid += entry->format(stat, id);
425bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
426501c373916e292764400dbae735f44b33378400fMark Salyzyn    if (index > 1) {  // print this only if interesting
427bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        std::string ditto("\" ");
428501c373916e292764400dbae735f44b33378400fMark Salyzyn        output += formatLine(std::string("  PID/UID   COMMAND LINE"), ditto,
429501c373916e292764400dbae735f44b33378400fMark Salyzyn                             hasDropped ? ditto : std::string(""));
430bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn        output += byPid;
431bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
432bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
433bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    return output;
434758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
435758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
436501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string PidEntry::formatHeader(const std::string& name,
437501c373916e292764400dbae735f44b33378400fMark Salyzyn                                   log_id_t /* id */) const {
438501c373916e292764400dbae735f44b33378400fMark Salyzyn    return formatLine(name, std::string("Size"), std::string("Pruned")) +
439501c373916e292764400dbae735f44b33378400fMark Salyzyn           formatLine(std::string("  PID/UID   COMMAND LINE"),
440501c373916e292764400dbae735f44b33378400fMark Salyzyn                      std::string("BYTES"), std::string("NUM"));
441758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
442758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
443501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string PidEntry::format(const LogStatistics& stat,
444501c373916e292764400dbae735f44b33378400fMark Salyzyn                             log_id_t /* id */) const {
445758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
446ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid = getPid();
447ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
448501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
449758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
450f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    formatTmp(stat, getName(), uid, name, size, 12);
451f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn
452758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
453758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    size_t dropped = getDropped();
454758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (dropped) {
455758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        pruned = android::base::StringPrintf("%zu", dropped);
456758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
457758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
458758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
459758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
460758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
461501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TidEntry::formatHeader(const std::string& name,
462501c373916e292764400dbae735f44b33378400fMark Salyzyn                                   log_id_t /* id */) const {
463501c373916e292764400dbae735f44b33378400fMark Salyzyn    return formatLine(name, std::string("Size"), std::string("Pruned")) +
464501c373916e292764400dbae735f44b33378400fMark Salyzyn           formatLine(std::string("  TID/UID   COMM"), std::string("BYTES"),
465758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                      std::string("NUM"));
466758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
467758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
468501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TidEntry::format(const LogStatistics& stat,
469501c373916e292764400dbae735f44b33378400fMark Salyzyn                             log_id_t /* id */) const {
470758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
471501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid);
472501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
473758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
474f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn    formatTmp(stat, getName(), uid, name, size, 12);
475f31ae3d666f6e723a7dde6734c6d8395f8bcdc11Mark Salyzyn
476758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
477758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    size_t dropped = getDropped();
478758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (dropped) {
479758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        pruned = android::base::StringPrintf("%zu", dropped);
480758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
481758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
482758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
483758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
484758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
485501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
486758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    bool isprune = worstUidEnabledForLogid(id);
487501c373916e292764400dbae735f44b33378400fMark Salyzyn    return formatLine(name, std::string("Size"),
488501c373916e292764400dbae735f44b33378400fMark Salyzyn                      std::string(isprune ? "Prune" : "")) +
489501c373916e292764400dbae735f44b33378400fMark Salyzyn           formatLine(std::string("    TAG/UID   TAGNAME"),
490501c373916e292764400dbae735f44b33378400fMark Salyzyn                      std::string("BYTES"), std::string(isprune ? "NUM" : ""));
491758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
492758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
493501c373916e292764400dbae735f44b33378400fMark Salyzynstd::string TagEntry::format(const LogStatistics& /* stat */,
494501c373916e292764400dbae735f44b33378400fMark Salyzyn                             log_id_t /* id */) const {
495758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name;
496758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    uid_t uid = getUid();
497758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (uid == (uid_t)-1) {
498501c373916e292764400dbae735f44b33378400fMark Salyzyn        name = android::base::StringPrintf("%7u", getKey());
499ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
500501c373916e292764400dbae735f44b33378400fMark Salyzyn        name = android::base::StringPrintf("%7u/%u", getKey(), uid);
501ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
502501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* nameTmp = getName();
503758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    if (nameTmp) {
504758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        name += android::base::StringPrintf(
505501c373916e292764400dbae735f44b33378400fMark Salyzyn            "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
506758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
507758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
508501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
509758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
510758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string pruned = "";
5116a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    size_t dropped = getDropped();
5126a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    if (dropped) {
5136a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        pruned = android::base::StringPrintf("%zu", dropped);
5146a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
515758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
516758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    return formatLine(name, size, pruned);
51734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
51834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
519f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzynstd::string TagNameEntry::formatHeader(const std::string& name,
520f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                                       log_id_t /* id */) const {
521f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    return formatLine(name, std::string("Size"), std::string("")) +
522f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn           formatLine(std::string("  TID/PID/UID   LOG_TAG NAME"),
523f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                      std::string("BYTES"), std::string(""));
524f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn}
525f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
526f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzynstd::string TagNameEntry::format(const LogStatistics& /* stat */,
527f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                                 log_id_t /* id */) const {
528f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string name;
529f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    pid_t tid = getTid();
530f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    pid_t pid = getPid();
531f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string pidstr;
532f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (pid != (pid_t)-1) {
533f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        pidstr = android::base::StringPrintf("%u", pid);
534f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr;
535f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
536f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    int len = 9 - pidstr.length();
537f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (len < 0) len = 0;
538f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if ((tid == (pid_t)-1) || (tid == pid)) {
539f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name = android::base::StringPrintf("%*s", len, "");
540f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    } else {
541f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name = android::base::StringPrintf("%*u", len, tid);
542f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
543f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    name += pidstr;
544f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    uid_t uid = getUid();
545f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (uid != (uid_t)-1) {
546f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name += android::base::StringPrintf("/%u", uid);
547f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
548f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
549f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string size = android::base::StringPrintf("%zu", getSizes());
550f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
551f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const char* nameTmp = getName();
552f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (nameTmp) {
553f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        size_t lenSpace = std::max(16 - name.length(), (size_t)1);
554f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        size_t len = EntryBaseConstants::total_len -
555f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                     EntryBaseConstants::pruned_len - size.length() -
556f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                     name.length() - lenSpace - 2;
557f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        size_t lenNameTmp = strlen(nameTmp);
558f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        while ((len < lenNameTmp) && (lenSpace > 1)) {
559f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            ++len;
560f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            --lenSpace;
561f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
562f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name += android::base::StringPrintf("%*s", (int)lenSpace, "");
563f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (len < lenNameTmp) {
564f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            name += "...";
565f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
566f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
567f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name += nameTmp;
568f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
569f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
570f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string pruned = "";
571f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
572f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    return formatLine(name, size, pruned);
573f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn}
574f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
57503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzynstatic std::string formatMsec(uint64_t val) {
57603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const unsigned subsecDigits = 3;
57703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const uint64_t sec = MS_PER_SEC;
57803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
57903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const uint64_t minute = 60 * sec;
58003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const uint64_t hour = 60 * minute;
58103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const uint64_t day = 24 * hour;
58203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
58303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    std::string output;
58403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (val < sec) return output;
58503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
58603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (val >= day) {
58703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
58803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        val = (val % day) + day;
58903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
59003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (val >= minute) {
59103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (val >= hour) {
59203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            output += android::base::StringPrintf("%" PRIu64 ":",
59303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                                                  (val / hour) % (day / hour));
59403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        }
59503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        output += android::base::StringPrintf(
59603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
59703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            (val / minute) % (hour / minute));
59803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
59903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    output +=
60003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
60103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                                    (val / sec) % (minute / sec));
60203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    val %= sec;
60303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    unsigned digits = subsecDigits;
60403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    while (digits && ((val % 10) == 0)) {
60503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        val /= 10;
60603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        --digits;
60703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
60803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (digits) {
60903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
61003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
61103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    return output;
61203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn}
61303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
614ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzynstd::string LogStatistics::format(uid_t uid, pid_t pid,
615ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                  unsigned int logMask) const {
6169a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    static const unsigned short spaces_total = 19;
61734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
61897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on total logging, current and for all time
61997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
620decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn    std::string output = "size/num";
62134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t oldLength;
62297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    short spaces = 1;
62334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
62497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
6259af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (!(logMask & (1 << id))) continue;
62697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
6279af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (spaces < 0) spaces = 0;
628decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn        output += android::base::StringPrintf("%*s%s", spaces, "",
629decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn                                              android_log_id_to_name(id));
63097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
63197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    }
6329af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    if (spaces < 0) spaces = 0;
6339af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    output += android::base::StringPrintf("%*sTotal", spaces, "");
634c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
6359af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    static const char TotalStr[] = "\nTotal";
6369af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    spaces = 10 - strlen(TotalStr);
6379af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    output += TotalStr;
638c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
6399af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    size_t totalSize = 0;
6409af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    size_t totalEls = 0;
64197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
6429af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (!(logMask & (1 << id))) continue;
64397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
6449af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (spaces < 0) spaces = 0;
6459af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        size_t szs = sizesTotal(id);
6469af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        totalSize += szs;
6479af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        size_t els = elementsTotal(id);
6489af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        totalEls += els;
649501c373916e292764400dbae735f44b33378400fMark Salyzyn        output +=
650501c373916e292764400dbae735f44b33378400fMark Salyzyn            android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
65197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
65234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
6539af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    if (spaces < 0) spaces = 0;
654501c373916e292764400dbae735f44b33378400fMark Salyzyn    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
655501c373916e292764400dbae735f44b33378400fMark Salyzyn                                          totalEls);
65634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
6579af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    static const char NowStr[] = "\nNow";
6589af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    spaces = 10 - strlen(NowStr);
6599af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    output += NowStr;
66034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
6619af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    totalSize = 0;
6629af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    totalEls = 0;
66397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
6649af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (!(logMask & (1 << id))) continue;
6659af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn
6669af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        size_t els = elements(id);
6679af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (els) {
6689af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            oldLength = output.length();
6699af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            if (spaces < 0) spaces = 0;
6709af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            size_t szs = sizes(id);
6719af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            totalSize += szs;
6729af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            totalEls += els;
673501c373916e292764400dbae735f44b33378400fMark Salyzyn            output +=
674501c373916e292764400dbae735f44b33378400fMark Salyzyn                android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
6759af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            spaces -= output.length() - oldLength;
67634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
6779af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        spaces += spaces_total;
6789af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    }
6799af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    if (spaces < 0) spaces = 0;
680501c373916e292764400dbae735f44b33378400fMark Salyzyn    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
681501c373916e292764400dbae735f44b33378400fMark Salyzyn                                          totalEls);
6829af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn
68303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    static const char SpanStr[] = "\nLogspan";
68403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    spaces = 10 - strlen(SpanStr);
68503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    output += SpanStr;
68603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
68703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    // Total reports the greater of the individual maximum time span, or the
68803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    // validated minimum start and maximum end time span if it makes sense.
68903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    uint64_t minTime = UINT64_MAX;
69003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    uint64_t maxTime = 0;
69103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    uint64_t maxSpan = 0;
69203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    totalSize = 0;
69303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
69403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_id_for_each(id) {
69503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (!(logMask & (1 << id))) continue;
69603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
69703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        // validity checking
69803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        uint64_t oldest = mOldest[id].msec();
69903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        uint64_t newest = mNewest[id].msec();
70003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (newest <= oldest) {
70103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            spaces += spaces_total;
70203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            continue;
70303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        }
70403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
70503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        uint64_t span = newest - oldest;
70603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (span > (monthSec * MS_PER_SEC)) {
70703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            spaces += spaces_total;
70803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            continue;
70903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        }
71003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
71103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        // total span
71203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (minTime > oldest) minTime = oldest;
71303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (maxTime < newest) maxTime = newest;
71403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (span > maxSpan) maxSpan = span;
71503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        totalSize += span;
71603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
71703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        uint64_t dropped = mNewestDropped[id].msec();
71803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (dropped < oldest) dropped = oldest;
71903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if (dropped > newest) dropped = newest;
72003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
72103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        oldLength = output.length();
72203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        output += android::base::StringPrintf("%*s%s", spaces, "",
72303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                                              formatMsec(span).c_str());
72403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span;
72503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        if ((permille > 1) && (permille < 999)) {
72603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            output += android::base::StringPrintf("(%u", permille / 10);
72703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            permille %= 10;
72803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            if (permille) {
72903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                output += android::base::StringPrintf(".%u", permille);
73003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            }
73103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn            output += android::base::StringPrintf("%%)");
73203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        }
73303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        spaces -= output.length() - oldLength;
73403bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        spaces += spaces_total;
73503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
73603bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
73703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        (maxTime > maxSpan)) {
73803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn        maxSpan = maxTime;
73903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    }
74003bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    if (spaces < 0) spaces = 0;
74103bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    output += android::base::StringPrintf("%*s%s", spaces, "",
74203bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn                                          formatMsec(maxSpan).c_str());
74303bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn
7449af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    static const char OverheadStr[] = "\nOverhead";
7459af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    spaces = 10 - strlen(OverheadStr);
7469af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    output += OverheadStr;
7479af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn
7489af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    totalSize = 0;
7499af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    log_id_for_each(id) {
7509af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (!(logMask & (1 << id))) continue;
75134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
75297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        size_t els = elements(id);
75334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (els) {
75497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            oldLength = output.length();
7559af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            if (spaces < 0) spaces = 0;
7569af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            // estimate the std::list overhead.
7579af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            static const size_t overhead =
7589af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn                ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) &
759501c373916e292764400dbae735f44b33378400fMark Salyzyn                 -sizeof(uint64_t)) +
7609af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn                sizeof(std::list<LogBufferElement*>);
7619af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            size_t szs = sizes(id) + els * overhead;
7629af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            totalSize += szs;
7639af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn            output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
76497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            spaces -= output.length() - oldLength;
76534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
76634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        spaces += spaces_total;
76734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
7686d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    totalSize += sizeOf();
7699af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    if (spaces < 0) spaces = 0;
7709af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn    output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
77134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
77297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on Chattiest
7738e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
774758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string name;
775758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
77697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Chattiest by application (UID)
77797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
7789af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (!(logMask & (1 << id))) continue;
7798e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
780501c373916e292764400dbae735f44b33378400fMark Salyzyn        name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:"
781501c373916e292764400dbae735f44b33378400fMark Salyzyn                                 : "Logging for your UID in %s log buffer:";
782ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += uidTable[id].format(*this, uid, pid, name, id);
783720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
78497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
785720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (enable) {
786501c373916e292764400dbae735f44b33378400fMark Salyzyn        name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:"
787501c373916e292764400dbae735f44b33378400fMark Salyzyn                                           : "Logging for this PID:";
788ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += pidTable.format(*this, uid, pid, name);
789ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest TIDs";
7909af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
791ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
792ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += tidTable.format(*this, uid, pid, name);
79317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
79417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
795344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
796ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest events log buffer TAGs";
7979af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
798ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
799ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
800344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
801344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
802083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
803ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name = "Chattiest security log buffer TAGs";
8049af33ee78c395af715e7b861f4e32272559e1fe9Mark Salyzyn        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
805ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        name += ":";
806501c373916e292764400dbae735f44b33378400fMark Salyzyn        output +=
807501c373916e292764400dbae735f44b33378400fMark Salyzyn            securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
808083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    }
809083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
810f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    if (enable) {
811f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name = "Chattiest TAGs";
812f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
813f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        name += ":";
814f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        output += tagNameTable.format(*this, uid, pid, name);
815f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
816f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
81773160acc5cb5236b30327569e6b51dbfe73e4a0fMark Salyzyn    return output;
81834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
8194ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn
820720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
821720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
822720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) {
82397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char buffer[512];
82497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
825501c373916e292764400dbae735f44b33378400fMark Salyzyn    FILE* fp = fopen(buffer, "r");
82697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (fp) {
82797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        while (fgets(buffer, sizeof(buffer), fp)) {
828c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            int uid = AID_LOGD;
829c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            char space = 0;
830c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            if ((sscanf(buffer, "Uid: %d%c", &uid, &space) == 2) &&
831c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn                isspace(space)) {
83297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                fclose(fp);
83397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                return uid;
8344ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            }
8354ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        }
83697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        fclose(fp);
8374ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    }
838501c373916e292764400dbae735f44b33378400fMark Salyzyn    return AID_LOGD;  // associate this with the logger
8394ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn}
840c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn
841c4e4823b00a94627e922eada1172688818471b0cMark Salyzynpid_t tidToPid(pid_t tid) {
842c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    char buffer[512];
843c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    snprintf(buffer, sizeof(buffer), "/proc/%u/status", tid);
844c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    FILE* fp = fopen(buffer, "r");
845c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    if (fp) {
846c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn        while (fgets(buffer, sizeof(buffer), fp)) {
847c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            int pid = tid;
848c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            char space = 0;
849c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            if ((sscanf(buffer, "Tgid: %d%c", &pid, &space) == 2) &&
850c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn                isspace(space)) {
851c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn                fclose(fp);
852c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn                return pid;
853c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn            }
854c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn        }
855c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn        fclose(fp);
856c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    }
857c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    return tid;
858c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn}
859720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
860720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
861720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) {
862511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    return pidTable.add(pid)->second.getUid();
863720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
864720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
865c4e4823b00a94627e922eada1172688818471b0cMark Salyzynpid_t LogStatistics::tidToPid(pid_t tid) {
866c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    return tidTable.add(tid)->second.getPid();
867c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn}
868c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn
869720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string
870501c373916e292764400dbae735f44b33378400fMark Salyzynconst char* LogStatistics::pidToName(pid_t pid) const {
871758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    // An inconvenient truth ... getName() can alter the object
872501c373916e292764400dbae735f44b33378400fMark Salyzyn    pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
873501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* name = writablePidTable.add(pid)->second.getName();
87481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    if (!name) {
87581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return NULL;
876720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
87781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    return strdup(name);
878720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
879