1 /* 2 * Copyright (C) 2017 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 17 #ifndef ATOM_MATCHING_TRACKER_H 18 #define ATOM_MATCHING_TRACKER_H 19 20 #include <utils/RefBase.h> 21 22 #include <set> 23 #include <unordered_map> 24 #include <vector> 25 26 #include "guardrail/StatsdStats.h" 27 #include "logd/LogEvent.h" 28 #include "matchers/matcher_util.h" 29 #include "src/statsd_config.pb.h" 30 31 namespace android { 32 namespace os { 33 namespace statsd { 34 35 struct MatcherInitResult { 36 optional<InvalidConfigReason> invalidConfigReason; 37 bool hasStringTransformation; 38 }; 39 40 class AtomMatchingTracker : public virtual RefBase { 41 public: AtomMatchingTracker(const int64_t id,const uint64_t protoHash)42 AtomMatchingTracker(const int64_t id, const uint64_t protoHash) 43 : mId(id), mInitialized(false), mProtoHash(protoHash){}; 44 ~AtomMatchingTracker()45 virtual ~AtomMatchingTracker(){}; 46 47 // Initialize this AtomMatchingTracker. 48 // matcherIndex: index of this AtomMatchingTracker in allAtomMatchingTrackers. 49 // allAtomMatchers: the list of the AtomMatcher proto config. This is needed because we don't 50 // store the proto object in memory. We only need it during initilization. 51 // allAtomMatchingTrackers: the list of the AtomMatchingTracker objects. It's a one-to-one 52 // mapping with allAtomMatchers. This is needed because the 53 // initialization is done recursively for 54 // CombinationAtomMatchingTrackers using DFS. 55 // stack: a bit map to record which matcher has been visited on the stack. This is for detecting 56 // circle dependency. 57 virtual MatcherInitResult init( 58 int matcherIndex, const std::vector<AtomMatcher>& allAtomMatchers, 59 const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, 60 const std::unordered_map<int64_t, int>& matcherMap, std::vector<uint8_t>& stack) = 0; 61 62 // Update appropriate state on config updates. Primarily, all indices need to be updated. 63 // This matcher and all of its children are guaranteed to be preserved across the update. 64 // matcher: the AtomMatcher proto from the config. 65 // atomMatchingTrackerMap: map from matcher id to index in mAllAtomMatchingTrackers 66 virtual optional<InvalidConfigReason> onConfigUpdated( 67 const AtomMatcher& matcher, 68 const std::unordered_map<int64_t, int>& atomMatchingTrackerMap) = 0; 69 70 // Called when a log event comes. 71 // event: the log event. 72 // matcherIndex: index of this AtomMatchingTracker in allAtomMatchingTrackers. 73 // allAtomMatchingTrackers: the list of all AtomMatchingTrackers. This is needed because the log 74 // processing is done recursively. 75 // matcherResults: The cached results for all matchers for this event. Parent matchers can 76 // directly access the children's matching results if they have been evaluated. 77 // Otherwise, call children matchers' onLogEvent. 78 // matcherTransformations: the cached transformations for all matchers for this event. 79 virtual void onLogEvent(const LogEvent& event, int matcherIndex, 80 const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, 81 std::vector<MatchingState>& matcherResults, 82 std::vector<std::shared_ptr<LogEvent>>& matcherTransformations) = 0; 83 84 // Get the tagIds that this matcher cares about. The combined collection is stored 85 // in MetricMananger, so that we can pass any LogEvents that are not interest of us. It uses 86 // some memory but hopefully it can save us much CPU time when there is flood of events. getAtomIds()87 virtual const std::set<int>& getAtomIds() const { 88 return mAtomIds; 89 } 90 getId()91 int64_t getId() const { 92 return mId; 93 } 94 getProtoHash()95 uint64_t getProtoHash() const { 96 return mProtoHash; 97 } 98 isInitialized()99 bool isInitialized() { 100 return mInitialized; 101 } 102 103 protected: 104 // Name of this matching. We don't really need the name, but it makes log message easy to debug. 105 const int64_t mId; 106 107 // Whether this AtomMatchingTracker has been properly initialized. 108 bool mInitialized; 109 110 // The collection of the event tag ids that this AtomMatchingTracker cares. So we can quickly 111 // return kNotMatched when we receive an event with an id not in the list. This is especially 112 // useful when we have a complex CombinationAtomMatchingTracker. 113 std::set<int> mAtomIds; 114 115 // Hash of the AtomMatcher's proto bytes from StatsdConfig. 116 // Used to determine if the definition of this matcher has changed across a config update. 117 const uint64_t mProtoHash; 118 119 FRIEND_TEST(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerSimple); 120 FRIEND_TEST(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerCombination); 121 FRIEND_TEST(ConfigUpdateTest, TestUpdateMatchers); 122 }; 123 124 } // namespace statsd 125 } // namespace os 126 } // namespace android 127 128 #endif // ATOM_MATCHING_TRACKER_H 129