blob: 173b7330d2d17686e03568540f1993e7861099a2 [file] [log] [blame]
Mark Salyzynd774bce2014-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
Tom Cherry479b5032020-05-07 14:44:43 -070017#include "LogStatistics.h"
18
Mark Salyzyncba1db12017-05-04 13:54:46 -070019#include <ctype.h>
Mark Salyzyn5766f802014-04-07 07:05:40 -070020#include <fcntl.h>
Mark Salyzynfb0967b2017-04-14 09:46:57 -070021#include <inttypes.h>
Mark Salyzyn14dd7df2016-04-07 11:06:31 -070022#include <pwd.h>
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070023#include <stdio.h>
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070024#include <string.h>
Mark Salyzyn14dd7df2016-04-07 11:06:31 -070025#include <sys/types.h>
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070026#include <unistd.h>
Mark Salyzynd774bce2014-02-06 14:48:50 -080027
Mark Salyzyn143461d2016-10-05 12:34:37 -070028#include <list>
Tom Cherryf0dc09b2020-07-09 09:51:16 -070029#include <vector>
Mark Salyzyn143461d2016-10-05 12:34:37 -070030
Tom Cherrya3d6aa62020-06-19 12:21:21 -070031#include <android-base/logging.h>
Tom Cherryf0dc09b2020-07-09 09:51:16 -070032#include <android-base/strings.h>
Mark Salyzynda924cb2017-04-14 09:46:57 -070033#include <private/android_logger.h>
Mark Salyzynd774bce2014-02-06 14:48:50 -080034
Tom Cherry8f459112020-06-02 15:39:21 -070035#include "LogBufferElement.h"
36
Mark Salyzynda924cb2017-04-14 09:46:57 -070037static const uint64_t hourSec = 60 * 60;
38static const uint64_t monthSec = 31 * 24 * hourSec;
39
Tom Cherry479b5032020-05-07 14:44:43 -070040std::atomic<size_t> LogStatistics::SizesTotal;
Mark Salyzync0123442016-09-12 10:29:17 -070041
Tom Cherry8a34ac42020-06-03 15:38:32 -070042static std::string TagNameKey(const LogStatisticsElement& element) {
43 if (IsBinary(element.log_id)) {
44 uint32_t tag = element.tag;
45 if (tag) {
46 const char* cp = android::tagToName(tag);
47 if (cp) {
48 return std::string(cp);
49 }
50 }
51 return android::base::StringPrintf("[%" PRIu32 "]", tag);
52 }
53 const char* msg = element.msg;
Tom Cherry8a34ac42020-06-03 15:38:32 -070054 ++msg;
55 uint16_t len = element.msg_len;
56 len = (len <= 1) ? 0 : strnlen(msg, len - 1);
57 if (!len) {
58 return "<NULL>";
59 }
60 return std::string(msg, len);
61}
62
Tom Cherryf0dc09b2020-07-09 09:51:16 -070063LogStatistics::LogStatistics(bool enable_statistics, bool track_total_size,
64 std::optional<log_time> start_time)
Tom Cherrya3d6aa62020-06-19 12:21:21 -070065 : enable(enable_statistics), track_total_size_(track_total_size) {
Mark Salyzynda924cb2017-04-14 09:46:57 -070066 log_time now(CLOCK_REALTIME);
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070067 log_id_for_each(id) {
68 mSizes[id] = 0;
69 mElements[id] = 0;
70 mSizesTotal[id] = 0;
71 mElementsTotal[id] = 0;
Tom Cherryf0dc09b2020-07-09 09:51:16 -070072 if (start_time) {
73 mOldest[id] = *start_time;
74 mNewest[id] = *start_time;
75 } else {
76 mOldest[id] = now;
77 mNewest[id] = now;
78 }
Mark Salyzynd774bce2014-02-06 14:48:50 -080079 }
80}
81
Mark Salyzyn1435b472015-03-16 08:26:05 -070082namespace android {
83
Mark Salyzyn65059532017-03-10 14:31:54 -080084size_t sizesTotal() {
85 return LogStatistics::sizesTotal();
86}
Mark Salyzync0123442016-09-12 10:29:17 -070087
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070088// caller must own and free character string
Mark Salyzyn65059532017-03-10 14:31:54 -080089char* pidToName(pid_t pid) {
Yi Kong36feb152018-07-13 17:39:22 -070090 char* retval = nullptr;
Mark Salyzyn65059532017-03-10 14:31:54 -080091 if (pid == 0) { // special case from auditd/klogd for kernel
Mark Salyzyne73a18b2014-10-15 08:49:39 -070092 retval = strdup("logd");
Mark Salyzyn9cf5d402015-03-10 13:51:35 -070093 } else {
Mark Salyzyn5766f802014-04-07 07:05:40 -070094 char buffer[512];
95 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
Tom Cherry17b77582020-06-17 11:40:55 -070096 int fd = open(buffer, O_RDONLY | O_CLOEXEC);
Mark Salyzyn5766f802014-04-07 07:05:40 -070097 if (fd >= 0) {
98 ssize_t ret = read(fd, buffer, sizeof(buffer));
99 if (ret > 0) {
Mark Salyzyn65059532017-03-10 14:31:54 -0800100 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn5766f802014-04-07 07:05:40 -0700101 // frameworks intermediate state
Mark Salyzyn3eeec052016-12-02 10:08:48 -0800102 if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn5766f802014-04-07 07:05:40 -0700103 retval = strdup(buffer);
104 }
105 }
106 close(fd);
107 }
108 }
109 return retval;
110}
Mark Salyzyn1435b472015-03-16 08:26:05 -0700111}
112
Tom Cherrya91e0702020-05-19 17:48:42 -0700113void LogStatistics::AddTotal(log_id_t log_id, uint16_t size) {
Tim Murray85d89812023-07-26 15:44:32 -0700114 auto lock = std::lock_guard{lock_};
Steven Moreland87b90e42023-08-31 15:45:15 +0000115
Mark Salyzynfb0967b2017-04-14 09:46:57 -0700116 mSizesTotal[log_id] += size;
117 SizesTotal += size;
118 ++mElementsTotal[log_id];
119}
120
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700121void LogStatistics::Add(LogStatisticsElement element) {
Tom Cherry479b5032020-05-07 14:44:43 -0700122 auto lock = std::lock_guard{lock_};
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700123
124 if (!track_total_size_) {
125 element.total_len = element.msg_len;
126 }
127
Tom Cherry8f459112020-06-02 15:39:21 -0700128 log_id_t log_id = element.log_id;
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700129 uint16_t size = element.total_len;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800130 mSizes[log_id] += size;
131 ++mElements[log_id];
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700132
Elliott Hughes225e5c62022-09-16 23:01:59 +0000133 mSizesTotal[log_id] += size;
134 SizesTotal += size;
135 ++mElementsTotal[log_id];
Mark Salyzyn1435b472015-03-16 08:26:05 -0700136
Tom Cherry8f459112020-06-02 15:39:21 -0700137 log_time stamp(element.realtime);
Mark Salyzynda924cb2017-04-14 09:46:57 -0700138 if (mNewest[log_id] < stamp) {
139 // A major time update invalidates the statistics :-(
140 log_time diff = stamp - mNewest[log_id];
141 mNewest[log_id] = stamp;
142
143 if (diff.tv_sec > hourSec) {
144 // approximate Do-Your-Best fixup
145 diff += mOldest[log_id];
146 if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
147 diff = stamp;
148 }
149 if (diff <= stamp) {
150 mOldest[log_id] = diff;
Mark Salyzynda924cb2017-04-14 09:46:57 -0700151 }
152 }
153 }
154
Mark Salyzyne73a18b2014-10-15 08:49:39 -0700155 if (log_id == LOG_ID_KERNEL) {
156 return;
157 }
158
Tom Cherry8f459112020-06-02 15:39:21 -0700159 uidTable[log_id].Add(element.uid, element);
160 if (element.uid == AID_SYSTEM) {
161 pidSystemTable[log_id].Add(element.pid, element);
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700162 }
Mark Salyzyne73a18b2014-10-15 08:49:39 -0700163
Mark Salyzyn1435b472015-03-16 08:26:05 -0700164 if (!enable) {
165 return;
166 }
167
Tom Cherry8f459112020-06-02 15:39:21 -0700168 pidTable.Add(element.pid, element);
169 tidTable.Add(element.tid, element);
Mark Salyzynf96ac902015-04-13 14:24:45 -0700170
Tom Cherry8f459112020-06-02 15:39:21 -0700171 uint32_t tag = element.tag;
Mark Salyzynf96ac902015-04-13 14:24:45 -0700172 if (tag) {
Mark Salyzync9690862015-12-04 10:59:45 -0800173 if (log_id == LOG_ID_SECURITY) {
Tom Cherryf1910142020-05-19 19:01:16 -0700174 securityTagTable.Add(tag, element);
Mark Salyzync9690862015-12-04 10:59:45 -0800175 } else {
Tom Cherryf1910142020-05-19 19:01:16 -0700176 tagTable.Add(tag, element);
Mark Salyzync9690862015-12-04 10:59:45 -0800177 }
Mark Salyzynf96ac902015-04-13 14:24:45 -0700178 }
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700179
Elliott Hughes225e5c62022-09-16 23:01:59 +0000180 tagNameTable.Add(TagNameKey(element), element);
Mark Salyzynd774bce2014-02-06 14:48:50 -0800181}
182
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700183void LogStatistics::Subtract(LogStatisticsElement element) {
Tom Cherry479b5032020-05-07 14:44:43 -0700184 auto lock = std::lock_guard{lock_};
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700185
186 if (!track_total_size_) {
187 element.total_len = element.msg_len;
188 }
189
Tom Cherry8f459112020-06-02 15:39:21 -0700190 log_id_t log_id = element.log_id;
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700191 uint16_t size = element.total_len;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800192 mSizes[log_id] -= size;
193 --mElements[log_id];
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700194
Tom Cherry8f459112020-06-02 15:39:21 -0700195 if (mOldest[log_id] < element.realtime) {
196 mOldest[log_id] = element.realtime;
Mark Salyzynda924cb2017-04-14 09:46:57 -0700197 }
198
Mark Salyzyne73a18b2014-10-15 08:49:39 -0700199 if (log_id == LOG_ID_KERNEL) {
200 return;
201 }
202
Tom Cherry8f459112020-06-02 15:39:21 -0700203 uidTable[log_id].Subtract(element.uid, element);
204 if (element.uid == AID_SYSTEM) {
205 pidSystemTable[log_id].Subtract(element.pid, element);
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700206 }
Mark Salyzynd774bce2014-02-06 14:48:50 -0800207
Mark Salyzyn1435b472015-03-16 08:26:05 -0700208 if (!enable) {
209 return;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800210 }
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700211
Tom Cherry8f459112020-06-02 15:39:21 -0700212 pidTable.Subtract(element.pid, element);
213 tidTable.Subtract(element.tid, element);
Mark Salyzynf96ac902015-04-13 14:24:45 -0700214
Tom Cherry8f459112020-06-02 15:39:21 -0700215 uint32_t tag = element.tag;
Mark Salyzynf96ac902015-04-13 14:24:45 -0700216 if (tag) {
Mark Salyzync9690862015-12-04 10:59:45 -0800217 if (log_id == LOG_ID_SECURITY) {
Tom Cherryf1910142020-05-19 19:01:16 -0700218 securityTagTable.Subtract(tag, element);
Mark Salyzync9690862015-12-04 10:59:45 -0800219 } else {
Tom Cherryf1910142020-05-19 19:01:16 -0700220 tagTable.Subtract(tag, element);
Mark Salyzync9690862015-12-04 10:59:45 -0800221 }
Mark Salyzynf96ac902015-04-13 14:24:45 -0700222 }
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700223
Tom Cherryf1910142020-05-19 19:01:16 -0700224 tagNameTable.Subtract(TagNameKey(element), element);
Mark Salyzyna69d5a42015-03-16 12:04:09 -0700225}
226
Tom Cherry479b5032020-05-07 14:44:43 -0700227const char* LogStatistics::UidToName(uid_t uid) const {
228 auto lock = std::lock_guard{lock_};
229 return UidToNameLocked(uid);
230}
231
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700232// caller must own and free character string
Tom Cherry479b5032020-05-07 14:44:43 -0700233const char* LogStatistics::UidToNameLocked(uid_t uid) const {
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700234 // Local hard coded favourites
235 if (uid == AID_LOGD) {
236 return strdup("auditd");
Mark Salyzynd774bce2014-02-06 14:48:50 -0800237 }
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700238
Mark Salyzyn14dd7df2016-04-07 11:06:31 -0700239 // Android system
240 if (uid < AID_APP) {
241 // in bionic, thread safe as long as we copy the results
Mark Salyzyn65059532017-03-10 14:31:54 -0800242 struct passwd* pwd = getpwuid(uid);
Mark Salyzyn14dd7df2016-04-07 11:06:31 -0700243 if (pwd) {
244 return strdup(pwd->pw_name);
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700245 }
Mark Salyzynd774bce2014-02-06 14:48:50 -0800246 }
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700247
Mark Salyzyn9018bc92015-03-16 08:26:05 -0700248 // Parse /data/system/packages.list
Jeff Sharkeybdeb8602016-12-13 11:55:19 -0700249 uid_t userId = uid % AID_USER_OFFSET;
Mark Salyzyn65059532017-03-10 14:31:54 -0800250 const char* name = android::uidToName(userId);
Mark Salyzynf9908b02015-04-29 12:48:45 -0700251 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
252 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
253 }
Mark Salyzyn9018bc92015-03-16 08:26:05 -0700254 if (name) {
255 return name;
256 }
Mark Salyzyn1435b472015-03-16 08:26:05 -0700257
Mark Salyzyn14dd7df2016-04-07 11:06:31 -0700258 // Android application
259 if (uid >= AID_APP) {
Mark Salyzyn65059532017-03-10 14:31:54 -0800260 struct passwd* pwd = getpwuid(uid);
Mark Salyzyn14dd7df2016-04-07 11:06:31 -0700261 if (pwd) {
262 return strdup(pwd->pw_name);
263 }
264 }
265
Mark Salyzyn1435b472015-03-16 08:26:05 -0700266 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn65059532017-03-10 14:31:54 -0800267 for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end();
268 ++it) {
269 const PidEntry& entry = it->second;
Mark Salyzyn1435b472015-03-16 08:26:05 -0700270
Tom Cherryf1910142020-05-19 19:01:16 -0700271 if (entry.uid() == uid) {
272 const char* nameTmp = entry.name();
Mark Salyzyn1435b472015-03-16 08:26:05 -0700273
Mark Salyzyn1761a842015-08-21 16:44:30 -0700274 if (nameTmp) {
Mark Salyzyn1435b472015-03-16 08:26:05 -0700275 if (!name) {
Mark Salyzyn1761a842015-08-21 16:44:30 -0700276 name = strdup(nameTmp);
Mark Salyzyn3eeec052016-12-02 10:08:48 -0800277 } else if (fastcmp<strcmp>(name, nameTmp)) {
Mark Salyzyn65059532017-03-10 14:31:54 -0800278 free(const_cast<char*>(name));
Yi Kong36feb152018-07-13 17:39:22 -0700279 name = nullptr;
Mark Salyzynf9908b02015-04-29 12:48:45 -0700280 break;
Mark Salyzyn1435b472015-03-16 08:26:05 -0700281 }
282 }
283 }
284 }
285
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700286 // No one
Mark Salyzyn1435b472015-03-16 08:26:05 -0700287 return name;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800288}
289
Tom Cherry479b5032020-05-07 14:44:43 -0700290// Prune at most 10% of the log entries or maxPrune, whichever is less.
291bool LogStatistics::ShouldPrune(log_id id, unsigned long max_size,
292 unsigned long* prune_rows) const {
293 static constexpr size_t kMinPrune = 4;
294 static constexpr size_t kMaxPrune = 256;
295
296 auto lock = std::lock_guard{lock_};
297 size_t sizes = mSizes[id];
298 if (sizes <= max_size) {
299 return false;
300 }
301 size_t size_over = sizes - ((max_size * 9) / 10);
Elliott Hughes225e5c62022-09-16 23:01:59 +0000302 size_t elements = mElements[id];
Tom Cherry479b5032020-05-07 14:44:43 -0700303 size_t min_elements = elements / 100;
304 if (min_elements < kMinPrune) {
305 min_elements = kMinPrune;
306 }
307 *prune_rows = elements * size_over / sizes;
308 if (*prune_rows < min_elements) {
309 *prune_rows = min_elements;
310 }
311 if (*prune_rows > kMaxPrune) {
312 *prune_rows = kMaxPrune;
313 }
314
315 return true;
316}
317
Mark Salyzyn65059532017-03-10 14:31:54 -0800318std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn1761a842015-08-21 16:44:30 -0700319 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn65059532017-03-10 14:31:54 -0800320 return formatLine(android::base::StringPrintf(name.c_str(),
321 android_log_id_to_name(id)),
Mark Salyzyn1761a842015-08-21 16:44:30 -0700322 std::string("Size"),
Mark Salyzyn65059532017-03-10 14:31:54 -0800323 std::string(isprune ? "+/- Pruned" : "")) +
324 formatLine(std::string("UID PACKAGE"), std::string("BYTES"),
Mark Salyzyn1761a842015-08-21 16:44:30 -0700325 std::string(isprune ? "NUM" : ""));
Mark Salyzynd774bce2014-02-06 14:48:50 -0800326}
327
Mark Salyzyn87118332017-04-13 15:35:22 -0700328// Helper to truncate name, if too long, and add name dressings
Tom Cherry479b5032020-05-07 14:44:43 -0700329void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name, std::string& size,
330 size_t nameLen) const {
Mark Salyzyn87118332017-04-13 15:35:22 -0700331 const char* allocNameTmp = nullptr;
Tom Cherry479b5032020-05-07 14:44:43 -0700332 if (!nameTmp) nameTmp = allocNameTmp = UidToNameLocked(uid);
Mark Salyzyn87118332017-04-13 15:35:22 -0700333 if (nameTmp) {
334 size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
Tom Cherryf1910142020-05-19 19:01:16 -0700335 size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
336 lenSpace - 2;
Mark Salyzyn87118332017-04-13 15:35:22 -0700337 size_t lenNameTmp = strlen(nameTmp);
338 while ((len < lenNameTmp) && (lenSpace > 1)) {
339 ++len;
340 --lenSpace;
341 }
342 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
343 if (len < lenNameTmp) {
344 name += "...";
345 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
346 }
347 name += nameTmp;
348 free(const_cast<char*>(allocNameTmp));
349 }
350}
351
Tom Cherryc5b802c2020-06-03 13:49:24 -0700352std::string UidEntry::format(const LogStatistics& stat, log_id_t id, uid_t uid) const
353 REQUIRES(stat.lock_) {
354 std::string name = android::base::StringPrintf("%u", uid);
Mark Salyzyn1761a842015-08-21 16:44:30 -0700355 std::string size = android::base::StringPrintf("%zu", getSizes());
356
Tom Cherryc5b802c2020-06-03 13:49:24 -0700357 stat.FormatTmp(nullptr, uid, name, size, 6);
Mark Salyzyn87118332017-04-13 15:35:22 -0700358
Mark Salyzyn1761a842015-08-21 16:44:30 -0700359 std::string pruned = "";
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700360 std::string output = formatLine(name, size, pruned);
361
Tom Cherryc5b802c2020-06-03 13:49:24 -0700362 if (uid != AID_SYSTEM) {
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700363 return output;
364 }
365
366 static const size_t maximum_sorted_entries = 32;
Tom Cherryc5b802c2020-06-03 13:49:24 -0700367 std::array<const pid_t*, maximum_sorted_entries> sorted_pids;
368 std::array<const PidEntry*, maximum_sorted_entries> sorted_entries;
369 stat.pidSystemTable[id].MaxEntries(uid, 0, sorted_pids, sorted_entries);
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700370
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700371 std::string byPid;
372 size_t index;
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700373 for (index = 0; index < maximum_sorted_entries; ++index) {
Tom Cherryc5b802c2020-06-03 13:49:24 -0700374 const PidEntry* entry = sorted_entries[index];
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700375 if (!entry) {
376 break;
377 }
378 if (entry->getSizes() <= (getSizes() / 100)) {
379 break;
380 }
Tom Cherryc5b802c2020-06-03 13:49:24 -0700381 byPid += entry->format(stat, id, *sorted_pids[index]);
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700382 }
Mark Salyzyn65059532017-03-10 14:31:54 -0800383 if (index > 1) { // print this only if interesting
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700384 std::string ditto("\" ");
Elliott Hughes225e5c62022-09-16 23:01:59 +0000385 output += formatLine(std::string(" PID/UID COMMAND LINE"), ditto, std::string(""));
Mark Salyzynedcbdfa2015-08-28 08:02:59 -0700386 output += byPid;
387 }
388
389 return output;
Mark Salyzyn1761a842015-08-21 16:44:30 -0700390}
391
Mark Salyzyn65059532017-03-10 14:31:54 -0800392std::string PidEntry::formatHeader(const std::string& name,
393 log_id_t /* id */) const {
394 return formatLine(name, std::string("Size"), std::string("Pruned")) +
395 formatLine(std::string(" PID/UID COMMAND LINE"),
396 std::string("BYTES"), std::string("NUM"));
Mark Salyzyn1761a842015-08-21 16:44:30 -0700397}
398
Tom Cherryc5b802c2020-06-03 13:49:24 -0700399std::string PidEntry::format(const LogStatistics& stat, log_id_t, pid_t pid) const
Tom Cherry479b5032020-05-07 14:44:43 -0700400 REQUIRES(stat.lock_) {
Tom Cherryc5b802c2020-06-03 13:49:24 -0700401 std::string name = android::base::StringPrintf("%5u/%u", pid, uid_);
Mark Salyzyn65059532017-03-10 14:31:54 -0800402 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn1761a842015-08-21 16:44:30 -0700403
Tom Cherryf1910142020-05-19 19:01:16 -0700404 stat.FormatTmp(name_, uid_, name, size, 12);
Mark Salyzyn87118332017-04-13 15:35:22 -0700405
Mark Salyzyn1761a842015-08-21 16:44:30 -0700406 std::string pruned = "";
Mark Salyzyn1761a842015-08-21 16:44:30 -0700407 return formatLine(name, size, pruned);
408}
409
Mark Salyzyn65059532017-03-10 14:31:54 -0800410std::string TidEntry::formatHeader(const std::string& name,
411 log_id_t /* id */) const {
412 return formatLine(name, std::string("Size"), std::string("Pruned")) +
413 formatLine(std::string(" TID/UID COMM"), std::string("BYTES"),
Mark Salyzyn1761a842015-08-21 16:44:30 -0700414 std::string("NUM"));
415}
416
Tom Cherryc5b802c2020-06-03 13:49:24 -0700417std::string TidEntry::format(const LogStatistics& stat, log_id_t, pid_t tid) const
Tom Cherry479b5032020-05-07 14:44:43 -0700418 REQUIRES(stat.lock_) {
Tom Cherryc5b802c2020-06-03 13:49:24 -0700419 std::string name = android::base::StringPrintf("%5u/%u", tid, uid_);
Mark Salyzyn65059532017-03-10 14:31:54 -0800420 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn1761a842015-08-21 16:44:30 -0700421
Tom Cherryf1910142020-05-19 19:01:16 -0700422 stat.FormatTmp(name_, uid_, name, size, 12);
Mark Salyzyn87118332017-04-13 15:35:22 -0700423
Mark Salyzyn1761a842015-08-21 16:44:30 -0700424 std::string pruned = "";
Mark Salyzyn1761a842015-08-21 16:44:30 -0700425 return formatLine(name, size, pruned);
426}
427
Mark Salyzyn65059532017-03-10 14:31:54 -0800428std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
Mark Salyzyn1761a842015-08-21 16:44:30 -0700429 bool isprune = worstUidEnabledForLogid(id);
Mark Salyzyn65059532017-03-10 14:31:54 -0800430 return formatLine(name, std::string("Size"),
431 std::string(isprune ? "Prune" : "")) +
432 formatLine(std::string(" TAG/UID TAGNAME"),
433 std::string("BYTES"), std::string(isprune ? "NUM" : ""));
Mark Salyzyn1761a842015-08-21 16:44:30 -0700434}
435
Tom Cherryc5b802c2020-06-03 13:49:24 -0700436std::string TagEntry::format(const LogStatistics&, log_id_t, uint32_t) const {
Mark Salyzyn1761a842015-08-21 16:44:30 -0700437 std::string name;
Tom Cherryf1910142020-05-19 19:01:16 -0700438 if (uid_ == (uid_t)-1) {
439 name = android::base::StringPrintf("%7u", key());
Mark Salyzyn1761a842015-08-21 16:44:30 -0700440 } else {
Tom Cherryf1910142020-05-19 19:01:16 -0700441 name = android::base::StringPrintf("%7u/%u", key(), uid_);
Mark Salyzyn1761a842015-08-21 16:44:30 -0700442 }
Tom Cherryf1910142020-05-19 19:01:16 -0700443 const char* nameTmp = this->name();
Mark Salyzyn1761a842015-08-21 16:44:30 -0700444 if (nameTmp) {
445 name += android::base::StringPrintf(
Mark Salyzyn65059532017-03-10 14:31:54 -0800446 "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
Mark Salyzyn1761a842015-08-21 16:44:30 -0700447 }
448
Mark Salyzyn65059532017-03-10 14:31:54 -0800449 std::string size = android::base::StringPrintf("%zu", getSizes());
Mark Salyzyn1761a842015-08-21 16:44:30 -0700450
451 std::string pruned = "";
Mark Salyzyn1761a842015-08-21 16:44:30 -0700452 return formatLine(name, size, pruned);
453}
454
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700455std::string TagNameEntry::formatHeader(const std::string& name,
456 log_id_t /* id */) const {
457 return formatLine(name, std::string("Size"), std::string("")) +
458 formatLine(std::string(" TID/PID/UID LOG_TAG NAME"),
459 std::string("BYTES"), std::string(""));
460}
461
Tom Cherry8a34ac42020-06-03 15:38:32 -0700462std::string TagNameEntry::format(const LogStatistics&, log_id_t,
463 const std::string& key_name) const {
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700464 std::string name;
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700465 std::string pidstr;
Tom Cherryf1910142020-05-19 19:01:16 -0700466 if (pid_ != (pid_t)-1) {
467 pidstr = android::base::StringPrintf("%u", pid_);
468 if (tid_ != (pid_t)-1 && tid_ != pid_) pidstr = "/" + pidstr;
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700469 }
470 int len = 9 - pidstr.length();
471 if (len < 0) len = 0;
Tom Cherryf1910142020-05-19 19:01:16 -0700472 if (tid_ == (pid_t)-1 || tid_ == pid_) {
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700473 name = android::base::StringPrintf("%*s", len, "");
474 } else {
Tom Cherryf1910142020-05-19 19:01:16 -0700475 name = android::base::StringPrintf("%*u", len, tid_);
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700476 }
477 name += pidstr;
Tom Cherryf1910142020-05-19 19:01:16 -0700478 if (uid_ != (uid_t)-1) {
479 name += android::base::StringPrintf("/%u", uid_);
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700480 }
481
482 std::string size = android::base::StringPrintf("%zu", getSizes());
483
Tom Cherryc5b802c2020-06-03 13:49:24 -0700484 const char* nameTmp = key_name.data();
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700485 if (nameTmp) {
486 size_t lenSpace = std::max(16 - name.length(), (size_t)1);
Tom Cherryf1910142020-05-19 19:01:16 -0700487 size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
488 lenSpace - 2;
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700489 size_t lenNameTmp = strlen(nameTmp);
490 while ((len < lenNameTmp) && (lenSpace > 1)) {
491 ++len;
492 --lenSpace;
493 }
494 name += android::base::StringPrintf("%*s", (int)lenSpace, "");
495 if (len < lenNameTmp) {
496 name += "...";
497 nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
498 }
499 name += nameTmp;
500 }
501
502 std::string pruned = "";
503
504 return formatLine(name, size, pruned);
505}
506
Mark Salyzynda924cb2017-04-14 09:46:57 -0700507static std::string formatMsec(uint64_t val) {
508 static const unsigned subsecDigits = 3;
509 static const uint64_t sec = MS_PER_SEC;
510
511 static const uint64_t minute = 60 * sec;
512 static const uint64_t hour = 60 * minute;
513 static const uint64_t day = 24 * hour;
514
515 std::string output;
516 if (val < sec) return output;
517
518 if (val >= day) {
519 output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
520 val = (val % day) + day;
521 }
522 if (val >= minute) {
523 if (val >= hour) {
524 output += android::base::StringPrintf("%" PRIu64 ":",
525 (val / hour) % (day / hour));
526 }
527 output += android::base::StringPrintf(
528 (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
529 (val / minute) % (hour / minute));
530 }
531 output +=
532 android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
533 (val / sec) % (minute / sec));
534 val %= sec;
535 unsigned digits = subsecDigits;
536 while (digits && ((val % 10) == 0)) {
537 val /= 10;
538 --digits;
539 }
540 if (digits) {
541 output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
542 }
543 return output;
544}
545
Tom Cherry479b5032020-05-07 14:44:43 -0700546template <typename TKey, typename TEntry>
547std::string LogStatistics::FormatTable(const LogHashtable<TKey, TEntry>& table, uid_t uid,
548 pid_t pid, const std::string& name, log_id_t id) const
549 REQUIRES(lock_) {
550 static const size_t maximum_sorted_entries = 32;
551 std::string output;
Tom Cherryc5b802c2020-06-03 13:49:24 -0700552 std::array<const TKey*, maximum_sorted_entries> sorted_keys;
553 std::array<const TEntry*, maximum_sorted_entries> sorted_entries;
554 table.MaxEntries(uid, pid, sorted_keys, sorted_entries);
Tom Cherry479b5032020-05-07 14:44:43 -0700555 bool header_printed = false;
556 for (size_t index = 0; index < maximum_sorted_entries; ++index) {
Tom Cherryc5b802c2020-06-03 13:49:24 -0700557 const TEntry* entry = sorted_entries[index];
Tom Cherry479b5032020-05-07 14:44:43 -0700558 if (!entry) {
559 break;
560 }
Tom Cherryc5b802c2020-06-03 13:49:24 -0700561 if (entry->getSizes() <= (sorted_entries[0]->getSizes() / 100)) {
Tom Cherry479b5032020-05-07 14:44:43 -0700562 break;
563 }
564 if (!header_printed) {
565 output += "\n\n";
566 output += entry->formatHeader(name, id);
567 header_printed = true;
568 }
Tom Cherryc5b802c2020-06-03 13:49:24 -0700569 output += entry->format(*this, id, *sorted_keys[index]);
Tom Cherry479b5032020-05-07 14:44:43 -0700570 }
571 return output;
572}
573
Tom Cherryf0dc09b2020-07-09 09:51:16 -0700574std::string LogStatistics::ReportInteresting() const {
575 auto lock = std::lock_guard{lock_};
576
577 std::vector<std::string> items;
578
579 log_id_for_each(i) { items.emplace_back(std::to_string(mElements[i])); }
580
581 log_id_for_each(i) { items.emplace_back(std::to_string(mSizes[i])); }
582
583 log_id_for_each(i) {
584 items.emplace_back(std::to_string(overhead_[i] ? *overhead_[i] : mSizes[i]));
585 }
586
587 log_id_for_each(i) {
588 uint64_t oldest = mOldest[i].msec() / 1000;
589 uint64_t newest = mNewest[i].msec() / 1000;
590
591 int span = newest - oldest;
592
593 items.emplace_back(std::to_string(span));
594 }
595
596 return android::base::Join(items, ",");
597}
598
Tom Cherry479b5032020-05-07 14:44:43 -0700599std::string LogStatistics::Format(uid_t uid, pid_t pid, unsigned int logMask) const {
600 auto lock = std::lock_guard{lock_};
601
Chih-Hung Hsieh9ff81552018-08-13 14:22:56 -0700602 static const uint16_t spaces_total = 19;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800603
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700604 // Report on total logging, current and for all time
Mark Salyzynd774bce2014-02-06 14:48:50 -0800605
Mark Salyzynbd4ee6a2015-08-19 15:33:01 -0700606 std::string output = "size/num";
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700607 size_t oldLength;
Chih-Hung Hsieh9ff81552018-08-13 14:22:56 -0700608 int16_t spaces = 1;
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700609
610 log_id_for_each(id) {
Mark Salyzyn143461d2016-10-05 12:34:37 -0700611 if (!(logMask & (1 << id))) continue;
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700612 oldLength = output.length();
Mark Salyzyn143461d2016-10-05 12:34:37 -0700613 if (spaces < 0) spaces = 0;
Mark Salyzynbd4ee6a2015-08-19 15:33:01 -0700614 output += android::base::StringPrintf("%*s%s", spaces, "",
615 android_log_id_to_name(id));
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700616 spaces += spaces_total + oldLength - output.length();
Mark Salyzynd774bce2014-02-06 14:48:50 -0800617 }
Mark Salyzyn143461d2016-10-05 12:34:37 -0700618 if (spaces < 0) spaces = 0;
619 output += android::base::StringPrintf("%*sTotal", spaces, "");
Mark Salyzynd774bce2014-02-06 14:48:50 -0800620
Mark Salyzyn143461d2016-10-05 12:34:37 -0700621 static const char TotalStr[] = "\nTotal";
622 spaces = 10 - strlen(TotalStr);
623 output += TotalStr;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800624
Mark Salyzyn143461d2016-10-05 12:34:37 -0700625 size_t totalSize = 0;
626 size_t totalEls = 0;
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700627 log_id_for_each(id) {
Mark Salyzyn143461d2016-10-05 12:34:37 -0700628 if (!(logMask & (1 << id))) continue;
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700629 oldLength = output.length();
Mark Salyzyn143461d2016-10-05 12:34:37 -0700630 if (spaces < 0) spaces = 0;
Tom Cherry479b5032020-05-07 14:44:43 -0700631 size_t szs = mSizesTotal[id];
Mark Salyzyn143461d2016-10-05 12:34:37 -0700632 totalSize += szs;
Tom Cherry479b5032020-05-07 14:44:43 -0700633 size_t els = mElementsTotal[id];
Mark Salyzyn143461d2016-10-05 12:34:37 -0700634 totalEls += els;
Mark Salyzyn65059532017-03-10 14:31:54 -0800635 output +=
636 android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700637 spaces += spaces_total + oldLength - output.length();
Mark Salyzynd774bce2014-02-06 14:48:50 -0800638 }
Mark Salyzyn143461d2016-10-05 12:34:37 -0700639 if (spaces < 0) spaces = 0;
Mark Salyzyn65059532017-03-10 14:31:54 -0800640 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
641 totalEls);
Mark Salyzynd774bce2014-02-06 14:48:50 -0800642
Mark Salyzyn143461d2016-10-05 12:34:37 -0700643 static const char NowStr[] = "\nNow";
644 spaces = 10 - strlen(NowStr);
645 output += NowStr;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800646
Mark Salyzyn143461d2016-10-05 12:34:37 -0700647 totalSize = 0;
648 totalEls = 0;
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700649 log_id_for_each(id) {
Mark Salyzyn143461d2016-10-05 12:34:37 -0700650 if (!(logMask & (1 << id))) continue;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800651
Tom Cherry479b5032020-05-07 14:44:43 -0700652 size_t els = mElements[id];
Devin Moore4af818e2023-06-06 17:23:19 +0000653 oldLength = output.length();
654 if (spaces < 0) spaces = 0;
655 size_t szs = mSizes[id];
656 totalSize += szs;
657 totalEls += els;
658 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
659 spaces -= output.length() - oldLength;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800660 spaces += spaces_total;
661 }
Mark Salyzyn143461d2016-10-05 12:34:37 -0700662 if (spaces < 0) spaces = 0;
Mark Salyzyn65059532017-03-10 14:31:54 -0800663 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
664 totalEls);
Mark Salyzyn143461d2016-10-05 12:34:37 -0700665
Mark Salyzynda924cb2017-04-14 09:46:57 -0700666 static const char SpanStr[] = "\nLogspan";
667 spaces = 10 - strlen(SpanStr);
668 output += SpanStr;
669
670 // Total reports the greater of the individual maximum time span, or the
671 // validated minimum start and maximum end time span if it makes sense.
672 uint64_t minTime = UINT64_MAX;
673 uint64_t maxTime = 0;
674 uint64_t maxSpan = 0;
675 totalSize = 0;
676
677 log_id_for_each(id) {
678 if (!(logMask & (1 << id))) continue;
679
680 // validity checking
681 uint64_t oldest = mOldest[id].msec();
682 uint64_t newest = mNewest[id].msec();
683 if (newest <= oldest) {
684 spaces += spaces_total;
685 continue;
686 }
687
688 uint64_t span = newest - oldest;
689 if (span > (monthSec * MS_PER_SEC)) {
690 spaces += spaces_total;
691 continue;
692 }
693
694 // total span
695 if (minTime > oldest) minTime = oldest;
696 if (maxTime < newest) maxTime = newest;
697 if (span > maxSpan) maxSpan = span;
698 totalSize += span;
699
Mark Salyzynda924cb2017-04-14 09:46:57 -0700700 oldLength = output.length();
Elliott Hughes225e5c62022-09-16 23:01:59 +0000701 output += android::base::StringPrintf("%*s%s", spaces, "", formatMsec(span).c_str());
Mark Salyzynda924cb2017-04-14 09:46:57 -0700702 spaces -= output.length() - oldLength;
703 spaces += spaces_total;
704 }
705 if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
706 (maxTime > maxSpan)) {
707 maxSpan = maxTime;
708 }
709 if (spaces < 0) spaces = 0;
710 output += android::base::StringPrintf("%*s%s", spaces, "",
711 formatMsec(maxSpan).c_str());
712
Mark Salyzyn143461d2016-10-05 12:34:37 -0700713 static const char OverheadStr[] = "\nOverhead";
714 spaces = 10 - strlen(OverheadStr);
715 output += OverheadStr;
716
717 totalSize = 0;
718 log_id_for_each(id) {
719 if (!(logMask & (1 << id))) continue;
720
Tom Cherry479b5032020-05-07 14:44:43 -0700721 size_t els = mElements[id];
Mark Salyzyn143461d2016-10-05 12:34:37 -0700722 if (els) {
723 oldLength = output.length();
724 if (spaces < 0) spaces = 0;
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700725 size_t szs = 0;
726 if (overhead_[id]) {
727 szs = *overhead_[id];
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700728 } else {
Elliott Hughes225e5c62022-09-16 23:01:59 +0000729 CHECK(track_total_size_);
730 szs = mSizes[id];
Tom Cherrya3d6aa62020-06-19 12:21:21 -0700731 }
Mark Salyzyn143461d2016-10-05 12:34:37 -0700732 totalSize += szs;
733 output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
734 spaces -= output.length() - oldLength;
735 }
736 spaces += spaces_total;
737 }
Mark Salyzyn17e72122016-10-06 09:55:21 -0700738 totalSize += sizeOf();
Mark Salyzyn143461d2016-10-05 12:34:37 -0700739 if (spaces < 0) spaces = 0;
740 output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
Mark Salyzynd774bce2014-02-06 14:48:50 -0800741
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700742 // Report on Chattiest
Mark Salyzyn692e3c32014-03-26 10:46:39 -0700743
Mark Salyzyn1761a842015-08-21 16:44:30 -0700744 std::string name;
745
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700746 // Chattiest by application (UID)
747 log_id_for_each(id) {
Mark Salyzyn143461d2016-10-05 12:34:37 -0700748 if (!(logMask & (1 << id))) continue;
Mark Salyzyn692e3c32014-03-26 10:46:39 -0700749
Mark Salyzyn65059532017-03-10 14:31:54 -0800750 name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:"
751 : "Logging for your UID in %s log buffer:";
Tom Cherry479b5032020-05-07 14:44:43 -0700752 output += FormatTable(uidTable[id], uid, pid, name, id);
Mark Salyzyn1435b472015-03-16 08:26:05 -0700753 }
Mark Salyzyn692e3c32014-03-26 10:46:39 -0700754
Mark Salyzyn1435b472015-03-16 08:26:05 -0700755 if (enable) {
Mark Salyzyn65059532017-03-10 14:31:54 -0800756 name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:"
757 : "Logging for this PID:";
Tom Cherry479b5032020-05-07 14:44:43 -0700758 output += FormatTable(pidTable, uid, pid, name);
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800759 name = "Chattiest TIDs";
Mark Salyzyn143461d2016-10-05 12:34:37 -0700760 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800761 name += ":";
Tom Cherry479b5032020-05-07 14:44:43 -0700762 output += FormatTable(tidTable, uid, pid, name);
Mark Salyzynaf5c67f2015-04-20 13:35:15 -0700763 }
764
Mark Salyzynf96ac902015-04-13 14:24:45 -0700765 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800766 name = "Chattiest events log buffer TAGs";
Mark Salyzyn143461d2016-10-05 12:34:37 -0700767 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800768 name += ":";
Tom Cherry479b5032020-05-07 14:44:43 -0700769 output += FormatTable(tagTable, uid, pid, name, LOG_ID_EVENTS);
Mark Salyzynf96ac902015-04-13 14:24:45 -0700770 }
771
Mark Salyzync9690862015-12-04 10:59:45 -0800772 if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800773 name = "Chattiest security log buffer TAGs";
Mark Salyzyn143461d2016-10-05 12:34:37 -0700774 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
Mark Salyzyn4a2fc1c2015-12-17 09:58:43 -0800775 name += ":";
Tom Cherry479b5032020-05-07 14:44:43 -0700776 output += FormatTable(securityTagTable, uid, pid, name, LOG_ID_SECURITY);
Mark Salyzync9690862015-12-04 10:59:45 -0800777 }
778
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700779 if (enable) {
780 name = "Chattiest TAGs";
781 if (pid) name += android::base::StringPrintf(" for PID %d", pid);
782 name += ":";
Tom Cherry479b5032020-05-07 14:44:43 -0700783 output += FormatTable(tagNameTable, uid, pid, name);
Mark Salyzyn9a8c5f52017-04-19 14:39:21 -0700784 }
785
Mark Salyzyn7c528d92015-08-20 10:01:44 -0700786 return output;
Mark Salyzynd774bce2014-02-06 14:48:50 -0800787}
Mark Salyzynf67c3792014-04-07 07:15:33 -0700788
Mark Salyzyn1435b472015-03-16 08:26:05 -0700789namespace android {
790
791uid_t pidToUid(pid_t pid) {
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700792 char buffer[512];
793 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
Tom Cherry17b77582020-06-17 11:40:55 -0700794 FILE* fp = fopen(buffer, "re");
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700795 if (fp) {
796 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzyncba1db12017-05-04 13:54:46 -0700797 int uid = AID_LOGD;
798 char space = 0;
799 if ((sscanf(buffer, "Uid: %d%c", &uid, &space) == 2) &&
800 isspace(space)) {
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700801 fclose(fp);
802 return uid;
Mark Salyzynf67c3792014-04-07 07:15:33 -0700803 }
804 }
Mark Salyzyn9cf5d402015-03-10 13:51:35 -0700805 fclose(fp);
Mark Salyzynf67c3792014-04-07 07:15:33 -0700806 }
Mark Salyzyn65059532017-03-10 14:31:54 -0800807 return AID_LOGD; // associate this with the logger
Mark Salyzynf67c3792014-04-07 07:15:33 -0700808}
Mark Salyzyn1435b472015-03-16 08:26:05 -0700809}
810
Tom Cherry479b5032020-05-07 14:44:43 -0700811uid_t LogStatistics::PidToUid(pid_t pid) {
812 auto lock = std::lock_guard{lock_};
Tom Cherryf1910142020-05-19 19:01:16 -0700813 return pidTable.Add(pid)->second.uid();
Mark Salyzyn1435b472015-03-16 08:26:05 -0700814}
815
816// caller must free character string
Tom Cherry479b5032020-05-07 14:44:43 -0700817const char* LogStatistics::PidToName(pid_t pid) const {
818 auto lock = std::lock_guard{lock_};
Mark Salyzyn1761a842015-08-21 16:44:30 -0700819 // An inconvenient truth ... getName() can alter the object
Mark Salyzyn65059532017-03-10 14:31:54 -0800820 pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
Tom Cherryf1910142020-05-19 19:01:16 -0700821 const char* name = writablePidTable.Add(pid)->second.name();
Mark Salyzyn14d39b32015-04-13 14:24:45 -0700822 if (!name) {
Yi Kong36feb152018-07-13 17:39:22 -0700823 return nullptr;
Mark Salyzyn1435b472015-03-16 08:26:05 -0700824 }
Mark Salyzyn14d39b32015-04-13 14:24:45 -0700825 return strdup(name);
Mark Salyzyn1435b472015-03-16 08:26:05 -0700826}