summaryrefslogtreecommitdiff
path: root/statsd/src/guardrail
diff options
context:
space:
mode:
authorVova Sharaienko <sharaienko@google.com>2023-11-04 03:49:14 +0000
committerVova Sharaienko <sharaienko@google.com>2023-12-01 21:46:09 +0000
commitbccdadfd8aca4f855a7b8a912cad4d05f28f2516 (patch)
treedf12695184cc5ff7bec6f8739774f18823067794 /statsd/src/guardrail
parenta1bc6a249f8a2db878ff42aaffc6f37c5e2ceef4 (diff)
downloadStatsD-bccdadfd8aca4f855a7b8a912cad4d05f28f2516.tar.gz
[statsd] Added socket loss stats dump to proto
- added tests for Statsd libstatssocket loss stats Bug: 296900300 Test: atest android.cts.statsd.metadata.MetadataTests Change-Id: Id7f8548d35819bd7c73c73b4e69a242616eaa808
Diffstat (limited to 'statsd/src/guardrail')
-rw-r--r--statsd/src/guardrail/StatsdStats.cpp105
-rw-r--r--statsd/src/guardrail/StatsdStats.h34
2 files changed, 112 insertions, 27 deletions
diff --git a/statsd/src/guardrail/StatsdStats.cpp b/statsd/src/guardrail/StatsdStats.cpp
index d659de7d..939d39fa 100644
--- a/statsd/src/guardrail/StatsdStats.cpp
+++ b/statsd/src/guardrail/StatsdStats.cpp
@@ -61,6 +61,7 @@ const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS = 20;
const int FIELD_ID_SHARD_OFFSET = 21;
const int FIELD_ID_STATSD_STATS_ID = 22;
const int FIELD_ID_SUBSCRIPTION_STATS = 23;
+const int FIELD_ID_SOCKET_LOSS_STATS = 24;
const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CALLING_UID = 1;
const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_ID = 2;
@@ -158,6 +159,25 @@ const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
+// SocketLossStats
+const int FIELD_ID_SOCKET_LOSS_STATS_PER_UID = 1;
+const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS = 2;
+
+// for LossStatsOverflowCounters proto
+const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_UID = 1;
+const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_COUNT = 2;
+
+// for LossStatsPerUid proto
+const int FIELD_ID_SOCKET_LOSS_STATS_UID = 1;
+const int FIELD_ID_SOCKET_LOSS_STATS_FIRST_TIMESTAMP_NANOS = 2;
+const int FIELD_ID_SOCKET_LOSS_STATS_LAST_TIMESTAMP_NANOS = 3;
+const int FIELD_ID_SOCKET_LOSS_ATOM_ID_LOSS_STATS = 4;
+
+// for AtomIdLossStats proto
+const int FIELD_ID_ATOM_ID_LOSS_STATS_ATOM_ID = 1;
+const int FIELD_ID_ATOM_ID_LOSS_STATS_ERROR = 2;
+const int FIELD_ID_ATOM_ID_LOSS_STATS_COUNT = 3;
+
// for RestrictedMetricStats proto
const int FIELD_ID_RESTRICTED_STATS_METRIC_ID = 1;
const int FIELD_ID_RESTRICTED_STATS_INSERT_ERROR = 2;
@@ -353,25 +373,26 @@ void StatsdStats::noteAtomSocketLoss(const SocketLossInfo& lossInfo) {
ALOGW("SocketLossEvent detected: %lld (firstLossTsNanos), %lld (lastLossTsNanos)",
(long long)lossInfo.firstLossTsNanos, (long long)lossInfo.lastLossTsNanos);
lock_guard<std::mutex> lock(mLock);
+
+ if (mSocketLossStats.size() == kMaxSocketLossStatsSize) {
+ // erase the oldest record
+ mSocketLossStats.pop_front();
+ }
+ mSocketLossStats.emplace_back(lossInfo.uid, lossInfo.firstLossTsNanos,
+ lossInfo.lastLossTsNanos);
for (size_t i = 0; i < lossInfo.atomIds.size(); i++) {
ALOGW("For uid %d atom %d was lost %d times with error %d", lossInfo.uid,
lossInfo.atomIds[i], lossInfo.counts[i], lossInfo.errors[i]);
- const auto lossInfoKey =
- std::make_tuple(lossInfo.uid, lossInfo.atomIds[i], lossInfo.errors[i]);
- auto counterIt = mSocketLossStats.find(lossInfoKey);
- if (counterIt != mSocketLossStats.end()) {
- counterIt->second += lossInfo.counts[i];
- } else if (mSocketLossStats.size() < kMaxSocketLossStatsSize) {
- mSocketLossStats[lossInfoKey] = lossInfo.counts[i];
- }
+ mSocketLossStats.back().mLossCountPerErrorAtomId.emplace_back(
+ lossInfo.atomIds[i], lossInfo.errors[i], lossInfo.counts[i]);
}
if (lossInfo.overflowCounter > 0) {
- auto overflowPerUid = mSocketLossStatsOverflowCounter.find(lossInfo.uid);
- if (overflowPerUid != mSocketLossStatsOverflowCounter.end()) {
+ auto overflowPerUid = mSocketLossStatsOverflowCounters.find(lossInfo.uid);
+ if (overflowPerUid != mSocketLossStatsOverflowCounters.end()) {
overflowPerUid->second += lossInfo.overflowCounter;
- } else if (mSocketLossStatsOverflowCounter.size() < kMaxSocketLossStatsSize) {
- mSocketLossStatsOverflowCounter[lossInfo.uid] = lossInfo.overflowCounter;
+ } else if (mSocketLossStatsOverflowCounters.size() < kMaxSocketLossStatsSize) {
+ mSocketLossStatsOverflowCounters[lossInfo.uid] = lossInfo.overflowCounter;
}
}
}
@@ -1060,7 +1081,7 @@ void StatsdStats::resetInternalLocked() {
mActivationBroadcastGuardrailStats.clear();
mPushedAtomErrorStats.clear();
mSocketLossStats.clear();
- mSocketLossStatsOverflowCounter.clear();
+ mSocketLossStatsOverflowCounters.clear();
mPushedAtomDropsStats.clear();
mRestrictedMetricQueryStats.clear();
mSubscriptionPullThreadWakeupCount = 0;
@@ -1387,17 +1408,18 @@ void StatsdStats::dumpStats(int out) const {
if (mSocketLossStats.size()) {
dprintf(out, "********SocketLossStats stats***********\n");
for (const auto& loss : mSocketLossStats) {
- const int32_t uid = std::get<0>(loss.first);
- const int32_t tag = std::get<1>(loss.first);
- const int32_t error = std::get<2>(loss.first);
- dprintf(out, "Socket loss: %d (uid), %d (tag) %d (error), %d (count)\n", uid, tag,
- error, loss.second);
+ dprintf(out, "Socket loss: %d (uid), first loss at %lld, last loss at %lld\n",
+ loss.mUid, (long long)loss.mFirstLossTsNanos, (long long)loss.mLastLossTsNanos);
+ for (const auto& counterInfo : loss.mLossCountPerErrorAtomId) {
+ dprintf(out, "\t\t %d (atomId) %d (error), %d (count)\n", counterInfo.mAtomId,
+ counterInfo.mError, counterInfo.mCount);
+ }
}
}
- if (mSocketLossStatsOverflowCounter.size()) {
- dprintf(out, "********mSocketLossStatsOverflowCounter stats***********\n");
- for (const auto& overflow : mSocketLossStatsOverflowCounter) {
+ if (mSocketLossStatsOverflowCounters.size()) {
+ dprintf(out, "********mSocketLossStatsOverflowCounters stats***********\n");
+ for (const auto& overflow : mSocketLossStatsOverflowCounters) {
dprintf(out, "Socket loss overflow for %d uid is %d times\n", overflow.first,
overflow.second);
}
@@ -1843,6 +1865,47 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
mSubscriptionPullThreadWakeupCount, &proto);
proto.end(token);
+ // libstatssocket specific stats
+
+ const uint64_t socketLossStatsToken =
+ proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS);
+
+ // socket loss stats info per uid/error/atom id counter
+ for (const auto& perUidLossInfo : mSocketLossStats) {
+ uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS_PER_UID |
+ FIELD_COUNT_REPEATED);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_UID, perUidLossInfo.mUid);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_FIRST_TIMESTAMP_NANOS,
+ perUidLossInfo.mFirstLossTsNanos);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_LAST_TIMESTAMP_NANOS,
+ perUidLossInfo.mLastLossTsNanos);
+ for (const auto& counterInfo : perUidLossInfo.mLossCountPerErrorAtomId) {
+ uint64_t token =
+ proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_ATOM_ID_LOSS_STATS |
+ FIELD_COUNT_REPEATED);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_ATOM_ID,
+ counterInfo.mAtomId);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_ERROR, counterInfo.mError);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_COUNT, counterInfo.mCount);
+ proto.end(token);
+ }
+ proto.end(token);
+ }
+
+ // socket loss stats overflow counters
+ for (const auto& overflowInfo : mSocketLossStatsOverflowCounters) {
+ uint64_t token =
+ proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS |
+ FIELD_COUNT_REPEATED);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_UID,
+ overflowInfo.first);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_COUNT,
+ overflowInfo.second);
+ proto.end(token);
+ }
+
+ proto.end(socketLossStatsToken);
+
output->clear();
proto.serializeToVector(output);
diff --git a/statsd/src/guardrail/StatsdStats.h b/statsd/src/guardrail/StatsdStats.h
index adf9c49b..c7ca8d0c 100644
--- a/statsd/src/guardrail/StatsdStats.h
+++ b/statsd/src/guardrail/StatsdStats.h
@@ -273,7 +273,7 @@ public:
static const int kMaxPushedAtomErrorStatsSize = 100;
// Maximum number of socket loss stats to track.
- static const int kMaxSocketLossStatsSize = 100;
+ static const int kMaxSocketLossStatsSize = 50;
// Maximum atom id value that we consider a platform pushed atom.
// This should be updated once highest pushed atom id in atoms.proto approaches this value.
@@ -855,15 +855,35 @@ private:
std::map<int, int> mPushedAtomErrorStats;
// Stores the number of times a pushed atom was lost due to socket error.
- // Represents counter per uid per tag per error
- // The max size of this map is kMaxSocketLossStatsSize.
- std::map<std::tuple<int32_t, int32_t, int32_t>, int32_t> mSocketLossStats;
+ // Represents counter per uid per tag per error with indication when the loss event was observed
+ // first & last time.
+ struct SocketLossStats {
+ SocketLossStats(int32_t uid, int64_t firstLossTsNanos, int64_t lastLossTsNanos)
+ : mUid(uid), mFirstLossTsNanos(firstLossTsNanos), mLastLossTsNanos(lastLossTsNanos) {
+ }
+
+ int32_t mUid;
+ int64_t mFirstLossTsNanos;
+ int64_t mLastLossTsNanos;
+ // atom loss count per error, atom id
+ struct AtomLossInfo {
+ AtomLossInfo(int32_t atomId, int32_t error, int32_t count)
+ : mAtomId(atomId), mError(error), mCount(count) {
+ }
+ int mAtomId;
+ int mError;
+ int mCount;
+ };
+ std::vector<AtomLossInfo> mLossCountPerErrorAtomId;
+ };
+ // The max size of this list is kMaxSocketLossStatsSize.
+ std::list<SocketLossStats> mSocketLossStats;
- // Stores the number of times a pushed atom loss info was dropped to be added into stats
+ // Stores the number of times a pushed atom loss info was dropped from the stats
// on libstatssocket side due to guardrail hit.
// Represents counter per uid.
// The max size of this map is kMaxSocketLossStatsSize.
- std::map<int32_t, int32_t> mSocketLossStatsOverflowCounter;
+ std::map<int32_t, int32_t> mSocketLossStatsOverflowCounters;
// Maps metric ID to its stats. The size is capped by the number of metrics.
std::map<int64_t, AtomMetricStats> mAtomMetricStats;
@@ -1019,6 +1039,8 @@ private:
FRIEND_TEST(StatsdStatsTest, TestSubscriptionPullThreadWakeup);
FRIEND_TEST(StatsdStatsTest, TestSubscriptionStartedMaxActiveSubscriptions);
FRIEND_TEST(StatsdStatsTest, TestSubscriptionStartedRemoveFinishedSubscription);
+ FRIEND_TEST(StatsdStatsTest, TestSocketLossStats);
+ FRIEND_TEST(StatsdStatsTest, TestSocketLossStatsOverflowCounter);
FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
};