LogStatistics.cpp revision 8e72c5384b288bc11af60e12686a44e502633e3d
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>
1834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <stdarg.h>
1934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <time.h>
2034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/logger.h>
2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <private/android_filesystem_config.h>
2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <utils/String8.h>
2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h"
2634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
279a03863e88da99ba010342c874252089dd771f7fMark SalyzynPidStatistics::PidStatistics(pid_t pid, char *name)
2834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        : pid(pid)
2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        , mSizesTotal(0)
3034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        , mElementsTotal(0)
3134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        , mSizes(0)
329a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , mElements(0)
339a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , name(name)
349a03863e88da99ba010342c874252089dd771f7fMark Salyzyn{ }
359a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
369a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#ifdef DO_NOT_ERROR_IF_PIDSTATISTICS_USES_A_COPY_CONSTRUCTOR
379a03863e88da99ba010342c874252089dd771f7fMark SalyzynPidStatistics::PidStatistics(const PidStatistics &copy)
389a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        : pid(copy->pid)
399a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , name(copy->name ? strdup(copy->name) : NULL)
409a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , mSizesTotal(copy->mSizesTotal)
419a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , mElementsTotal(copy->mElementsTotal)
429a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , mSizes(copy->mSizes)
439a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        , mElements(copy->mElements)
449a03863e88da99ba010342c874252089dd771f7fMark Salyzyn{ }
459a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#endif
469a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
479a03863e88da99ba010342c874252089dd771f7fMark SalyzynPidStatistics::~PidStatistics() {
489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    free(name);
499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
519a03863e88da99ba010342c874252089dd771f7fMark Salyzynvoid PidStatistics::setName(char *new_name) {
529a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    free(name);
539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    name = new_name;
549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
5534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
5634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid PidStatistics::add(unsigned short size) {
5734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    mSizesTotal += size;
5834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    ++mElementsTotal;
5934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    mSizes += size;
6034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    ++mElements;
6134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
6234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
6334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynbool PidStatistics::subtract(unsigned short size) {
6434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    mSizes -= size;
6534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    --mElements;
668e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    return (mElements == 0) && kill(pid, 0) && (errno != EPERM);
6734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
6834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
6934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid PidStatistics::addTotal(size_t size, size_t element) {
7034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (pid == gone) {
7134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        mSizesTotal += size;
7234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        mElementsTotal += element;
7334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
7434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
7534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
769a03863e88da99ba010342c874252089dd771f7fMark Salyzyn// must call free to release return value
779a03863e88da99ba010342c874252089dd771f7fMark Salyzynchar *PidStatistics::pidToName(pid_t pid) {
789a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    char *retval = NULL;
799a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    if (pid != PidStatistics::gone) {
809a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        char buffer[512];
819a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
829a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        int fd = open(buffer, O_RDONLY);
839a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        if (fd >= 0) {
849a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            ssize_t ret = read(fd, buffer, sizeof(buffer));
859a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            if (ret > 0) {
869a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                buffer[sizeof(buffer)-1] = '\0';
879a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                // frameworks intermediate state
889a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                if (strcmp(buffer, "<pre-initialized>")) {
899a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                    retval = strdup(buffer);
909a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                }
919a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            }
929a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            close(fd);
939a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        }
949a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    }
959a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    return retval;
969a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
979a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
9834facab86b0fe7ec613de92b46b637f864fb0682Mark SalyzynUidStatistics::UidStatistics(uid_t uid)
9934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        : uid(uid) {
10034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    Pids.clear();
10134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
10234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
10334facab86b0fe7ec613de92b46b637f864fb0682Mark SalyzynUidStatistics::~UidStatistics() {
10434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
10534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end();) {
10634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        delete (*it);
10734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        it = Pids.erase(it);
10834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
10934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
11034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
11134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid UidStatistics::add(unsigned short size, pid_t pid) {
11234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatistics *p;
11334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator last;
11434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
11534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (last = it = begin(); it != end(); last = it, ++it) {
11634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        p = *it;
11734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (pid == p->getPid()) {
11834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            p->add(size);
11934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            // poor-man sort, bubble upwards if bigger than last
12034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if ((last != it) && ((*last)->sizesTotal() < p->sizesTotal())) {
12134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                Pids.erase(it);
12234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                Pids.insert(last, p);
12334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
12434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            return;
12534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
12634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
12734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // poor-man sort, insert if bigger than last or last is the gone entry.
12834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    bool insert = (last != it)
12934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        && ((p->getPid() == p->gone)
13034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            || ((*last)->sizesTotal() < (size_t) size));
1319a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    p = new PidStatistics(pid, pidToName(pid));
13234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (insert) {
13334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        Pids.insert(last, p);
13434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    } else {
13534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        Pids.push_back(p);
13634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
13734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    p->add(size);
13834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
13934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
14034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid UidStatistics::subtract(unsigned short size, pid_t pid) {
14134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
14234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
14334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        PidStatistics *p = *it;
14434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (pid == p->getPid()) {
14534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (p->subtract(size)) {
14634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                size_t szsTotal = p->sizesTotal();
14734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                size_t elsTotal = p->elementsTotal();
14834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                delete p;
14934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                Pids.erase(it);
15034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                it = end();
15134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                --it;
15234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                if (it == end()) {
15334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    p = new PidStatistics(p->gone);
15434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    Pids.push_back(p);
15534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                } else {
15634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    p = *it;
15734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    if (p->getPid() != p->gone) {
15834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                        p = new PidStatistics(p->gone);
15934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                        Pids.push_back(p);
16034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    }
16134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
16234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                p->addTotal(szsTotal, elsTotal);
16334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
16434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            return;
16534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
16634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
16734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
16834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
16934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t UidStatistics::sizes(pid_t pid) {
17034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
17134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
17234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
17334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        PidStatistics *p = *it;
17434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((pid == pid_all) || (pid == p->getPid())) {
17534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            sizes += p->sizes();
17634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
17734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
17834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
17934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
18034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
18134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t UidStatistics::elements(pid_t pid) {
18234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
18334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
18434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
18534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        PidStatistics *p = *it;
18634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((pid == pid_all) || (pid == p->getPid())) {
18734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            elements += p->elements();
18834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
18934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
19034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
19134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
19234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t UidStatistics::sizesTotal(pid_t pid) {
19434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
19534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
19634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
19734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        PidStatistics *p = *it;
19834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((pid == pid_all) || (pid == p->getPid())) {
19934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            sizes += p->sizesTotal();
20034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
20134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
20234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
20334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
20434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
20534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t UidStatistics::elementsTotal(pid_t pid) {
20634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
20734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    PidStatisticsCollection::iterator it;
20834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
20934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        PidStatistics *p = *it;
21034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((pid == pid_all) || (pid == p->getPid())) {
21134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            elements += p->elementsTotal();
21234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
21334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
21434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
21534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
21634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
21734facab86b0fe7ec613de92b46b637f864fb0682Mark SalyzynLidStatistics::LidStatistics() {
21834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    Uids.clear();
21934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
22034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
22134facab86b0fe7ec613de92b46b637f864fb0682Mark SalyzynLidStatistics::~LidStatistics() {
22234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
22334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end();) {
22434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        delete (*it);
22534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        it = Uids.erase(it);
22634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
22734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
22834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
22934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid LidStatistics::add(unsigned short size, uid_t uid, pid_t pid) {
23034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatistics *u;
23134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
23234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator last;
23334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
23434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (uid == (uid_t) -1) { // init
23534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        uid = (uid_t) AID_ROOT;
23634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
23734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
23834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (last = it = begin(); it != end(); last = it, ++it) {
23934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        u = *it;
24034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (uid == u->getUid()) {
24134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            u->add(size, pid);
24234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if ((last != it) && ((*last)->sizesTotal() < u->sizesTotal())) {
24334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                Uids.erase(it);
24434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                Uids.insert(last, u);
24534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
24634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            return;
24734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
24834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
24934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    u = new UidStatistics(uid);
25034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if ((last != it) && ((*last)->sizesTotal() < (size_t) size)) {
25134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        Uids.insert(last, u);
25234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    } else {
25334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        Uids.push_back(u);
25434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
25534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    u->add(size, pid);
25634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
25734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid LidStatistics::subtract(unsigned short size, uid_t uid, pid_t pid) {
25934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
26034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
26134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatistics *u = *it;
26234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (uid == u->getUid()) {
26334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            u->subtract(size, pid);
26434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            return;
26534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
26634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
26734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
26834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
26934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LidStatistics::sizes(uid_t uid, pid_t pid) {
27034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
27134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
27234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
27334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatistics *u = *it;
27434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((uid == uid_all) || (uid == u->getUid())) {
27534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            sizes += u->sizes(pid);
27634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
27734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
27834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
27934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
28034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
28134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LidStatistics::elements(uid_t uid, pid_t pid) {
28234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
28334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
28434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
28534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatistics *u = *it;
28634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((uid == uid_all) || (uid == u->getUid())) {
28734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            elements += u->elements(pid);
28834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
28934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
29034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
29134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
29234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LidStatistics::sizesTotal(uid_t uid, pid_t pid) {
29434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
29534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
29634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
29734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatistics *u = *it;
29834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((uid == uid_all) || (uid == u->getUid())) {
29934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            sizes += u->sizesTotal(pid);
30034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
30134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
30234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
30334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
30434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
30534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LidStatistics::elementsTotal(uid_t uid, pid_t pid) {
30634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
30734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    UidStatisticsCollection::iterator it;
30834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (it = begin(); it != end(); ++it) {
30934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatistics *u = *it;
31034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if ((uid == uid_all) || (uid == u->getUid())) {
31134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            elements += u->elementsTotal(pid);
31234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
31334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
31434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
31534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
31634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
31734facab86b0fe7ec613de92b46b637f864fb0682Mark SalyzynLogStatistics::LogStatistics()
31834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        : start(CLOCK_MONOTONIC) {
31934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
32034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        mSizes[i] = 0;
32134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        mElements[i] = 0;
32234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
323e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
324e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    dgram_qlen_statistics = false;
325e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    for(unsigned short bucket = 0; dgram_qlen(bucket); ++bucket) {
326e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        mMinimum[bucket].tv_sec = (uint32_t)-1;
327e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        mMinimum[bucket].tv_nsec = 999999999UL;
328e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    }
329e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn}
330e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
331e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   Each bucket below represents a dgram_qlen of log messages. By
332e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   finding the minimum period of time from start to finish
333e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   of each dgram_qlen, we can get a performance expectation for
334e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   the user space logger. The net result is that the period
335e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   of time divided by the dgram_qlen will give us the average time
336e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   between log messages; at the point where the average time
337e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   is greater than the throughput capability of the logger
338e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   we will not longer require the benefits of the FIFO formed
339e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   by max_dgram_qlen. We will also expect to see a very visible
340e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   knee in the average time between log messages at this point,
341e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   so we do not necessarily have to compare the rate against the
342e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   measured performance (BM_log_maximum_retry) of the logger.
343e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//
344e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   for example (reformatted):
345e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//
346e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//       Minimum time between log events per dgram_qlen:
347e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//       1   2   3   5   10  20  30  50  100  200 300 400 500 600
348e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//       5u2 12u 13u 15u 16u 27u 30u 36u 407u 3m1 3m3 3m9 3m9 5m5
349e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//
350e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   demonstrates a clear knee rising at 100, so this means that for this
351e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   case max_dgram_qlen = 100 would be more than sufficient to handle the
352e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   worst that the system could stuff into the logger. The
353e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   BM_log_maximum_retry performance (derated by the log collection) on the
354e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   same system was 33.2us so we would almost be fine with max_dgram_qlen = 50.
355e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   BM_log_maxumum_retry with statistics off is roughly 20us, so
356e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   max_dgram_qlen = 20 would work. We will be more than willing to have
357e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   a large engineering margin so the rule of thumb that lead us to 100 is
358e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//   fine.
359e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn//
360e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn// bucket dgram_qlen are tuned for /proc/sys/net/unix/max_dgram_qlen = 300
361e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzynconst unsigned short LogStatistics::mBuckets[] = {
362e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 400, 500, 600
363e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn};
364e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
365e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzynunsigned short LogStatistics::dgram_qlen(unsigned short bucket) {
366e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    if (bucket >= sizeof(mBuckets) / sizeof(mBuckets[0])) {
367e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        return 0;
368e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    }
369e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    return mBuckets[bucket];
370e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn}
371e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
372e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzynunsigned long long LogStatistics::minimum(unsigned short bucket) {
373e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    if (mMinimum[bucket].tv_sec == LONG_MAX) {
374e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        return 0;
375e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    }
376e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    return mMinimum[bucket].nsec();
377e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn}
378e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
379e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzynvoid LogStatistics::recordDiff(log_time diff, unsigned short bucket) {
380e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    if ((diff.tv_sec || diff.tv_nsec) && (mMinimum[bucket] > diff)) {
381e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        mMinimum[bucket] = diff;
382e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    }
38334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
38434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
38534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid LogStatistics::add(unsigned short size,
38634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                        log_id_t log_id, uid_t uid, pid_t pid) {
38734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    mSizes[log_id] += size;
38834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    ++mElements[log_id];
38934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    id(log_id).add(size, uid, pid);
39034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
39134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
39234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynvoid LogStatistics::subtract(unsigned short size,
39334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                             log_id_t log_id, uid_t uid, pid_t pid) {
39434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    mSizes[log_id] -= size;
39534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    --mElements[log_id];
39634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    id(log_id).subtract(size, uid, pid);
39734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
39834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
39934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LogStatistics::sizes(log_id_t log_id, uid_t uid, pid_t pid) {
40034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (log_id != log_id_all) {
40134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        return id(log_id).sizes(uid, pid);
40234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
40334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
40434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
40534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        sizes += id(i).sizes(uid, pid);
40634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
40734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
40834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
40934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
41034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LogStatistics::elements(log_id_t log_id, uid_t uid, pid_t pid) {
41134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (log_id != log_id_all) {
41234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        return id(log_id).elements(uid, pid);
41334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
41434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
41534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
41634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        elements += id(i).elements(uid, pid);
41734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
41834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
41934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
42034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
42134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LogStatistics::sizesTotal(log_id_t log_id, uid_t uid, pid_t pid) {
42234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (log_id != log_id_all) {
42334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        return id(log_id).sizesTotal(uid, pid);
42434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
42534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes = 0;
42634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
42734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        sizes += id(i).sizesTotal(uid, pid);
42834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
42934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return sizes;
43034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
43134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
43234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynsize_t LogStatistics::elementsTotal(log_id_t log_id, uid_t uid, pid_t pid) {
43334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (log_id != log_id_all) {
43434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        return id(log_id).elementsTotal(uid, pid);
43534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
43634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements = 0;
43734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
43834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        elements += id(i).elementsTotal(uid, pid);
43934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
44034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return elements;
44134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
44234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
443dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynvoid LogStatistics::format(char **buf,
444dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn                           uid_t uid, unsigned int logMask, log_time oldest) {
4459a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    static const unsigned short spaces_current = 13;
4469a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    static const unsigned short spaces_total = 19;
44734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
44834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (*buf) {
449239605ef64d34ced82c97870e3f3f5c4145be58cGreg Hackmann        free(*buf);
45034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        *buf = NULL;
45134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
45234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
45334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    android::String8 string("        span -> size/num");
45434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t oldLength;
45534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    short spaces = 2;
45634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
45734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
45834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (logMask & (1 << i)) {
45934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            oldLength = string.length();
460e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (spaces < 0) {
461e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces = 0;
462e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
46334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            string.appendFormat("%*s%s", spaces, "", android_log_id_to_name(i));
46434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            spaces += spaces_total + oldLength - string.length();
46534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
46634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
46734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
46834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    spaces = 1;
46934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_time t(CLOCK_MONOTONIC);
47034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    unsigned long long d = t.nsec() - start.nsec();
47134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    string.appendFormat("\nTotal%4llu:%02llu:%02llu.%09llu",
47234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                  d / NS_PER_SEC / 60 / 60, (d / NS_PER_SEC / 60) % 60,
47334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                  (d / NS_PER_SEC) % 60, d % NS_PER_SEC);
47434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
47534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
47634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (!(logMask & (1 << i))) {
47734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            continue;
47834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
47934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        oldLength = string.length();
480e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        if (spaces < 0) {
481e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            spaces = 0;
482e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        }
48334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        string.appendFormat("%*s%zu/%zu", spaces, "",
48434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                            sizesTotal(i), elementsTotal(i));
48534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        spaces += spaces_total + oldLength - string.length();
48634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
48734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
48834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    spaces = 1;
48934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    d = t.nsec() - oldest.nsec();
49034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    string.appendFormat("\nNow%6llu:%02llu:%02llu.%09llu",
49134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                  d / NS_PER_SEC / 60 / 60, (d / NS_PER_SEC / 60) % 60,
49234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                  (d / NS_PER_SEC) % 60, d % NS_PER_SEC);
49334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
49434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
49534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (!(logMask & (1 << i))) {
49634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            continue;
49734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
49834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
49934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        size_t els = elements(i);
50034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (els) {
50134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            oldLength = string.length();
502e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (spaces < 0) {
503e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces = 0;
504e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
50534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            string.appendFormat("%*s%zu/%zu", spaces, "", sizes(i), els);
50634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            spaces -= string.length() - oldLength;
50734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
50834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        spaces += spaces_total;
50934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
51034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
5118e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    // Construct list of worst spammers by Pid
5128e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    static const unsigned char num_spammers = 10;
5138e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    bool header = false;
5148e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5158e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    log_id_for_each(i) {
5168e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        if (!(logMask & (1 << i))) {
5178e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            continue;
5188e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
5198e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5208e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        PidStatisticsCollection pids;
5218e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        pids.clear();
5228e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5238e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        LidStatistics &l = id(i);
5248e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        UidStatisticsCollection::iterator iu;
5258e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        for (iu = l.begin(); iu != l.end(); ++iu) {
5268e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            UidStatistics &u = *(*iu);
5278e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            PidStatisticsCollection::iterator ip;
5288e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            for (ip = u.begin(); ip != u.end(); ++ip) {
5298e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                PidStatistics *p = (*ip);
5308e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                if (p->getPid() == p->gone) {
5318e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    break;
5328e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                }
5338e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5348e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                size_t mySizes = p->sizes();
5358e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5368e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                PidStatisticsCollection::iterator q;
5378e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                unsigned char num = 0;
5388e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                for (q = pids.begin(); q != pids.end(); ++q) {
5398e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    if (mySizes > (*q)->sizes()) {
5408e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        pids.insert(q, p);
5418e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        break;
5428e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    }
5438e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    // do we need to traverse deeper in the list?
5448e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    if (++num > num_spammers) {
5458e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        break;
5468e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    }
5478e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                }
5488e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                if (q == pids.end()) {
5498e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                   pids.push_back(p);
5508e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                }
5518e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            }
5528e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
5538e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5548e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        size_t threshold = sizes(i);
5558e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        if (threshold < 65536) {
5568e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            threshold = 65536;
5578e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
5588e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        threshold /= 100;
5598e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5608e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        PidStatisticsCollection::iterator pt = pids.begin();
5618e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5628e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        for(int line = 0;
5638e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                (pt != pids.end()) && (line < num_spammers);
5648e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                ++line, pt = pids.erase(pt)) {
5658e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            PidStatistics *p = *pt;
5668e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5678e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            size_t sizes = p->sizes();
5688e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            if (sizes < threshold) {
5698e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                break;
5708e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            }
5718e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5728e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            char *name = p->getName();
5738e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            pid_t pid = p->getPid();
5748e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            if (!name || !*name) {
5758e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                name = pidToName(pid);
5768e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                if (name) {
5778e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    if (*name) {
5788e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        p->setName(name);
5798e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    } else {
5808e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        free(name);
5818e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                        name = NULL;
5828e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                    }
5838e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                }
5848e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            }
5858e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5868e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            if (!header) {
5878e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                string.appendFormat("\n\nChattiest clients:\n"
5888e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                                    "log id %-*s PID[?] name",
5898e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                                    spaces_total, "size/total");
5908e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                header = true;
5918e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            }
5928e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5938e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            size_t sizesTotal = p->sizesTotal();
5948e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5958e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            android::String8 sz("");
5968e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            sz.appendFormat((sizes != sizesTotal) ? "%zu/%zu" : "%zu",
5978e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                            sizes, sizesTotal);
5988e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
5998e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            android::String8 pd("");
6008e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            pd.appendFormat("%u%c", pid,
6018e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                            (kill(pid, 0) && (errno != EPERM)) ? '?' : ' ');
6028e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
6038e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            string.appendFormat("\n%-7s%-*s %-7s%s",
6048e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                                line ? "" : android_log_id_to_name(i),
6058e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                                spaces_total, sz.string(), pd.string(),
6068e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                                name ? name : "");
6078e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
6088e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
6098e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        pids.clear();
6108e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn    }
6118e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
612e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    if (dgram_qlen_statistics) {
613e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        const unsigned short spaces_time = 6;
614e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        const unsigned long long max_seconds = 100000;
615e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        spaces = 0;
616e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        string.append("\n\nMinimum time between log events per dgram_qlen:\n");
617e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        for(unsigned short i = 0; dgram_qlen(i); ++i) {
618e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            oldLength = string.length();
619e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (spaces < 0) {
620e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces = 0;
621e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
622e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            string.appendFormat("%*s%u", spaces, "", dgram_qlen(i));
623e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            spaces += spaces_time + oldLength - string.length();
624e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        }
625e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        string.append("\n");
626e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        spaces = 0;
627e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        unsigned short n;
628e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        for(unsigned short i = 0; (n = dgram_qlen(i)); ++i) {
629e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            unsigned long long duration = minimum(i);
630e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (duration) {
631e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                duration /= n;
632e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (duration >= (NS_PER_SEC * max_seconds)) {
633e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    duration = NS_PER_SEC * (max_seconds - 1);
634e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
635e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                oldLength = string.length();
636e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (spaces < 0) {
637e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    spaces = 0;
638e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
639e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                string.appendFormat("%*s", spaces, "");
640e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (duration >= (NS_PER_SEC * 10)) {
641e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    string.appendFormat("%llu",
642e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                        (duration + (NS_PER_SEC / 2))
643e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                            / NS_PER_SEC);
644e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                } else if (duration >= (NS_PER_SEC / (1000 / 10))) {
645e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    string.appendFormat("%llum",
646e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                        (duration + (NS_PER_SEC / 2 / 1000))
647e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                            / (NS_PER_SEC / 1000));
648e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                } else if (duration >= (NS_PER_SEC / (1000000 / 10))) {
649e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    string.appendFormat("%lluu",
650e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                         (duration + (NS_PER_SEC / 2 / 1000000))
651e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                             / (NS_PER_SEC / 1000000));
652e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                } else {
653e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    string.appendFormat("%llun", duration);
654e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
655e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces -= string.length() - oldLength;
656e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
657e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            spaces += spaces_time;
658e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        }
659e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn    }
660e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
66134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    log_id_for_each(i) {
66234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (!(logMask & (1 << i))) {
66334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            continue;
66434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
66534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
6668e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        header = false;
66734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        bool first = true;
66834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
66934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        UidStatisticsCollection::iterator ut;
67034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        for(ut = id(i).begin(); ut != id(i).end(); ++ut) {
67134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            UidStatistics *up = *ut;
67234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if ((uid != AID_ROOT) && (uid != up->getUid())) {
67334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                continue;
67434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
67534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
67634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            PidStatisticsCollection::iterator pt = up->begin();
67734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (pt == up->end()) {
67834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                continue;
67934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
68034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
68134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            android::String8 intermediate;
68234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
68334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (!header) {
68434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                // header below tuned to match spaces_total and spaces_current
68534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces = 0;
68634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                intermediate = string.format("%s: UID/PID Total size/num",
68734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                             android_log_id_to_name(i));
68834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("\n\n%-31sNow          "
68934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                         "UID/PID[?]  Total              Now",
69034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                    intermediate.string());
69134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                intermediate.clear();
69234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                header = true;
69334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
69434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
69534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            bool oneline = ++pt == up->end();
69634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            --pt;
69734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
69834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (!oneline) {
69934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                first = true;
700e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            } else if (!first && (spaces > 0)) {
70134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("%*s", spaces, "");
70234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
70334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            spaces = 0;
70434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
70534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            uid_t u = up->getUid();
70634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            pid_t p = (*pt)->getPid();
70734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
70834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            intermediate = string.format(oneline
70934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                             ? ((p == PidStatistics::gone)
71034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                                 ? "%d/?"
71134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                                 : "%d/%d")
71234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                             : "%d",
71334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                         u, p);
7148e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            string.appendFormat(first ? "\n%-12s" : "%-12s",
71534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                intermediate.string());
71634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            intermediate.clear();
71734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
71834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            size_t elsTotal = up->elementsTotal();
71934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            oldLength = string.length();
72034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            string.appendFormat("%zu/%zu", up->sizesTotal(), elsTotal);
72134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            spaces += spaces_total + oldLength - string.length();
72234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
72334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            size_t els = up->elements();
72434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (els == elsTotal) {
725e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (spaces < 0) {
726e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    spaces = 0;
727e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
72834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("%*s=", spaces, "");
72934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces = -1;
73034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            } else if (els) {
73134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                oldLength = string.length();
732e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (spaces < 0) {
733e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    spaces = 0;
734e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
73534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("%*s%zu/%zu", spaces, "", up->sizes(), els);
73634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces -= string.length() - oldLength;
73734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
73834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            spaces += spaces_current;
73934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
74034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            first = !first;
74134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
74234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (oneline) {
74334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                continue;
74434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
74534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
74634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            size_t gone_szs = 0;
74734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            size_t gone_els = 0;
74834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
74934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            for(; pt != up->end(); ++pt) {
75034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                PidStatistics *pp = *pt;
75134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                pid_t p = pp->getPid();
75234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
75334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                // If a PID no longer has any current logs, and is not
75434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                // active anymore, skip & report totals for gone.
75534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                elsTotal = pp->elementsTotal();
75634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                size_t szsTotal = pp->sizesTotal();
75734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                if (p == pp->gone) {
75834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    gone_szs += szsTotal;
75934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    gone_els += elsTotal;
76034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    continue;
76134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
76234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                els = pp->elements();
7638e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                bool gone = kill(p, 0) && (errno != EPERM);
76434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                if (gone && (els == 0)) {
76534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    // ToDo: garbage collection: move this statistical bucket
76634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    //       from its current UID/PID to UID/? (races and
76734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    //       wrap around are our achilles heel). Below is
76834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    //       merely lipservice to catch PIDs that were still
76934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    //       around when the stats were pruned to zero.
77034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    gone_szs += szsTotal;
77134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    gone_els += elsTotal;
77234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    continue;
77334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
77434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
775e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (!first && (spaces > 0)) {
77634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    string.appendFormat("%*s", spaces, "");
77734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
77834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces = 0;
77934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
7808e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                intermediate = string.format(gone ? "%d/%d?" : "%d/%d", u, p);
7818e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                string.appendFormat(first ? "\n%-12s" : "%-12s",
78234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                    intermediate.string());
78334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                intermediate.clear();
78434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
78534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                oldLength = string.length();
78634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("%zu/%zu", szsTotal, elsTotal);
78734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces += spaces_total + oldLength - string.length();
78834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
78934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                if (els == elsTotal) {
790e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    if (spaces < 0) {
791e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                        spaces = 0;
792e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    }
79334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    string.appendFormat("%*s=", spaces, "");
79434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    spaces = -1;
79534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                } else if (els) {
79634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    oldLength = string.length();
797e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    if (spaces < 0) {
798e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                        spaces = 0;
799e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                    }
80034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    string.appendFormat("%*s%zu/%zu", spaces, "",
80134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                        pp->sizes(), els);
80234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    spaces -= string.length() - oldLength;
80334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
80434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces += spaces_current;
80534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
80634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                first = !first;
80734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
80834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
80934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            if (gone_els) {
810e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                if (!first && (spaces > 0)) {
81134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                    string.appendFormat("%*s", spaces, "");
81234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                }
81334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
81434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                intermediate = string.format("%d/?", u);
8158e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn                string.appendFormat(first ? "\n%-12s" : "%-12s",
81634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                    intermediate.string());
81734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                intermediate.clear();
81834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
81934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces = spaces_total + spaces_current;
82034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
82134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                oldLength = string.length();
82234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                string.appendFormat("%zu/%zu", gone_szs, gone_els);
82334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                spaces -= string.length() - oldLength;
82434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
82534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                first = !first;
82634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
82734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
82834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
82934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
830dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    *buf = strdup(string.string());
83134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
8324ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn
8334ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) {
8344ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    log_id_for_each(i) {
8354ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        LidStatistics &l = id(i);
8364ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        UidStatisticsCollection::iterator iu;
8374ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        for (iu = l.begin(); iu != l.end(); ++iu) {
8384ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            UidStatistics &u = *(*iu);
8394ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            PidStatisticsCollection::iterator ip;
8404ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            for (ip = u.begin(); ip != u.end(); ++ip) {
8414ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn                if ((*ip)->getPid() == pid) {
8424ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn                    return u.getUid();
8434ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn                }
8444ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            }
8454ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        }
8464ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    }
8474ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    return getuid(); // associate this with the logger
8484ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn}
849