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
1734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#ifndef _LOGD_LOG_STATISTICS_H__
1834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define _LOGD_LOG_STATISTICS_H__
1934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
20b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn#include <ctype.h>
21f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn#include <inttypes.h>
22f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn#include <stdint.h>
23720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <stdlib.h>
24f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn#include <string.h>
2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <sys/types.h>
2634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
27501c373916e292764400dbae735f44b33378400fMark Salyzyn#include <algorithm>  // std::max
28b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn#include <memory>
29e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes#include <string>
30e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes#include <string_view>
31511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn#include <unordered_map>
32511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
334f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
34501c373916e292764400dbae735f44b33378400fMark Salyzyn#include <android/log.h>
3503bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn#include <log/log_time.h>
36758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <private/android_filesystem_config.h>
37f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn#include <utils/FastStrcmp.h>
3897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
3997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h"
405ac5c6b19364b5b3061a59db796b2357c95c3b64Mark Salyzyn#include "LogUtils.h"
4134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
4234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \
43501c373916e292764400dbae735f44b33378400fMark Salyzyn    for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t)((i) + 1))
4434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
45758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynclass LogStatistics;
46758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
47720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry>
48511338dd575572d567c04d69eaea60627b6c3452Mark Salyzynclass LogHashtable {
49511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    std::unordered_map<TKey, TEntry> map;
50511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
516d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t bucket_size() const {
526d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        size_t count = 0;
536d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for (size_t idx = 0; idx < map.bucket_count(); ++idx) {
546d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size_t bucket_size = map.bucket_size(idx);
556d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (bucket_size == 0) bucket_size = 1;
566d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            count += bucket_size;
576d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
586d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        float load_factor = map.max_load_factor();
596d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        if (load_factor < 1.0) return count;
606d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return count * load_factor;
616d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
626d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
636d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    static const size_t unordered_map_per_entry_overhead = sizeof(void*);
646d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    static const size_t unordered_map_bucket_overhead = sizeof(void*);
656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
66501c373916e292764400dbae735f44b33378400fMark Salyzyn   public:
67501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t size() const {
68501c373916e292764400dbae735f44b33378400fMark Salyzyn        return map.size();
69501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
70b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn
716d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    // Estimate unordered_map memory usage.
726d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
736d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return sizeof(*this) +
74b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn               (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) +
756d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn               (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead);
766d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
776d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
78511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
79501c373916e292764400dbae735f44b33378400fMark Salyzyn    typedef
80501c373916e292764400dbae735f44b33378400fMark Salyzyn        typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
81511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
82501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::unique_ptr<const TEntry* []> sort(uid_t uid, pid_t pid,
83ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                           size_t len) const {
84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!len) {
85f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            std::unique_ptr<const TEntry* []> sorted(nullptr);
86720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
87720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
88720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
89501c373916e292764400dbae735f44b33378400fMark Salyzyn        const TEntry** retval = new const TEntry*[len];
90758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        memset(retval, 0, sizeof(*retval) * len);
91720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
92501c373916e292764400dbae735f44b33378400fMark Salyzyn        for (const_iterator it = map.begin(); it != map.end(); ++it) {
93501c373916e292764400dbae735f44b33378400fMark Salyzyn            const TEntry& entry = it->second;
94ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
95ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if ((uid != AID_ROOT) && (uid != entry.getUid())) {
96ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
97ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
98ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if (pid && entry.getPid() && (pid != entry.getPid())) {
99ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
100ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
101ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
102758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            size_t sizes = entry.getSizes();
103758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            ssize_t index = len - 1;
104501c373916e292764400dbae735f44b33378400fMark Salyzyn            while ((!retval[index] || (sizes > retval[index]->getSizes())) &&
105501c373916e292764400dbae735f44b33378400fMark Salyzyn                   (--index >= 0))
106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
107758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (++index < (ssize_t)len) {
108758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                size_t num = len - index - 1;
109758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                if (num) {
110758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    memmove(&retval[index + 1], &retval[index],
111758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                            num * sizeof(retval[0]));
112720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
113758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                retval[index] = &entry;
114720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
115720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
116501c373916e292764400dbae735f44b33378400fMark Salyzyn        std::unique_ptr<const TEntry* []> sorted(retval);
117720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
118720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
119720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
120f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline iterator add(const TKey& key, const LogBufferElement* element) {
121511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
122511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
123758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(element))).first;
124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
125758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.add(element);
12681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
127511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
12981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
130511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key) {
131511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
132511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
133511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(key))).first;
134511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
135511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(key);
13681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
137511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
13981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
140f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    void subtract(TKey&& key, const LogBufferElement* element) {
141f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        iterator it = map.find(std::move(key));
142f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if ((it != map.end()) && it->second.subtract(element)) {
143f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            map.erase(it);
144f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
145f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
146f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
147f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    void subtract(const TKey& key, const LogBufferElement* element) {
148511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if ((it != map.end()) && it->second.subtract(element)) {
150511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            map.erase(it);
15181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
15281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
15381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
154f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void drop(TKey key, const LogBufferElement* element) {
155511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
156511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it != map.end()) {
157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.drop(element);
15881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
15981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
16081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
161501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline iterator begin() {
162501c373916e292764400dbae735f44b33378400fMark Salyzyn        return map.begin();
163501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
164501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline const_iterator begin() const {
165501c373916e292764400dbae735f44b33378400fMark Salyzyn        return map.begin();
166501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
167501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline iterator end() {
168501c373916e292764400dbae735f44b33378400fMark Salyzyn        return map.end();
169501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
170501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline const_iterator end() const {
171501c373916e292764400dbae735f44b33378400fMark Salyzyn        return map.end();
172501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
174501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string format(const LogStatistics& stat, uid_t uid, pid_t pid,
175501c373916e292764400dbae735f44b33378400fMark Salyzyn                       const std::string& name = std::string(""),
176501c373916e292764400dbae735f44b33378400fMark Salyzyn                       log_id_t id = LOG_ID_MAX) const {
177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        static const size_t maximum_sorted_entries = 32;
178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        std::string output;
179501c373916e292764400dbae735f44b33378400fMark Salyzyn        std::unique_ptr<const TEntry* []> sorted =
180501c373916e292764400dbae735f44b33378400fMark Salyzyn            sort(uid, pid, maximum_sorted_entries);
181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!sorted.get()) {
182758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return output;
183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        bool headerPrinted = false;
185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for (size_t index = 0; index < maximum_sorted_entries; ++index) {
186501c373916e292764400dbae735f44b33378400fMark Salyzyn            const TEntry* entry = sorted[index];
187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!entry) {
188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
190758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
192758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
193758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!headerPrinted) {
194758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += "\n\n";
195758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += entry->formatHeader(name, id);
196758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                headerPrinted = true;
197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            output += entry->format(stat, id);
199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return output;
201758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
202720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
203720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants {
205501c373916e292764400dbae735f44b33378400fMark Salyzynstatic constexpr size_t pruned_len = 14;
206501c373916e292764400dbae735f44b33378400fMark Salyzynstatic constexpr size_t total_len = 80;
207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
20981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
21097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
21134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
212501c373916e292764400dbae735f44b33378400fMark Salyzyn    EntryBase() : size(0) {
213501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
214f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit EntryBase(const LogBufferElement* element)
215f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        : size(element->getMsgLen()) {
216501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
21734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
218501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t getSizes() const {
219501c373916e292764400dbae735f44b33378400fMark Salyzyn        return size;
220501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
22181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
222f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
223501c373916e292764400dbae735f44b33378400fMark Salyzyn        size += element->getMsgLen();
224501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
225f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline bool subtract(const LogBufferElement* element) {
226758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        size -= element->getMsgLen();
227758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return !size;
228758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
229758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
230501c373916e292764400dbae735f44b33378400fMark Salyzyn    static std::string formatLine(const std::string& name,
231501c373916e292764400dbae735f44b33378400fMark Salyzyn                                  const std::string& size,
232501c373916e292764400dbae735f44b33378400fMark Salyzyn                                  const std::string& pruned) {
233501c373916e292764400dbae735f44b33378400fMark Salyzyn        ssize_t drop_len =
234501c373916e292764400dbae735f44b33378400fMark Salyzyn            std::max(pruned.length() + 1, EntryBaseConstants::pruned_len);
235501c373916e292764400dbae735f44b33378400fMark Salyzyn        ssize_t size_len =
236501c373916e292764400dbae735f44b33378400fMark Salyzyn            std::max(size.length() + 1, EntryBaseConstants::total_len -
237501c373916e292764400dbae735f44b33378400fMark Salyzyn                                            name.length() - drop_len - 1);
238501c373916e292764400dbae735f44b33378400fMark Salyzyn
239501c373916e292764400dbae735f44b33378400fMark Salyzyn        std::string ret = android::base::StringPrintf(
240501c373916e292764400dbae735f44b33378400fMark Salyzyn            "%s%*s%*s", name.c_str(), (int)size_len, size.c_str(),
241501c373916e292764400dbae735f44b33378400fMark Salyzyn            (int)drop_len, pruned.c_str());
242b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        // remove any trailing spaces
243b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        size_t pos = ret.size();
244b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        size_t len = 0;
245b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        while (pos && isspace(ret[--pos])) ++len;
246b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        if (len) ret.erase(pos + 1, len);
247b545e1c9e3d5989e2e889e65436524fdcfed930eMark Salyzyn        return ret + "\n";
248758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
24981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
25081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
25181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
25281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
25381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
254501c373916e292764400dbae735f44b33378400fMark Salyzyn    EntryBaseDropped() : dropped(0) {
255501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
256f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit EntryBaseDropped(const LogBufferElement* element)
257501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBase(element), dropped(element->getDropped()) {
258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
25981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
260501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t getDropped() const {
261501c373916e292764400dbae735f44b33378400fMark Salyzyn        return dropped;
262501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
263ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
264f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
265758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped += element->getDropped();
266758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
26781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
268f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline bool subtract(const LogBufferElement* element) {
269758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped -= element->getDropped();
270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return EntryBase::subtract(element) && !dropped;
27181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
272f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void drop(const LogBufferElement* element) {
27381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
274758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::subtract(element);
27581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
27681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
27781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
27881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
27981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
280ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
28181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
282f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit UidEntry(const LogBufferElement* element)
283501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
284501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element->getUid()),
285501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element->getPid()) {
286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
28781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
288501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline const uid_t& getKey() const {
289501c373916e292764400dbae735f44b33378400fMark Salyzyn        return uid;
290501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
291501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline const uid_t& getUid() const {
292501c373916e292764400dbae735f44b33378400fMark Salyzyn        return getKey();
293501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
294501c373916e292764400dbae735f44b33378400fMark Salyzyn    inline const pid_t& getPid() const {
295501c373916e292764400dbae735f44b33378400fMark Salyzyn        return pid;
296501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
297ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
298f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
299ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
300ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
301ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
302a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        EntryBaseDropped::add(element);
303ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    }
304758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
305501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string formatHeader(const std::string& name, log_id_t id) const;
306501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string format(const LogStatistics& stat, log_id_t id) const;
30734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
30834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
30981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
310720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
311720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
312501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* name;
313720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
314501c373916e292764400dbae735f44b33378400fMark Salyzyn    explicit PidEntry(pid_t pid)
315501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(),
316501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(pid),
317501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(android::pidToUid(pid)),
318501c373916e292764400dbae735f44b33378400fMark Salyzyn          name(android::pidToName(pid)) {
319501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
320f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit PidEntry(const LogBufferElement* element)
321501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
322501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element->getPid()),
323501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element->getUid()),
324501c373916e292764400dbae735f44b33378400fMark Salyzyn          name(android::pidToName(pid)) {
325758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
326501c373916e292764400dbae735f44b33378400fMark Salyzyn    PidEntry(const PidEntry& element)
327501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
328501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element.pid),
329501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element.uid),
330f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          name(element.name ? strdup(element.name) : nullptr) {
331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
332501c373916e292764400dbae735f44b33378400fMark Salyzyn    ~PidEntry() {
333501c373916e292764400dbae735f44b33378400fMark Salyzyn        free(name);
334758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
335720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
336501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getKey() const {
337501c373916e292764400dbae735f44b33378400fMark Salyzyn        return pid;
338501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
339501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getPid() const {
340501c373916e292764400dbae735f44b33378400fMark Salyzyn        return getKey();
341501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
342501c373916e292764400dbae735f44b33378400fMark Salyzyn    const uid_t& getUid() const {
343501c373916e292764400dbae735f44b33378400fMark Salyzyn        return uid;
344501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
345501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* getName() const {
346501c373916e292764400dbae735f44b33378400fMark Salyzyn        return name;
347501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
34881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
349758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t newPid) {
3500eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn        if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
351aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
352f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            name = nullptr;
353aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
35481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(newPid);
35681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
35781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
35881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
359f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (getUid() != incomingUid) {
362758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
36381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
364758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(element->getPid());
36581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
366758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getPid());
36781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
36981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
371501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string formatHeader(const std::string& name, log_id_t id) const;
372501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string format(const LogStatistics& stat, log_id_t id) const;
373344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn};
374344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
37517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped {
37617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t tid;
377ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
37817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    uid_t uid;
379501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* name;
380501c373916e292764400dbae735f44b33378400fMark Salyzyn
381501c373916e292764400dbae735f44b33378400fMark Salyzyn    TidEntry(pid_t tid, pid_t pid)
382501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(),
383501c373916e292764400dbae735f44b33378400fMark Salyzyn          tid(tid),
384501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(pid),
385501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(android::pidToUid(tid)),
386501c373916e292764400dbae735f44b33378400fMark Salyzyn          name(android::tidToName(tid)) {
387501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
388c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    TidEntry(pid_t tid)
389c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn        : EntryBaseDropped(),
390c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn          tid(tid),
391c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn          pid(android::tidToPid(tid)),
392c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn          uid(android::pidToUid(tid)),
393c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn          name(android::tidToName(tid)) {
394c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    }
395f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TidEntry(const LogBufferElement* element)
396501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
397501c373916e292764400dbae735f44b33378400fMark Salyzyn          tid(element->getTid()),
398501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element->getPid()),
399501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element->getUid()),
400501c373916e292764400dbae735f44b33378400fMark Salyzyn          name(android::tidToName(tid)) {
401501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
402501c373916e292764400dbae735f44b33378400fMark Salyzyn    TidEntry(const TidEntry& element)
403501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
404501c373916e292764400dbae735f44b33378400fMark Salyzyn          tid(element.tid),
405501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element.pid),
406501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element.uid),
407f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          name(element.name ? strdup(element.name) : nullptr) {
408501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
409501c373916e292764400dbae735f44b33378400fMark Salyzyn    ~TidEntry() {
410501c373916e292764400dbae735f44b33378400fMark Salyzyn        free(name);
411501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
412501c373916e292764400dbae735f44b33378400fMark Salyzyn
413501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getKey() const {
414501c373916e292764400dbae735f44b33378400fMark Salyzyn        return tid;
415501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
416501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getTid() const {
417501c373916e292764400dbae735f44b33378400fMark Salyzyn        return getKey();
418501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
419501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getPid() const {
420501c373916e292764400dbae735f44b33378400fMark Salyzyn        return pid;
421501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
422501c373916e292764400dbae735f44b33378400fMark Salyzyn    const uid_t& getUid() const {
423501c373916e292764400dbae735f44b33378400fMark Salyzyn        return uid;
424501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
425501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* getName() const {
426501c373916e292764400dbae735f44b33378400fMark Salyzyn        return name;
427501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
42817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
429758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t incomingTid) {
4300eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn        if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
43117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
432f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            name = nullptr;
43317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
43417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (!name) {
435758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(incomingTid);
43617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
43717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
43817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
439f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
440758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
441ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        pid_t incomingPid = element->getPid();
442ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
443758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
444ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = incomingPid;
44517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
446758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(element->getTid());
44717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        } else {
448758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getTid());
44917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
450758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
45117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
452758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
453501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string formatHeader(const std::string& name, log_id_t id) const;
454501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string format(const LogStatistics& stat, log_id_t id) const;
45517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn};
45617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
4576a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynstruct TagEntry : public EntryBaseDropped {
458344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t tag;
459ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
460344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    uid_t uid;
461344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
462f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TagEntry(const LogBufferElement* element)
463501c373916e292764400dbae735f44b33378400fMark Salyzyn        : EntryBaseDropped(element),
464501c373916e292764400dbae735f44b33378400fMark Salyzyn          tag(element->getTag()),
465501c373916e292764400dbae735f44b33378400fMark Salyzyn          pid(element->getPid()),
466501c373916e292764400dbae735f44b33378400fMark Salyzyn          uid(element->getUid()) {
467758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
468344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
469501c373916e292764400dbae735f44b33378400fMark Salyzyn    const uint32_t& getKey() const {
470501c373916e292764400dbae735f44b33378400fMark Salyzyn        return tag;
471501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
472501c373916e292764400dbae735f44b33378400fMark Salyzyn    const pid_t& getPid() const {
473501c373916e292764400dbae735f44b33378400fMark Salyzyn        return pid;
474501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
475501c373916e292764400dbae735f44b33378400fMark Salyzyn    const uid_t& getUid() const {
476501c373916e292764400dbae735f44b33378400fMark Salyzyn        return uid;
477501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
478501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* getName() const {
479501c373916e292764400dbae735f44b33378400fMark Salyzyn        return android::tagToName(tag);
480501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
48181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
482f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
483ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (uid != element->getUid()) {
484344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn            uid = -1;
485344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        }
486ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
487ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
488ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
489a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        EntryBaseDropped::add(element);
490344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
491758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
492501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string formatHeader(const std::string& name, log_id_t id) const;
493501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::string format(const LogStatistics& stat, log_id_t id) const;
494720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
495720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
496f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzynstruct TagNameKey {
497f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string* alloc;
498e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes    std::string_view name;  // Saves space if const char*
499f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
500f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TagNameKey(const LogBufferElement* element)
501f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        : alloc(nullptr), name("", strlen("")) {
502f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (element->isBinary()) {
503f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            uint32_t tag = element->getTag();
504f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            if (tag) {
505f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                const char* cp = android::tagToName(tag);
506f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                if (cp) {
507e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes                    name = std::string_view(cp, strlen(cp));
508f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                    return;
509f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                }
510f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            }
511f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            alloc = new std::string(
512f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                android::base::StringPrintf("[%" PRIu32 "]", tag));
513f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            if (!alloc) return;
514e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes            name = std::string_view(alloc->c_str(), alloc->size());
515f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            return;
516f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
517f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        const char* msg = element->getMsg();
518f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (!msg) {
519e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes            name = std::string_view("chatty", strlen("chatty"));
520f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            return;
521f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
522f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        ++msg;
523f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        unsigned short len = element->getMsgLen();
524f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        len = (len <= 1) ? 0 : strnlen(msg, len - 1);
525f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (!len) {
526e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes            name = std::string_view("<NULL>", strlen("<NULL>"));
527f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            return;
528f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
529f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        alloc = new std::string(msg, len);
530f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (!alloc) return;
531e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes        name = std::string_view(alloc->c_str(), alloc->size());
532f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
533f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
534f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TagNameKey(TagNameKey&& rval)
535f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        : alloc(rval.alloc), name(rval.name.data(), rval.name.length()) {
536f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        rval.alloc = nullptr;
537f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
538f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
539f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TagNameKey(const TagNameKey& rval)
540f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        : alloc(rval.alloc ? new std::string(*rval.alloc) : nullptr),
541f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          name(alloc ? alloc->data() : rval.name.data(), rval.name.length()) {
542f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
543f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
544f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    ~TagNameKey() {
545f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (alloc) delete alloc;
546f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
547f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
548e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes    operator const std::string_view() const {
549f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name;
550f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
551f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
552f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const char* data() const {
553f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name.data();
554f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
555f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    size_t length() const {
556f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name.length();
557f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
558f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
559f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    bool operator==(const TagNameKey& rval) const {
560f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (length() != rval.length()) return false;
561f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (length() == 0) return true;
562f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return fastcmp<strncmp>(data(), rval.data(), length()) == 0;
563f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
564f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    bool operator!=(const TagNameKey& rval) const {
565f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return !(*this == rval);
566f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
567f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
568f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    size_t getAllocLength() const {
569f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return alloc ? alloc->length() + 1 + sizeof(std::string) : 0;
570f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
571f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn};
572f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
573f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn// Hash for TagNameKey
574f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyntemplate <>
575f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzynstruct std::hash<TagNameKey>
576f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    : public std::unary_function<const TagNameKey&, size_t> {
577f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    size_t operator()(const TagNameKey& __t) const noexcept {
578f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (!__t.length()) return 0;
579e805883a2b088a187ce4339e04387efbeb35b512Elliott Hughes        return std::hash<std::string_view>()(std::string_view(__t));
580f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
581f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn};
582f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
583f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzynstruct TagNameEntry : public EntryBase {
584f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    pid_t tid;
585f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    pid_t pid;
586f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    uid_t uid;
587f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    TagNameKey name;
588f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
589f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    explicit TagNameEntry(const LogBufferElement* element)
590f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        : EntryBase(element),
591f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          tid(element->getTid()),
592f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          pid(element->getPid()),
593f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          uid(element->getUid()),
594f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn          name(element) {
595f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
596f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
597f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const TagNameKey& getKey() const {
598f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name;
599f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
600f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const pid_t& getTid() const {
601f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return tid;
602f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
603f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const pid_t& getPid() const {
604f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return pid;
605f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
606f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const uid_t& getUid() const {
607f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return uid;
608f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
609f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    const char* getName() const {
610f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name.data();
611f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
612f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    size_t getNameAllocLength() const {
613f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        return name.getAllocLength();
614f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
615f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
616f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    inline void add(const LogBufferElement* element) {
617f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (uid != element->getUid()) {
618f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            uid = -1;
619f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
620f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (pid != element->getPid()) {
621f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            pid = -1;
622f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
623f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        if (tid != element->getTid()) {
624f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn            tid = -1;
625f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        }
626f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        EntryBase::add(element);
627f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    }
628f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
629f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string formatHeader(const std::string& name, log_id_t id) const;
630f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    std::string format(const LogStatistics& stat, log_id_t id) const;
631f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn};
632f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
6336a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyntemplate <typename TEntry>
6346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynclass LogFindWorst {
635501c373916e292764400dbae735f44b33378400fMark Salyzyn    std::unique_ptr<const TEntry* []> sorted;
6366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
637501c373916e292764400dbae735f44b33378400fMark Salyzyn   public:
638501c373916e292764400dbae735f44b33378400fMark Salyzyn    explicit LogFindWorst(std::unique_ptr<const TEntry* []>&& sorted)
639501c373916e292764400dbae735f44b33378400fMark Salyzyn        : sorted(std::move(sorted)) {
640501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
6416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
642501c373916e292764400dbae735f44b33378400fMark Salyzyn    void findWorst(int& worst, size_t& worst_sizes, size_t& second_worst_sizes,
643501c373916e292764400dbae735f44b33378400fMark Salyzyn                   size_t threshold) {
6446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
6456a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst_sizes = sorted[0]->getSizes();
6466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            if ((worst_sizes > threshold)
6476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // Allow time horizon to extend roughly tenfold, assume
6486a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // average entry length is 100 characters.
649501c373916e292764400dbae735f44b33378400fMark Salyzyn                && (worst_sizes > (10 * sorted[0]->getDropped()))) {
6506a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                worst = sorted[0]->getKey();
6516a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                second_worst_sizes = sorted[1]->getSizes();
6526a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                if (second_worst_sizes < threshold) {
6536a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    second_worst_sizes = threshold;
6546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                }
6556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            }
6566a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
6576a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
6586a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
659501c373916e292764400dbae735f44b33378400fMark Salyzyn    void findWorst(int& worst, size_t worst_sizes, size_t& second_worst_sizes) {
6606a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
6616a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst = sorted[0]->getKey();
662501c373916e292764400dbae735f44b33378400fMark Salyzyn            second_worst_sizes =
663501c373916e292764400dbae735f44b33378400fMark Salyzyn                worst_sizes - sorted[0]->getSizes() + sorted[1]->getSizes();
6646a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
6656a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
6666a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn};
6676a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
66834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
66934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
670c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    friend UidEntry;
671c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
67234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
67334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
67458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t mDroppedElements[LOG_ID_MAX];
67597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
67697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
67703bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_time mOldest[LOG_ID_MAX];
67803bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_time mNewest[LOG_ID_MAX];
67903bb7593e40e8f56d7c5f021bab579674fcc5c8cMark Salyzyn    log_time mNewestDropped[LOG_ID_MAX];
6803296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn    static size_t SizesTotal;
681720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
68234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
68397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
684720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
68597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
686e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
687bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    // pid of system to size list
688bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t;
689bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    pidSystemTable_t pidSystemTable[LOG_ID_MAX];
690bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
691720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
692720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
693720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
694720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
69517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    // tid to uid list
69617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
69717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    tidTable_t tidTable;
69817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
699344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    // tag list
700344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
701344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    tagTable_t tagTable;
702344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
703083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    // security tag list
704083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    tagTable_t securityTagTable;
705083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
706f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    // global tag list
707f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    typedef LogHashtable<TagNameKey, TagNameEntry> tagNameTable_t;
708f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn    tagNameTable_t tagNameTable;
709f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn
7106d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
7116d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() +
712b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      tagTable.sizeOf() + securityTagTable.sizeOf() +
713f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn                      tagNameTable.sizeOf() +
714b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      (pidTable.size() * sizeof(pidTable_t::iterator)) +
715b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      (tagTable.size() * sizeof(tagTable_t::iterator));
716501c373916e292764400dbae735f44b33378400fMark Salyzyn        for (auto it : pidTable) {
7176d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
7186d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
7196d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
720501c373916e292764400dbae735f44b33378400fMark Salyzyn        for (auto it : tidTable) {
7216d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
7226d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
7236d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
724f99a7d602a6fe90058e47d5e6140dfc9b30f7481Mark Salyzyn        for (auto it : tagNameTable) size += it.second.getNameAllocLength();
7256d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        log_id_for_each(id) {
7266d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += uidTable[id].sizeOf();
727b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn            size += uidTable[id].size() * sizeof(uidTable_t::iterator);
7286d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += pidSystemTable[id].sizeOf();
729501c373916e292764400dbae735f44b33378400fMark Salyzyn            size +=
730501c373916e292764400dbae735f44b33378400fMark Salyzyn                pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator);
7316d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
7326d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return size;
7336d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
7346d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
735501c373916e292764400dbae735f44b33378400fMark Salyzyn   public:
73634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
73734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
738501c373916e292764400dbae735f44b33378400fMark Salyzyn    void enableStatistics() {
739501c373916e292764400dbae735f44b33378400fMark Salyzyn        enable = true;
740501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
74134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
74202dd2f42f8713b09ed0526e4eb49812957b66d5eMark Salyzyn    void addTotal(LogBufferElement* entry);
743501c373916e292764400dbae735f44b33378400fMark Salyzyn    void add(LogBufferElement* entry);
744501c373916e292764400dbae735f44b33378400fMark Salyzyn    void subtract(LogBufferElement* entry);
745ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
746501c373916e292764400dbae735f44b33378400fMark Salyzyn    void drop(LogBufferElement* entry);
747aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn    // Correct for coalescing two entries referencing dropped content
748501c373916e292764400dbae735f44b33378400fMark Salyzyn    void erase(LogBufferElement* element) {
74958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        log_id_t log_id = element->getLogId();
75058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mElements[log_id];
75158b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
75258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
753e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
7546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) {
7556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len));
7566a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
757501c373916e292764400dbae735f44b33378400fMark Salyzyn    LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len,
758501c373916e292764400dbae735f44b33378400fMark Salyzyn                                    log_id id) {
7596a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len));
760758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
7616a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) {
7626a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len));
763bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
76434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
76534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
766501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t sizes(log_id_t id) const {
767501c373916e292764400dbae735f44b33378400fMark Salyzyn        return mSizes[id];
768501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
769501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t elements(log_id_t id) const {
770501c373916e292764400dbae735f44b33378400fMark Salyzyn        return mElements[id];
771501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
77258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t realElements(log_id_t id) const {
77358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        return mElements[id] - mDroppedElements[id];
77458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
775501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t sizesTotal(log_id_t id) const {
776501c373916e292764400dbae735f44b33378400fMark Salyzyn        return mSizesTotal[id];
777501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
778501c373916e292764400dbae735f44b33378400fMark Salyzyn    size_t elementsTotal(log_id_t id) const {
779501c373916e292764400dbae735f44b33378400fMark Salyzyn        return mElementsTotal[id];
780501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
781501c373916e292764400dbae735f44b33378400fMark Salyzyn    static size_t sizesTotal() {
782501c373916e292764400dbae735f44b33378400fMark Salyzyn        return SizesTotal;
783501c373916e292764400dbae735f44b33378400fMark Salyzyn    }
78434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
785ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
7869a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
787ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    // helper (must be locked directly or implicitly by mLogElementsLock)
788501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* pidToName(pid_t pid) const;
7894ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
790c4e4823b00a94627e922eada1172688818471b0cMark Salyzyn    pid_t tidToPid(pid_t tid);
791501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* uidToName(uid_t uid) const;
79234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
79334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
794501c373916e292764400dbae735f44b33378400fMark Salyzyn#endif  // _LOGD_LOG_STATISTICS_H__
795