Remove kAtomsWithUidField from atoms_info
Instead of using the map from atoms_info, we now receive uid information in the form of StatsEvent annotations. The isUid annotation is exposed from both LogEvent and FieldValue. Test: bit statsd_test:* Test: atest GtsStatsdHostTestCases Bug: 150414601 Change-Id: Iebbe4ce5668de1ab91485daa1be9197cde6e8309
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
cmds/statsd/src/external/puller_util.cpp
vendored
32
cmds/statsd/src/external/puller_util.cpp
vendored
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
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));
|
||||
|
||||
// Tag found in kAtomsWithUidField and has matching uid
|
||||
// Make event with is_uid annotation.
|
||||
LogEvent event2(/*uid=*/0, /*pid=*/0);
|
||||
makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
20
cmds/statsd/tests/external/puller_util_test.cpp
vendored
20
cmds/statsd/tests/external/puller_util_test.cpp
vendored
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user