blob: 90c49c0ee5989d523e9fdb6ba36f4250f51db008 [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
23#include <log/logger.h>
24#include <private/android_filesystem_config.h>
25#include <utils/String8.h>
26
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
54 if (strcmp(buffer, "<pre-initialized>")) {
55 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
164 ssize_t index = -1;
165 while ((index = pidTable.next(index)) != -1) {
166 const PidEntry &entry = pidTable.entryAt(index);
167
168 if (entry.getUid() == uid) {
169 const char *n = entry.getName();
170
171 if (n) {
172 if (!name) {
173 name = strdup(n);
174 } else if (strcmp(name, n)) {
175 free(name);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700176 name = NULL;
177 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700178 }
179 }
180 }
181 }
182
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700183 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700184 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800185}
186
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700187static void format_line(android::String8 &output,
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700188 android::String8 &name, android::String8 &size, android::String8 &pruned) {
189 static const size_t pruned_len = 6;
190 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700191
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700192 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
193 ssize_t size_len = std::max(size.length() + 1,
194 total_len - name.length() - drop_len - 1);
195
196 if (pruned.length()) {
197 output.appendFormat("%s%*s%*s\n", name.string(),
198 (int)size_len, size.string(),
199 (int)drop_len, pruned.string());
200 } else {
201 output.appendFormat("%s%*s\n", name.string(),
202 (int)size_len, size.string());
203 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800204}
205
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700206void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700207 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800208
209 if (*buf) {
Greg Hackmann239605e2014-04-06 21:25:58 -0700210 free(*buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800211 *buf = NULL;
212 }
213
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700214 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800215
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700216 android::String8 output("size/num");
217 size_t oldLength;
218 short spaces = 1;
219
220 log_id_for_each(id) {
221 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700222 continue;
223 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700224 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700225 if (spaces < 0) {
226 spaces = 0;
227 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700228 output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id));
229 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800230 }
231
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700232 spaces = 4;
233 output.appendFormat("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800234
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700235 log_id_for_each(id) {
236 if (!(logMask & (1 << id))) {
237 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800238 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700239 oldLength = output.length();
240 if (spaces < 0) {
241 spaces = 0;
242 }
243 output.appendFormat("%*s%zu/%zu", spaces, "",
244 sizesTotal(id), elementsTotal(id));
245 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800246 }
247
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700248 spaces = 6;
249 output.appendFormat("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800250
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700251 log_id_for_each(id) {
252 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800253 continue;
254 }
255
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700256 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800257 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700258 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800259 if (spaces < 0) {
260 spaces = 0;
261 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700262 output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els);
263 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800264 }
265 spaces += spaces_total;
266 }
267
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700268 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700269
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700270 // Chattiest by application (UID)
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700271 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700272 log_id_for_each(id) {
273 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700274 continue;
275 }
276
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700277 bool headerPrinted = false;
278 std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
279 ssize_t index = -1;
280 while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700281 const UidEntry *entry = sorted[index];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700282 uid_t u = entry->getKey();
283 if ((uid != AID_ROOT) && (u != uid)) {
284 continue;
285 }
286
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700287 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700288 output.appendFormat("\n\n");
289 android::String8 name("");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700290 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700291 name.appendFormat(
292 "Chattiest UIDs in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700293 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700294 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700295 name.appendFormat(
296 "Logging for your UID in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700297 android_log_id_to_name(id));
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700298 }
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700299 android::String8 size("Size");
300 android::String8 pruned("Pruned");
Mark Salyzynae769232015-03-17 17:17:25 -0700301 if (!worstUidEnabledForLogid(id)) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700302 pruned.setTo("");
303 }
304 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700305
306 name.setTo("UID PACKAGE");
307 size.setTo("BYTES");
308 pruned.setTo("LINES");
309 if (!worstUidEnabledForLogid(id)) {
310 pruned.setTo("");
311 }
312 format_line(output, name, size, pruned);
313
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700314 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700315 }
316
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700317 android::String8 name("");
318 name.appendFormat("%u", u);
319 char *n = uidToName(u);
320 if (n) {
321 name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n);
322 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700323 }
324
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700325 android::String8 size("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700326 size.appendFormat("%zu", entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700327
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700328 android::String8 pruned("");
329 size_t dropped = entry->getDropped();
330 if (dropped) {
331 pruned.appendFormat("%zu", dropped);
332 }
333
334 format_line(output, 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 Salyzyn5720d2c2015-04-21 07:43:16 -0700351 output.appendFormat("\n\n");
352 android::String8 name("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700353 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700354 name.appendFormat("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700355 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700356 name.appendFormat("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700357 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700358 android::String8 size("Size");
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700359 android::String8 pruned("Pruned");
360 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700361
362 name.setTo(" PID/UID COMMAND LINE");
363 size.setTo("BYTES");
364 pruned.setTo("LINES");
365 format_line(output, name, size, pruned);
366
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700367 headerPrinted = true;
368 }
369
370 android::String8 name("");
371 name.appendFormat("%5u/%u", entry->getKey(), u);
372 const char *n = entry->getName();
373 if (n) {
374 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
375 } else {
376 char *un = uidToName(u);
377 if (un) {
378 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
379 free(un);
380 }
381 }
382
383 android::String8 size("");
384 size.appendFormat("%zu", entry->getSizes());
385
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700386 android::String8 pruned("");
387 size_t dropped = entry->getDropped();
388 if (dropped) {
389 pruned.appendFormat("%zu", dropped);
390 }
391
392 format_line(output, name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700393 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700394 }
395
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700396 if (enable) {
397 // Tid table
398 bool headerPrinted = false;
399 // sort() returns list of references, unique_ptr makes sure self-delete
400 std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
401 ssize_t index = -1;
402 while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
403 const TidEntry *entry = sorted[index];
404 uid_t u = entry->getUid();
405 if ((uid != AID_ROOT) && (u != uid)) {
406 continue;
407 }
408
409 if (!headerPrinted) { // Only print header if we have table to print
410 output.appendFormat("\n\n");
411 android::String8 name("Chattiest TIDs:");
412 android::String8 size("Size");
413 android::String8 pruned("Pruned");
414 format_line(output, name, size, pruned);
415
416 name.setTo(" TID/UID COMM");
417 size.setTo("BYTES");
418 pruned.setTo("LINES");
419 format_line(output, name, size, pruned);
420
421 headerPrinted = true;
422 }
423
424 android::String8 name("");
425 name.appendFormat("%5u/%u", entry->getKey(), u);
426 const char *n = entry->getName();
427 if (n) {
428 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
429 } else {
430 // if we do not have a PID name, lets punt to try UID name?
431 char *un = uidToName(u);
432 if (un) {
433 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
434 free(un);
435 }
436 // We tried, better to not have a name at all, we still
437 // have TID/UID by number to report in any case.
438 }
439
440 android::String8 size("");
441 size.appendFormat("%zu", entry->getSizes());
442
443 android::String8 pruned("");
444 size_t dropped = entry->getDropped();
445 if (dropped) {
446 pruned.appendFormat("%zu", dropped);
447 }
448
449 format_line(output, name, size, pruned);
450 }
451 }
452
Mark Salyzyn344bff42015-04-13 14:24:45 -0700453 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
454 // Tag table
455 bool headerPrinted = false;
456 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
457 ssize_t index = -1;
458 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
459 const TagEntry *entry = sorted[index];
460 uid_t u = entry->getUid();
461 if ((uid != AID_ROOT) && (u != uid)) {
462 continue;
463 }
464
465 android::String8 pruned("");
466
467 if (!headerPrinted) {
468 output.appendFormat("\n\n");
469 android::String8 name("Chattiest events log buffer TAGs:");
470 android::String8 size("Size");
471 format_line(output, name, size, pruned);
472
473 name.setTo(" TAG/UID TAGNAME");
474 size.setTo("BYTES");
475 format_line(output, name, size, pruned);
476
477 headerPrinted = true;
478 }
479
480 android::String8 name("");
481 if (u == (uid_t)-1) {
482 name.appendFormat("%7u", entry->getKey());
483 } else {
484 name.appendFormat("%7u/%u", entry->getKey(), u);
485 }
486 const char *n = entry->getName();
487 if (n) {
488 name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
489 }
490
491 android::String8 size("");
492 size.appendFormat("%zu", entry->getSizes());
493
494 format_line(output, name, size, pruned);
495 }
496 }
497
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700498 *buf = strdup(output.string());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800499}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700500
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700501namespace android {
502
503uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700504 char buffer[512];
505 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
506 FILE *fp = fopen(buffer, "r");
507 if (fp) {
508 while (fgets(buffer, sizeof(buffer), fp)) {
509 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700510 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700511 fclose(fp);
512 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700513 }
514 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700515 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700516 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700517 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700518}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700519
520}
521
522uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700523 return pidTable.entryAt(pidTable.add(pid)).getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700524}
525
526// caller must free character string
527char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700528 const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
529 if (!name) {
530 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700531 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700532 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700533}