blob: d20d90e58fc3098a4009efa96609f9222ef0bf98 [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
Mark Salyzyn9a038632014-04-07 07:05:40 -070017#include <fcntl.h>
Mark Salyzyn02dd2f42017-04-14 09:46:57 -070018#include <inttypes.h>
Mark Salyzynb8a95bd2016-04-07 11:06:31 -070019#include <pwd.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070020#include <stdio.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070021#include <string.h>
Mark Salyzynb8a95bd2016-04-07 11:06:31 -070022#include <sys/types.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070023#include <unistd.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080024
Mark Salyzyn9af33ee2016-10-05 12:34:37 -070025#include <list>
26
Mark Salyzyn03bb7592017-04-14 09:46:57 -070027#include <private/android_logger.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080028
29#include "LogStatistics.h"
30
Mark Salyzyn03bb7592017-04-14 09:46:57 -070031static const uint64_t hourSec = 60 * 60;
32static const uint64_t monthSec = 31 * 24 * hourSec;
33
Mark Salyzyn32962912016-09-12 10:29:17 -070034size_t LogStatistics::SizesTotal;
35
Mark Salyzyn77187782015-05-12 15:21:31 -070036LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn03bb7592017-04-14 09:46:57 -070037 log_time now(CLOCK_REALTIME);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070038 log_id_for_each(id) {
39 mSizes[id] = 0;
40 mElements[id] = 0;
Mark Salyzyn58b8be82015-09-30 07:40:09 -070041 mDroppedElements[id] = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070042 mSizesTotal[id] = 0;
43 mElementsTotal[id] = 0;
Mark Salyzyn03bb7592017-04-14 09:46:57 -070044 mOldest[id] = now;
45 mNewest[id] = now;
46 mNewestDropped[id] = now;
Mark Salyzyn34facab2014-02-06 14:48:50 -080047 }
48}
49
Mark Salyzyn720f6d12015-03-16 08:26:05 -070050namespace android {
51
Mark Salyzyn501c3732017-03-10 14:31:54 -080052size_t sizesTotal() {
53 return LogStatistics::sizesTotal();
54}
Mark Salyzyn32962912016-09-12 10:29:17 -070055
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070056// caller must own and free character string
Mark Salyzyn501c3732017-03-10 14:31:54 -080057char* pidToName(pid_t pid) {
58 char* retval = NULL;
59 if (pid == 0) { // special case from auditd/klogd for kernel
Mark Salyzynae4d9282014-10-15 08:49:39 -070060 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070061 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070062 char buffer[512];
63 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
64 int fd = open(buffer, O_RDONLY);
65 if (fd >= 0) {
66 ssize_t ret = read(fd, buffer, sizeof(buffer));
67 if (ret > 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -080068 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn9a038632014-04-07 07:05:40 -070069 // frameworks intermediate state
Mark Salyzyn0eeb06b2016-12-02 10:08:48 -080070 if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070071 retval = strdup(buffer);
72 }
73 }
74 close(fd);
75 }
76 }
77 return retval;
78}
Mark Salyzyn720f6d12015-03-16 08:26:05 -070079}
80
Mark Salyzyn02dd2f42017-04-14 09:46:57 -070081void LogStatistics::addTotal(LogBufferElement* element) {
82 if (element->getDropped()) return;
83
84 log_id_t log_id = element->getLogId();
85 unsigned short size = element->getMsgLen();
86 mSizesTotal[log_id] += size;
87 SizesTotal += size;
88 ++mElementsTotal[log_id];
89}
90
Mark Salyzyn501c3732017-03-10 14:31:54 -080091void LogStatistics::add(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -070092 log_id_t log_id = element->getLogId();
93 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080094 mSizes[log_id] += size;
95 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070096
Mark Salyzyn02dd2f42017-04-14 09:46:57 -070097 // When caller adding a chatty entry, they will have already
98 // called add() and subtract() for each entry as they are
99 // evaluated and trimmed, thus recording size and number of
100 // elements, but we must recognize the manufactured dropped
101 // entry as not contributing to the lifetime totals.
Mark Salyzyna2c02222016-12-13 10:31:29 -0800102 if (element->getDropped()) {
103 ++mDroppedElements[log_id];
104 } else {
Mark Salyzyna2c02222016-12-13 10:31:29 -0800105 mSizesTotal[log_id] += size;
Mark Salyzyn32962912016-09-12 10:29:17 -0700106 SizesTotal += size;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800107 ++mElementsTotal[log_id];
108 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700109
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700110 log_time stamp(element->getRealTime());
111 if (mNewest[log_id] < stamp) {
112 // A major time update invalidates the statistics :-(
113 log_time diff = stamp - mNewest[log_id];
114 mNewest[log_id] = stamp;
115
116 if (diff.tv_sec > hourSec) {
117 // approximate Do-Your-Best fixup
118 diff += mOldest[log_id];
119 if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
120 diff = stamp;
121 }
122 if (diff <= stamp) {
123 mOldest[log_id] = diff;
124 if (mNewestDropped[log_id] < diff) {
125 mNewestDropped[log_id] = diff;
126 }
127 }
128 }
129 }
130
Mark Salyzynae4d9282014-10-15 08:49:39 -0700131 if (log_id == LOG_ID_KERNEL) {
132 return;
133 }
134
Mark Salyzyn758058f2015-08-21 16:44:30 -0700135 uidTable[log_id].add(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700136 if (element->getUid() == AID_SYSTEM) {
137 pidSystemTable[log_id].add(element->getPid(), element);
138 }
Mark Salyzynae4d9282014-10-15 08:49:39 -0700139
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700140 if (!enable) {
141 return;
142 }
143
Mark Salyzyn758058f2015-08-21 16:44:30 -0700144 pidTable.add(element->getPid(), element);
145 tidTable.add(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700146
Mark Salyzyn758058f2015-08-21 16:44:30 -0700147 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700148 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800149 if (log_id == LOG_ID_SECURITY) {
150 securityTagTable.add(tag, element);
151 } else {
152 tagTable.add(tag, element);
153 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700154 }
Mark Salyzynf99a7d62017-04-19 14:39:21 -0700155
156 if (!element->getDropped()) {
157 tagNameTable.add(TagNameKey(element), element);
158 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800159}
160
Mark Salyzyn501c3732017-03-10 14:31:54 -0800161void LogStatistics::subtract(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700162 log_id_t log_id = element->getLogId();
163 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800164 mSizes[log_id] -= size;
165 --mElements[log_id];
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700166 if (element->getDropped()) {
167 --mDroppedElements[log_id];
168 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700169
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700170 if (mOldest[log_id] < element->getRealTime()) {
171 mOldest[log_id] = element->getRealTime();
172 }
173
Mark Salyzynae4d9282014-10-15 08:49:39 -0700174 if (log_id == LOG_ID_KERNEL) {
175 return;
176 }
177
Mark Salyzyn758058f2015-08-21 16:44:30 -0700178 uidTable[log_id].subtract(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700179 if (element->getUid() == AID_SYSTEM) {
180 pidSystemTable[log_id].subtract(element->getPid(), element);
181 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800182
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700183 if (!enable) {
184 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800185 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700186
Mark Salyzyn758058f2015-08-21 16:44:30 -0700187 pidTable.subtract(element->getPid(), element);
188 tidTable.subtract(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700189
Mark Salyzyn758058f2015-08-21 16:44:30 -0700190 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700191 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800192 if (log_id == LOG_ID_SECURITY) {
193 securityTagTable.subtract(tag, element);
194 } else {
195 tagTable.subtract(tag, element);
196 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700197 }
Mark Salyzynf99a7d62017-04-19 14:39:21 -0700198
199 if (!element->getDropped()) {
200 tagNameTable.subtract(TagNameKey(element), element);
201 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800202}
203
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700204// Atomically set an entry to drop
205// entry->setDropped(1) must follow this call, caller should do this explicitly.
Mark Salyzyn501c3732017-03-10 14:31:54 -0800206void LogStatistics::drop(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700207 log_id_t log_id = element->getLogId();
208 unsigned short size = element->getMsgLen();
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700209 mSizes[log_id] -= size;
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700210 ++mDroppedElements[log_id];
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700211
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700212 if (mNewestDropped[log_id] < element->getRealTime()) {
213 mNewestDropped[log_id] = element->getRealTime();
214 }
215
Mark Salyzyn758058f2015-08-21 16:44:30 -0700216 uidTable[log_id].drop(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700217 if (element->getUid() == AID_SYSTEM) {
218 pidSystemTable[log_id].drop(element->getPid(), element);
219 }
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700220
221 if (!enable) {
222 return;
223 }
224
Mark Salyzyn758058f2015-08-21 16:44:30 -0700225 pidTable.drop(element->getPid(), element);
226 tidTable.drop(element->getTid(), element);
Mark Salyzyn6a066942016-07-14 15:34:30 -0700227
228 uint32_t tag = element->getTag();
229 if (tag) {
230 if (log_id == LOG_ID_SECURITY) {
231 securityTagTable.drop(tag, element);
232 } else {
233 tagTable.drop(tag, element);
234 }
235 }
Mark Salyzynf99a7d62017-04-19 14:39:21 -0700236
237 tagNameTable.subtract(TagNameKey(element), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700238}
239
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700240// caller must own and free character string
Mark Salyzyn3c501b52017-04-18 14:09:45 -0700241// Requires parent LogBuffer::wrlock() to be held
Mark Salyzyn501c3732017-03-10 14:31:54 -0800242const char* LogStatistics::uidToName(uid_t uid) const {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700243 // Local hard coded favourites
244 if (uid == AID_LOGD) {
245 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800246 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700247
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700248 // Android system
249 if (uid < AID_APP) {
250 // in bionic, thread safe as long as we copy the results
Mark Salyzyn501c3732017-03-10 14:31:54 -0800251 struct passwd* pwd = getpwuid(uid);
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700252 if (pwd) {
253 return strdup(pwd->pw_name);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700254 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800255 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700256
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700257 // Parse /data/system/packages.list
Jeff Sharkeydff44702016-12-13 11:55:19 -0700258 uid_t userId = uid % AID_USER_OFFSET;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800259 const char* name = android::uidToName(userId);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700260 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
261 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
262 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700263 if (name) {
264 return name;
265 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700266
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700267 // Android application
268 if (uid >= AID_APP) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800269 struct passwd* pwd = getpwuid(uid);
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700270 if (pwd) {
271 return strdup(pwd->pw_name);
272 }
273 }
274
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700275 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn501c3732017-03-10 14:31:54 -0800276 for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end();
277 ++it) {
278 const PidEntry& entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700279
280 if (entry.getUid() == uid) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800281 const char* nameTmp = entry.getName();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700282
Mark Salyzyn758058f2015-08-21 16:44:30 -0700283 if (nameTmp) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700284 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700285 name = strdup(nameTmp);
Mark Salyzyn0eeb06b2016-12-02 10:08:48 -0800286 } else if (fastcmp<strcmp>(name, nameTmp)) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800287 free(const_cast<char*>(name));
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700288 name = NULL;
289 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700290 }
291 }
292 }
293 }
294
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700295 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700296 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800297}
298
Mark Salyzyn501c3732017-03-10 14:31:54 -0800299std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700300 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800301 return formatLine(android::base::StringPrintf(name.c_str(),
302 android_log_id_to_name(id)),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700303 std::string("Size"),
Mark Salyzyn501c3732017-03-10 14:31:54 -0800304 std::string(isprune ? "+/- Pruned" : "")) +
305 formatLine(std::string("UID PACKAGE"), std::string("BYTES"),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700306 std::string(isprune ? "NUM" : ""));
Mark Salyzyn34facab2014-02-06 14:48:50 -0800307}
308
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700309// Helper to truncate name, if too long, and add name dressings
310static void formatTmp(const LogStatistics& stat, const char* nameTmp, uid_t uid,
311 std::string& name, std::string& size, size_t nameLen) {
312 const char* allocNameTmp = nullptr;
313 if (!nameTmp) nameTmp = allocNameTmp = stat.uidToName(uid);
314 if (nameTmp) {
315 size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
316 size_t len = EntryBaseConstants::total_len -
317 EntryBaseConstants::pruned_len - size.length() -
318 name.length() - lenSpace - 2;
319 size_t lenNameTmp = strlen(nameTmp);
320 while ((len < lenNameTmp) && (lenSpace > 1)) {
321 ++len;
322 --lenSpace;
323 }
324 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
325 if (len < lenNameTmp) {
326 name += "...";
327 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
328 }
329 name += nameTmp;
330 free(const_cast<char*>(allocNameTmp));
331 }
332}
333
Mark Salyzyn501c3732017-03-10 14:31:54 -0800334std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800335 uid_t uid = getUid();
Mark Salyzyn758058f2015-08-21 16:44:30 -0700336 std::string name = android::base::StringPrintf("%u", uid);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700337 std::string size = android::base::StringPrintf("%zu", getSizes());
338
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700339 formatTmp(stat, nullptr, uid, name, size, 6);
340
Mark Salyzyn758058f2015-08-21 16:44:30 -0700341 std::string pruned = "";
Mark Salyzync723df82015-08-24 11:08:00 -0700342 if (worstUidEnabledForLogid(id)) {
343 size_t totalDropped = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800344 for (LogStatistics::uidTable_t::const_iterator it =
345 stat.uidTable[id].begin();
346 it != stat.uidTable[id].end(); ++it) {
Mark Salyzync723df82015-08-24 11:08:00 -0700347 totalDropped += it->second.getDropped();
348 }
349 size_t sizes = stat.sizes(id);
350 size_t totalSize = stat.sizesTotal(id);
351 size_t totalElements = stat.elementsTotal(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800352 float totalVirtualSize =
353 (float)sizes + (float)totalDropped * totalSize / totalElements;
Mark Salyzync723df82015-08-24 11:08:00 -0700354 size_t entrySize = getSizes();
355 float virtualEntrySize = entrySize;
356 int realPermille = virtualEntrySize * 1000.0 / sizes;
357 size_t dropped = getDropped();
358 if (dropped) {
359 pruned = android::base::StringPrintf("%zu", dropped);
360 virtualEntrySize += (float)dropped * totalSize / totalElements;
361 }
362 int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800363 int permille =
364 (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1);
Mark Salyzync723df82015-08-24 11:08:00 -0700365 if ((permille < -1) || (1 < permille)) {
366 std::string change;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800367 const char* units = "%";
368 const char* prefix = (permille > 0) ? "+" : "";
Mark Salyzync723df82015-08-24 11:08:00 -0700369
370 if (permille > 999) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800371 permille = (permille + 1000) / 100; // Now tenths fold
Mark Salyzync723df82015-08-24 11:08:00 -0700372 units = "X";
373 prefix = "";
374 }
375 if ((-99 < permille) && (permille < 99)) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800376 change = android::base::StringPrintf(
377 "%s%d.%u%s", prefix, permille / 10,
Mark Salyzync723df82015-08-24 11:08:00 -0700378 ((permille < 0) ? (-permille % 10) : (permille % 10)),
379 units);
380 } else {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800381 change = android::base::StringPrintf(
382 "%s%d%s", prefix, (permille + 5) / 10, units);
Mark Salyzync723df82015-08-24 11:08:00 -0700383 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800384 ssize_t spaces = EntryBaseConstants::pruned_len - 2 -
385 pruned.length() - change.length();
Mark Salyzync723df82015-08-24 11:08:00 -0700386 if ((spaces <= 0) && pruned.length()) {
387 spaces = 1;
388 }
Mark Salyzynd966e222016-12-19 22:23:03 +0000389 if (spaces > 0) {
Mark Salyzync723df82015-08-24 11:08:00 -0700390 change += android::base::StringPrintf("%*s", (int)spaces, "");
391 }
392 pruned = change + pruned;
393 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700394 }
395
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700396 std::string output = formatLine(name, size, pruned);
397
398 if (uid != AID_SYSTEM) {
399 return output;
400 }
401
402 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800403 std::unique_ptr<const PidEntry* []> sorted =
404 stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700405
406 if (!sorted.get()) {
407 return output;
408 }
409 std::string byPid;
410 size_t index;
411 bool hasDropped = false;
412 for (index = 0; index < maximum_sorted_entries; ++index) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800413 const PidEntry* entry = sorted[index];
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700414 if (!entry) {
415 break;
416 }
417 if (entry->getSizes() <= (getSizes() / 100)) {
418 break;
419 }
420 if (entry->getDropped()) {
421 hasDropped = true;
422 }
423 byPid += entry->format(stat, id);
424 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800425 if (index > 1) { // print this only if interesting
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700426 std::string ditto("\" ");
Mark Salyzyn501c3732017-03-10 14:31:54 -0800427 output += formatLine(std::string(" PID/UID COMMAND LINE"), ditto,
428 hasDropped ? ditto : std::string(""));
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700429 output += byPid;
430 }
431
432 return output;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700433}
434
Mark Salyzyn501c3732017-03-10 14:31:54 -0800435std::string PidEntry::formatHeader(const std::string& name,
436 log_id_t /* id */) const {
437 return formatLine(name, std::string("Size"), std::string("Pruned")) +
438 formatLine(std::string(" PID/UID COMMAND LINE"),
439 std::string("BYTES"), std::string("NUM"));
Mark Salyzyn758058f2015-08-21 16:44:30 -0700440}
441
Mark Salyzyn501c3732017-03-10 14:31:54 -0800442std::string PidEntry::format(const LogStatistics& stat,
443 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700444 uid_t uid = getUid();
Mark Salyzynee3b8382015-12-17 09:58:43 -0800445 pid_t pid = getPid();
446 std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800447 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700448
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700449 formatTmp(stat, getName(), uid, name, size, 12);
450
Mark Salyzyn758058f2015-08-21 16:44:30 -0700451 std::string pruned = "";
452 size_t dropped = getDropped();
453 if (dropped) {
454 pruned = android::base::StringPrintf("%zu", dropped);
455 }
456
457 return formatLine(name, size, pruned);
458}
459
Mark Salyzyn501c3732017-03-10 14:31:54 -0800460std::string TidEntry::formatHeader(const std::string& name,
461 log_id_t /* id */) const {
462 return formatLine(name, std::string("Size"), std::string("Pruned")) +
463 formatLine(std::string(" TID/UID COMM"), std::string("BYTES"),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700464 std::string("NUM"));
465}
466
Mark Salyzyn501c3732017-03-10 14:31:54 -0800467std::string TidEntry::format(const LogStatistics& stat,
468 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700469 uid_t uid = getUid();
Mark Salyzyn501c3732017-03-10 14:31:54 -0800470 std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800471 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700472
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700473 formatTmp(stat, getName(), uid, name, size, 12);
474
Mark Salyzyn758058f2015-08-21 16:44:30 -0700475 std::string pruned = "";
476 size_t dropped = getDropped();
477 if (dropped) {
478 pruned = android::base::StringPrintf("%zu", dropped);
479 }
480
481 return formatLine(name, size, pruned);
482}
483
Mark Salyzyn501c3732017-03-10 14:31:54 -0800484std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700485 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800486 return formatLine(name, std::string("Size"),
487 std::string(isprune ? "Prune" : "")) +
488 formatLine(std::string(" TAG/UID TAGNAME"),
489 std::string("BYTES"), std::string(isprune ? "NUM" : ""));
Mark Salyzyn758058f2015-08-21 16:44:30 -0700490}
491
Mark Salyzyn501c3732017-03-10 14:31:54 -0800492std::string TagEntry::format(const LogStatistics& /* stat */,
493 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700494 std::string name;
495 uid_t uid = getUid();
496 if (uid == (uid_t)-1) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800497 name = android::base::StringPrintf("%7u", getKey());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700498 } else {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800499 name = android::base::StringPrintf("%7u/%u", getKey(), uid);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700500 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800501 const char* nameTmp = getName();
Mark Salyzyn758058f2015-08-21 16:44:30 -0700502 if (nameTmp) {
503 name += android::base::StringPrintf(
Mark Salyzyn501c3732017-03-10 14:31:54 -0800504 "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700505 }
506
Mark Salyzyn501c3732017-03-10 14:31:54 -0800507 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700508
509 std::string pruned = "";
Mark Salyzyn6a066942016-07-14 15:34:30 -0700510 size_t dropped = getDropped();
511 if (dropped) {
512 pruned = android::base::StringPrintf("%zu", dropped);
513 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700514
515 return formatLine(name, size, pruned);
516}
517
Mark Salyzynf99a7d62017-04-19 14:39:21 -0700518std::string TagNameEntry::formatHeader(const std::string& name,
519 log_id_t /* id */) const {
520 return formatLine(name, std::string("Size"), std::string("")) +
521 formatLine(std::string(" TID/PID/UID LOG_TAG NAME"),
522 std::string("BYTES"), std::string(""));
523}
524
525std::string TagNameEntry::format(const LogStatistics& /* stat */,
526 log_id_t /* id */) const {
527 std::string name;
528 pid_t tid = getTid();
529 pid_t pid = getPid();
530 std::string pidstr;
531 if (pid != (pid_t)-1) {
532 pidstr = android::base::StringPrintf("%u", pid);
533 if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr;
534 }
535 int len = 9 - pidstr.length();
536 if (len < 0) len = 0;
537 if ((tid == (pid_t)-1) || (tid == pid)) {
538 name = android::base::StringPrintf("%*s", len, "");
539 } else {
540 name = android::base::StringPrintf("%*u", len, tid);
541 }
542 name += pidstr;
543 uid_t uid = getUid();
544 if (uid != (uid_t)-1) {
545 name += android::base::StringPrintf("/%u", uid);
546 }
547
548 std::string size = android::base::StringPrintf("%zu", getSizes());
549
550 const char* nameTmp = getName();
551 if (nameTmp) {
552 size_t lenSpace = std::max(16 - name.length(), (size_t)1);
553 size_t len = EntryBaseConstants::total_len -
554 EntryBaseConstants::pruned_len - size.length() -
555 name.length() - lenSpace - 2;
556 size_t lenNameTmp = strlen(nameTmp);
557 while ((len < lenNameTmp) && (lenSpace > 1)) {
558 ++len;
559 --lenSpace;
560 }
561 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
562 if (len < lenNameTmp) {
563 name += "...";
564 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
565 }
566 name += nameTmp;
567 }
568
569 std::string pruned = "";
570
571 return formatLine(name, size, pruned);
572}
573
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700574static std::string formatMsec(uint64_t val) {
575 static const unsigned subsecDigits = 3;
576 static const uint64_t sec = MS_PER_SEC;
577
578 static const uint64_t minute = 60 * sec;
579 static const uint64_t hour = 60 * minute;
580 static const uint64_t day = 24 * hour;
581
582 std::string output;
583 if (val < sec) return output;
584
585 if (val >= day) {
586 output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
587 val = (val % day) + day;
588 }
589 if (val >= minute) {
590 if (val >= hour) {
591 output += android::base::StringPrintf("%" PRIu64 ":",
592 (val / hour) % (day / hour));
593 }
594 output += android::base::StringPrintf(
595 (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
596 (val / minute) % (hour / minute));
597 }
598 output +=
599 android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
600 (val / sec) % (minute / sec));
601 val %= sec;
602 unsigned digits = subsecDigits;
603 while (digits && ((val % 10) == 0)) {
604 val /= 10;
605 --digits;
606 }
607 if (digits) {
608 output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
609 }
610 return output;
611}
612
Mark Salyzynee3b8382015-12-17 09:58:43 -0800613std::string LogStatistics::format(uid_t uid, pid_t pid,
614 unsigned int logMask) const {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700615 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800616
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700617 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800618
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700619 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700620 size_t oldLength;
621 short spaces = 1;
622
623 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700624 if (!(logMask & (1 << id))) continue;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700625 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700626 if (spaces < 0) spaces = 0;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700627 output += android::base::StringPrintf("%*s%s", spaces, "",
628 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700629 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800630 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700631 if (spaces < 0) spaces = 0;
632 output += android::base::StringPrintf("%*sTotal", spaces, "");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800633
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700634 static const char TotalStr[] = "\nTotal";
635 spaces = 10 - strlen(TotalStr);
636 output += TotalStr;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800637
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700638 size_t totalSize = 0;
639 size_t totalEls = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700640 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700641 if (!(logMask & (1 << id))) continue;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700642 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700643 if (spaces < 0) spaces = 0;
644 size_t szs = sizesTotal(id);
645 totalSize += szs;
646 size_t els = elementsTotal(id);
647 totalEls += els;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800648 output +=
649 android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700650 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800651 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700652 if (spaces < 0) spaces = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800653 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
654 totalEls);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800655
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700656 static const char NowStr[] = "\nNow";
657 spaces = 10 - strlen(NowStr);
658 output += NowStr;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800659
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700660 totalSize = 0;
661 totalEls = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700662 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700663 if (!(logMask & (1 << id))) continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800664
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700665 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800666 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700667 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700668 if (spaces < 0) spaces = 0;
669 size_t szs = sizes(id);
670 totalSize += szs;
671 totalEls += els;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800672 output +=
673 android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700674 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800675 }
676 spaces += spaces_total;
677 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700678 if (spaces < 0) spaces = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800679 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
680 totalEls);
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700681
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700682 static const char SpanStr[] = "\nLogspan";
683 spaces = 10 - strlen(SpanStr);
684 output += SpanStr;
685
686 // Total reports the greater of the individual maximum time span, or the
687 // validated minimum start and maximum end time span if it makes sense.
688 uint64_t minTime = UINT64_MAX;
689 uint64_t maxTime = 0;
690 uint64_t maxSpan = 0;
691 totalSize = 0;
692
693 log_id_for_each(id) {
694 if (!(logMask & (1 << id))) continue;
695
696 // validity checking
697 uint64_t oldest = mOldest[id].msec();
698 uint64_t newest = mNewest[id].msec();
699 if (newest <= oldest) {
700 spaces += spaces_total;
701 continue;
702 }
703
704 uint64_t span = newest - oldest;
705 if (span > (monthSec * MS_PER_SEC)) {
706 spaces += spaces_total;
707 continue;
708 }
709
710 // total span
711 if (minTime > oldest) minTime = oldest;
712 if (maxTime < newest) maxTime = newest;
713 if (span > maxSpan) maxSpan = span;
714 totalSize += span;
715
716 uint64_t dropped = mNewestDropped[id].msec();
717 if (dropped < oldest) dropped = oldest;
718 if (dropped > newest) dropped = newest;
719
720 oldLength = output.length();
721 output += android::base::StringPrintf("%*s%s", spaces, "",
722 formatMsec(span).c_str());
723 unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span;
724 if ((permille > 1) && (permille < 999)) {
725 output += android::base::StringPrintf("(%u", permille / 10);
726 permille %= 10;
727 if (permille) {
728 output += android::base::StringPrintf(".%u", permille);
729 }
730 output += android::base::StringPrintf("%%)");
731 }
732 spaces -= output.length() - oldLength;
733 spaces += spaces_total;
734 }
735 if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
736 (maxTime > maxSpan)) {
737 maxSpan = maxTime;
738 }
739 if (spaces < 0) spaces = 0;
740 output += android::base::StringPrintf("%*s%s", spaces, "",
741 formatMsec(maxSpan).c_str());
742
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700743 static const char OverheadStr[] = "\nOverhead";
744 spaces = 10 - strlen(OverheadStr);
745 output += OverheadStr;
746
747 totalSize = 0;
748 log_id_for_each(id) {
749 if (!(logMask & (1 << id))) continue;
750
751 size_t els = elements(id);
752 if (els) {
753 oldLength = output.length();
754 if (spaces < 0) spaces = 0;
755 // estimate the std::list overhead.
756 static const size_t overhead =
757 ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) &
Mark Salyzyn501c3732017-03-10 14:31:54 -0800758 -sizeof(uint64_t)) +
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700759 sizeof(std::list<LogBufferElement*>);
760 size_t szs = sizes(id) + els * overhead;
761 totalSize += szs;
762 output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
763 spaces -= output.length() - oldLength;
764 }
765 spaces += spaces_total;
766 }
Mark Salyzyn6d981af2016-10-06 09:55:21 -0700767 totalSize += sizeOf();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700768 if (spaces < 0) spaces = 0;
769 output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800770
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700771 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700772
Mark Salyzyn758058f2015-08-21 16:44:30 -0700773 std::string name;
774
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700775 // Chattiest by application (UID)
776 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700777 if (!(logMask & (1 << id))) continue;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700778
Mark Salyzyn501c3732017-03-10 14:31:54 -0800779 name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:"
780 : "Logging for your UID in %s log buffer:";
Mark Salyzynee3b8382015-12-17 09:58:43 -0800781 output += uidTable[id].format(*this, uid, pid, name, id);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700782 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700783
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700784 if (enable) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800785 name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:"
786 : "Logging for this PID:";
Mark Salyzynee3b8382015-12-17 09:58:43 -0800787 output += pidTable.format(*this, uid, pid, name);
788 name = "Chattiest TIDs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700789 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800790 name += ":";
791 output += tidTable.format(*this, uid, pid, name);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700792 }
793
Mark Salyzyn344bff42015-04-13 14:24:45 -0700794 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800795 name = "Chattiest events log buffer TAGs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700796 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800797 name += ":";
798 output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700799 }
800
Mark Salyzyn083b0372015-12-04 10:59:45 -0800801 if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800802 name = "Chattiest security log buffer TAGs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700803 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800804 name += ":";
Mark Salyzyn501c3732017-03-10 14:31:54 -0800805 output +=
806 securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
Mark Salyzyn083b0372015-12-04 10:59:45 -0800807 }
808
Mark Salyzynf99a7d62017-04-19 14:39:21 -0700809 if (enable) {
810 name = "Chattiest TAGs";
811 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
812 name += ":";
813 output += tagNameTable.format(*this, uid, pid, name);
814 }
815
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700816 return output;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800817}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700818
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700819namespace android {
820
821uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700822 char buffer[512];
823 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800824 FILE* fp = fopen(buffer, "r");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700825 if (fp) {
826 while (fgets(buffer, sizeof(buffer), fp)) {
827 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700828 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700829 fclose(fp);
830 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700831 }
832 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700833 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700834 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800835 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700836}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700837}
838
839uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700840 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700841}
842
843// caller must free character string
Mark Salyzyn501c3732017-03-10 14:31:54 -0800844const char* LogStatistics::pidToName(pid_t pid) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700845 // An inconvenient truth ... getName() can alter the object
Mark Salyzyn501c3732017-03-10 14:31:54 -0800846 pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
847 const char* name = writablePidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700848 if (!name) {
849 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700850 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700851 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700852}