blob: 578dee59d9282509cd9484e9dc48fef07d89bfad [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 <string>
24
25#include <base/stringprintf.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080026#include <log/logger.h>
27#include <private/android_filesystem_config.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080028
29#include "LogStatistics.h"
30
Mark Salyzyn77187782015-05-12 15:21:31 -070031LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070032 log_id_for_each(id) {
33 mSizes[id] = 0;
34 mElements[id] = 0;
35 mSizesTotal[id] = 0;
36 mElementsTotal[id] = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -080037 }
38}
39
Mark Salyzyn720f6d12015-03-16 08:26:05 -070040namespace android {
41
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070042// caller must own and free character string
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070043char *pidToName(pid_t pid) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070044 char *retval = NULL;
Mark Salyzynae4d9282014-10-15 08:49:39 -070045 if (pid == 0) { // special case from auditd/klogd for kernel
46 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070047 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070048 char buffer[512];
49 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
50 int fd = open(buffer, O_RDONLY);
51 if (fd >= 0) {
52 ssize_t ret = read(fd, buffer, sizeof(buffer));
53 if (ret > 0) {
54 buffer[sizeof(buffer)-1] = '\0';
55 // frameworks intermediate state
56 if (strcmp(buffer, "<pre-initialized>")) {
57 retval = strdup(buffer);
58 }
59 }
60 close(fd);
61 }
62 }
63 return retval;
64}
65
Mark Salyzyn720f6d12015-03-16 08:26:05 -070066}
67
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070068void LogStatistics::add(LogBufferElement *e) {
69 log_id_t log_id = e->getLogId();
70 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080071 mSizes[log_id] += size;
72 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070073
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070074 mSizesTotal[log_id] += size;
75 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070076
Mark Salyzynae4d9282014-10-15 08:49:39 -070077 if (log_id == LOG_ID_KERNEL) {
78 return;
79 }
80
81 uidTable[log_id].add(e->getUid(), e);
82
Mark Salyzyn720f6d12015-03-16 08:26:05 -070083 if (!enable) {
84 return;
85 }
86
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070087 pidTable.add(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -070088 tidTable.add(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -070089
90 uint32_t tag = e->getTag();
91 if (tag) {
92 tagTable.add(tag, e);
93 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080094}
95
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070096void LogStatistics::subtract(LogBufferElement *e) {
97 log_id_t log_id = e->getLogId();
98 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080099 mSizes[log_id] -= size;
100 --mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700101
Mark Salyzynae4d9282014-10-15 08:49:39 -0700102 if (log_id == LOG_ID_KERNEL) {
103 return;
104 }
105
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700106 uidTable[log_id].subtract(e->getUid(), e);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800107
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700108 if (!enable) {
109 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800110 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700111
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700112 pidTable.subtract(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700113 tidTable.subtract(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700114
115 uint32_t tag = e->getTag();
116 if (tag) {
117 tagTable.subtract(tag, e);
118 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800119}
120
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700121// Atomically set an entry to drop
122// entry->setDropped(1) must follow this call, caller should do this explicitly.
123void LogStatistics::drop(LogBufferElement *e) {
124 log_id_t log_id = e->getLogId();
125 unsigned short size = e->getMsgLen();
126 mSizes[log_id] -= size;
127
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700128 uidTable[log_id].drop(e->getUid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700129
130 if (!enable) {
131 return;
132 }
133
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700134 pidTable.drop(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700135 tidTable.drop(e->getTid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700136}
137
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700138// caller must own and free character string
139char *LogStatistics::uidToName(uid_t uid) {
140 // Local hard coded favourites
141 if (uid == AID_LOGD) {
142 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800143 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700144
145 // Android hard coded
146 const struct android_id_info *info = android_ids;
147
148 for (size_t i = 0; i < android_id_count; ++i) {
149 if (info->aid == uid) {
150 return strdup(info->name);
151 }
152 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800153 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700154
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700155 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700156 uid_t userId = uid % AID_USER;
157 char *name = android::uidToName(userId);
158 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
159 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
160 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700161 if (name) {
162 return name;
163 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700164
165 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn511338d2015-05-19 09:12:30 -0700166 for(pidTable_t::iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
167 const PidEntry &entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700168
169 if (entry.getUid() == uid) {
170 const char *n = entry.getName();
171
172 if (n) {
173 if (!name) {
174 name = strdup(n);
175 } else if (strcmp(name, n)) {
176 free(name);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700177 name = NULL;
178 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700179 }
180 }
181 }
182 }
183
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700184 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700185 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800186}
187
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700188static std::string format_line(
189 const std::string &name,
190 const std::string &size,
191 const std::string &pruned) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700192 static const size_t pruned_len = 6;
193 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700194
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700195 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
196 ssize_t size_len = std::max(size.length() + 1,
197 total_len - name.length() - drop_len - 1);
198
199 if (pruned.length()) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700200 return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
201 (int)size_len, size.c_str(),
202 (int)drop_len, pruned.c_str());
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700203 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700204 return android::base::StringPrintf("%s%*s\n", name.c_str(),
205 (int)size_len, size.c_str());
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700206 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800207}
208
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700209void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700210 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800211
212 if (*buf) {
Greg Hackmann239605e2014-04-06 21:25:58 -0700213 free(*buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800214 *buf = NULL;
215 }
216
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700217 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800218
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700219 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700220 size_t oldLength;
221 short spaces = 1;
222
223 log_id_for_each(id) {
224 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700225 continue;
226 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700227 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700228 if (spaces < 0) {
229 spaces = 0;
230 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700231 output += android::base::StringPrintf("%*s%s", spaces, "",
232 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700233 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800234 }
235
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700236 spaces = 4;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700237 output += android::base::StringPrintf("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800238
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700239 log_id_for_each(id) {
240 if (!(logMask & (1 << id))) {
241 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800242 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700243 oldLength = output.length();
244 if (spaces < 0) {
245 spaces = 0;
246 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700247 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
248 sizesTotal(id),
249 elementsTotal(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700250 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800251 }
252
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700253 spaces = 6;
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700254 output += android::base::StringPrintf("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800255
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700256 log_id_for_each(id) {
257 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800258 continue;
259 }
260
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700261 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800262 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700263 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800264 if (spaces < 0) {
265 spaces = 0;
266 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700267 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
268 sizes(id), els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700269 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800270 }
271 spaces += spaces_total;
272 }
273
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700274 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700275
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700276 // Chattiest by application (UID)
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700277 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700278 log_id_for_each(id) {
279 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700280 continue;
281 }
282
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700283 bool headerPrinted = false;
284 std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
285 ssize_t index = -1;
286 while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700287 const UidEntry *entry = sorted[index];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700288 uid_t u = entry->getKey();
289 if ((uid != AID_ROOT) && (u != uid)) {
290 continue;
291 }
292
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700293 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700294 output += android::base::StringPrintf("\n\n");
295 std::string name;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700296 if (uid == AID_ROOT) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700297 name = android::base::StringPrintf(
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700298 "Chattiest UIDs in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700299 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700300 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700301 name = android::base::StringPrintf(
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700302 "Logging for your UID in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700303 android_log_id_to_name(id));
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700304 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700305 std::string size = "Size";
306 std::string pruned = "Pruned";
Mark Salyzynae769232015-03-17 17:17:25 -0700307 if (!worstUidEnabledForLogid(id)) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700308 pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700309 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700310 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700311
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700312 name = "UID PACKAGE";
313 size = "BYTES";
314 pruned = "LINES";
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700315 if (!worstUidEnabledForLogid(id)) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700316 pruned = "";
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700317 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700318 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700319
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700320 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700321 }
322
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700323 std::string name = android::base::StringPrintf("%u", u);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700324 char *n = uidToName(u);
325 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700326 name += android::base::StringPrintf(
327 "%*s%s", (int)std::max(6 - name.length(), (size_t)1),
328 "", n);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700329 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700330 }
331
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700332 std::string size = android::base::StringPrintf("%zu",
333 entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700334
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700335 std::string pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700336 size_t dropped = entry->getDropped();
337 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700338 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700339 }
340
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700341 output += format_line(name, size, pruned);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700342 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700343 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700344
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700345 if (enable) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700346 // Pid table
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700347 bool headerPrinted = false;
348 std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
349 ssize_t index = -1;
350 while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
351 const PidEntry *entry = sorted[index];
352 uid_t u = entry->getUid();
353 if ((uid != AID_ROOT) && (u != uid)) {
354 continue;
355 }
356
357 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700358 output += android::base::StringPrintf("\n\n");
359 std::string name;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700360 if (uid == AID_ROOT) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700361 name = android::base::StringPrintf("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700362 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700363 name = android::base::StringPrintf("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700364 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700365 std::string size = "Size";
366 std::string pruned = "Pruned";
367 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700368
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700369 name = " PID/UID COMMAND LINE";
370 size = "BYTES";
371 pruned = "LINES";
372 output += format_line(name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700373
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700374 headerPrinted = true;
375 }
376
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700377 std::string name = android::base::StringPrintf("%5u/%u",
378 entry->getKey(), u);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700379 const char *n = entry->getName();
380 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700381 name += android::base::StringPrintf(
382 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
383 "", n);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700384 } else {
385 char *un = uidToName(u);
386 if (un) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700387 name += android::base::StringPrintf(
388 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
389 "", un);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700390 free(un);
391 }
392 }
393
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700394 std::string size = android::base::StringPrintf("%zu",
395 entry->getSizes());
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700396
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700397 std::string pruned = "";
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700398 size_t dropped = entry->getDropped();
399 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700400 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700401 }
402
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700403 output += format_line(name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700404 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700405 }
406
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700407 if (enable) {
408 // Tid table
409 bool headerPrinted = false;
410 // sort() returns list of references, unique_ptr makes sure self-delete
411 std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
412 ssize_t index = -1;
413 while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
414 const TidEntry *entry = sorted[index];
415 uid_t u = entry->getUid();
416 if ((uid != AID_ROOT) && (u != uid)) {
417 continue;
418 }
419
420 if (!headerPrinted) { // Only print header if we have table to print
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700421 output += android::base::StringPrintf("\n\n");
422 std::string name = "Chattiest TIDs:";
423 std::string size = "Size";
424 std::string pruned = "Pruned";
425 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700426
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700427 name = " TID/UID COMM";
428 size = "BYTES";
429 pruned = "LINES";
430 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700431
432 headerPrinted = true;
433 }
434
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700435 std::string name = android::base::StringPrintf("%5u/%u",
436 entry->getKey(), u);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700437 const char *n = entry->getName();
438 if (n) {
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 "", n);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700442 } else {
443 // if we do not have a PID name, lets punt to try UID name?
444 char *un = uidToName(u);
445 if (un) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700446 name += android::base::StringPrintf(
447 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
448 "", un);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700449 free(un);
450 }
451 // We tried, better to not have a name at all, we still
452 // have TID/UID by number to report in any case.
453 }
454
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700455 std::string size = android::base::StringPrintf("%zu",
456 entry->getSizes());
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700457
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700458 std::string pruned = "";
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700459 size_t dropped = entry->getDropped();
460 if (dropped) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700461 pruned = android::base::StringPrintf("%zu", dropped);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700462 }
463
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700464 output += format_line(name, size, pruned);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700465 }
466 }
467
Mark Salyzyn344bff42015-04-13 14:24:45 -0700468 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
469 // Tag table
470 bool headerPrinted = false;
471 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
472 ssize_t index = -1;
473 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
474 const TagEntry *entry = sorted[index];
475 uid_t u = entry->getUid();
476 if ((uid != AID_ROOT) && (u != uid)) {
477 continue;
478 }
479
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700480 std::string pruned = "";
Mark Salyzyn344bff42015-04-13 14:24:45 -0700481
482 if (!headerPrinted) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700483 output += android::base::StringPrintf("\n\n");
484 std::string name = "Chattiest events log buffer TAGs:";
485 std::string size = "Size";
486 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700487
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700488 name = " TAG/UID TAGNAME";
489 size = "BYTES";
490 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700491
492 headerPrinted = true;
493 }
494
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700495 std::string name;
Mark Salyzyn344bff42015-04-13 14:24:45 -0700496 if (u == (uid_t)-1) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700497 name = android::base::StringPrintf("%7u",
498 entry->getKey());
Mark Salyzyn344bff42015-04-13 14:24:45 -0700499 } else {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700500 name = android::base::StringPrintf("%7u/%u",
501 entry->getKey(), u);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700502 }
503 const char *n = entry->getName();
504 if (n) {
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700505 name += android::base::StringPrintf(
506 "%*s%s", (int)std::max(14 - name.length(), (size_t)1),
507 "", n);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700508 }
509
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700510 std::string size = android::base::StringPrintf("%zu",
511 entry->getSizes());
Mark Salyzyn344bff42015-04-13 14:24:45 -0700512
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700513 output += format_line(name, size, pruned);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700514 }
515 }
516
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700517 *buf = strdup(output.c_str());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800518}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700519
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700520namespace android {
521
522uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700523 char buffer[512];
524 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
525 FILE *fp = fopen(buffer, "r");
526 if (fp) {
527 while (fgets(buffer, sizeof(buffer), fp)) {
528 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700529 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700530 fclose(fp);
531 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700532 }
533 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700534 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700535 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700536 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700537}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700538
539}
540
541uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700542 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700543}
544
545// caller must free character string
546char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700547 const char *name = pidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700548 if (!name) {
549 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700550 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700551 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700552}