blob: 6f7d264dae048ad016272a0c0e7846ee1944a7c8 [file] [log] [blame]
Mark Salyzyn34facab2014-02-06 14:48:50 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _LOGD_LOG_STATISTICS_H__
18#define _LOGD_LOG_STATISTICS_H__
19
Mark Salyzyn720f6d12015-03-16 08:26:05 -070020#include <memory>
21#include <stdlib.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080022#include <sys/types.h>
23
Mark Salyzyn758058f2015-08-21 16:44:30 -070024#include <algorithm> // std::max
25#include <string> // std::string
Mark Salyzyn511338d2015-05-19 09:12:30 -070026#include <unordered_map>
27
Elliott Hughes4f713192015-12-04 22:00:26 -080028#include <android-base/stringprintf.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080029#include <log/log.h>
Mark Salyzyn758058f2015-08-21 16:44:30 -070030#include <private/android_filesystem_config.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070031
32#include "LogBufferElement.h"
Mark Salyzyn5ac5c6b2015-08-28 08:02:59 -070033#include "LogUtils.h"
Mark Salyzyn34facab2014-02-06 14:48:50 -080034
35#define log_id_for_each(i) \
36 for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1))
37
Mark Salyzyn758058f2015-08-21 16:44:30 -070038class LogStatistics;
39
Mark Salyzyn720f6d12015-03-16 08:26:05 -070040template <typename TKey, typename TEntry>
Mark Salyzyn511338d2015-05-19 09:12:30 -070041class LogHashtable {
42
43 std::unordered_map<TKey, TEntry> map;
44
Mark Salyzyn720f6d12015-03-16 08:26:05 -070045public:
Mark Salyzyn511338d2015-05-19 09:12:30 -070046
47 typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
Mark Salyzyn758058f2015-08-21 16:44:30 -070048 typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
Mark Salyzyn511338d2015-05-19 09:12:30 -070049
Mark Salyzynee3b8382015-12-17 09:58:43 -080050 std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid,
51 size_t len) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -070052 if (!len) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -070053 std::unique_ptr<const TEntry *[]> sorted(NULL);
54 return sorted;
55 }
56
Mark Salyzyn758058f2015-08-21 16:44:30 -070057 const TEntry **retval = new const TEntry* [len];
58 memset(retval, 0, sizeof(*retval) * len);
Mark Salyzyn720f6d12015-03-16 08:26:05 -070059
Mark Salyzyn758058f2015-08-21 16:44:30 -070060 for(const_iterator it = map.begin(); it != map.end(); ++it) {
Mark Salyzyn511338d2015-05-19 09:12:30 -070061 const TEntry &entry = it->second;
Mark Salyzynee3b8382015-12-17 09:58:43 -080062
63 if ((uid != AID_ROOT) && (uid != entry.getUid())) {
64 continue;
65 }
66 if (pid && entry.getPid() && (pid != entry.getPid())) {
67 continue;
68 }
69
Mark Salyzyn758058f2015-08-21 16:44:30 -070070 size_t sizes = entry.getSizes();
71 ssize_t index = len - 1;
72 while ((!retval[index] || (sizes > retval[index]->getSizes()))
73 && (--index >= 0))
Mark Salyzyn720f6d12015-03-16 08:26:05 -070074 ;
Mark Salyzyn758058f2015-08-21 16:44:30 -070075 if (++index < (ssize_t)len) {
76 size_t num = len - index - 1;
77 if (num) {
78 memmove(&retval[index + 1], &retval[index],
79 num * sizeof(retval[0]));
Mark Salyzyn720f6d12015-03-16 08:26:05 -070080 }
Mark Salyzyn758058f2015-08-21 16:44:30 -070081 retval[index] = &entry;
Mark Salyzyn720f6d12015-03-16 08:26:05 -070082 }
83 }
84 std::unique_ptr<const TEntry *[]> sorted(retval);
85 return sorted;
86 }
87
Mark Salyzyn758058f2015-08-21 16:44:30 -070088 inline iterator add(TKey key, LogBufferElement *element) {
Mark Salyzyn511338d2015-05-19 09:12:30 -070089 iterator it = map.find(key);
90 if (it == map.end()) {
Mark Salyzyn758058f2015-08-21 16:44:30 -070091 it = map.insert(std::make_pair(key, TEntry(element))).first;
Mark Salyzyn511338d2015-05-19 09:12:30 -070092 } else {
Mark Salyzyn758058f2015-08-21 16:44:30 -070093 it->second.add(element);
Mark Salyzyn511338d2015-05-19 09:12:30 -070094 }
95 return it;
Mark Salyzyn720f6d12015-03-16 08:26:05 -070096 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070097
Mark Salyzyn511338d2015-05-19 09:12:30 -070098 inline iterator add(TKey key) {
99 iterator it = map.find(key);
100 if (it == map.end()) {
101 it = map.insert(std::make_pair(key, TEntry(key))).first;
102 } else {
103 it->second.add(key);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700104 }
Mark Salyzyn511338d2015-05-19 09:12:30 -0700105 return it;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700106 }
107
Mark Salyzyn758058f2015-08-21 16:44:30 -0700108 void subtract(TKey key, LogBufferElement *element) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700109 iterator it = map.find(key);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700110 if ((it != map.end()) && it->second.subtract(element)) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700111 map.erase(it);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700112 }
113 }
114
Mark Salyzyn758058f2015-08-21 16:44:30 -0700115 inline void drop(TKey key, LogBufferElement *element) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700116 iterator it = map.find(key);
117 if (it != map.end()) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700118 it->second.drop(element);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700119 }
120 }
121
Mark Salyzyn511338d2015-05-19 09:12:30 -0700122 inline iterator begin() { return map.begin(); }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700123 inline const_iterator begin() const { return map.begin(); }
Mark Salyzyn511338d2015-05-19 09:12:30 -0700124 inline iterator end() { return map.end(); }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700125 inline const_iterator end() const { return map.end(); }
Mark Salyzyn511338d2015-05-19 09:12:30 -0700126
Mark Salyzyn758058f2015-08-21 16:44:30 -0700127 std::string format(
128 const LogStatistics &stat,
129 uid_t uid,
Mark Salyzynee3b8382015-12-17 09:58:43 -0800130 pid_t pid,
Mark Salyzyn758058f2015-08-21 16:44:30 -0700131 const std::string &name = std::string(""),
132 log_id_t id = LOG_ID_MAX) const {
133 static const size_t maximum_sorted_entries = 32;
134 std::string output;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800135 std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid,
136 maximum_sorted_entries);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700137 if (!sorted.get()) {
138 return output;
139 }
140 bool headerPrinted = false;
141 for (size_t index = 0; index < maximum_sorted_entries; ++index) {
142 const TEntry *entry = sorted[index];
143 if (!entry) {
144 break;
145 }
146 if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
147 break;
148 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700149 if (!headerPrinted) {
150 output += "\n\n";
151 output += entry->formatHeader(name, id);
152 headerPrinted = true;
153 }
154 output += entry->format(stat, id);
155 }
156 return output;
157 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700158};
159
Mark Salyzyn758058f2015-08-21 16:44:30 -0700160namespace EntryBaseConstants {
161 static constexpr size_t pruned_len = 14;
162 static constexpr size_t total_len = 80;
163}
164
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700165struct EntryBase {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700166 size_t size;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700167
168 EntryBase():size(0) { }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700169 EntryBase(LogBufferElement *element):size(element->getMsgLen()) { }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700170
171 size_t getSizes() const { return size; }
172
Mark Salyzyn758058f2015-08-21 16:44:30 -0700173 inline void add(LogBufferElement *element) { size += element->getMsgLen(); }
174 inline bool subtract(LogBufferElement *element) {
175 size -= element->getMsgLen();
176 return !size;
177 }
178
179 static std::string formatLine(
180 const std::string &name,
181 const std::string &size,
182 const std::string &pruned) {
183 ssize_t drop_len = std::max(pruned.length() + 1,
184 EntryBaseConstants::pruned_len);
185 ssize_t size_len = std::max(size.length() + 1,
186 EntryBaseConstants::total_len
187 - name.length() - drop_len - 1);
188
189 if (pruned.length()) {
190 return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
191 (int)size_len, size.c_str(),
192 (int)drop_len, pruned.c_str());
193 } else {
194 return android::base::StringPrintf("%s%*s\n", name.c_str(),
195 (int)size_len, size.c_str());
196 }
197 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700198};
199
200struct EntryBaseDropped : public EntryBase {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700201 size_t dropped;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800202
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700203 EntryBaseDropped():dropped(0) { }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700204 EntryBaseDropped(LogBufferElement *element):
205 EntryBase(element),
206 dropped(element->getDropped()){
207 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800208
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700209 size_t getDropped() const { return dropped; }
210
Mark Salyzyn758058f2015-08-21 16:44:30 -0700211 inline void add(LogBufferElement *element) {
212 dropped += element->getDropped();
213 EntryBase::add(element);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700214 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700215 inline bool subtract(LogBufferElement *element) {
216 dropped -= element->getDropped();
217 return EntryBase::subtract(element) && !dropped;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700218 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700219 inline void drop(LogBufferElement *element) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700220 dropped += 1;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700221 EntryBase::subtract(element);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700222 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800223};
224
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700225struct UidEntry : public EntryBaseDropped {
226 const uid_t uid;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800227 pid_t pid;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700228
Mark Salyzyn758058f2015-08-21 16:44:30 -0700229 UidEntry(LogBufferElement *element):
230 EntryBaseDropped(element),
Mark Salyzynee3b8382015-12-17 09:58:43 -0800231 uid(element->getUid()),
232 pid(element->getPid()) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700233 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700234
235 inline const uid_t&getKey() const { return uid; }
Mark Salyzynee3b8382015-12-17 09:58:43 -0800236 inline const uid_t&getUid() const { return getKey(); }
237 inline const pid_t&getPid() const { return pid; }
238
239 inline void add(LogBufferElement *element) {
240 if (pid != element->getPid()) {
241 pid = -1;
242 }
243 EntryBase::add(element);
244 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700245
246 std::string formatHeader(const std::string &name, log_id_t id) const;
247 std::string format(const LogStatistics &stat, log_id_t id) const;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700248};
249
250namespace android {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700251uid_t pidToUid(pid_t pid);
252}
253
254struct PidEntry : public EntryBaseDropped {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700255 const pid_t pid;
256 uid_t uid;
257 char *name;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700258
Mark Salyzyn758058f2015-08-21 16:44:30 -0700259 PidEntry(pid_t pid):
260 EntryBaseDropped(),
261 pid(pid),
262 uid(android::pidToUid(pid)),
263 name(android::pidToName(pid)) {
264 }
265 PidEntry(LogBufferElement *element):
266 EntryBaseDropped(element),
267 pid(element->getPid()),
268 uid(element->getUid()),
269 name(android::pidToName(pid)) {
270 }
271 PidEntry(const PidEntry &element):
272 EntryBaseDropped(element),
273 pid(element.pid),
274 uid(element.uid),
275 name(element.name ? strdup(element.name) : NULL) {
276 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700277 ~PidEntry() { free(name); }
278
279 const pid_t&getKey() const { return pid; }
Mark Salyzynee3b8382015-12-17 09:58:43 -0800280 const pid_t&getPid() const { return getKey(); }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700281 const uid_t&getUid() const { return uid; }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700282 const char*getName() const { return name; }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700283
Mark Salyzyn758058f2015-08-21 16:44:30 -0700284 inline void add(pid_t newPid) {
Mark Salyzynddda2122015-10-02 09:22:52 -0700285 if (name && !fast<strncmp>(name, "zygote", 6)) {
Mark Salyzynaa43ae22015-04-20 10:27:38 -0700286 free(name);
287 name = NULL;
288 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700289 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700290 name = android::pidToName(newPid);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700291 }
292 }
293
Mark Salyzyn758058f2015-08-21 16:44:30 -0700294 inline void add(LogBufferElement *element) {
295 uid_t incomingUid = element->getUid();
296 if (getUid() != incomingUid) {
297 uid = incomingUid;
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700298 free(name);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700299 name = android::pidToName(element->getPid());
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700300 } else {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700301 add(element->getPid());
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700302 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700303 EntryBaseDropped::add(element);
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700304 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700305
306 std::string formatHeader(const std::string &name, log_id_t id) const;
307 std::string format(const LogStatistics &stat, log_id_t id) const;
Mark Salyzyn344bff42015-04-13 14:24:45 -0700308};
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700309
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700310struct TidEntry : public EntryBaseDropped {
311 const pid_t tid;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800312 pid_t pid;
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700313 uid_t uid;
314 char *name;
315
Mark Salyzynee3b8382015-12-17 09:58:43 -0800316 TidEntry(pid_t tid, pid_t pid):
Mark Salyzyn758058f2015-08-21 16:44:30 -0700317 EntryBaseDropped(),
318 tid(tid),
Mark Salyzynee3b8382015-12-17 09:58:43 -0800319 pid(pid),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700320 uid(android::pidToUid(tid)),
321 name(android::tidToName(tid)) {
322 }
323 TidEntry(LogBufferElement *element):
324 EntryBaseDropped(element),
325 tid(element->getTid()),
Mark Salyzynee3b8382015-12-17 09:58:43 -0800326 pid(element->getPid()),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700327 uid(element->getUid()),
328 name(android::tidToName(tid)) {
329 }
330 TidEntry(const TidEntry &element):
331 EntryBaseDropped(element),
332 tid(element.tid),
Mark Salyzynee3b8382015-12-17 09:58:43 -0800333 pid(element.pid),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700334 uid(element.uid),
335 name(element.name ? strdup(element.name) : NULL) {
336 }
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700337 ~TidEntry() { free(name); }
338
339 const pid_t&getKey() const { return tid; }
Mark Salyzynee3b8382015-12-17 09:58:43 -0800340 const pid_t&getTid() const { return getKey(); }
341 const pid_t&getPid() const { return pid; }
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700342 const uid_t&getUid() const { return uid; }
343 const char*getName() const { return name; }
344
Mark Salyzyn758058f2015-08-21 16:44:30 -0700345 inline void add(pid_t incomingTid) {
Mark Salyzynddda2122015-10-02 09:22:52 -0700346 if (name && !fast<strncmp>(name, "zygote", 6)) {
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700347 free(name);
348 name = NULL;
349 }
350 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700351 name = android::tidToName(incomingTid);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700352 }
353 }
354
Mark Salyzyn758058f2015-08-21 16:44:30 -0700355 inline void add(LogBufferElement *element) {
356 uid_t incomingUid = element->getUid();
Mark Salyzynee3b8382015-12-17 09:58:43 -0800357 pid_t incomingPid = element->getPid();
358 if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700359 uid = incomingUid;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800360 pid = incomingPid;
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700361 free(name);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700362 name = android::tidToName(element->getTid());
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700363 } else {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700364 add(element->getTid());
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700365 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700366 EntryBaseDropped::add(element);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700367 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700368
369 std::string formatHeader(const std::string &name, log_id_t id) const;
370 std::string format(const LogStatistics &stat, log_id_t id) const;
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700371};
372
Mark Salyzyn344bff42015-04-13 14:24:45 -0700373struct TagEntry : public EntryBase {
374 const uint32_t tag;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800375 pid_t pid;
Mark Salyzyn344bff42015-04-13 14:24:45 -0700376 uid_t uid;
377
Mark Salyzyn758058f2015-08-21 16:44:30 -0700378 TagEntry(LogBufferElement *element):
379 EntryBase(element),
380 tag(element->getTag()),
Mark Salyzynee3b8382015-12-17 09:58:43 -0800381 pid(element->getPid()),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700382 uid(element->getUid()) {
383 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700384
385 const uint32_t&getKey() const { return tag; }
Mark Salyzynee3b8382015-12-17 09:58:43 -0800386 const pid_t&getPid() const { return pid; }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700387 const uid_t&getUid() const { return uid; }
388 const char*getName() const { return android::tagToName(tag); }
389
Mark Salyzyn758058f2015-08-21 16:44:30 -0700390 inline void add(LogBufferElement *element) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800391 if (uid != element->getUid()) {
Mark Salyzyn344bff42015-04-13 14:24:45 -0700392 uid = -1;
393 }
Mark Salyzynee3b8382015-12-17 09:58:43 -0800394 if (pid != element->getPid()) {
395 pid = -1;
396 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700397 EntryBase::add(element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700398 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700399
400 std::string formatHeader(const std::string &name, log_id_t id) const;
401 std::string format(const LogStatistics &stat, log_id_t id) const;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700402};
403
Mark Salyzyn34facab2014-02-06 14:48:50 -0800404// Log Statistics
405class LogStatistics {
Mark Salyzync723df82015-08-24 11:08:00 -0700406 friend UidEntry;
407
Mark Salyzyn34facab2014-02-06 14:48:50 -0800408 size_t mSizes[LOG_ID_MAX];
409 size_t mElements[LOG_ID_MAX];
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700410 size_t mDroppedElements[LOG_ID_MAX];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700411 size_t mSizesTotal[LOG_ID_MAX];
412 size_t mElementsTotal[LOG_ID_MAX];
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700413 bool enable;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800414
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700415 // uid to size list
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700416 typedef LogHashtable<uid_t, UidEntry> uidTable_t;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700417 uidTable_t uidTable[LOG_ID_MAX];
Mark Salyzyne457b742014-02-19 17:18:31 -0800418
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700419 // pid of system to size list
420 typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t;
421 pidSystemTable_t pidSystemTable[LOG_ID_MAX];
422
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700423 // pid to uid list
424 typedef LogHashtable<pid_t, PidEntry> pidTable_t;
425 pidTable_t pidTable;
426
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700427 // tid to uid list
428 typedef LogHashtable<pid_t, TidEntry> tidTable_t;
429 tidTable_t tidTable;
430
Mark Salyzyn344bff42015-04-13 14:24:45 -0700431 // tag list
432 typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
433 tagTable_t tagTable;
434
Mark Salyzyn083b0372015-12-04 10:59:45 -0800435 // security tag list
436 tagTable_t securityTagTable;
437
Mark Salyzyn34facab2014-02-06 14:48:50 -0800438public:
Mark Salyzyn34facab2014-02-06 14:48:50 -0800439 LogStatistics();
440
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700441 void enableStatistics() { enable = true; }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800442
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700443 void add(LogBufferElement *entry);
444 void subtract(LogBufferElement *entry);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700445 // entry->setDropped(1) must follow this call
446 void drop(LogBufferElement *entry);
Mark Salyzynaaad42f2015-09-30 07:40:09 -0700447 // Correct for coalescing two entries referencing dropped content
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700448 void erase(LogBufferElement *element) {
449 log_id_t log_id = element->getLogId();
450 --mElements[log_id];
451 --mDroppedElements[log_id];
452 }
Mark Salyzyne457b742014-02-19 17:18:31 -0800453
Mark Salyzynee3b8382015-12-17 09:58:43 -0800454 std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid,
455 size_t len, log_id id) {
456 return uidTable[id].sort(uid, pid, len);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700457 }
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700458 std::unique_ptr<const PidEntry *[]> sort(uid_t uid, pid_t pid,
459 size_t len, log_id id, uid_t) {
460 return pidSystemTable[id].sort(uid, pid, len);
461 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800462
463 // fast track current value by id only
464 size_t sizes(log_id_t id) const { return mSizes[id]; }
465 size_t elements(log_id_t id) const { return mElements[id]; }
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700466 size_t realElements(log_id_t id) const {
467 return mElements[id] - mDroppedElements[id];
468 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700469 size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
470 size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800471
Mark Salyzynee3b8382015-12-17 09:58:43 -0800472 std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
Mark Salyzyn9a038632014-04-07 07:05:40 -0700473
Mark Salyzyned777e92015-06-24 16:22:54 -0700474 // helper (must be locked directly or implicitly by mLogElementsLock)
Mark Salyzyn758058f2015-08-21 16:44:30 -0700475 const char *pidToName(pid_t pid) const;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700476 uid_t pidToUid(pid_t pid);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700477 const char *uidToName(uid_t uid) const;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800478};
479
480#endif // _LOGD_LOG_STATISTICS_H__