blob: a9c30867bc90400a6fa3263371e007b20d20ca49 [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 Salyzyn97c1c2b2015-03-10 13:51:35 -070017#include <algorithm> // std::max
Mark Salyzyn9a038632014-04-07 07:05:40 -070018#include <fcntl.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070019#include <stdio.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070020#include <string.h>
21#include <unistd.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080022
Mark Salyzyndecbcd92015-08-19 15:33:01 -070023#include <base/stringprintf.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080024#include <log/logger.h>
25#include <private/android_filesystem_config.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080026
27#include "LogStatistics.h"
28
Mark Salyzyn77187782015-05-12 15:21:31 -070029LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070030 log_id_for_each(id) {
31 mSizes[id] = 0;
32 mElements[id] = 0;
33 mSizesTotal[id] = 0;
34 mElementsTotal[id] = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -080035 }
36}
37
Mark Salyzyn720f6d12015-03-16 08:26:05 -070038namespace android {
39
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070040// caller must own and free character string
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070041char *pidToName(pid_t pid) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070042 char *retval = NULL;
Mark Salyzynae4d9282014-10-15 08:49:39 -070043 if (pid == 0) { // special case from auditd/klogd for kernel
44 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070045 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070046 char buffer[512];
47 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
48 int fd = open(buffer, O_RDONLY);
49 if (fd >= 0) {
50 ssize_t ret = read(fd, buffer, sizeof(buffer));
51 if (ret > 0) {
52 buffer[sizeof(buffer)-1] = '\0';
53 // frameworks intermediate state
Mark Salyzynddda2122015-10-02 09:22:52 -070054 if (fast<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070055 retval = strdup(buffer);
56 }
57 }
58 close(fd);
59 }
60 }
61 return retval;
62}
63
Mark Salyzyn720f6d12015-03-16 08:26:05 -070064}
65
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070066void LogStatistics::add(LogBufferElement *e) {
67 log_id_t log_id = e->getLogId();
68 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080069 mSizes[log_id] += size;
70 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070071
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070072 mSizesTotal[log_id] += size;
73 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070074
Mark Salyzynae4d9282014-10-15 08:49:39 -070075 if (log_id == LOG_ID_KERNEL) {
76 return;
77 }
78
79 uidTable[log_id].add(e->getUid(), e);
80
Mark Salyzyn720f6d12015-03-16 08:26:05 -070081 if (!enable) {
82 return;
83 }
84
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070085 pidTable.add(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -070086 tidTable.add(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -070087
88 uint32_t tag = e->getTag();
89 if (tag) {
90 tagTable.add(tag, e);
91 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080092}
93
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070094void LogStatistics::subtract(LogBufferElement *e) {
95 log_id_t log_id = e->getLogId();
96 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080097 mSizes[log_id] -= size;
98 --mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070099
Mark Salyzynae4d9282014-10-15 08:49:39 -0700100 if (log_id == LOG_ID_KERNEL) {
101 return;
102 }
103
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700104 uidTable[log_id].subtract(e->getUid(), e);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800105
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700106 if (!enable) {
107 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800108 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700109
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700110 pidTable.subtract(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700111 tidTable.subtract(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700112
113 uint32_t tag = e->getTag();
114 if (tag) {
115 tagTable.subtract(tag, e);
116 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800117}
118
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700119// Atomically set an entry to drop
120// entry->setDropped(1) must follow this call, caller should do this explicitly.
121void LogStatistics::drop(LogBufferElement *e) {
122 log_id_t log_id = e->getLogId();
123 unsigned short size = e->getMsgLen();
124 mSizes[log_id] -= size;
125
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700126 uidTable[log_id].drop(e->getUid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700127
128 if (!enable) {
129 return;
130 }
131
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700132 pidTable.drop(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700133 tidTable.drop(e->getTid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700134}
135
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700136// caller must own and free character string
137char *LogStatistics::uidToName(uid_t uid) {
138 // Local hard coded favourites
139 if (uid == AID_LOGD) {
140 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800141 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700142
143 // Android hard coded
144 const struct android_id_info *info = android_ids;
145
146 for (size_t i = 0; i < android_id_count; ++i) {
147 if (info->aid == uid) {
148 return strdup(info->name);
149 }
150 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800151 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700152
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700153 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700154 uid_t userId = uid % AID_USER;
155 char *name = android::uidToName(userId);
156 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
157 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
158 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700159 if (name) {
160 return name;
161 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700162
163 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn511338d2015-05-19 09:12:30 -0700164 for(pidTable_t::iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
165 const PidEntry &entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700166
167 if (entry.getUid() == uid) {
168 const char *n = entry.getName();
169
170 if (n) {
171 if (!name) {
172 name = strdup(n);
Mark Salyzynddda2122015-10-02 09:22:52 -0700173 } else if (fast<strcmp>(name, n)) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700174 free(name);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700175 name = NULL;
176 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700177 }
178 }
179 }
180 }
181
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700182 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700183 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800184}
185
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700186static std::string format_line(
187 const std::string &name,
188 const std::string &size,
189 const std::string &pruned) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700190 static const size_t pruned_len = 6;
191 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700192
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700193 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
194 ssize_t size_len = std::max(size.length() + 1,
195 total_len - name.length() - drop_len - 1);
196
197 if (pruned.length()) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700198 return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
199 (int)size_len, size.c_str(),
200 (int)drop_len, pruned.c_str());
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700201 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700202 return android::base::StringPrintf("%s%*s\n", name.c_str(),
203 (int)size_len, size.c_str());
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700204 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800205}
206
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700207std::string LogStatistics::format(uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700208 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800209
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700210 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800211
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700212 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700213 size_t oldLength;
214 short spaces = 1;
215
216 log_id_for_each(id) {
217 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700218 continue;
219 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700220 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700221 if (spaces < 0) {
222 spaces = 0;
223 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700224 output += android::base::StringPrintf("%*s%s", spaces, "",
225 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700226 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800227 }
228
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700229 spaces = 4;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700230 output += android::base::StringPrintf("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800231
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700232 log_id_for_each(id) {
233 if (!(logMask & (1 << id))) {
234 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800235 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700236 oldLength = output.length();
237 if (spaces < 0) {
238 spaces = 0;
239 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700240 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
241 sizesTotal(id),
242 elementsTotal(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700243 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800244 }
245
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700246 spaces = 6;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700247 output += android::base::StringPrintf("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800248
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700249 log_id_for_each(id) {
250 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800251 continue;
252 }
253
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700254 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800255 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700256 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800257 if (spaces < 0) {
258 spaces = 0;
259 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700260 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
261 sizes(id), els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700262 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800263 }
264 spaces += spaces_total;
265 }
266
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700267 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700268
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700269 // Chattiest by application (UID)
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700270 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700271 log_id_for_each(id) {
272 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700273 continue;
274 }
275
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700276 bool headerPrinted = false;
277 std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
278 ssize_t index = -1;
279 while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700280 const UidEntry *entry = sorted[index];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700281 uid_t u = entry->getKey();
282 if ((uid != AID_ROOT) && (u != uid)) {
283 continue;
284 }
285
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700286 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700287 output += android::base::StringPrintf("\n\n");
288 std::string name;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700289 if (uid == AID_ROOT) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700290 name = android::base::StringPrintf(
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700291 "Chattiest UIDs in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700292 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700293 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700294 name = android::base::StringPrintf(
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700295 "Logging for your UID in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700296 android_log_id_to_name(id));
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700297 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700298 std::string size = "Size";
299 std::string pruned = "Pruned";
Mark Salyzynae769232015-03-17 17:17:25 -0700300 if (!worstUidEnabledForLogid(id)) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700301 pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700302 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700303 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700304
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700305 name = "UID PACKAGE";
306 size = "BYTES";
307 pruned = "LINES";
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700308 if (!worstUidEnabledForLogid(id)) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700309 pruned = "";
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700310 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700311 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700312
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700313 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700314 }
315
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700316 std::string name = android::base::StringPrintf("%u", u);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700317 char *n = uidToName(u);
318 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700319 name += android::base::StringPrintf(
320 "%*s%s", (int)std::max(6 - name.length(), (size_t)1),
321 "", n);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700322 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700323 }
324
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700325 std::string size = android::base::StringPrintf("%zu",
326 entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700327
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700328 std::string pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700329 size_t dropped = entry->getDropped();
330 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700331 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700332 }
333
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700334 output += format_line(name, size, pruned);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700335 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700336 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700337
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700338 if (enable) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700339 // Pid table
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700340 bool headerPrinted = false;
341 std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
342 ssize_t index = -1;
343 while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
344 const PidEntry *entry = sorted[index];
345 uid_t u = entry->getUid();
346 if ((uid != AID_ROOT) && (u != uid)) {
347 continue;
348 }
349
350 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700351 output += android::base::StringPrintf("\n\n");
352 std::string name;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700353 if (uid == AID_ROOT) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700354 name = android::base::StringPrintf("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700355 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700356 name = android::base::StringPrintf("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700357 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700358 std::string size = "Size";
359 std::string pruned = "Pruned";
360 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700361
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700362 name = " PID/UID COMMAND LINE";
363 size = "BYTES";
364 pruned = "LINES";
365 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700366
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700367 headerPrinted = true;
368 }
369
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700370 std::string name = android::base::StringPrintf("%5u/%u",
371 entry->getKey(), u);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700372 const char *n = entry->getName();
373 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700374 name += android::base::StringPrintf(
375 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
376 "", n);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700377 } else {
378 char *un = uidToName(u);
379 if (un) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700380 name += android::base::StringPrintf(
381 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
382 "", un);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700383 free(un);
384 }
385 }
386
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700387 std::string size = android::base::StringPrintf("%zu",
388 entry->getSizes());
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700389
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700390 std::string pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700391 size_t dropped = entry->getDropped();
392 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700393 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700394 }
395
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700396 output += format_line(name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700397 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700398 }
399
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700400 if (enable) {
401 // Tid table
402 bool headerPrinted = false;
403 // sort() returns list of references, unique_ptr makes sure self-delete
404 std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
405 ssize_t index = -1;
406 while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
407 const TidEntry *entry = sorted[index];
408 uid_t u = entry->getUid();
409 if ((uid != AID_ROOT) && (u != uid)) {
410 continue;
411 }
412
413 if (!headerPrinted) { // Only print header if we have table to print
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700414 output += android::base::StringPrintf("\n\n");
415 std::string name = "Chattiest TIDs:";
416 std::string size = "Size";
417 std::string pruned = "Pruned";
418 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700419
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700420 name = " TID/UID COMM";
421 size = "BYTES";
422 pruned = "LINES";
423 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700424
425 headerPrinted = true;
426 }
427
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700428 std::string name = android::base::StringPrintf("%5u/%u",
429 entry->getKey(), u);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700430 const char *n = entry->getName();
431 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700432 name += android::base::StringPrintf(
433 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
434 "", n);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700435 } else {
436 // if we do not have a PID name, lets punt to try UID name?
437 char *un = uidToName(u);
438 if (un) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700439 name += android::base::StringPrintf(
440 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
441 "", un);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700442 free(un);
443 }
444 // We tried, better to not have a name at all, we still
445 // have TID/UID by number to report in any case.
446 }
447
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700448 std::string size = android::base::StringPrintf("%zu",
449 entry->getSizes());
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700450
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700451 std::string pruned = "";
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700452 size_t dropped = entry->getDropped();
453 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700454 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700455 }
456
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700457 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700458 }
459 }
460
Mark Salyzyn344bff42015-04-13 14:24:45 -0700461 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
462 // Tag table
463 bool headerPrinted = false;
464 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
465 ssize_t index = -1;
466 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
467 const TagEntry *entry = sorted[index];
468 uid_t u = entry->getUid();
469 if ((uid != AID_ROOT) && (u != uid)) {
470 continue;
471 }
472
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700473 std::string pruned = "";
Mark Salyzyn344bff42015-04-13 14:24:45 -0700474
475 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700476 output += android::base::StringPrintf("\n\n");
477 std::string name = "Chattiest events log buffer TAGs:";
478 std::string size = "Size";
479 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700480
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700481 name = " TAG/UID TAGNAME";
482 size = "BYTES";
483 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700484
485 headerPrinted = true;
486 }
487
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700488 std::string name;
Mark Salyzyn344bff42015-04-13 14:24:45 -0700489 if (u == (uid_t)-1) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700490 name = android::base::StringPrintf("%7u",
491 entry->getKey());
Mark Salyzyn344bff42015-04-13 14:24:45 -0700492 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700493 name = android::base::StringPrintf("%7u/%u",
494 entry->getKey(), u);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700495 }
496 const char *n = entry->getName();
497 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700498 name += android::base::StringPrintf(
499 "%*s%s", (int)std::max(14 - name.length(), (size_t)1),
500 "", n);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700501 }
502
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700503 std::string size = android::base::StringPrintf("%zu",
504 entry->getSizes());
Mark Salyzyn344bff42015-04-13 14:24:45 -0700505
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700506 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700507 }
508 }
509
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700510 return output;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800511}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700512
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700513namespace android {
514
515uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700516 char buffer[512];
517 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
518 FILE *fp = fopen(buffer, "r");
519 if (fp) {
520 while (fgets(buffer, sizeof(buffer), fp)) {
521 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700522 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700523 fclose(fp);
524 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700525 }
526 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700527 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700528 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700529 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700530}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700531
532}
533
534uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700535 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700536}
537
538// caller must free character string
539char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700540 const char *name = pidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700541 if (!name) {
542 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700543 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700544 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700545}