blob: bf0e30b0980019c8b3b2961aad34e4c3fd259279 [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 Salyzyn9a038632014-04-07 07:05:40 -070017#include <fcntl.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070018#include <stdio.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070019#include <string.h>
20#include <unistd.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080021
22#include <log/logger.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080023
24#include "LogStatistics.h"
25
Mark Salyzyn77187782015-05-12 15:21:31 -070026LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070027 log_id_for_each(id) {
28 mSizes[id] = 0;
29 mElements[id] = 0;
Mark Salyzyn58b8be82015-09-30 07:40:09 -070030 mDroppedElements[id] = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070031 mSizesTotal[id] = 0;
32 mElementsTotal[id] = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -080033 }
34}
35
Mark Salyzyn720f6d12015-03-16 08:26:05 -070036namespace android {
37
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070038// caller must own and free character string
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070039char *pidToName(pid_t pid) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070040 char *retval = NULL;
Mark Salyzynae4d9282014-10-15 08:49:39 -070041 if (pid == 0) { // special case from auditd/klogd for kernel
42 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070043 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070044 char buffer[512];
45 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
46 int fd = open(buffer, O_RDONLY);
47 if (fd >= 0) {
48 ssize_t ret = read(fd, buffer, sizeof(buffer));
49 if (ret > 0) {
50 buffer[sizeof(buffer)-1] = '\0';
51 // frameworks intermediate state
Mark Salyzynddda2122015-10-02 09:22:52 -070052 if (fast<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070053 retval = strdup(buffer);
54 }
55 }
56 close(fd);
57 }
58 }
59 return retval;
60}
61
Mark Salyzyn720f6d12015-03-16 08:26:05 -070062}
63
Mark Salyzyn758058f2015-08-21 16:44:30 -070064void LogStatistics::add(LogBufferElement *element) {
65 log_id_t log_id = element->getLogId();
66 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080067 mSizes[log_id] += size;
68 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070069
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070070 mSizesTotal[log_id] += size;
71 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070072
Mark Salyzynae4d9282014-10-15 08:49:39 -070073 if (log_id == LOG_ID_KERNEL) {
74 return;
75 }
76
Mark Salyzyn758058f2015-08-21 16:44:30 -070077 uidTable[log_id].add(element->getUid(), element);
Mark Salyzynae4d9282014-10-15 08:49:39 -070078
Mark Salyzyn720f6d12015-03-16 08:26:05 -070079 if (!enable) {
80 return;
81 }
82
Mark Salyzyn758058f2015-08-21 16:44:30 -070083 pidTable.add(element->getPid(), element);
84 tidTable.add(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -070085
Mark Salyzyn758058f2015-08-21 16:44:30 -070086 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -070087 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -080088 if (log_id == LOG_ID_SECURITY) {
89 securityTagTable.add(tag, element);
90 } else {
91 tagTable.add(tag, element);
92 }
Mark Salyzyn344bff42015-04-13 14:24:45 -070093 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080094}
95
Mark Salyzyn758058f2015-08-21 16:44:30 -070096void LogStatistics::subtract(LogBufferElement *element) {
97 log_id_t log_id = element->getLogId();
98 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080099 mSizes[log_id] -= size;
100 --mElements[log_id];
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700101 if (element->getDropped()) {
102 --mDroppedElements[log_id];
103 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700104
Mark Salyzynae4d9282014-10-15 08:49:39 -0700105 if (log_id == LOG_ID_KERNEL) {
106 return;
107 }
108
Mark Salyzyn758058f2015-08-21 16:44:30 -0700109 uidTable[log_id].subtract(element->getUid(), element);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800110
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700111 if (!enable) {
112 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800113 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700114
Mark Salyzyn758058f2015-08-21 16:44:30 -0700115 pidTable.subtract(element->getPid(), element);
116 tidTable.subtract(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700117
Mark Salyzyn758058f2015-08-21 16:44:30 -0700118 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700119 if (tag) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800120 if (log_id == LOG_ID_SECURITY) {
121 securityTagTable.subtract(tag, element);
122 } else {
123 tagTable.subtract(tag, element);
124 }
Mark Salyzyn344bff42015-04-13 14:24:45 -0700125 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800126}
127
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700128// Atomically set an entry to drop
129// entry->setDropped(1) must follow this call, caller should do this explicitly.
Mark Salyzyn758058f2015-08-21 16:44:30 -0700130void LogStatistics::drop(LogBufferElement *element) {
131 log_id_t log_id = element->getLogId();
132 unsigned short size = element->getMsgLen();
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700133 mSizes[log_id] -= size;
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700134 ++mDroppedElements[log_id];
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700135
Mark Salyzyn758058f2015-08-21 16:44:30 -0700136 uidTable[log_id].drop(element->getUid(), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700137
138 if (!enable) {
139 return;
140 }
141
Mark Salyzyn758058f2015-08-21 16:44:30 -0700142 pidTable.drop(element->getPid(), element);
143 tidTable.drop(element->getTid(), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700144}
145
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700146// caller must own and free character string
Mark Salyzyn758058f2015-08-21 16:44:30 -0700147const char *LogStatistics::uidToName(uid_t uid) const {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700148 // Local hard coded favourites
149 if (uid == AID_LOGD) {
150 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800151 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700152
153 // Android hard coded
154 const struct android_id_info *info = android_ids;
155
156 for (size_t i = 0; i < android_id_count; ++i) {
157 if (info->aid == uid) {
158 return strdup(info->name);
159 }
160 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800161 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700162
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700163 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700164 uid_t userId = uid % AID_USER;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700165 const char *name = android::uidToName(userId);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700166 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
167 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
168 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700169 if (name) {
170 return name;
171 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700172
173 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn758058f2015-08-21 16:44:30 -0700174 for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700175 const PidEntry &entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700176
177 if (entry.getUid() == uid) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700178 const char *nameTmp = entry.getName();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700179
Mark Salyzyn758058f2015-08-21 16:44:30 -0700180 if (nameTmp) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700181 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700182 name = strdup(nameTmp);
183 } else if (fast<strcmp>(name, nameTmp)) {
184 free(const_cast<char *>(name));
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700185 name = NULL;
186 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700187 }
188 }
189 }
190 }
191
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700192 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700193 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800194}
195
Mark Salyzyn758058f2015-08-21 16:44:30 -0700196std::string UidEntry::formatHeader(const std::string &name, log_id_t id) const {
197 bool isprune = worstUidEnabledForLogid(id);
198 return formatLine(android::base::StringPrintf(
199 name.c_str(), android_log_id_to_name(id)),
200 std::string("Size"),
Mark Salyzync723df82015-08-24 11:08:00 -0700201 std::string(isprune ? "+/- Pruned" : ""))
Mark Salyzyn758058f2015-08-21 16:44:30 -0700202 + formatLine(std::string("UID PACKAGE"),
203 std::string("BYTES"),
204 std::string(isprune ? "NUM" : ""));
Mark Salyzyn34facab2014-02-06 14:48:50 -0800205}
206
Mark Salyzync723df82015-08-24 11:08:00 -0700207std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700208 uid_t uid = getKey();
209 std::string name = android::base::StringPrintf("%u", uid);
210 const char *nameTmp = stat.uidToName(uid);
211 if (nameTmp) {
212 name += android::base::StringPrintf(
213 "%*s%s", (int)std::max(6 - name.length(), (size_t)1),
214 "", nameTmp);
215 free(const_cast<char *>(nameTmp));
216 }
217
218 std::string size = android::base::StringPrintf("%zu", getSizes());
219
220 std::string pruned = "";
Mark Salyzync723df82015-08-24 11:08:00 -0700221 if (worstUidEnabledForLogid(id)) {
222 size_t totalDropped = 0;
223 for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin();
224 it != stat.uidTable[id].end(); ++it) {
225 totalDropped += it->second.getDropped();
226 }
227 size_t sizes = stat.sizes(id);
228 size_t totalSize = stat.sizesTotal(id);
229 size_t totalElements = stat.elementsTotal(id);
230 float totalVirtualSize = (float)sizes + (float)totalDropped * totalSize
231 / totalElements;
232 size_t entrySize = getSizes();
233 float virtualEntrySize = entrySize;
234 int realPermille = virtualEntrySize * 1000.0 / sizes;
235 size_t dropped = getDropped();
236 if (dropped) {
237 pruned = android::base::StringPrintf("%zu", dropped);
238 virtualEntrySize += (float)dropped * totalSize / totalElements;
239 }
240 int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
241 int permille = (realPermille - virtualPermille) * 1000L
242 / (virtualPermille ?: 1);
243 if ((permille < -1) || (1 < permille)) {
244 std::string change;
245 const char *units = "%";
246 const char *prefix = (permille > 0) ? "+" : "";
247
248 if (permille > 999) {
249 permille = (permille + 1000) / 100; // Now tenths fold
250 units = "X";
251 prefix = "";
252 }
253 if ((-99 < permille) && (permille < 99)) {
254 change = android::base::StringPrintf("%s%d.%u%s",
255 prefix,
256 permille / 10,
257 ((permille < 0) ? (-permille % 10) : (permille % 10)),
258 units);
259 } else {
260 change = android::base::StringPrintf("%s%d%s",
261 prefix,
262 (permille + 5) / 10, units);
263 }
264 ssize_t spaces = EntryBaseConstants::pruned_len
265 - 2 - pruned.length() - change.length();
266 if ((spaces <= 0) && pruned.length()) {
267 spaces = 1;
268 }
269 if (spaces > 0) {
270 change += android::base::StringPrintf("%*s", (int)spaces, "");
271 }
272 pruned = change + pruned;
273 }
Mark Salyzyn758058f2015-08-21 16:44:30 -0700274 }
275
276 return formatLine(name, size, pruned);
277}
278
279std::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
280 return formatLine(name,
281 std::string("Size"),
282 std::string("Pruned"))
283 + formatLine(std::string(" PID/UID COMMAND LINE"),
284 std::string("BYTES"),
285 std::string("NUM"));
286}
287
288std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
289 uid_t uid = getUid();
290 std::string name = android::base::StringPrintf("%5u/%u",
291 getKey(), uid);
292 const char *nameTmp = getName();
293 if (nameTmp) {
294 name += android::base::StringPrintf(
295 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
296 "", nameTmp);
297 } else if ((nameTmp = stat.uidToName(uid))) {
298 name += android::base::StringPrintf(
299 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
300 "", nameTmp);
301 free(const_cast<char *>(nameTmp));
302 }
303
304 std::string size = android::base::StringPrintf("%zu",
305 getSizes());
306
307 std::string pruned = "";
308 size_t dropped = getDropped();
309 if (dropped) {
310 pruned = android::base::StringPrintf("%zu", dropped);
311 }
312
313 return formatLine(name, size, pruned);
314}
315
316std::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
317 return formatLine(name,
318 std::string("Size"),
319 std::string("Pruned"))
320 + formatLine(std::string(" TID/UID COMM"),
321 std::string("BYTES"),
322 std::string("NUM"));
323}
324
325std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
326 uid_t uid = getUid();
327 std::string name = android::base::StringPrintf("%5u/%u",
328 getKey(), uid);
329 const char *nameTmp = getName();
330 if (nameTmp) {
331 name += android::base::StringPrintf(
332 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
333 "", nameTmp);
334 } else if ((nameTmp = stat.uidToName(uid))) {
335 // if we do not have a PID name, lets punt to try UID name?
336 name += android::base::StringPrintf(
337 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
338 "", nameTmp);
339 free(const_cast<char *>(nameTmp));
340 // We tried, better to not have a name at all, we still
341 // have TID/UID by number to report in any case.
342 }
343
344 std::string size = android::base::StringPrintf("%zu",
345 getSizes());
346
347 std::string pruned = "";
348 size_t dropped = getDropped();
349 if (dropped) {
350 pruned = android::base::StringPrintf("%zu", dropped);
351 }
352
353 return formatLine(name, size, pruned);
354}
355
356std::string TagEntry::formatHeader(const std::string &name, log_id_t id) const {
357 bool isprune = worstUidEnabledForLogid(id);
358 return formatLine(name,
359 std::string("Size"),
360 std::string(isprune ? "Prune" : ""))
361 + formatLine(std::string(" TAG/UID TAGNAME"),
362 std::string("BYTES"),
363 std::string(isprune ? "NUM" : ""));
364}
365
366std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const {
367 std::string name;
368 uid_t uid = getUid();
369 if (uid == (uid_t)-1) {
370 name = android::base::StringPrintf("%7u",
371 getKey());
372 } else {
373 name = android::base::StringPrintf("%7u/%u",
374 getKey(), uid);
375 }
376 const char *nameTmp = getName();
377 if (nameTmp) {
378 name += android::base::StringPrintf(
379 "%*s%s", (int)std::max(14 - name.length(), (size_t)1),
380 "", nameTmp);
381 }
382
383 std::string size = android::base::StringPrintf("%zu",
384 getSizes());
385
386 std::string pruned = "";
387
388 return formatLine(name, size, pruned);
389}
390
391std::string LogStatistics::format(uid_t uid, unsigned int logMask) const {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700392 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800393
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700394 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800395
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700396 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700397 size_t oldLength;
398 short spaces = 1;
399
400 log_id_for_each(id) {
401 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700402 continue;
403 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700404 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700405 if (spaces < 0) {
406 spaces = 0;
407 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700408 output += android::base::StringPrintf("%*s%s", spaces, "",
409 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700410 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800411 }
412
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700413 spaces = 4;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700414 output += "\nTotal";
Mark Salyzyn34facab2014-02-06 14:48:50 -0800415
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700416 log_id_for_each(id) {
417 if (!(logMask & (1 << id))) {
418 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800419 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700420 oldLength = output.length();
421 if (spaces < 0) {
422 spaces = 0;
423 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700424 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
425 sizesTotal(id),
426 elementsTotal(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700427 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800428 }
429
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700430 spaces = 6;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700431 output += "\nNow";
Mark Salyzyn34facab2014-02-06 14:48:50 -0800432
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700433 log_id_for_each(id) {
434 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800435 continue;
436 }
437
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700438 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800439 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700440 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800441 if (spaces < 0) {
442 spaces = 0;
443 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700444 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
445 sizes(id), els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700446 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800447 }
448 spaces += spaces_total;
449 }
450
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700451 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700452
Mark Salyzyn758058f2015-08-21 16:44:30 -0700453 std::string name;
454
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700455 // Chattiest by application (UID)
456 log_id_for_each(id) {
457 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700458 continue;
459 }
460
Mark Salyzyn758058f2015-08-21 16:44:30 -0700461 name = (uid == AID_ROOT)
462 ? "Chattiest UIDs in %s log buffer:"
463 : "Logging for your UID in %s log buffer:";
464 output += uidTable[id].format(*this, uid, name, id);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700465 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700466
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700467 if (enable) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700468 name = (uid == AID_ROOT) ? "Chattiest PIDs:" : "Logging for this PID:";
469 output += pidTable.format(*this, uid, name);
470 name = "Chattiest TIDs:";
471 output += tidTable.format(*this, uid, name);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700472 }
473
Mark Salyzyn344bff42015-04-13 14:24:45 -0700474 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700475 name = "Chattiest events log buffer TAGs:";
476 output += tagTable.format(*this, uid, name, LOG_ID_EVENTS);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700477 }
478
Mark Salyzyn083b0372015-12-04 10:59:45 -0800479 if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
480 name = "Chattiest security log buffer TAGs:";
481 output += securityTagTable.format(*this, uid, name, LOG_ID_SECURITY);
482 }
483
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700484 return output;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800485}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700486
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700487namespace android {
488
489uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700490 char buffer[512];
491 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
492 FILE *fp = fopen(buffer, "r");
493 if (fp) {
494 while (fgets(buffer, sizeof(buffer), fp)) {
495 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700496 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700497 fclose(fp);
498 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700499 }
500 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700501 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700502 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700503 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700504}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700505
506}
507
508uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700509 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700510}
511
512// caller must free character string
Mark Salyzyn758058f2015-08-21 16:44:30 -0700513const char *LogStatistics::pidToName(pid_t pid) const {
514 // An inconvenient truth ... getName() can alter the object
515 pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable);
516 const char *name = writablePidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700517 if (!name) {
518 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700519 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700520 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700521}