1caf339d004fad667748b68912c254df4e75cdc5aYao Chen/* 2caf339d004fad667748b68912c254df4e75cdc5aYao Chen * Copyright (C) 2017 The Android Open Source Project 3caf339d004fad667748b68912c254df4e75cdc5aYao Chen * 4caf339d004fad667748b68912c254df4e75cdc5aYao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5caf339d004fad667748b68912c254df4e75cdc5aYao Chen * you may not use this file except in compliance with the License. 6caf339d004fad667748b68912c254df4e75cdc5aYao Chen * You may obtain a copy of the License at 7caf339d004fad667748b68912c254df4e75cdc5aYao Chen * 8caf339d004fad667748b68912c254df4e75cdc5aYao Chen * http://www.apache.org/licenses/LICENSE-2.0 9caf339d004fad667748b68912c254df4e75cdc5aYao Chen * 10caf339d004fad667748b68912c254df4e75cdc5aYao Chen * Unless required by applicable law or agreed to in writing, software 11caf339d004fad667748b68912c254df4e75cdc5aYao Chen * distributed under the License is distributed on an "AS IS" BASIS, 12caf339d004fad667748b68912c254df4e75cdc5aYao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13caf339d004fad667748b68912c254df4e75cdc5aYao Chen * See the License for the specific language governing permissions and 14caf339d004fad667748b68912c254df4e75cdc5aYao Chen * limitations under the License. 15caf339d004fad667748b68912c254df4e75cdc5aYao Chen */ 16caf339d004fad667748b68912c254df4e75cdc5aYao Chen 179fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato#include "Log.h" 189fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato 19caf339d004fad667748b68912c254df4e75cdc5aYao Chen#include "CombinationLogMatchingTracker.h" 209fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato#include "matchers/matcher_util.h" 219fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato 229fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratonamespace android { 239fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratonamespace os { 249fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratonamespace statsd { 25caf339d004fad667748b68912c254df4e75cdc5aYao Chen 26caf339d004fad667748b68912c254df4e75cdc5aYao Chenusing std::set; 27caf339d004fad667748b68912c254df4e75cdc5aYao Chenusing std::string; 28caf339d004fad667748b68912c254df4e75cdc5aYao Chenusing std::unique_ptr; 29caf339d004fad667748b68912c254df4e75cdc5aYao Chenusing std::unordered_map; 30caf339d004fad667748b68912c254df4e75cdc5aYao Chenusing std::vector; 31caf339d004fad667748b68912c254df4e75cdc5aYao Chen 3294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-macCombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index) 3394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac : LogMatchingTracker(id, index) { 34caf339d004fad667748b68912c254df4e75cdc5aYao Chen} 35caf339d004fad667748b68912c254df4e75cdc5aYao Chen 36caf339d004fad667748b68912c254df4e75cdc5aYao ChenCombinationLogMatchingTracker::~CombinationLogMatchingTracker() { 37caf339d004fad667748b68912c254df4e75cdc5aYao Chen} 38caf339d004fad667748b68912c254df4e75cdc5aYao Chen 39b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafonbool CombinationLogMatchingTracker::init(const vector<AtomMatcher>& allLogMatchers, 40caf339d004fad667748b68912c254df4e75cdc5aYao Chen const vector<sp<LogMatchingTracker>>& allTrackers, 4194e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac const unordered_map<int64_t, int>& matcherMap, 42caf339d004fad667748b68912c254df4e75cdc5aYao Chen vector<bool>& stack) { 43caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (mInitialized) { 44caf339d004fad667748b68912c254df4e75cdc5aYao Chen return true; 45caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 46caf339d004fad667748b68912c254df4e75cdc5aYao Chen 47caf339d004fad667748b68912c254df4e75cdc5aYao Chen // mark this node as visited in the recursion stack. 48caf339d004fad667748b68912c254df4e75cdc5aYao Chen stack[mIndex] = true; 49caf339d004fad667748b68912c254df4e75cdc5aYao Chen 50b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon AtomMatcher_Combination matcher = allLogMatchers[mIndex].combination(); 51caf339d004fad667748b68912c254df4e75cdc5aYao Chen 52caf339d004fad667748b68912c254df4e75cdc5aYao Chen // LogicalOperation is missing in the config 53caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (!matcher.has_operation()) { 54caf339d004fad667748b68912c254df4e75cdc5aYao Chen return false; 55caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 56caf339d004fad667748b68912c254df4e75cdc5aYao Chen 57caf339d004fad667748b68912c254df4e75cdc5aYao Chen mLogicalOperation = matcher.operation(); 58caf339d004fad667748b68912c254df4e75cdc5aYao Chen 59caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (mLogicalOperation == LogicalOperation::NOT && matcher.matcher_size() != 1) { 60caf339d004fad667748b68912c254df4e75cdc5aYao Chen return false; 61caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 62caf339d004fad667748b68912c254df4e75cdc5aYao Chen 6394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac for (const auto& child : matcher.matcher()) { 64caf339d004fad667748b68912c254df4e75cdc5aYao Chen auto pair = matcherMap.find(child); 65caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (pair == matcherMap.end()) { 6694e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac ALOGW("Matcher %lld not found in the config", (long long)child); 67caf339d004fad667748b68912c254df4e75cdc5aYao Chen return false; 68caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 69caf339d004fad667748b68912c254df4e75cdc5aYao Chen 70caf339d004fad667748b68912c254df4e75cdc5aYao Chen int childIndex = pair->second; 71caf339d004fad667748b68912c254df4e75cdc5aYao Chen 72caf339d004fad667748b68912c254df4e75cdc5aYao Chen // if the child is a visited node in the recursion -> circle detected. 73caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (stack[childIndex]) { 74caf339d004fad667748b68912c254df4e75cdc5aYao Chen ALOGE("Circle detected in matcher config"); 75caf339d004fad667748b68912c254df4e75cdc5aYao Chen return false; 76caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 77caf339d004fad667748b68912c254df4e75cdc5aYao Chen 78caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (!allTrackers[childIndex]->init(allLogMatchers, allTrackers, matcherMap, stack)) { 7994e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac ALOGW("child matcher init failed %lld", (long long)child); 80caf339d004fad667748b68912c254df4e75cdc5aYao Chen return false; 81caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 82caf339d004fad667748b68912c254df4e75cdc5aYao Chen 83caf339d004fad667748b68912c254df4e75cdc5aYao Chen mChildren.push_back(childIndex); 84caf339d004fad667748b68912c254df4e75cdc5aYao Chen 852087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac const set<int>& childTagIds = allTrackers[childIndex]->getAtomIds(); 862087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac mAtomIds.insert(childTagIds.begin(), childTagIds.end()); 87caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 88caf339d004fad667748b68912c254df4e75cdc5aYao Chen 89caf339d004fad667748b68912c254df4e75cdc5aYao Chen mInitialized = true; 90caf339d004fad667748b68912c254df4e75cdc5aYao Chen // unmark this node in the recursion stack. 91caf339d004fad667748b68912c254df4e75cdc5aYao Chen stack[mIndex] = false; 92caf339d004fad667748b68912c254df4e75cdc5aYao Chen return true; 93caf339d004fad667748b68912c254df4e75cdc5aYao Chen} 94caf339d004fad667748b68912c254df4e75cdc5aYao Chen 95c4dfae56c10a1dd571baa78c750f2e68c919d74fJoe Onoratovoid CombinationLogMatchingTracker::onLogEvent(const LogEvent& event, 96caf339d004fad667748b68912c254df4e75cdc5aYao Chen const vector<sp<LogMatchingTracker>>& allTrackers, 97caf339d004fad667748b68912c254df4e75cdc5aYao Chen vector<MatchingState>& matcherResults) { 98caf339d004fad667748b68912c254df4e75cdc5aYao Chen // this event has been processed. 99caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (matcherResults[mIndex] != MatchingState::kNotComputed) { 100caf339d004fad667748b68912c254df4e75cdc5aYao Chen return; 101caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 102caf339d004fad667748b68912c254df4e75cdc5aYao Chen 1032087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) { 104caf339d004fad667748b68912c254df4e75cdc5aYao Chen matcherResults[mIndex] = MatchingState::kNotMatched; 105caf339d004fad667748b68912c254df4e75cdc5aYao Chen return; 106caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 107caf339d004fad667748b68912c254df4e75cdc5aYao Chen 108caf339d004fad667748b68912c254df4e75cdc5aYao Chen // evaluate children matchers if they haven't been evaluated. 109caf339d004fad667748b68912c254df4e75cdc5aYao Chen for (const int childIndex : mChildren) { 110caf339d004fad667748b68912c254df4e75cdc5aYao Chen if (matcherResults[childIndex] == MatchingState::kNotComputed) { 111caf339d004fad667748b68912c254df4e75cdc5aYao Chen const sp<LogMatchingTracker>& child = allTrackers[childIndex]; 112caf339d004fad667748b68912c254df4e75cdc5aYao Chen child->onLogEvent(event, allTrackers, matcherResults); 113caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 114caf339d004fad667748b68912c254df4e75cdc5aYao Chen } 115caf339d004fad667748b68912c254df4e75cdc5aYao Chen 116caf339d004fad667748b68912c254df4e75cdc5aYao Chen bool matched = combinationMatch(mChildren, mLogicalOperation, matcherResults); 117caf339d004fad667748b68912c254df4e75cdc5aYao Chen matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched; 118caf339d004fad667748b68912c254df4e75cdc5aYao Chen} 119caf339d004fad667748b68912c254df4e75cdc5aYao Chen 120caf339d004fad667748b68912c254df4e75cdc5aYao Chen} // namespace statsd 121caf339d004fad667748b68912c254df4e75cdc5aYao Chen} // namespace os 122caf339d004fad667748b68912c254df4e75cdc5aYao Chen} // namespace android 123