diff options
| -rw-r--r-- | cmds/statsd/src/FieldValue.cpp | 18 | ||||
| -rw-r--r-- | cmds/statsd/src/FieldValue.h | 12 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsLogProcessor.cpp | 26 | ||||
| -rw-r--r-- | cmds/statsd/src/external/puller_util.cpp | 32 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.cpp | 8 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.h | 1 | ||||
| -rw-r--r-- | cmds/statsd/src/matchers/matcher_util.cpp | 18 | ||||
| -rw-r--r-- | cmds/statsd/tests/LogEntryMatcher_test.cpp | 25 | ||||
| -rw-r--r-- | cmds/statsd/tests/external/puller_util_test.cpp | 20 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/atoms_info_writer.cpp | 23 |
10 files changed, 74 insertions, 109 deletions
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 4385964f7f0e..cfc1de49e259 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -120,9 +120,9 @@ bool isAttributionUidField(const FieldValue& value) { } int32_t getUidIfExists(const FieldValue& value) { - // the field is uid field if the field is the uid field in attribution node or marked as - // is_uid in atoms.proto - bool isUid = isAttributionUidField(value) || isUidField(value.mField, value.mValue); + // the field is uid field if the field is the uid field in attribution node + // or annotated as such in the atom + bool isUid = isAttributionUidField(value) || isUidField(value); return isUid ? value.mValue.int_value : -1; } @@ -134,16 +134,8 @@ bool isAttributionUidField(const Field& field, const Value& value) { return false; } -bool isUidField(const Field& field, const Value& value) { - auto it = android::util::AtomsInfo::kAtomsWithUidField.find(field.getTag()); - - if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) { - int uidField = it->second; // uidField is the field number in proto - return field.getDepth() == 0 && field.getPosAtDepth(0) == uidField && - value.getType() == INT; - } - - return false; +bool isUidField(const FieldValue& fieldValue) { + return fieldValue.mAnnotations.isUidField(); } Value::Value(const Value& from) { diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index 3536e5a5c962..92e09ea0f8f9 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -367,7 +367,8 @@ public: enum { NESTED_POS = 0x0, PRIMARY_POS = 0x1, - EXCLUSIVE_POS = 0x2 + EXCLUSIVE_POS = 0x2, + UID_POS = 0x3 }; inline void setNested(bool nested) { setBitmaskAtPos(NESTED_POS, nested); } @@ -376,6 +377,8 @@ public: inline void setExclusiveState(bool exclusive) { setBitmaskAtPos(EXCLUSIVE_POS, exclusive); } + inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); } + inline void setResetState(int resetState) { mResetState = resetState; } // Default value = false @@ -387,6 +390,9 @@ public: // Default value = false inline bool isExclusiveState() const { return getValueFromBitmask(EXCLUSIVE_POS); } + // Default value = false + inline bool isUidField() const { return getValueFromBitmask(UID_POS); } + // If a reset state is not sent in the StatsEvent, returns -1. Note that a // reset satate is only sent if and only if a reset should be triggered. inline int getResetState() const { return mResetState; } @@ -402,7 +408,7 @@ private: } // This is a bitmask over all annotations stored in boolean form. Because - // there are only 3 booleans, just one byte is required. + // there are only 4 booleans, just one byte is required. uint8_t mBooleanBitmask = 0; int mResetState = -1; @@ -449,7 +455,7 @@ int getUidIfExists(const FieldValue& value); void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output); bool isAttributionUidField(const Field& field, const Value& value); -bool isUidField(const Field& field, const Value& value); +bool isUidField(const FieldValue& fieldValue); bool equalDimensions(const std::vector<Matcher>& dimension_a, const std::vector<Matcher>& dimension_b); diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 982a63e3e08c..325cbc7e80e5 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -138,13 +138,6 @@ void StatsLogProcessor::onPeriodicAlarmFired( } } -void updateUid(Value* value, int hostUid) { - int uid = value->int_value; - if (uid != hostUid) { - value->setInt(hostUid); - } -} - void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const { if (android::util::AtomsInfo::kAtomsWithAttributionChain.find(event->GetTagId()) != android::util::AtomsInfo::kAtomsWithAttributionChain.end()) { @@ -154,22 +147,15 @@ void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event } if (isAttributionUidField(value)) { const int hostUid = mUidMap->getHostUidOrSelf(value.mValue.int_value); - updateUid(&value.mValue, hostUid); + value.mValue.setInt(hostUid); } } } else { - auto it = android::util::AtomsInfo::kAtomsWithUidField.find(event->GetTagId()); - if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) { - int uidField = it->second; // uidField is the field number in proto, - // starting from 1 - if (uidField > 0 && (int)event->getValues().size() >= uidField && - (event->getValues())[uidField - 1].mValue.getType() == INT) { - Value& value = (*event->getMutableValues())[uidField - 1].mValue; - const int hostUid = mUidMap->getHostUidOrSelf(value.int_value); - updateUid(&value, hostUid); - } else { - ALOGE("Malformed log, uid not found. %s", event->ToString().c_str()); - } + int uidFieldIndex = event->getUidFieldIndex(); + if (uidFieldIndex != -1) { + Value& value = (*event->getMutableValues())[uidFieldIndex].mValue; + const int hostUid = mUidMap->getHostUidOrSelf(value.int_value); + value.setInt(hostUid); } } } diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index aee725698c30..90247cf9d68c 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -49,10 +49,14 @@ using namespace std; */ void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap, int tagId, const vector<int>& additiveFieldsVec) { - if ((android::util::AtomsInfo::kAtomsWithAttributionChain.find(tagId) == - android::util::AtomsInfo::kAtomsWithAttributionChain.end()) && - (android::util::AtomsInfo::kAtomsWithUidField.find(tagId) == - android::util::AtomsInfo::kAtomsWithUidField.end())) { + bool hasAttributionChain = (android::util::AtomsInfo::kAtomsWithAttributionChain.find(tagId) != + android::util::AtomsInfo::kAtomsWithAttributionChain.end()); + // To check if any LogEvent has a uid field, we can just check the first + // LogEvent because all atoms with this tagId should have the uid + // annotation. + bool hasUidField = (data[0]->getUidFieldIndex() != -1); + + if (!hasAttributionChain && !hasUidField) { VLOG("No uid or attribution chain to merge, atom %d", tagId); return; } @@ -75,19 +79,13 @@ void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const } } } else { - auto it = android::util::AtomsInfo::kAtomsWithUidField.find(tagId); - if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) { - int uidField = it->second; // uidField is the field number in proto, - // starting from 1 - if (uidField > 0 && (int)event->getValues().size() >= uidField && - (event->getValues())[uidField - 1].mValue.getType() == INT) { - Value& value = (*event->getMutableValues())[uidField - 1].mValue; - const int hostUid = uidMap->getHostUidOrSelf(value.int_value); - value.setInt(hostUid); - } else { - ALOGE("Malformed log, uid not found. %s", event->ToString().c_str()); - return; - } + int uidFieldIndex = event->getUidFieldIndex(); + if (uidFieldIndex != -1) { + Value& value = (*event->getMutableValues())[uidFieldIndex].mValue; + const int hostUid = uidMap->getHostUidOrSelf(value.int_value); + value.setInt(hostUid); + } else { + ALOGE("Malformed log, uid not found. %s", event->ToString().c_str()); } } } diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 96bf04f4f6d6..8b6a86464155 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -240,14 +240,20 @@ void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last, last[1] = last[2] = false; } +// Assumes that mValues is not empty +bool LogEvent::checkPreviousValueType(Type expected) { + return mValues[mValues.size() - 1].mValue.getType() == expected; +} + void LogEvent::parseIsUidAnnotation(uint8_t annotationType) { - if (mValues.empty() || annotationType != BOOL_TYPE) { + if (mValues.empty() || !checkPreviousValueType(INT) || annotationType != BOOL_TYPE) { mValid = false; return; } bool isUid = readNextValue<uint8_t>(); if (isUid) mUidFieldIndex = mValues.size() - 1; + mValues[mValues.size() - 1].mAnnotations.setUidField(isUid); } void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) { diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 9e21c777e6ff..4eeb7d64a463 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -213,6 +213,7 @@ private: void parseExclusiveStateAnnotation(uint8_t annotationType); void parseTriggerStateResetAnnotation(uint8_t annotationType); void parseStateNestedAnnotation(uint8_t annotationType); + bool checkPreviousValueType(Type expected); /** * The below three variables are only valid during the execution of diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp index 1f8bbd7f528c..2b4c6a3cbf1e 100644 --- a/cmds/statsd/src/matchers/matcher_util.cpp +++ b/cmds/statsd/src/matchers/matcher_util.cpp @@ -81,18 +81,17 @@ bool combinationMatch(const vector<int>& children, const LogicalOperation& opera return matched; } -bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value, - const string& str_match) { - if (isAttributionUidField(field, value) || isUidField(field, value)) { - int uid = value.int_value; +bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) { + if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) { + int uid = fieldValue.mValue.int_value; auto aidIt = UidMap::sAidToUidMapping.find(str_match); if (aidIt != UidMap::sAidToUidMapping.end()) { return ((int)aidIt->second) == uid; } std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/); return packageNames.find(str_match) != packageNames.end(); - } else if (value.getType() == STRING) { - return value.str_value == str_match; + } else if (fieldValue.mValue.getType() == STRING) { + return fieldValue.mValue.str_value == str_match; } return false; } @@ -228,8 +227,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } case FieldValueMatcher::ValueMatcherCase::kEqString: { for (int i = start; i < end; i++) { - if (tryMatchString(uidMap, values[i].mField, values[i].mValue, - matcher.eq_string())) { + if (tryMatchString(uidMap, values[i], matcher.eq_string())) { return true; } } @@ -240,7 +238,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, for (int i = start; i < end; i++) { bool notEqAll = true; for (const auto& str : str_list.str_value()) { - if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) { + if (tryMatchString(uidMap, values[i], str)) { notEqAll = false; break; } @@ -255,7 +253,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, const auto& str_list = matcher.eq_any_string(); for (int i = start; i < end; i++) { for (const auto& str : str_list.str_value()) { - if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) { + if (tryMatchString(uidMap, values[i], str)) { return true; } } diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 9cdf5827d1f8..26423d464027 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -18,6 +18,7 @@ #include <log/logprint.h> #include <stdio.h> +#include "annotations.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "matchers/matcher_util.h" #include "stats_event.h" @@ -73,14 +74,13 @@ void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t parseStatsEventToLogEvent(statsEvent, logEvent); } -void makeIntStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, - const int32_t value, const string& name) { +void makeIntWithBoolAnnotationLogEvent(LogEvent* logEvent, const int32_t atomId, + const int32_t field, const uint8_t annotationId, + const bool annotationValue) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); - AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - - AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_writeString(statsEvent, name.c_str()); + AStatsEvent_writeInt32(statsEvent, field); + AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue); parseStatsEventToLogEvent(statsEvent, logEvent); } @@ -376,21 +376,20 @@ TEST(AtomMatcherTest, TestUidFieldMatcher) { simpleMatcher->add_field_value_matcher()->set_field(1); simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0"); - // Set up the event + // Make event without is_uid annotation. LogEvent event1(/*uid=*/0, /*pid=*/0); makeIntLogEvent(&event1, TAG_ID, 0, 1111); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); + // Make event with is_uid annotation. LogEvent event2(/*uid=*/0, /*pid=*/0); - makeIntStringLogEvent(&event2, TAG_ID_2, 0, 1111, "some value"); - - // Tag not in kAtomsWithUidField - EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); + makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true); - // Tag found in kAtomsWithUidField and has matching uid + // Event has is_uid annotation, so mapping from uid to package name occurs. simpleMatcher->set_atom_id(TAG_ID_2); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); - // Tag found in kAtomsWithUidField but has non-matching uid + // Event has is_uid annotation, but uid maps to different package name. simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); } diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 3e1cc5e458ed..c2cfb371d329 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -21,6 +21,7 @@ #include <vector> #include "../metrics/metrics_test_helper.h" +#include "annotations.h" #include "stats_event.h" #include "statslog_statsdtest.h" #include "tests/statsd_test_util.h" @@ -53,15 +54,15 @@ int hostNonAdditiveData = 22; void extractIntoVector(vector<shared_ptr<LogEvent>> events, vector<vector<int>>& ret) { - ret.clear(); - status_t err; - for (const auto& event : events) { - vector<int> vec; - vec.push_back(event->GetInt(1, &err)); - vec.push_back(event->GetInt(2, &err)); - vec.push_back(event->GetInt(3, &err)); - ret.push_back(vec); - } + ret.clear(); + status_t err; + for (const auto& event : events) { + vector<int> vec; + vec.push_back(event->GetInt(1, &err)); + vec.push_back(event->GetInt(2, &err)); + vec.push_back(event->GetInt(3, &err)); + ret.push_back(vec); + } } std::shared_ptr<LogEvent> makeUidLogEvent(uint64_t timestampNs, int uid, int data1, int data2) { @@ -70,6 +71,7 @@ std::shared_ptr<LogEvent> makeUidLogEvent(uint64_t timestampNs, int uid, int dat AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true); AStatsEvent_writeInt32(statsEvent, data1); AStatsEvent_writeInt32(statsEvent, data2); diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp index 23a0f7278271..5fe94987aa65 100644 --- a/tools/stats_log_api_gen/atoms_info_writer.cpp +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -42,7 +42,6 @@ static void write_atoms_info_header_body(FILE* out, const Atoms& atoms) { fprintf(out, " const static std::set<int> " "kTruncatingTimestampAtomBlackList;\n"); - fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); fprintf(out, " const static std::set<int> kAtomsWithAttributionChain;\n"); fprintf(out, " const static std::map<int, StateAtomFieldOptions> " @@ -101,28 +100,6 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { fprintf(out, "};\n"); fprintf(out, "\n"); - fprintf(out, "static std::map<int, int> getAtomUidField() {\n"); - fprintf(out, " std::map<int, int> uidField;\n"); - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - if ((*atomIt)->uidField == 0) { - continue; - } - fprintf(out, - "\n // Adding uid field for atom " - "(%d)%s\n", - (*atomIt)->code, (*atomIt)->name.c_str()); - fprintf(out, " uidField[%d /* %s */] = %d;\n", (*atomIt)->code, - make_constant_name((*atomIt)->name).c_str(), (*atomIt)->uidField); - } - - fprintf(out, " return uidField;\n"); - fprintf(out, "};\n"); - - fprintf(out, - "const std::map<int, int> AtomsInfo::kAtomsWithUidField = " - "getAtomUidField();\n"); - fprintf(out, "static std::map<int, StateAtomFieldOptions> " "getStateAtomFieldOptions() {\n"); |