| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 1 | /* | 
|  | 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 Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 17 | #include <fcntl.h> | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 18 | #include <pwd.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 19 | #include <stdio.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 20 | #include <string.h> | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 21 | #include <sys/types.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 22 | #include <unistd.h> | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 23 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 24 | #include <list> | 
|  | 25 |  | 
| Mark Salyzyn | aeaaf81 | 2016-09-30 13:30:33 -0700 | [diff] [blame] | 26 | #include <android/log.h> | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 27 |  | 
|  | 28 | #include "LogStatistics.h" | 
|  | 29 |  | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 30 | size_t LogStatistics::SizesTotal; | 
|  | 31 |  | 
| Mark Salyzyn | 7718778 | 2015-05-12 15:21:31 -0700 | [diff] [blame] | 32 | LogStatistics::LogStatistics() : enable(false) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 33 | log_id_for_each(id) { | 
|  | 34 | mSizes[id] = 0; | 
|  | 35 | mElements[id] = 0; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 36 | mDroppedElements[id] = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 37 | mSizesTotal[id] = 0; | 
|  | 38 | mElementsTotal[id] = 0; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 39 | } | 
|  | 40 | } | 
|  | 41 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 42 | namespace android { | 
|  | 43 |  | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 44 | size_t sizesTotal() { return LogStatistics::sizesTotal(); } | 
|  | 45 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 46 | // caller must own and free character string | 
| Mark Salyzyn | 81b3eab | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 47 | char *pidToName(pid_t pid) { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 48 | char *retval = NULL; | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 49 | if (pid == 0) { // special case from auditd/klogd for kernel | 
|  | 50 | retval = strdup("logd"); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 51 | } else { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 52 | char buffer[512]; | 
|  | 53 | snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); | 
|  | 54 | int fd = open(buffer, O_RDONLY); | 
|  | 55 | if (fd >= 0) { | 
|  | 56 | ssize_t ret = read(fd, buffer, sizeof(buffer)); | 
|  | 57 | if (ret > 0) { | 
|  | 58 | buffer[sizeof(buffer)-1] = '\0'; | 
|  | 59 | // frameworks intermediate state | 
| Mark Salyzyn | 0eeb06b | 2016-12-02 10:08:48 -0800 | [diff] [blame] | 60 | if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 61 | retval = strdup(buffer); | 
|  | 62 | } | 
|  | 63 | } | 
|  | 64 | close(fd); | 
|  | 65 | } | 
|  | 66 | } | 
|  | 67 | return retval; | 
|  | 68 | } | 
|  | 69 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 70 | } | 
|  | 71 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 72 | void LogStatistics::add(LogBufferElement *element) { | 
|  | 73 | log_id_t log_id = element->getLogId(); | 
|  | 74 | unsigned short size = element->getMsgLen(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 75 | mSizes[log_id] += size; | 
|  | 76 | ++mElements[log_id]; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 77 |  | 
| Mark Salyzyn | a2c0222 | 2016-12-13 10:31:29 -0800 | [diff] [blame] | 78 | if (element->getDropped()) { | 
|  | 79 | ++mDroppedElements[log_id]; | 
|  | 80 | } else { | 
|  | 81 | // When caller adding a chatty entry, they will have already | 
|  | 82 | // called add() and subtract() for each entry as they are | 
|  | 83 | // evaluated and trimmed, thus recording size and number of | 
|  | 84 | // elements, but we must recognize the manufactured dropped | 
|  | 85 | // entry as not contributing to the lifetime totals. | 
|  | 86 | mSizesTotal[log_id] += size; | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 87 | SizesTotal += size; | 
| Mark Salyzyn | a2c0222 | 2016-12-13 10:31:29 -0800 | [diff] [blame] | 88 | ++mElementsTotal[log_id]; | 
|  | 89 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 90 |  | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 91 | if (log_id == LOG_ID_KERNEL) { | 
|  | 92 | return; | 
|  | 93 | } | 
|  | 94 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 95 | uidTable[log_id].add(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 96 | if (element->getUid() == AID_SYSTEM) { | 
|  | 97 | pidSystemTable[log_id].add(element->getPid(), element); | 
|  | 98 | } | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 99 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 100 | if (!enable) { | 
|  | 101 | return; | 
|  | 102 | } | 
|  | 103 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 104 | pidTable.add(element->getPid(), element); | 
|  | 105 | tidTable.add(element->getTid(), element); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 106 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 107 | uint32_t tag = element->getTag(); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 108 | if (tag) { | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 109 | if (log_id == LOG_ID_SECURITY) { | 
|  | 110 | securityTagTable.add(tag, element); | 
|  | 111 | } else { | 
|  | 112 | tagTable.add(tag, element); | 
|  | 113 | } | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 114 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 115 | } | 
|  | 116 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 117 | void LogStatistics::subtract(LogBufferElement *element) { | 
|  | 118 | log_id_t log_id = element->getLogId(); | 
|  | 119 | unsigned short size = element->getMsgLen(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 120 | mSizes[log_id] -= size; | 
|  | 121 | --mElements[log_id]; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 122 | if (element->getDropped()) { | 
|  | 123 | --mDroppedElements[log_id]; | 
|  | 124 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 125 |  | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 126 | if (log_id == LOG_ID_KERNEL) { | 
|  | 127 | return; | 
|  | 128 | } | 
|  | 129 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 130 | uidTable[log_id].subtract(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 131 | if (element->getUid() == AID_SYSTEM) { | 
|  | 132 | pidSystemTable[log_id].subtract(element->getPid(), element); | 
|  | 133 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 134 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 135 | if (!enable) { | 
|  | 136 | return; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 137 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 138 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 139 | pidTable.subtract(element->getPid(), element); | 
|  | 140 | tidTable.subtract(element->getTid(), element); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 141 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 142 | uint32_t tag = element->getTag(); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 143 | if (tag) { | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 144 | if (log_id == LOG_ID_SECURITY) { | 
|  | 145 | securityTagTable.subtract(tag, element); | 
|  | 146 | } else { | 
|  | 147 | tagTable.subtract(tag, element); | 
|  | 148 | } | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 149 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 150 | } | 
|  | 151 |  | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 152 | // Atomically set an entry to drop | 
|  | 153 | // entry->setDropped(1) must follow this call, caller should do this explicitly. | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 154 | void LogStatistics::drop(LogBufferElement *element) { | 
|  | 155 | log_id_t log_id = element->getLogId(); | 
|  | 156 | unsigned short size = element->getMsgLen(); | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 157 | mSizes[log_id] -= size; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 158 | ++mDroppedElements[log_id]; | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 159 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 160 | uidTable[log_id].drop(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 161 | if (element->getUid() == AID_SYSTEM) { | 
|  | 162 | pidSystemTable[log_id].drop(element->getPid(), element); | 
|  | 163 | } | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 164 |  | 
|  | 165 | if (!enable) { | 
|  | 166 | return; | 
|  | 167 | } | 
|  | 168 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 169 | pidTable.drop(element->getPid(), element); | 
|  | 170 | tidTable.drop(element->getTid(), element); | 
| Mark Salyzyn | 6a06694 | 2016-07-14 15:34:30 -0700 | [diff] [blame] | 171 |  | 
|  | 172 | uint32_t tag = element->getTag(); | 
|  | 173 | if (tag) { | 
|  | 174 | if (log_id == LOG_ID_SECURITY) { | 
|  | 175 | securityTagTable.drop(tag, element); | 
|  | 176 | } else { | 
|  | 177 | tagTable.drop(tag, element); | 
|  | 178 | } | 
|  | 179 | } | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 180 | } | 
|  | 181 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 182 | // caller must own and free character string | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 183 | const char *LogStatistics::uidToName(uid_t uid) const { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 184 | // Local hard coded favourites | 
|  | 185 | if (uid == AID_LOGD) { | 
|  | 186 | return strdup("auditd"); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 187 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 188 |  | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 189 | // Android system | 
|  | 190 | if (uid < AID_APP) { | 
|  | 191 | // in bionic, thread safe as long as we copy the results | 
|  | 192 | struct passwd *pwd = getpwuid(uid); | 
|  | 193 | if (pwd) { | 
|  | 194 | return strdup(pwd->pw_name); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 195 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 196 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 197 |  | 
| Mark Salyzyn | 08739ba | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 198 | // Parse /data/system/packages.list | 
| Jeff Sharkey | dff4470 | 2016-12-13 11:55:19 -0700 | [diff] [blame] | 199 | uid_t userId = uid % AID_USER_OFFSET; | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 200 | const char *name = android::uidToName(userId); | 
| Mark Salyzyn | 023f51f | 2015-04-29 12:48:45 -0700 | [diff] [blame] | 201 | if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { | 
|  | 202 | name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); | 
|  | 203 | } | 
| Mark Salyzyn | 08739ba | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 204 | if (name) { | 
|  | 205 | return name; | 
|  | 206 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 207 |  | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 208 | // Android application | 
|  | 209 | if (uid >= AID_APP) { | 
|  | 210 | struct passwd *pwd = getpwuid(uid); | 
|  | 211 | if (pwd) { | 
|  | 212 | return strdup(pwd->pw_name); | 
|  | 213 | } | 
|  | 214 | } | 
|  | 215 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 216 | // report uid -> pid(s) -> pidToName if unique | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 217 | for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) { | 
| Mark Salyzyn | 511338d | 2015-05-19 09:12:30 -0700 | [diff] [blame] | 218 | const PidEntry &entry = it->second; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 219 |  | 
|  | 220 | if (entry.getUid() == uid) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 221 | const char *nameTmp = entry.getName(); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 222 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 223 | if (nameTmp) { | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 224 | if (!name) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 225 | name = strdup(nameTmp); | 
| Mark Salyzyn | 0eeb06b | 2016-12-02 10:08:48 -0800 | [diff] [blame] | 226 | } else if (fastcmp<strcmp>(name, nameTmp)) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 227 | free(const_cast<char *>(name)); | 
| Mark Salyzyn | 023f51f | 2015-04-29 12:48:45 -0700 | [diff] [blame] | 228 | name = NULL; | 
|  | 229 | break; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 230 | } | 
|  | 231 | } | 
|  | 232 | } | 
|  | 233 | } | 
|  | 234 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 235 | // No one | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 236 | return name; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 237 | } | 
|  | 238 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 239 | std::string UidEntry::formatHeader(const std::string &name, log_id_t id) const { | 
|  | 240 | bool isprune = worstUidEnabledForLogid(id); | 
|  | 241 | return formatLine(android::base::StringPrintf( | 
|  | 242 | name.c_str(), android_log_id_to_name(id)), | 
|  | 243 | std::string("Size"), | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 244 | std::string(isprune ? "+/-  Pruned" : "")) | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 245 | + formatLine(std::string("UID   PACKAGE"), | 
|  | 246 | std::string("BYTES"), | 
|  | 247 | std::string(isprune ? "NUM" : "")); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 248 | } | 
|  | 249 |  | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 250 | std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 251 | uid_t uid = getUid(); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 252 | std::string name = android::base::StringPrintf("%u", uid); | 
|  | 253 | const char *nameTmp = stat.uidToName(uid); | 
|  | 254 | if (nameTmp) { | 
|  | 255 | name += android::base::StringPrintf( | 
|  | 256 | "%*s%s", (int)std::max(6 - name.length(), (size_t)1), | 
|  | 257 | "", nameTmp); | 
|  | 258 | free(const_cast<char *>(nameTmp)); | 
|  | 259 | } | 
|  | 260 |  | 
|  | 261 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
|  | 262 |  | 
|  | 263 | std::string pruned = ""; | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 264 | if (worstUidEnabledForLogid(id)) { | 
|  | 265 | size_t totalDropped = 0; | 
|  | 266 | for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin(); | 
|  | 267 | it != stat.uidTable[id].end(); ++it) { | 
|  | 268 | totalDropped += it->second.getDropped(); | 
|  | 269 | } | 
|  | 270 | size_t sizes = stat.sizes(id); | 
|  | 271 | size_t totalSize = stat.sizesTotal(id); | 
|  | 272 | size_t totalElements = stat.elementsTotal(id); | 
|  | 273 | float totalVirtualSize = (float)sizes + (float)totalDropped * totalSize | 
|  | 274 | / totalElements; | 
|  | 275 | size_t entrySize = getSizes(); | 
|  | 276 | float virtualEntrySize = entrySize; | 
|  | 277 | int realPermille = virtualEntrySize * 1000.0 / sizes; | 
|  | 278 | size_t dropped = getDropped(); | 
|  | 279 | if (dropped) { | 
|  | 280 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 281 | virtualEntrySize += (float)dropped * totalSize / totalElements; | 
|  | 282 | } | 
|  | 283 | int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; | 
|  | 284 | int permille = (realPermille - virtualPermille) * 1000L | 
|  | 285 | / (virtualPermille ?: 1); | 
|  | 286 | if ((permille < -1) || (1 < permille)) { | 
|  | 287 | std::string change; | 
|  | 288 | const char *units = "%"; | 
|  | 289 | const char *prefix = (permille > 0) ? "+" : ""; | 
|  | 290 |  | 
|  | 291 | if (permille > 999) { | 
|  | 292 | permille = (permille + 1000) / 100; // Now tenths fold | 
|  | 293 | units = "X"; | 
|  | 294 | prefix = ""; | 
|  | 295 | } | 
|  | 296 | if ((-99 < permille) && (permille < 99)) { | 
|  | 297 | change = android::base::StringPrintf("%s%d.%u%s", | 
|  | 298 | prefix, | 
|  | 299 | permille / 10, | 
|  | 300 | ((permille < 0) ? (-permille % 10) : (permille % 10)), | 
|  | 301 | units); | 
|  | 302 | } else { | 
|  | 303 | change = android::base::StringPrintf("%s%d%s", | 
|  | 304 | prefix, | 
|  | 305 | (permille + 5) / 10, units); | 
|  | 306 | } | 
|  | 307 | ssize_t spaces = EntryBaseConstants::pruned_len | 
|  | 308 | - 2 - pruned.length() - change.length(); | 
|  | 309 | if ((spaces <= 0) && pruned.length()) { | 
|  | 310 | spaces = 1; | 
|  | 311 | } | 
| Mark Salyzyn | d966e22 | 2016-12-19 22:23:03 +0000 | [diff] [blame] | 312 | if (spaces > 0) { | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 313 | change += android::base::StringPrintf("%*s", (int)spaces, ""); | 
|  | 314 | } | 
|  | 315 | pruned = change + pruned; | 
|  | 316 | } | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 317 | } | 
|  | 318 |  | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 319 | std::string output = formatLine(name, size, pruned); | 
|  | 320 |  | 
|  | 321 | if (uid != AID_SYSTEM) { | 
|  | 322 | return output; | 
|  | 323 | } | 
|  | 324 |  | 
|  | 325 | static const size_t maximum_sorted_entries = 32; | 
|  | 326 | std::unique_ptr<const PidEntry *[]> sorted | 
|  | 327 | = stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); | 
|  | 328 |  | 
|  | 329 | if (!sorted.get()) { | 
|  | 330 | return output; | 
|  | 331 | } | 
|  | 332 | std::string byPid; | 
|  | 333 | size_t index; | 
|  | 334 | bool hasDropped = false; | 
|  | 335 | for (index = 0; index < maximum_sorted_entries; ++index) { | 
|  | 336 | const PidEntry *entry = sorted[index]; | 
|  | 337 | if (!entry) { | 
|  | 338 | break; | 
|  | 339 | } | 
|  | 340 | if (entry->getSizes() <= (getSizes() / 100)) { | 
|  | 341 | break; | 
|  | 342 | } | 
|  | 343 | if (entry->getDropped()) { | 
|  | 344 | hasDropped = true; | 
|  | 345 | } | 
|  | 346 | byPid += entry->format(stat, id); | 
|  | 347 | } | 
|  | 348 | if (index > 1) { // print this only if interesting | 
|  | 349 | std::string ditto("\" "); | 
|  | 350 | output += formatLine(std::string("  PID/UID   COMMAND LINE"), | 
|  | 351 | ditto, hasDropped ? ditto : std::string("")); | 
|  | 352 | output += byPid; | 
|  | 353 | } | 
|  | 354 |  | 
|  | 355 | return output; | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 356 | } | 
|  | 357 |  | 
|  | 358 | std::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { | 
|  | 359 | return formatLine(name, | 
|  | 360 | std::string("Size"), | 
|  | 361 | std::string("Pruned")) | 
|  | 362 | + formatLine(std::string("  PID/UID   COMMAND LINE"), | 
|  | 363 | std::string("BYTES"), | 
|  | 364 | std::string("NUM")); | 
|  | 365 | } | 
|  | 366 |  | 
|  | 367 | std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { | 
|  | 368 | uid_t uid = getUid(); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 369 | pid_t pid = getPid(); | 
|  | 370 | std::string name = android::base::StringPrintf("%5u/%u", pid, uid); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 371 | const char *nameTmp = getName(); | 
|  | 372 | if (nameTmp) { | 
|  | 373 | name += android::base::StringPrintf( | 
|  | 374 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 
|  | 375 | "", nameTmp); | 
|  | 376 | } else if ((nameTmp = stat.uidToName(uid))) { | 
|  | 377 | name += android::base::StringPrintf( | 
|  | 378 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 
|  | 379 | "", nameTmp); | 
|  | 380 | free(const_cast<char *>(nameTmp)); | 
|  | 381 | } | 
|  | 382 |  | 
|  | 383 | std::string size = android::base::StringPrintf("%zu", | 
|  | 384 | getSizes()); | 
|  | 385 |  | 
|  | 386 | std::string pruned = ""; | 
|  | 387 | size_t dropped = getDropped(); | 
|  | 388 | if (dropped) { | 
|  | 389 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 390 | } | 
|  | 391 |  | 
|  | 392 | return formatLine(name, size, pruned); | 
|  | 393 | } | 
|  | 394 |  | 
|  | 395 | std::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { | 
|  | 396 | return formatLine(name, | 
|  | 397 | std::string("Size"), | 
|  | 398 | std::string("Pruned")) | 
|  | 399 | + formatLine(std::string("  TID/UID   COMM"), | 
|  | 400 | std::string("BYTES"), | 
|  | 401 | std::string("NUM")); | 
|  | 402 | } | 
|  | 403 |  | 
|  | 404 | std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { | 
|  | 405 | uid_t uid = getUid(); | 
|  | 406 | std::string name = android::base::StringPrintf("%5u/%u", | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 407 | getTid(), uid); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 408 | const char *nameTmp = getName(); | 
|  | 409 | if (nameTmp) { | 
|  | 410 | name += android::base::StringPrintf( | 
|  | 411 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 
|  | 412 | "", nameTmp); | 
|  | 413 | } else if ((nameTmp = stat.uidToName(uid))) { | 
|  | 414 | // if we do not have a PID name, lets punt to try UID name? | 
|  | 415 | name += android::base::StringPrintf( | 
|  | 416 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 
|  | 417 | "", nameTmp); | 
|  | 418 | free(const_cast<char *>(nameTmp)); | 
|  | 419 | // We tried, better to not have a name at all, we still | 
|  | 420 | // have TID/UID by number to report in any case. | 
|  | 421 | } | 
|  | 422 |  | 
|  | 423 | std::string size = android::base::StringPrintf("%zu", | 
|  | 424 | getSizes()); | 
|  | 425 |  | 
|  | 426 | std::string pruned = ""; | 
|  | 427 | size_t dropped = getDropped(); | 
|  | 428 | if (dropped) { | 
|  | 429 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 430 | } | 
|  | 431 |  | 
|  | 432 | return formatLine(name, size, pruned); | 
|  | 433 | } | 
|  | 434 |  | 
|  | 435 | std::string TagEntry::formatHeader(const std::string &name, log_id_t id) const { | 
|  | 436 | bool isprune = worstUidEnabledForLogid(id); | 
|  | 437 | return formatLine(name, | 
|  | 438 | std::string("Size"), | 
|  | 439 | std::string(isprune ? "Prune" : "")) | 
|  | 440 | + formatLine(std::string("    TAG/UID   TAGNAME"), | 
|  | 441 | std::string("BYTES"), | 
|  | 442 | std::string(isprune ? "NUM" : "")); | 
|  | 443 | } | 
|  | 444 |  | 
|  | 445 | std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const { | 
|  | 446 | std::string name; | 
|  | 447 | uid_t uid = getUid(); | 
|  | 448 | if (uid == (uid_t)-1) { | 
|  | 449 | name = android::base::StringPrintf("%7u", | 
|  | 450 | getKey()); | 
|  | 451 | } else { | 
|  | 452 | name = android::base::StringPrintf("%7u/%u", | 
|  | 453 | getKey(), uid); | 
|  | 454 | } | 
| Mark Salyzyn | 61e9ce6 | 2016-09-12 14:51:54 -0700 | [diff] [blame] | 455 | const char *nameTmp = getName(); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 456 | if (nameTmp) { | 
|  | 457 | name += android::base::StringPrintf( | 
| Mark Salyzyn | 61e9ce6 | 2016-09-12 14:51:54 -0700 | [diff] [blame] | 458 | "%*s%s", (int)std::max(14 - name.length(), (size_t)1), | 
|  | 459 | "", nameTmp); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 460 | } | 
|  | 461 |  | 
|  | 462 | std::string size = android::base::StringPrintf("%zu", | 
|  | 463 | getSizes()); | 
|  | 464 |  | 
|  | 465 | std::string pruned = ""; | 
| Mark Salyzyn | 6a06694 | 2016-07-14 15:34:30 -0700 | [diff] [blame] | 466 | size_t dropped = getDropped(); | 
|  | 467 | if (dropped) { | 
|  | 468 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 469 | } | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 470 |  | 
|  | 471 | return formatLine(name, size, pruned); | 
|  | 472 | } | 
|  | 473 |  | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 474 | std::string LogStatistics::format(uid_t uid, pid_t pid, | 
|  | 475 | unsigned int logMask) const { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 476 | static const unsigned short spaces_total = 19; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 477 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 478 | // Report on total logging, current and for all time | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 479 |  | 
| Mark Salyzyn | decbcd9 | 2015-08-19 15:33:01 -0700 | [diff] [blame] | 480 | std::string output = "size/num"; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 481 | size_t oldLength; | 
|  | 482 | short spaces = 1; | 
|  | 483 |  | 
|  | 484 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 485 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 486 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 487 | if (spaces < 0) spaces = 0; | 
| Mark Salyzyn | decbcd9 | 2015-08-19 15:33:01 -0700 | [diff] [blame] | 488 | output += android::base::StringPrintf("%*s%s", spaces, "", | 
|  | 489 | android_log_id_to_name(id)); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 490 | spaces += spaces_total + oldLength - output.length(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 491 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 492 | if (spaces < 0) spaces = 0; | 
|  | 493 | output += android::base::StringPrintf("%*sTotal", spaces, ""); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 494 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 495 | static const char TotalStr[] = "\nTotal"; | 
|  | 496 | spaces = 10 - strlen(TotalStr); | 
|  | 497 | output += TotalStr; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 498 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 499 | size_t totalSize = 0; | 
|  | 500 | size_t totalEls = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 501 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 502 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 503 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 504 | if (spaces < 0) spaces = 0; | 
|  | 505 | size_t szs = sizesTotal(id); | 
|  | 506 | totalSize += szs; | 
|  | 507 | size_t els = elementsTotal(id); | 
|  | 508 | totalEls += els; | 
|  | 509 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 510 | spaces += spaces_total + oldLength - output.length(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 511 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 512 | if (spaces < 0) spaces = 0; | 
|  | 513 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 514 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 515 | static const char NowStr[] = "\nNow"; | 
|  | 516 | spaces = 10 - strlen(NowStr); | 
|  | 517 | output += NowStr; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 518 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 519 | totalSize = 0; | 
|  | 520 | totalEls = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 521 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 522 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 523 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 524 | size_t els = elements(id); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 525 | if (els) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 526 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 527 | if (spaces < 0) spaces = 0; | 
|  | 528 | size_t szs = sizes(id); | 
|  | 529 | totalSize += szs; | 
|  | 530 | totalEls += els; | 
|  | 531 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 532 | spaces -= output.length() - oldLength; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 533 | } | 
|  | 534 | spaces += spaces_total; | 
|  | 535 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 536 | if (spaces < 0) spaces = 0; | 
|  | 537 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); | 
|  | 538 |  | 
|  | 539 | static const char OverheadStr[] = "\nOverhead"; | 
|  | 540 | spaces = 10 - strlen(OverheadStr); | 
|  | 541 | output += OverheadStr; | 
|  | 542 |  | 
|  | 543 | totalSize = 0; | 
|  | 544 | log_id_for_each(id) { | 
|  | 545 | if (!(logMask & (1 << id))) continue; | 
|  | 546 |  | 
|  | 547 | size_t els = elements(id); | 
|  | 548 | if (els) { | 
|  | 549 | oldLength = output.length(); | 
|  | 550 | if (spaces < 0) spaces = 0; | 
|  | 551 | // estimate the std::list overhead. | 
|  | 552 | static const size_t overhead = | 
|  | 553 | ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & | 
|  | 554 | -sizeof(uint64_t)) + | 
|  | 555 | sizeof(std::list<LogBufferElement*>); | 
|  | 556 | size_t szs = sizes(id) + els * overhead; | 
|  | 557 | totalSize += szs; | 
|  | 558 | output += android::base::StringPrintf("%*s%zu", spaces, "", szs); | 
|  | 559 | spaces -= output.length() - oldLength; | 
|  | 560 | } | 
|  | 561 | spaces += spaces_total; | 
|  | 562 | } | 
| Mark Salyzyn | 6d981af | 2016-10-06 09:55:21 -0700 | [diff] [blame] | 563 | totalSize += sizeOf(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 564 | if (spaces < 0) spaces = 0; | 
|  | 565 | output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 566 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 567 | // Report on Chattiest | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 568 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 569 | std::string name; | 
|  | 570 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 571 | // Chattiest by application (UID) | 
|  | 572 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 573 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 574 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 575 | name = (uid == AID_ROOT) | 
|  | 576 | ? "Chattiest UIDs in %s log buffer:" | 
|  | 577 | : "Logging for your UID in %s log buffer:"; | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 578 | output += uidTable[id].format(*this, uid, pid, name, id); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 579 | } | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 580 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 581 | if (enable) { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 582 | name = ((uid == AID_ROOT) && !pid) | 
|  | 583 | ? "Chattiest PIDs:" | 
|  | 584 | : "Logging for this PID:"; | 
|  | 585 | output += pidTable.format(*this, uid, pid, name); | 
|  | 586 | name = "Chattiest TIDs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 587 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 588 | name += ":"; | 
|  | 589 | output += tidTable.format(*this, uid, pid, name); | 
| Mark Salyzyn | 17ed679 | 2015-04-20 13:35:15 -0700 | [diff] [blame] | 590 | } | 
|  | 591 |  | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 592 | if (enable && (logMask & (1 << LOG_ID_EVENTS))) { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 593 | name = "Chattiest events log buffer TAGs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 594 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 595 | name += ":"; | 
|  | 596 | output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 597 | } | 
|  | 598 |  | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 599 | if (enable && (logMask & (1 << LOG_ID_SECURITY))) { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 600 | name = "Chattiest security log buffer TAGs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 601 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 602 | name += ":"; | 
|  | 603 | output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 604 | } | 
|  | 605 |  | 
| Mark Salyzyn | 73160ac | 2015-08-20 10:01:44 -0700 | [diff] [blame] | 606 | return output; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 607 | } | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 608 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 609 | namespace android { | 
|  | 610 |  | 
|  | 611 | uid_t pidToUid(pid_t pid) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 612 | char buffer[512]; | 
|  | 613 | snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); | 
|  | 614 | FILE *fp = fopen(buffer, "r"); | 
|  | 615 | if (fp) { | 
|  | 616 | while (fgets(buffer, sizeof(buffer), fp)) { | 
|  | 617 | int uid; | 
| Mark Salyzyn | c32afdf | 2015-04-14 13:07:29 -0700 | [diff] [blame] | 618 | if (sscanf(buffer, "Uid: %d", &uid) == 1) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 619 | fclose(fp); | 
|  | 620 | return uid; | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 621 | } | 
|  | 622 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 623 | fclose(fp); | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 624 | } | 
| Mark Salyzyn | e3aeeee | 2015-03-17 07:56:32 -0700 | [diff] [blame] | 625 | return AID_LOGD; // associate this with the logger | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 626 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 627 |  | 
|  | 628 | } | 
|  | 629 |  | 
|  | 630 | uid_t LogStatistics::pidToUid(pid_t pid) { | 
| Mark Salyzyn | 511338d | 2015-05-19 09:12:30 -0700 | [diff] [blame] | 631 | return pidTable.add(pid)->second.getUid(); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 632 | } | 
|  | 633 |  | 
|  | 634 | // caller must free character string | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 635 | const char *LogStatistics::pidToName(pid_t pid) const { | 
|  | 636 | // An inconvenient truth ... getName() can alter the object | 
|  | 637 | pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable); | 
|  | 638 | const char *name = writablePidTable.add(pid)->second.getName(); | 
| Mark Salyzyn | 81b3eab | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 639 | if (!name) { | 
|  | 640 | return NULL; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 641 | } | 
| Mark Salyzyn | 81b3eab | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 642 | return strdup(name); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 643 | } |