xref: /aosp_15_r20/system/logging/logd/PruneList.cpp (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #include "PruneList.h"
18*598139dcSAndroid Build Coastguard Worker 
19*598139dcSAndroid Build Coastguard Worker #include <ctype.h>
20*598139dcSAndroid Build Coastguard Worker 
21*598139dcSAndroid Build Coastguard Worker #include <android-base/logging.h>
22*598139dcSAndroid Build Coastguard Worker #include <android-base/properties.h>
23*598139dcSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
24*598139dcSAndroid Build Coastguard Worker #include <android-base/strings.h>
25*598139dcSAndroid Build Coastguard Worker 
Matches(LogBufferElement * element) const26*598139dcSAndroid Build Coastguard Worker bool Prune::Matches(LogBufferElement* element) const {
27*598139dcSAndroid Build Coastguard Worker     return (uid_ == UID_ALL || uid_ == element->uid()) &&
28*598139dcSAndroid Build Coastguard Worker            (pid_ == PID_ALL || pid_ == element->pid());
29*598139dcSAndroid Build Coastguard Worker }
30*598139dcSAndroid Build Coastguard Worker 
Format() const31*598139dcSAndroid Build Coastguard Worker std::string Prune::Format() const {
32*598139dcSAndroid Build Coastguard Worker     if (uid_ != UID_ALL) {
33*598139dcSAndroid Build Coastguard Worker         if (pid_ != PID_ALL) {
34*598139dcSAndroid Build Coastguard Worker             return android::base::StringPrintf("%u/%u", uid_, pid_);
35*598139dcSAndroid Build Coastguard Worker         }
36*598139dcSAndroid Build Coastguard Worker         return android::base::StringPrintf("%u", uid_);
37*598139dcSAndroid Build Coastguard Worker     }
38*598139dcSAndroid Build Coastguard Worker     if (pid_ != PID_ALL) {
39*598139dcSAndroid Build Coastguard Worker         return android::base::StringPrintf("/%u", pid_);
40*598139dcSAndroid Build Coastguard Worker     }
41*598139dcSAndroid Build Coastguard Worker     // NB: pid_ == PID_ALL can not happen if uid_ == UID_ALL
42*598139dcSAndroid Build Coastguard Worker     return std::string("/");
43*598139dcSAndroid Build Coastguard Worker }
44*598139dcSAndroid Build Coastguard Worker 
PruneList()45*598139dcSAndroid Build Coastguard Worker PruneList::PruneList() {
46*598139dcSAndroid Build Coastguard Worker     Init(nullptr);
47*598139dcSAndroid Build Coastguard Worker }
48*598139dcSAndroid Build Coastguard Worker 
Init(const char * str)49*598139dcSAndroid Build Coastguard Worker bool PruneList::Init(const char* str) {
50*598139dcSAndroid Build Coastguard Worker     high_priority_prune_.clear();
51*598139dcSAndroid Build Coastguard Worker     low_priority_prune_.clear();
52*598139dcSAndroid Build Coastguard Worker 
53*598139dcSAndroid Build Coastguard Worker     // default here means take ro.logd.filter, persist.logd.filter then internal default in order.
54*598139dcSAndroid Build Coastguard Worker     if (str && !strcmp(str, "default")) {
55*598139dcSAndroid Build Coastguard Worker         str = nullptr;
56*598139dcSAndroid Build Coastguard Worker     }
57*598139dcSAndroid Build Coastguard Worker     if (str && !strcmp(str, "disable")) {
58*598139dcSAndroid Build Coastguard Worker         str = "";
59*598139dcSAndroid Build Coastguard Worker     }
60*598139dcSAndroid Build Coastguard Worker 
61*598139dcSAndroid Build Coastguard Worker     std::string filter;
62*598139dcSAndroid Build Coastguard Worker 
63*598139dcSAndroid Build Coastguard Worker     if (str) {
64*598139dcSAndroid Build Coastguard Worker         filter = str;
65*598139dcSAndroid Build Coastguard Worker     } else {
66*598139dcSAndroid Build Coastguard Worker         filter = android::base::GetProperty("ro.logd.filter", "default");
67*598139dcSAndroid Build Coastguard Worker         auto persist_filter = android::base::GetProperty("persist.logd.filter", "default");
68*598139dcSAndroid Build Coastguard Worker         // default here means take ro.logd.filter
69*598139dcSAndroid Build Coastguard Worker         if (persist_filter != "default") {
70*598139dcSAndroid Build Coastguard Worker             filter = persist_filter;
71*598139dcSAndroid Build Coastguard Worker         }
72*598139dcSAndroid Build Coastguard Worker     }
73*598139dcSAndroid Build Coastguard Worker 
74*598139dcSAndroid Build Coastguard Worker     // default here means take internal default.
75*598139dcSAndroid Build Coastguard Worker     if (filter == "default") {
76*598139dcSAndroid Build Coastguard Worker         filter = "~! ~1000/!";
77*598139dcSAndroid Build Coastguard Worker     }
78*598139dcSAndroid Build Coastguard Worker     if (filter == "disable") {
79*598139dcSAndroid Build Coastguard Worker         filter = "";
80*598139dcSAndroid Build Coastguard Worker     }
81*598139dcSAndroid Build Coastguard Worker 
82*598139dcSAndroid Build Coastguard Worker     worst_uid_enabled_ = false;
83*598139dcSAndroid Build Coastguard Worker     worst_pid_of_system_enabled_ = false;
84*598139dcSAndroid Build Coastguard Worker 
85*598139dcSAndroid Build Coastguard Worker     for (str = filter.c_str(); *str; ++str) {
86*598139dcSAndroid Build Coastguard Worker         if (isspace(*str)) {
87*598139dcSAndroid Build Coastguard Worker             continue;
88*598139dcSAndroid Build Coastguard Worker         }
89*598139dcSAndroid Build Coastguard Worker 
90*598139dcSAndroid Build Coastguard Worker         std::list<Prune>* list;
91*598139dcSAndroid Build Coastguard Worker         if (*str == '~' || *str == '!') {  // ~ supported, ! undocumented
92*598139dcSAndroid Build Coastguard Worker             ++str;
93*598139dcSAndroid Build Coastguard Worker             // special case, prune the worst UID of those using at least 1/8th of the buffer.
94*598139dcSAndroid Build Coastguard Worker             if (*str == '!') {
95*598139dcSAndroid Build Coastguard Worker                 worst_uid_enabled_ = true;
96*598139dcSAndroid Build Coastguard Worker                 ++str;
97*598139dcSAndroid Build Coastguard Worker                 if (!*str) {
98*598139dcSAndroid Build Coastguard Worker                     break;
99*598139dcSAndroid Build Coastguard Worker                 }
100*598139dcSAndroid Build Coastguard Worker                 if (!isspace(*str)) {
101*598139dcSAndroid Build Coastguard Worker                     LOG(ERROR) << "Nothing expected after '~!', but found '" << str << "'";
102*598139dcSAndroid Build Coastguard Worker                     return false;
103*598139dcSAndroid Build Coastguard Worker                 }
104*598139dcSAndroid Build Coastguard Worker                 continue;
105*598139dcSAndroid Build Coastguard Worker             }
106*598139dcSAndroid Build Coastguard Worker             // special case, translated to worst PID of System at priority
107*598139dcSAndroid Build Coastguard Worker             static const char WORST_SYSTEM_PID[] = "1000/!";
108*598139dcSAndroid Build Coastguard Worker             if (!strncmp(str, WORST_SYSTEM_PID, sizeof(WORST_SYSTEM_PID) - 1)) {
109*598139dcSAndroid Build Coastguard Worker                 worst_pid_of_system_enabled_ = true;
110*598139dcSAndroid Build Coastguard Worker                 str += sizeof(WORST_SYSTEM_PID) - 1;
111*598139dcSAndroid Build Coastguard Worker                 if (!*str) {
112*598139dcSAndroid Build Coastguard Worker                     break;
113*598139dcSAndroid Build Coastguard Worker                 }
114*598139dcSAndroid Build Coastguard Worker                 if (!isspace(*str)) {
115*598139dcSAndroid Build Coastguard Worker                     LOG(ERROR) << "Nothing expected after '~1000/!', but found '" << str << "'";
116*598139dcSAndroid Build Coastguard Worker                     return false;
117*598139dcSAndroid Build Coastguard Worker                 }
118*598139dcSAndroid Build Coastguard Worker                 continue;
119*598139dcSAndroid Build Coastguard Worker             }
120*598139dcSAndroid Build Coastguard Worker             if (!*str) {
121*598139dcSAndroid Build Coastguard Worker                 LOG(ERROR) << "Expected UID or PID after '~', but found nothing";
122*598139dcSAndroid Build Coastguard Worker                 return false;
123*598139dcSAndroid Build Coastguard Worker             }
124*598139dcSAndroid Build Coastguard Worker             list = &high_priority_prune_;
125*598139dcSAndroid Build Coastguard Worker         } else {
126*598139dcSAndroid Build Coastguard Worker             list = &low_priority_prune_;
127*598139dcSAndroid Build Coastguard Worker         }
128*598139dcSAndroid Build Coastguard Worker 
129*598139dcSAndroid Build Coastguard Worker         uid_t uid = Prune::UID_ALL;
130*598139dcSAndroid Build Coastguard Worker         if (isdigit(*str)) {
131*598139dcSAndroid Build Coastguard Worker             uid = 0;
132*598139dcSAndroid Build Coastguard Worker             do {
133*598139dcSAndroid Build Coastguard Worker                 uid = uid * 10 + *str++ - '0';
134*598139dcSAndroid Build Coastguard Worker             } while (isdigit(*str));
135*598139dcSAndroid Build Coastguard Worker         }
136*598139dcSAndroid Build Coastguard Worker 
137*598139dcSAndroid Build Coastguard Worker         pid_t pid = Prune::PID_ALL;
138*598139dcSAndroid Build Coastguard Worker         if (*str == '/') {
139*598139dcSAndroid Build Coastguard Worker             ++str;
140*598139dcSAndroid Build Coastguard Worker             if (isdigit(*str)) {
141*598139dcSAndroid Build Coastguard Worker                 pid = 0;
142*598139dcSAndroid Build Coastguard Worker                 do {
143*598139dcSAndroid Build Coastguard Worker                     pid = pid * 10 + *str++ - '0';
144*598139dcSAndroid Build Coastguard Worker                 } while (isdigit(*str));
145*598139dcSAndroid Build Coastguard Worker             }
146*598139dcSAndroid Build Coastguard Worker         }
147*598139dcSAndroid Build Coastguard Worker 
148*598139dcSAndroid Build Coastguard Worker         if (uid == Prune::UID_ALL && pid == Prune::PID_ALL) {
149*598139dcSAndroid Build Coastguard Worker             LOG(ERROR) << "Expected UID/PID combination, but found none";
150*598139dcSAndroid Build Coastguard Worker             return false;
151*598139dcSAndroid Build Coastguard Worker         }
152*598139dcSAndroid Build Coastguard Worker 
153*598139dcSAndroid Build Coastguard Worker         if (*str && !isspace(*str)) {
154*598139dcSAndroid Build Coastguard Worker             LOG(ERROR) << "Nothing expected after UID/PID combination, but found '" << str << "'";
155*598139dcSAndroid Build Coastguard Worker             return false;
156*598139dcSAndroid Build Coastguard Worker         }
157*598139dcSAndroid Build Coastguard Worker 
158*598139dcSAndroid Build Coastguard Worker         list->emplace_back(uid, pid);
159*598139dcSAndroid Build Coastguard Worker         if (!*str) {
160*598139dcSAndroid Build Coastguard Worker             break;
161*598139dcSAndroid Build Coastguard Worker         }
162*598139dcSAndroid Build Coastguard Worker     }
163*598139dcSAndroid Build Coastguard Worker 
164*598139dcSAndroid Build Coastguard Worker     return true;
165*598139dcSAndroid Build Coastguard Worker }
166*598139dcSAndroid Build Coastguard Worker 
Format() const167*598139dcSAndroid Build Coastguard Worker std::string PruneList::Format() const {
168*598139dcSAndroid Build Coastguard Worker     std::vector<std::string> prune_rules;
169*598139dcSAndroid Build Coastguard Worker 
170*598139dcSAndroid Build Coastguard Worker     if (worst_uid_enabled_) {
171*598139dcSAndroid Build Coastguard Worker         prune_rules.emplace_back("~!");
172*598139dcSAndroid Build Coastguard Worker     }
173*598139dcSAndroid Build Coastguard Worker     if (worst_pid_of_system_enabled_) {
174*598139dcSAndroid Build Coastguard Worker         prune_rules.emplace_back("~1000/!");
175*598139dcSAndroid Build Coastguard Worker     }
176*598139dcSAndroid Build Coastguard Worker     for (const auto& rule : low_priority_prune_) {
177*598139dcSAndroid Build Coastguard Worker         prune_rules.emplace_back(rule.Format());
178*598139dcSAndroid Build Coastguard Worker     }
179*598139dcSAndroid Build Coastguard Worker     for (const auto& rule : high_priority_prune_) {
180*598139dcSAndroid Build Coastguard Worker         prune_rules.emplace_back("~" + rule.Format());
181*598139dcSAndroid Build Coastguard Worker     }
182*598139dcSAndroid Build Coastguard Worker     return android::base::Join(prune_rules, " ");
183*598139dcSAndroid Build Coastguard Worker }
184*598139dcSAndroid Build Coastguard Worker 
IsHighPriority(LogBufferElement * element) const185*598139dcSAndroid Build Coastguard Worker bool PruneList::IsHighPriority(LogBufferElement* element) const {
186*598139dcSAndroid Build Coastguard Worker     for (const auto& rule : high_priority_prune_) {
187*598139dcSAndroid Build Coastguard Worker         if (rule.Matches(element)) {
188*598139dcSAndroid Build Coastguard Worker             return true;
189*598139dcSAndroid Build Coastguard Worker         }
190*598139dcSAndroid Build Coastguard Worker     }
191*598139dcSAndroid Build Coastguard Worker     return false;
192*598139dcSAndroid Build Coastguard Worker }
193*598139dcSAndroid Build Coastguard Worker 
IsLowPriority(LogBufferElement * element) const194*598139dcSAndroid Build Coastguard Worker bool PruneList::IsLowPriority(LogBufferElement* element) const {
195*598139dcSAndroid Build Coastguard Worker     for (const auto& rule : low_priority_prune_) {
196*598139dcSAndroid Build Coastguard Worker         if (rule.Matches(element)) {
197*598139dcSAndroid Build Coastguard Worker             return true;
198*598139dcSAndroid Build Coastguard Worker         }
199*598139dcSAndroid Build Coastguard Worker     }
200*598139dcSAndroid Build Coastguard Worker     return false;
201*598139dcSAndroid Build Coastguard Worker }
202