src/matchers/matcher_util.cpp \
src/matchers/SimpleLogMatchingTracker.cpp \
src/metrics/CountAnomalyTracker.cpp \
+ src/metrics/MetricProducer.cpp \
src/metrics/CountMetricProducer.cpp \
src/metrics/DurationMetricProducer.cpp \
src/metrics/MetricsManager.cpp \
mCondition = conditionMet;
}
-void CountMetricProducer::onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
+void CountMetricProducer::onMatchedLogEventInternal(
+ const size_t matcherIndex, const HashableDimensionKey& eventKey,
+ const map<string, HashableDimensionKey>& conditionKey, bool condition,
+ const LogEvent& event) {
uint64_t eventTimeNs = event.GetTimestampNs();
- // this is old event, maybe statsd restarted?
- if (eventTimeNs < mStartTimeNs) {
- return;
- }
flushCounterIfNeeded(eventTimeNs);
- if (mConditionSliced) {
- map<string, HashableDimensionKey> conditionKeys;
- for (const auto& link : mConditionLinks) {
- VLOG("Condition link key_in_main size %d", link.key_in_main_size());
- HashableDimensionKey conditionKey = getDimensionKeyForCondition(event, link);
- conditionKeys[link.condition()] = conditionKey;
- }
- if (mWizard->query(mConditionTrackerIndex, conditionKeys) != ConditionState::kTrue) {
- VLOG("metric %lld sliced condition not met", mMetric.metric_id());
- return;
- }
- } else {
- if (!mCondition) {
- VLOG("metric %lld condition not met", mMetric.metric_id());
- return;
- }
- }
-
- HashableDimensionKey hashableKey;
-
- if (mDimension.size() > 0) {
- vector<KeyValuePair> key = getDimensionKey(event, mDimension);
- hashableKey = getHashableKey(key);
- // Add the HashableDimensionKey->vector<KeyValuePair> to the map, because StatsLogReport
- // expects vector<KeyValuePair>.
- if (mDimensionKeyMap.find(hashableKey) == mDimensionKeyMap.end()) {
- mDimensionKeyMap[hashableKey] = key;
- }
- } else {
- hashableKey = DEFAULT_DIMENSION_KEY;
+ if (condition == false) {
+ return;
}
- auto it = mCurrentSlicedCounter.find(hashableKey);
+ auto it = mCurrentSlicedCounter.find(eventKey);
if (it == mCurrentSlicedCounter.end()) {
// create a counter for the new key
- mCurrentSlicedCounter[hashableKey] = 1;
+ mCurrentSlicedCounter[eventKey] = 1;
} else {
// increment the existing value
count++;
}
- VLOG("metric %lld %s->%d", mMetric.metric_id(), hashableKey.c_str(),
- mCurrentSlicedCounter[hashableKey]);
+ VLOG("metric %lld %s->%d", mMetric.metric_id(), eventKey.c_str(),
+ mCurrentSlicedCounter[eventKey]);
}
// When a new matched event comes in, we check if event falls into the current
} // namespace statsd
} // namespace os
-} // namespace android
+} // namespace android
\ No newline at end of file
virtual ~CountMetricProducer();
- void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) override;
-
void onConditionChanged(const bool conditionMet) override;
void finish() override;
// TODO: Implement this later.
virtual void notifyAppUpgrade(const string& apk, const int uid, const int version) override{};
+protected:
+ void onMatchedLogEventInternal(const size_t matcherIndex, const HashableDimensionKey& eventKey,
+ const std::map<std::string, HashableDimensionKey>& conditionKey,
+ bool condition, const LogEvent& event) override;
+
private:
const CountMetric mMetric;
return report;
};
-void DurationMetricProducer::onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
- if (event.GetTimestampNs() < mStartTimeNs) {
- return;
- }
-
+void DurationMetricProducer::onMatchedLogEventInternal(
+ const size_t matcherIndex, const HashableDimensionKey& eventKey,
+ const map<string, HashableDimensionKey>& conditionKeys, bool condition,
+ const LogEvent& event) {
flushDurationIfNeeded(event.GetTimestampNs());
if (matcherIndex == mStopAllIndex) {
return;
}
- HashableDimensionKey hashableKey;
- if (mDimension.size() > 0) {
- // hook up sliced counter with AnomalyMonitor.
- vector<KeyValuePair> key = getDimensionKey(event, mDimension);
- hashableKey = getHashableKey(key);
- // Add the HashableDimensionKey->DimensionKey to the map, because StatsLogReport expects
- // vector<KeyValuePair>.
- if (mDimensionKeyMap.find(hashableKey) == mDimensionKeyMap.end()) {
- mDimensionKeyMap[hashableKey] = key;
- }
- } else {
- hashableKey = DEFAULT_DIMENSION_KEY;
- }
-
- if (mCurrentSlicedDuration.find(hashableKey) == mCurrentSlicedDuration.end() &&
- mConditionSliced) {
+ if (mCurrentSlicedDuration.find(eventKey) == mCurrentSlicedDuration.end() && mConditionSliced) {
// add the durationInfo for the current bucket.
- auto& durationInfo = mCurrentSlicedDuration[hashableKey];
- auto& conditionKeys = durationInfo.conditionKeys;
- // get and cache the keys for query condition.
- for (const auto& link : mConditionLinks) {
- HashableDimensionKey conditionKey = getDimensionKeyForCondition(event, link);
- conditionKeys[link.condition()] = conditionKey;
- }
- }
-
- bool conditionMet;
- if (mConditionSliced) {
- const auto& conditionKeys = mCurrentSlicedDuration[hashableKey].conditionKeys;
- conditionMet =
- mWizard->query(mConditionTrackerIndex, conditionKeys) == ConditionState::kTrue;
- } else {
- conditionMet = mCondition;
+ auto& durationInfo = mCurrentSlicedDuration[eventKey];
+ durationInfo.conditionKeys = conditionKeys;
}
if (matcherIndex == mStartIndex) {
- VLOG("Metric %lld Key: %s Start, Condition %d", mMetric.metric_id(), hashableKey.c_str(),
- conditionMet);
- noteStart(hashableKey, conditionMet, event.GetTimestampNs());
+ VLOG("Metric %lld Key: %s Start, Condition %d", mMetric.metric_id(), eventKey.c_str(),
+ condition);
+ noteStart(eventKey, condition, event.GetTimestampNs());
} else if (matcherIndex == mStopIndex) {
- VLOG("Metric %lld Key: %s Stop, Condition %d", mMetric.metric_id(), hashableKey.c_str(),
- conditionMet);
- noteStop(hashableKey, event.GetTimestampNs());
+ VLOG("Metric %lld Key: %s Stop, Condition %d", mMetric.metric_id(), eventKey.c_str(),
+ condition);
+ noteStop(eventKey, event.GetTimestampNs());
}
}
virtual ~DurationMetricProducer();
- void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) override;
-
void onConditionChanged(const bool conditionMet) override;
void finish() override;
// TODO: Implement this later.
virtual void notifyAppUpgrade(const string& apk, const int uid, const int version) override{};
+protected:
+ void onMatchedLogEventInternal(const size_t matcherIndex, const HashableDimensionKey& eventKey,
+ const std::map<std::string, HashableDimensionKey>& conditionKeys,
+ bool condition, const LogEvent& event) override;
+
private:
const DurationMetric mMetric;
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "MetricProducer.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::map;
+
+void MetricProducer::onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
+ uint64_t eventTimeNs = event.GetTimestampNs();
+ // this is old event, maybe statsd restarted?
+ if (eventTimeNs < mStartTimeNs) {
+ return;
+ }
+
+ HashableDimensionKey eventKey;
+
+ if (mDimension.size() > 0) {
+ vector<KeyValuePair> key = getDimensionKey(event, mDimension);
+ eventKey = getHashableKey(key);
+ // Add the HashableDimensionKey->vector<KeyValuePair> to the map, because StatsLogReport
+ // expects vector<KeyValuePair>.
+ if (mDimensionKeyMap.find(eventKey) == mDimensionKeyMap.end()) {
+ mDimensionKeyMap[eventKey] = key;
+ }
+ } else {
+ eventKey = DEFAULT_DIMENSION_KEY;
+ }
+
+ bool condition;
+
+ map<string, HashableDimensionKey> conditionKeys;
+ if (mConditionSliced) {
+ for (const auto& link : mConditionLinks) {
+ HashableDimensionKey conditionKey = getDimensionKeyForCondition(event, link);
+ conditionKeys[link.condition()] = conditionKey;
+ }
+ if (mWizard->query(mConditionTrackerIndex, conditionKeys) != ConditionState::kTrue) {
+ condition = false;
+ } else {
+ condition = true;
+ }
+ } else {
+ condition = mCondition;
+ }
+
+ onMatchedLogEventInternal(matcherIndex, eventKey, conditionKeys, condition, event);
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
\ No newline at end of file
virtual ~MetricProducer(){};
// Consume the parsed stats log entry that already matched the "what" of the metric.
- virtual void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) = 0;
+ void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event);
virtual void onConditionChanged(const bool condition) = 0;
std::unordered_map<HashableDimensionKey, std::vector<KeyValuePair>> mDimensionKeyMap;
std::vector<EventConditionLink> mConditionLinks;
+
+ /*
+ * Individual metrics can implement their own business logic here. All pre-processing is done.
+ *
+ * [matcherIndex]: the index of the matcher which matched this event. This is interesting to
+ * DurationMetric, because it has start/stop/stop_all 3 matchers.
+ * [eventKey]: the extracted dimension key for the final output. if the metric doesn't have
+ * dimensions, it will be DEFAULT_DIMENSION_KEY
+ * [conditionKey]: the keys of conditions which should be used to query the condition for this
+ * target event (from EventConditionLink). This is passed to individual metrics
+ * because DurationMetric needs it to be cached.
+ * [condition]: whether condition is met. If condition is sliced, this is the result coming from
+ * query with ConditionWizard; If condition is not sliced, this is the
+ * nonSlicedCondition.
+ * [event]: the log event, just in case the metric needs its data, e.g., EventMetric.
+ */
+ virtual void onMatchedLogEventInternal(
+ const size_t matcherIndex, const HashableDimensionKey& eventKey,
+ const std::map<std::string, HashableDimensionKey>& conditionKey, bool condition,
+ const LogEvent& event) = 0;
};
} // namespace statsd