blob: 594bd0dd5c64d65c2abd2dfe1980ab0702f10450 [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;
Mark Salyzyn903156d2017-04-19 14:39:21 -070035size_t TagNameEntry::droppedElsewhere;
Mark Salyzyn32962912016-09-12 10:29:17 -070036
Mark Salyzyn77187782015-05-12 15:21:31 -070037LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn03bb7592017-04-14 09:46:57 -070038 log_time now(CLOCK_REALTIME);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070039 log_id_for_each(id) {
40 mSizes[id] = 0;
41 mElements[id] = 0;
Mark Salyzyn58b8be82015-09-30 07:40:09 -070042 mDroppedElements[id] = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070043 mSizesTotal[id] = 0;
44 mElementsTotal[id] = 0;
Mark Salyzyn03bb7592017-04-14 09:46:57 -070045 mOldest[id] = now;
46 mNewest[id] = now;
47 mNewestDropped[id] = now;
Mark Salyzyn34facab2014-02-06 14:48:50 -080048 }
49}
50
Mark Salyzyn720f6d12015-03-16 08:26:05 -070051namespace android {
52
Mark Salyzyn501c3732017-03-10 14:31:54 -080053size_t sizesTotal() {
54 return LogStatistics::sizesTotal();
55}
Mark Salyzyn32962912016-09-12 10:29:17 -070056
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070057// caller must own and free character string
Mark Salyzyn501c3732017-03-10 14:31:54 -080058char* pidToName(pid_t pid) {
59 char* retval = NULL;
60 if (pid == 0) { // special case from auditd/klogd for kernel
Mark Salyzynae4d9282014-10-15 08:49:39 -070061 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070062 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070063 char buffer[512];
64 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
65 int fd = open(buffer, O_RDONLY);
66 if (fd >= 0) {
67 ssize_t ret = read(fd, buffer, sizeof(buffer));
68 if (ret > 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -080069 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn9a038632014-04-07 07:05:40 -070070 // frameworks intermediate state
Mark Salyzyn0eeb06b2016-12-02 10:08:48 -080071 if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070072 retval = strdup(buffer);
73 }
74 }
75 close(fd);
76 }
77 }
78 return retval;
79}
Mark Salyzyn720f6d12015-03-16 08:26:05 -070080}
81
Mark Salyzyn02dd2f42017-04-14 09:46:57 -070082void LogStatistics::addTotal(LogBufferElement* element) {
83 if (element->getDropped()) return;
84
85 log_id_t log_id = element->getLogId();
86 unsigned short size = element->getMsgLen();
87 mSizesTotal[log_id] += size;
88 SizesTotal += size;
89 ++mElementsTotal[log_id];
90}
91
Mark Salyzyn501c3732017-03-10 14:31:54 -080092void LogStatistics::add(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -070093 log_id_t log_id = element->getLogId();
94 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080095 mSizes[log_id] += size;
96 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070097
Mark Salyzyn02dd2f42017-04-14 09:46:57 -070098 // When caller adding a chatty entry, they will have already
99 // called add() and subtract() for each entry as they are
100 // evaluated and trimmed, thus recording size and number of
101 // elements, but we must recognize the manufactured dropped
102 // entry as not contributing to the lifetime totals.
Mark Salyzyna2c02222016-12-13 10:31:29 -0800103 if (element->getDropped()) {
104 ++mDroppedElements[log_id];
105 } else {
Mark Salyzyna2c02222016-12-13 10:31:29 -0800106 mSizesTotal[log_id] += size;
Mark Salyzyn32962912016-09-12 10:29:17 -0700107 SizesTotal += size;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800108 ++mElementsTotal[log_id];
109 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700110
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700111 log_time stamp(element->getRealTime());
112 if (mNewest[log_id] < stamp) {
113 // A major time update invalidates the statistics :-(
114 log_time diff = stamp - mNewest[log_id];
115 mNewest[log_id] = stamp;
116
117 if (diff.tv_sec > hourSec) {
118 // approximate Do-Your-Best fixup
119 diff += mOldest[log_id];
120 if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
121 diff = stamp;
122 }
123 if (diff <= stamp) {
124 mOldest[log_id] = diff;
125 if (mNewestDropped[log_id] < diff) {
126 mNewestDropped[log_id] = diff;
127 }
128 }
129 }
130 }
131
Mark Salyzynae4d9282014-10-15 08:49:39 -0700132 if (log_id == LOG_ID_KERNEL) {
133 return;
134 }
135
Mark Salyzyn758058f2015-08-21 16:44:30 -0700136 uidTable[log_id].add(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700137 if (element->getUid() == AID_SYSTEM) {
138 pidSystemTable[log_id].add(element->getPid(), element);
139 }
Mark Salyzynae4d9282014-10-15 08:49:39 -0700140
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700141 if (!enable) {
142 return;
143 }
144
Mark Salyzyn758058f2015-08-21 16:44:30 -0700145 pidTable.add(element->getPid(), element);
146 tidTable.add(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700147
Mark Salyzyn758058f2015-08-21 16:44:30 -0700148 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700149 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800150 if (log_id == LOG_ID_SECURITY) {
151 securityTagTable.add(tag, element);
152 } else {
153 tagTable.add(tag, element);
154 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700155 }
Mark Salyzyn903156d2017-04-19 14:39:21 -0700156
157 tagNameTable.add(TagNameEntry(element).getKey(), element);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800158}
159
Mark Salyzyn501c3732017-03-10 14:31:54 -0800160void LogStatistics::subtract(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700161 log_id_t log_id = element->getLogId();
162 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800163 mSizes[log_id] -= size;
164 --mElements[log_id];
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700165 if (element->getDropped()) {
166 --mDroppedElements[log_id];
167 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700168
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700169 if (mOldest[log_id] < element->getRealTime()) {
170 mOldest[log_id] = element->getRealTime();
171 }
172
Mark Salyzynae4d9282014-10-15 08:49:39 -0700173 if (log_id == LOG_ID_KERNEL) {
174 return;
175 }
176
Mark Salyzyn758058f2015-08-21 16:44:30 -0700177 uidTable[log_id].subtract(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700178 if (element->getUid() == AID_SYSTEM) {
179 pidSystemTable[log_id].subtract(element->getPid(), element);
180 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800181
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700182 if (!enable) {
183 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800184 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700185
Mark Salyzyn758058f2015-08-21 16:44:30 -0700186 pidTable.subtract(element->getPid(), element);
187 tidTable.subtract(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700188
Mark Salyzyn758058f2015-08-21 16:44:30 -0700189 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700190 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800191 if (log_id == LOG_ID_SECURITY) {
192 securityTagTable.subtract(tag, element);
193 } else {
194 tagTable.subtract(tag, element);
195 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700196 }
Mark Salyzyn903156d2017-04-19 14:39:21 -0700197
198 tagNameTable.subtract(TagNameEntry(element).getKey(), element);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800199}
200
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700201// Atomically set an entry to drop
202// entry->setDropped(1) must follow this call, caller should do this explicitly.
Mark Salyzyn501c3732017-03-10 14:31:54 -0800203void LogStatistics::drop(LogBufferElement* element) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700204 log_id_t log_id = element->getLogId();
205 unsigned short size = element->getMsgLen();
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700206 mSizes[log_id] -= size;
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700207 ++mDroppedElements[log_id];
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700208
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700209 if (mNewestDropped[log_id] < element->getRealTime()) {
210 mNewestDropped[log_id] = element->getRealTime();
211 }
212
Mark Salyzyn758058f2015-08-21 16:44:30 -0700213 uidTable[log_id].drop(element->getUid(), element);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700214 if (element->getUid() == AID_SYSTEM) {
215 pidSystemTable[log_id].drop(element->getPid(), element);
216 }
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700217
218 if (!enable) {
219 return;
220 }
221
Mark Salyzyn758058f2015-08-21 16:44:30 -0700222 pidTable.drop(element->getPid(), element);
223 tidTable.drop(element->getTid(), element);
Mark Salyzyn6a066942016-07-14 15:34:30 -0700224
225 uint32_t tag = element->getTag();
226 if (tag) {
227 if (log_id == LOG_ID_SECURITY) {
228 securityTagTable.drop(tag, element);
229 } else {
230 tagTable.drop(tag, element);
231 }
232 }
Mark Salyzyn903156d2017-04-19 14:39:21 -0700233
234 tagNameTable.drop(TagNameEntry(element).getKey(), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700235}
236
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700237// caller must own and free character string
Mark Salyzyn3c501b52017-04-18 14:09:45 -0700238// Requires parent LogBuffer::wrlock() to be held
Mark Salyzyn501c3732017-03-10 14:31:54 -0800239const char* LogStatistics::uidToName(uid_t uid) const {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700240 // Local hard coded favourites
241 if (uid == AID_LOGD) {
242 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800243 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700244
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700245 // Android system
246 if (uid < AID_APP) {
247 // in bionic, thread safe as long as we copy the results
Mark Salyzyn501c3732017-03-10 14:31:54 -0800248 struct passwd* pwd = getpwuid(uid);
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700249 if (pwd) {
250 return strdup(pwd->pw_name);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700251 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800252 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700253
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700254 // Parse /data/system/packages.list
Jeff Sharkeydff44702016-12-13 11:55:19 -0700255 uid_t userId = uid % AID_USER_OFFSET;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800256 const char* name = android::uidToName(userId);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700257 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
258 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
259 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700260 if (name) {
261 return name;
262 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700263
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700264 // Android application
265 if (uid >= AID_APP) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800266 struct passwd* pwd = getpwuid(uid);
Mark Salyzynb8a95bd2016-04-07 11:06:31 -0700267 if (pwd) {
268 return strdup(pwd->pw_name);
269 }
270 }
271
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700272 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn501c3732017-03-10 14:31:54 -0800273 for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end();
274 ++it) {
275 const PidEntry& entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700276
277 if (entry.getUid() == uid) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800278 const char* nameTmp = entry.getName();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700279
Mark Salyzyn758058f2015-08-21 16:44:30 -0700280 if (nameTmp) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700281 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700282 name = strdup(nameTmp);
Mark Salyzyn0eeb06b2016-12-02 10:08:48 -0800283 } else if (fastcmp<strcmp>(name, nameTmp)) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800284 free(const_cast<char*>(name));
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700285 name = NULL;
286 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700287 }
288 }
289 }
290 }
291
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700292 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700293 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800294}
295
Mark Salyzyn501c3732017-03-10 14:31:54 -0800296std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700297 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800298 return formatLine(android::base::StringPrintf(name.c_str(),
299 android_log_id_to_name(id)),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700300 std::string("Size"),
Mark Salyzyn501c3732017-03-10 14:31:54 -0800301 std::string(isprune ? "+/- Pruned" : "")) +
302 formatLine(std::string("UID PACKAGE"), std::string("BYTES"),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700303 std::string(isprune ? "NUM" : ""));
Mark Salyzyn34facab2014-02-06 14:48:50 -0800304}
305
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700306// Helper to truncate name, if too long, and add name dressings
307static void formatTmp(const LogStatistics& stat, const char* nameTmp, uid_t uid,
308 std::string& name, std::string& size, size_t nameLen) {
309 const char* allocNameTmp = nullptr;
310 if (!nameTmp) nameTmp = allocNameTmp = stat.uidToName(uid);
311 if (nameTmp) {
312 size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
313 size_t len = EntryBaseConstants::total_len -
314 EntryBaseConstants::pruned_len - size.length() -
315 name.length() - lenSpace - 2;
316 size_t lenNameTmp = strlen(nameTmp);
317 while ((len < lenNameTmp) && (lenSpace > 1)) {
318 ++len;
319 --lenSpace;
320 }
321 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
322 if (len < lenNameTmp) {
323 name += "...";
324 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
325 }
326 name += nameTmp;
327 free(const_cast<char*>(allocNameTmp));
328 }
329}
330
Mark Salyzyn501c3732017-03-10 14:31:54 -0800331std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800332 uid_t uid = getUid();
Mark Salyzyn758058f2015-08-21 16:44:30 -0700333 std::string name = android::base::StringPrintf("%u", uid);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700334 std::string size = android::base::StringPrintf("%zu", getSizes());
335
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700336 formatTmp(stat, nullptr, uid, name, size, 6);
337
Mark Salyzyn758058f2015-08-21 16:44:30 -0700338 std::string pruned = "";
Mark Salyzync723df82015-08-24 11:08:00 -0700339 if (worstUidEnabledForLogid(id)) {
340 size_t totalDropped = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800341 for (LogStatistics::uidTable_t::const_iterator it =
342 stat.uidTable[id].begin();
343 it != stat.uidTable[id].end(); ++it) {
Mark Salyzync723df82015-08-24 11:08:00 -0700344 totalDropped += it->second.getDropped();
345 }
346 size_t sizes = stat.sizes(id);
347 size_t totalSize = stat.sizesTotal(id);
348 size_t totalElements = stat.elementsTotal(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800349 float totalVirtualSize =
350 (float)sizes + (float)totalDropped * totalSize / totalElements;
Mark Salyzync723df82015-08-24 11:08:00 -0700351 size_t entrySize = getSizes();
352 float virtualEntrySize = entrySize;
353 int realPermille = virtualEntrySize * 1000.0 / sizes;
354 size_t dropped = getDropped();
355 if (dropped) {
356 pruned = android::base::StringPrintf("%zu", dropped);
357 virtualEntrySize += (float)dropped * totalSize / totalElements;
358 }
359 int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800360 int permille =
361 (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1);
Mark Salyzync723df82015-08-24 11:08:00 -0700362 if ((permille < -1) || (1 < permille)) {
363 std::string change;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800364 const char* units = "%";
365 const char* prefix = (permille > 0) ? "+" : "";
Mark Salyzync723df82015-08-24 11:08:00 -0700366
367 if (permille > 999) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800368 permille = (permille + 1000) / 100; // Now tenths fold
Mark Salyzync723df82015-08-24 11:08:00 -0700369 units = "X";
370 prefix = "";
371 }
372 if ((-99 < permille) && (permille < 99)) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800373 change = android::base::StringPrintf(
374 "%s%d.%u%s", prefix, permille / 10,
Mark Salyzync723df82015-08-24 11:08:00 -0700375 ((permille < 0) ? (-permille % 10) : (permille % 10)),
376 units);
377 } else {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800378 change = android::base::StringPrintf(
379 "%s%d%s", prefix, (permille + 5) / 10, units);
Mark Salyzync723df82015-08-24 11:08:00 -0700380 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800381 ssize_t spaces = EntryBaseConstants::pruned_len - 2 -
382 pruned.length() - change.length();
Mark Salyzync723df82015-08-24 11:08:00 -0700383 if ((spaces <= 0) && pruned.length()) {
384 spaces = 1;
385 }
Mark Salyzynd966e222016-12-19 22:23:03 +0000386 if (spaces > 0) {
Mark Salyzync723df82015-08-24 11:08:00 -0700387 change += android::base::StringPrintf("%*s", (int)spaces, "");
388 }
389 pruned = change + pruned;
390 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700391 }
392
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700393 std::string output = formatLine(name, size, pruned);
394
395 if (uid != AID_SYSTEM) {
396 return output;
397 }
398
399 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800400 std::unique_ptr<const PidEntry* []> sorted =
401 stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries);
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700402
403 if (!sorted.get()) {
404 return output;
405 }
406 std::string byPid;
407 size_t index;
408 bool hasDropped = false;
409 for (index = 0; index < maximum_sorted_entries; ++index) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800410 const PidEntry* entry = sorted[index];
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700411 if (!entry) {
412 break;
413 }
414 if (entry->getSizes() <= (getSizes() / 100)) {
415 break;
416 }
417 if (entry->getDropped()) {
418 hasDropped = true;
419 }
420 byPid += entry->format(stat, id);
421 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800422 if (index > 1) { // print this only if interesting
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700423 std::string ditto("\" ");
Mark Salyzyn501c3732017-03-10 14:31:54 -0800424 output += formatLine(std::string(" PID/UID COMMAND LINE"), ditto,
425 hasDropped ? ditto : std::string(""));
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700426 output += byPid;
427 }
428
429 return output;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700430}
431
Mark Salyzyn501c3732017-03-10 14:31:54 -0800432std::string PidEntry::formatHeader(const std::string& name,
433 log_id_t /* id */) const {
434 return formatLine(name, std::string("Size"), std::string("Pruned")) +
435 formatLine(std::string(" PID/UID COMMAND LINE"),
436 std::string("BYTES"), std::string("NUM"));
Mark Salyzyn758058f2015-08-21 16:44:30 -0700437}
438
Mark Salyzyn501c3732017-03-10 14:31:54 -0800439std::string PidEntry::format(const LogStatistics& stat,
440 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700441 uid_t uid = getUid();
Mark Salyzynee3b8382015-12-17 09:58:43 -0800442 pid_t pid = getPid();
443 std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800444 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700445
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700446 formatTmp(stat, getName(), uid, name, size, 12);
447
Mark Salyzyn758058f2015-08-21 16:44:30 -0700448 std::string pruned = "";
449 size_t dropped = getDropped();
450 if (dropped) {
451 pruned = android::base::StringPrintf("%zu", dropped);
452 }
453
454 return formatLine(name, size, pruned);
455}
456
Mark Salyzyn501c3732017-03-10 14:31:54 -0800457std::string TidEntry::formatHeader(const std::string& name,
458 log_id_t /* id */) const {
459 return formatLine(name, std::string("Size"), std::string("Pruned")) +
460 formatLine(std::string(" TID/UID COMM"), std::string("BYTES"),
Mark Salyzyn758058f2015-08-21 16:44:30 -0700461 std::string("NUM"));
462}
463
Mark Salyzyn501c3732017-03-10 14:31:54 -0800464std::string TidEntry::format(const LogStatistics& stat,
465 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700466 uid_t uid = getUid();
Mark Salyzyn501c3732017-03-10 14:31:54 -0800467 std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800468 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700469
Mark Salyzynf31ae3d2017-04-13 15:35:22 -0700470 formatTmp(stat, getName(), uid, name, size, 12);
471
Mark Salyzyn758058f2015-08-21 16:44:30 -0700472 std::string pruned = "";
473 size_t dropped = getDropped();
474 if (dropped) {
475 pruned = android::base::StringPrintf("%zu", dropped);
476 }
477
478 return formatLine(name, size, pruned);
479}
480
Mark Salyzyn501c3732017-03-10 14:31:54 -0800481std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700482 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800483 return formatLine(name, std::string("Size"),
484 std::string(isprune ? "Prune" : "")) +
485 formatLine(std::string(" TAG/UID TAGNAME"),
486 std::string("BYTES"), std::string(isprune ? "NUM" : ""));
Mark Salyzyn758058f2015-08-21 16:44:30 -0700487}
488
Mark Salyzyn501c3732017-03-10 14:31:54 -0800489std::string TagEntry::format(const LogStatistics& /* stat */,
490 log_id_t /* id */) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700491 std::string name;
492 uid_t uid = getUid();
493 if (uid == (uid_t)-1) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800494 name = android::base::StringPrintf("%7u", getKey());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700495 } else {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800496 name = android::base::StringPrintf("%7u/%u", getKey(), uid);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700497 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800498 const char* nameTmp = getName();
Mark Salyzyn758058f2015-08-21 16:44:30 -0700499 if (nameTmp) {
500 name += android::base::StringPrintf(
Mark Salyzyn501c3732017-03-10 14:31:54 -0800501 "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
Mark Salyzyn758058f2015-08-21 16:44:30 -0700502 }
503
Mark Salyzyn501c3732017-03-10 14:31:54 -0800504 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn758058f2015-08-21 16:44:30 -0700505
506 std::string pruned = "";
Mark Salyzyn6a066942016-07-14 15:34:30 -0700507 size_t dropped = getDropped();
508 if (dropped) {
509 pruned = android::base::StringPrintf("%zu", dropped);
510 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700511
512 return formatLine(name, size, pruned);
513}
514
Mark Salyzyn903156d2017-04-19 14:39:21 -0700515std::string TagNameEntry::formatHeader(const std::string& name,
516 log_id_t /* id */) const {
517 return formatLine(name, std::string("Size"), std::string("Prune")) +
518 formatLine(std::string(" TID/PID/UID LOG_TAG NAME"),
519 std::string("BYTES"), std::string("NUM"));
520}
521
522std::string TagNameEntry::format(const LogStatistics& /* stat */,
523 log_id_t /* id */) const {
524 std::string name;
525 pid_t tid = getTid();
526 pid_t pid = getPid();
527 std::string pidstr;
528 if (pid != (pid_t)-1) {
529 pidstr = android::base::StringPrintf("%u", pid);
530 if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr;
531 }
532 int len = 9 - pidstr.length();
533 if (len < 0) len = 0;
534 if ((tid == (pid_t)-1) || (tid == pid)) {
535 name = android::base::StringPrintf("%*s", len, "");
536 } else {
537 name = android::base::StringPrintf("%*u", len, tid);
538 }
539 name += pidstr;
540 uid_t uid = getUid();
541 if (uid != (uid_t)-1) {
542 name += android::base::StringPrintf("/%u", uid);
543 }
544
545 std::string size = android::base::StringPrintf("%zu", getSizes());
546
547 const char* nameTmp = getName();
548 if (nameTmp) {
549 size_t lenSpace = std::max(16 - name.length(), (size_t)1);
550 size_t len = EntryBaseConstants::total_len -
551 EntryBaseConstants::pruned_len - size.length() -
552 name.length() - lenSpace - 2;
553 size_t lenNameTmp = strlen(nameTmp);
554 while ((len < lenNameTmp) && (lenSpace > 1)) {
555 ++len;
556 --lenSpace;
557 }
558 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
559 if (len < lenNameTmp) {
560 name += "...";
561 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
562 }
563 name += nameTmp;
564 }
565
566 std::string pruned = "";
567
568 // Because of TagNameEntry::droppedElsewhere, dropped count can get
569 // modified for "chatty" tags. Since the size is always zero this
570 // modification is a "can not happen".
571 TagNameEntry& me = const_cast<TagNameEntry&>(*this);
572 size_t dropped = me.getDropped();
573 if (dropped) {
574 pruned = android::base::StringPrintf("%zu", dropped);
575 }
576
577 return formatLine(name, size, pruned);
578}
579
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700580static std::string formatMsec(uint64_t val) {
581 static const unsigned subsecDigits = 3;
582 static const uint64_t sec = MS_PER_SEC;
583
584 static const uint64_t minute = 60 * sec;
585 static const uint64_t hour = 60 * minute;
586 static const uint64_t day = 24 * hour;
587
588 std::string output;
589 if (val < sec) return output;
590
591 if (val >= day) {
592 output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
593 val = (val % day) + day;
594 }
595 if (val >= minute) {
596 if (val >= hour) {
597 output += android::base::StringPrintf("%" PRIu64 ":",
598 (val / hour) % (day / hour));
599 }
600 output += android::base::StringPrintf(
601 (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
602 (val / minute) % (hour / minute));
603 }
604 output +=
605 android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
606 (val / sec) % (minute / sec));
607 val %= sec;
608 unsigned digits = subsecDigits;
609 while (digits && ((val % 10) == 0)) {
610 val /= 10;
611 --digits;
612 }
613 if (digits) {
614 output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
615 }
616 return output;
617}
618
Mark Salyzynee3b8382015-12-17 09:58:43 -0800619std::string LogStatistics::format(uid_t uid, pid_t pid,
620 unsigned int logMask) const {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700621 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800622
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700623 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800624
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700625 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700626 size_t oldLength;
627 short spaces = 1;
628
629 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700630 if (!(logMask & (1 << id))) continue;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700631 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700632 if (spaces < 0) spaces = 0;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700633 output += android::base::StringPrintf("%*s%s", spaces, "",
634 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700635 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800636 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700637 if (spaces < 0) spaces = 0;
638 output += android::base::StringPrintf("%*sTotal", spaces, "");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800639
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700640 static const char TotalStr[] = "\nTotal";
641 spaces = 10 - strlen(TotalStr);
642 output += TotalStr;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800643
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700644 size_t totalSize = 0;
645 size_t totalEls = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700646 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700647 if (!(logMask & (1 << id))) continue;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700648 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700649 if (spaces < 0) spaces = 0;
650 size_t szs = sizesTotal(id);
651 totalSize += szs;
652 size_t els = elementsTotal(id);
653 totalEls += els;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800654 output +=
655 android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700656 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800657 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700658 if (spaces < 0) spaces = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800659 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
660 totalEls);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800661
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700662 static const char NowStr[] = "\nNow";
663 spaces = 10 - strlen(NowStr);
664 output += NowStr;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800665
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700666 totalSize = 0;
667 totalEls = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700668 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700669 if (!(logMask & (1 << id))) continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800670
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700671 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800672 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700673 oldLength = output.length();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700674 if (spaces < 0) spaces = 0;
675 size_t szs = sizes(id);
676 totalSize += szs;
677 totalEls += els;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800678 output +=
679 android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700680 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800681 }
682 spaces += spaces_total;
683 }
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700684 if (spaces < 0) spaces = 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800685 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
686 totalEls);
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700687
Mark Salyzyn03bb7592017-04-14 09:46:57 -0700688 static const char SpanStr[] = "\nLogspan";
689 spaces = 10 - strlen(SpanStr);
690 output += SpanStr;
691
692 // Total reports the greater of the individual maximum time span, or the
693 // validated minimum start and maximum end time span if it makes sense.
694 uint64_t minTime = UINT64_MAX;
695 uint64_t maxTime = 0;
696 uint64_t maxSpan = 0;
697 totalSize = 0;
698
699 log_id_for_each(id) {
700 if (!(logMask & (1 << id))) continue;
701
702 // validity checking
703 uint64_t oldest = mOldest[id].msec();
704 uint64_t newest = mNewest[id].msec();
705 if (newest <= oldest) {
706 spaces += spaces_total;
707 continue;
708 }
709
710 uint64_t span = newest - oldest;
711 if (span > (monthSec * MS_PER_SEC)) {
712 spaces += spaces_total;
713 continue;
714 }
715
716 // total span
717 if (minTime > oldest) minTime = oldest;
718 if (maxTime < newest) maxTime = newest;
719 if (span > maxSpan) maxSpan = span;
720 totalSize += span;
721
722 uint64_t dropped = mNewestDropped[id].msec();
723 if (dropped < oldest) dropped = oldest;
724 if (dropped > newest) dropped = newest;
725
726 oldLength = output.length();
727 output += android::base::StringPrintf("%*s%s", spaces, "",
728 formatMsec(span).c_str());
729 unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span;
730 if ((permille > 1) && (permille < 999)) {
731 output += android::base::StringPrintf("(%u", permille / 10);
732 permille %= 10;
733 if (permille) {
734 output += android::base::StringPrintf(".%u", permille);
735 }
736 output += android::base::StringPrintf("%%)");
737 }
738 spaces -= output.length() - oldLength;
739 spaces += spaces_total;
740 }
741 if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
742 (maxTime > maxSpan)) {
743 maxSpan = maxTime;
744 }
745 if (spaces < 0) spaces = 0;
746 output += android::base::StringPrintf("%*s%s", spaces, "",
747 formatMsec(maxSpan).c_str());
748
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700749 static const char OverheadStr[] = "\nOverhead";
750 spaces = 10 - strlen(OverheadStr);
751 output += OverheadStr;
752
753 totalSize = 0;
754 log_id_for_each(id) {
755 if (!(logMask & (1 << id))) continue;
756
757 size_t els = elements(id);
758 if (els) {
759 oldLength = output.length();
760 if (spaces < 0) spaces = 0;
761 // estimate the std::list overhead.
762 static const size_t overhead =
763 ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) &
Mark Salyzyn501c3732017-03-10 14:31:54 -0800764 -sizeof(uint64_t)) +
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700765 sizeof(std::list<LogBufferElement*>);
766 size_t szs = sizes(id) + els * overhead;
767 totalSize += szs;
768 output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
769 spaces -= output.length() - oldLength;
770 }
771 spaces += spaces_total;
772 }
Mark Salyzyn6d981af2016-10-06 09:55:21 -0700773 totalSize += sizeOf();
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700774 if (spaces < 0) spaces = 0;
775 output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800776
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700777 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700778
Mark Salyzyn758058f2015-08-21 16:44:30 -0700779 std::string name;
780
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700781 // Chattiest by application (UID)
782 log_id_for_each(id) {
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700783 if (!(logMask & (1 << id))) continue;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700784
Mark Salyzyn501c3732017-03-10 14:31:54 -0800785 name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:"
786 : "Logging for your UID in %s log buffer:";
Mark Salyzynee3b8382015-12-17 09:58:43 -0800787 output += uidTable[id].format(*this, uid, pid, name, id);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700788 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700789
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700790 if (enable) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800791 name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:"
792 : "Logging for this PID:";
Mark Salyzynee3b8382015-12-17 09:58:43 -0800793 output += pidTable.format(*this, uid, pid, name);
794 name = "Chattiest TIDs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700795 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800796 name += ":";
797 output += tidTable.format(*this, uid, pid, name);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700798 }
799
Mark Salyzyn903156d2017-04-19 14:39:21 -0700800 if (enable) {
801 name = "Chattiest TAGs";
802 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
803 name += ":";
804 output += tagNameTable.format(*this, uid, pid, name);
805 }
806
Mark Salyzyn344bff42015-04-13 14:24:45 -0700807 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800808 name = "Chattiest events log buffer TAGs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700809 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800810 name += ":";
811 output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700812 }
813
Mark Salyzyn083b0372015-12-04 10:59:45 -0800814 if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800815 name = "Chattiest security log buffer TAGs";
Mark Salyzyn9af33ee2016-10-05 12:34:37 -0700816 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzynee3b8382015-12-17 09:58:43 -0800817 name += ":";
Mark Salyzyn501c3732017-03-10 14:31:54 -0800818 output +=
819 securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
Mark Salyzyn083b0372015-12-04 10:59:45 -0800820 }
821
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700822 return output;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800823}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700824
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700825namespace android {
826
827uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700828 char buffer[512];
829 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800830 FILE* fp = fopen(buffer, "r");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700831 if (fp) {
832 while (fgets(buffer, sizeof(buffer), fp)) {
833 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700834 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700835 fclose(fp);
836 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700837 }
838 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700839 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700840 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800841 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700842}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700843}
844
845uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700846 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700847}
848
849// caller must free character string
Mark Salyzyn501c3732017-03-10 14:31:54 -0800850const char* LogStatistics::pidToName(pid_t pid) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700851 // An inconvenient truth ... getName() can alter the object
Mark Salyzyn501c3732017-03-10 14:31:54 -0800852 pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
853 const char* name = writablePidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700854 if (!name) {
855 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700856 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700857 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700858}