blob: 48c2fe66e88c09907f076326deade2be521fb6c8 [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
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);
173 } else if (strcmp(name, n)) {
174 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 Salyzyn97c1c2b2015-03-10 13:51:35 -0700186static void format_line(android::String8 &output,
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700187 android::String8 &name, android::String8 &size, android::String8 &pruned) {
188 static const size_t pruned_len = 6;
189 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700190
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700191 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
192 ssize_t size_len = std::max(size.length() + 1,
193 total_len - name.length() - drop_len - 1);
194
195 if (pruned.length()) {
196 output.appendFormat("%s%*s%*s\n", name.string(),
197 (int)size_len, size.string(),
198 (int)drop_len, pruned.string());
199 } else {
200 output.appendFormat("%s%*s\n", name.string(),
201 (int)size_len, size.string());
202 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800203}
204
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700205void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700206 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800207
208 if (*buf) {
Greg Hackmann239605e2014-04-06 21:25:58 -0700209 free(*buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800210 *buf = NULL;
211 }
212
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700213 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800214
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700215 android::String8 output("size/num");
216 size_t oldLength;
217 short spaces = 1;
218
219 log_id_for_each(id) {
220 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700221 continue;
222 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700223 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700224 if (spaces < 0) {
225 spaces = 0;
226 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700227 output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id));
228 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800229 }
230
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700231 spaces = 4;
232 output.appendFormat("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800233
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700234 log_id_for_each(id) {
235 if (!(logMask & (1 << id))) {
236 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800237 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700238 oldLength = output.length();
239 if (spaces < 0) {
240 spaces = 0;
241 }
242 output.appendFormat("%*s%zu/%zu", spaces, "",
243 sizesTotal(id), elementsTotal(id));
244 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800245 }
246
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700247 spaces = 6;
248 output.appendFormat("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800249
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700250 log_id_for_each(id) {
251 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800252 continue;
253 }
254
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700255 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800256 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700257 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800258 if (spaces < 0) {
259 spaces = 0;
260 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700261 output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els);
262 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 Salyzyn5720d2c2015-04-21 07:43:16 -0700287 output.appendFormat("\n\n");
288 android::String8 name("");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700289 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700290 name.appendFormat(
291 "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 Salyzyn5720d2c2015-04-21 07:43:16 -0700294 name.appendFormat(
295 "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 Salyzynab0dcf62015-03-16 12:04:09 -0700298 android::String8 size("Size");
299 android::String8 pruned("Pruned");
Mark Salyzynae769232015-03-17 17:17:25 -0700300 if (!worstUidEnabledForLogid(id)) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700301 pruned.setTo("");
302 }
303 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700304
305 name.setTo("UID PACKAGE");
306 size.setTo("BYTES");
307 pruned.setTo("LINES");
308 if (!worstUidEnabledForLogid(id)) {
309 pruned.setTo("");
310 }
311 format_line(output, name, size, pruned);
312
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700313 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700314 }
315
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700316 android::String8 name("");
317 name.appendFormat("%u", u);
318 char *n = uidToName(u);
319 if (n) {
320 name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n);
321 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700322 }
323
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700324 android::String8 size("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700325 size.appendFormat("%zu", entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700326
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700327 android::String8 pruned("");
328 size_t dropped = entry->getDropped();
329 if (dropped) {
330 pruned.appendFormat("%zu", dropped);
331 }
332
333 format_line(output, name, size, pruned);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700334 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700335 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700336
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700337 if (enable) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700338 // Pid table
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700339 bool headerPrinted = false;
340 std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
341 ssize_t index = -1;
342 while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
343 const PidEntry *entry = sorted[index];
344 uid_t u = entry->getUid();
345 if ((uid != AID_ROOT) && (u != uid)) {
346 continue;
347 }
348
349 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700350 output.appendFormat("\n\n");
351 android::String8 name("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700352 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700353 name.appendFormat("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700354 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700355 name.appendFormat("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700356 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700357 android::String8 size("Size");
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700358 android::String8 pruned("Pruned");
359 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700360
361 name.setTo(" PID/UID COMMAND LINE");
362 size.setTo("BYTES");
363 pruned.setTo("LINES");
364 format_line(output, name, size, pruned);
365
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700366 headerPrinted = true;
367 }
368
369 android::String8 name("");
370 name.appendFormat("%5u/%u", entry->getKey(), u);
371 const char *n = entry->getName();
372 if (n) {
373 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
374 } else {
375 char *un = uidToName(u);
376 if (un) {
377 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
378 free(un);
379 }
380 }
381
382 android::String8 size("");
383 size.appendFormat("%zu", entry->getSizes());
384
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700385 android::String8 pruned("");
386 size_t dropped = entry->getDropped();
387 if (dropped) {
388 pruned.appendFormat("%zu", dropped);
389 }
390
391 format_line(output, name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700392 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700393 }
394
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700395 if (enable) {
396 // Tid table
397 bool headerPrinted = false;
398 // sort() returns list of references, unique_ptr makes sure self-delete
399 std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
400 ssize_t index = -1;
401 while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
402 const TidEntry *entry = sorted[index];
403 uid_t u = entry->getUid();
404 if ((uid != AID_ROOT) && (u != uid)) {
405 continue;
406 }
407
408 if (!headerPrinted) { // Only print header if we have table to print
409 output.appendFormat("\n\n");
410 android::String8 name("Chattiest TIDs:");
411 android::String8 size("Size");
412 android::String8 pruned("Pruned");
413 format_line(output, name, size, pruned);
414
415 name.setTo(" TID/UID COMM");
416 size.setTo("BYTES");
417 pruned.setTo("LINES");
418 format_line(output, name, size, pruned);
419
420 headerPrinted = true;
421 }
422
423 android::String8 name("");
424 name.appendFormat("%5u/%u", entry->getKey(), u);
425 const char *n = entry->getName();
426 if (n) {
427 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
428 } else {
429 // if we do not have a PID name, lets punt to try UID name?
430 char *un = uidToName(u);
431 if (un) {
432 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
433 free(un);
434 }
435 // We tried, better to not have a name at all, we still
436 // have TID/UID by number to report in any case.
437 }
438
439 android::String8 size("");
440 size.appendFormat("%zu", entry->getSizes());
441
442 android::String8 pruned("");
443 size_t dropped = entry->getDropped();
444 if (dropped) {
445 pruned.appendFormat("%zu", dropped);
446 }
447
448 format_line(output, name, size, pruned);
449 }
450 }
451
Mark Salyzyn344bff42015-04-13 14:24:45 -0700452 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
453 // Tag table
454 bool headerPrinted = false;
455 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
456 ssize_t index = -1;
457 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
458 const TagEntry *entry = sorted[index];
459 uid_t u = entry->getUid();
460 if ((uid != AID_ROOT) && (u != uid)) {
461 continue;
462 }
463
464 android::String8 pruned("");
465
466 if (!headerPrinted) {
467 output.appendFormat("\n\n");
468 android::String8 name("Chattiest events log buffer TAGs:");
469 android::String8 size("Size");
470 format_line(output, name, size, pruned);
471
472 name.setTo(" TAG/UID TAGNAME");
473 size.setTo("BYTES");
474 format_line(output, name, size, pruned);
475
476 headerPrinted = true;
477 }
478
479 android::String8 name("");
480 if (u == (uid_t)-1) {
481 name.appendFormat("%7u", entry->getKey());
482 } else {
483 name.appendFormat("%7u/%u", entry->getKey(), u);
484 }
485 const char *n = entry->getName();
486 if (n) {
487 name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
488 }
489
490 android::String8 size("");
491 size.appendFormat("%zu", entry->getSizes());
492
493 format_line(output, name, size, pruned);
494 }
495 }
496
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700497 *buf = strdup(output.string());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800498}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700499
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700500namespace android {
501
502uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700503 char buffer[512];
504 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
505 FILE *fp = fopen(buffer, "r");
506 if (fp) {
507 while (fgets(buffer, sizeof(buffer), fp)) {
508 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700509 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700510 fclose(fp);
511 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700512 }
513 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700514 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700515 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700516 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700517}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700518
519}
520
521uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700522 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700523}
524
525// caller must free character string
526char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700527 const char *name = pidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700528 if (!name) {
529 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700530 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700531 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700532}