Dump the stats for count/gauge/value metrics.

Bug: b/74159560

Test: statsd test
Change-Id: I1410309ecfdfc2a5becf8d0c620c68a621ebc5fa
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 22b2a30..2b187b2 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -99,6 +99,24 @@
     VLOG("~CountMetricProducer() called");
 }
 
+void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+    if (mCurrentSlicedCounter == nullptr ||
+        mCurrentSlicedCounter->size() == 0) {
+        return;
+    }
+
+    fprintf(out, "CountMetric %lld dimension size %lu\n", (long long)mMetricId,
+            (unsigned long)mCurrentSlicedCounter->size());
+    if (verbose) {
+        for (const auto& it : *mCurrentSlicedCounter) {
+            fprintf(out, "\t(what)%s\t(condition)%s  %lld\n",
+                it.first.getDimensionKeyInWhat().toString().c_str(),
+                it.first.getDimensionKeyInCondition().toString().c_str(),
+                (unsigned long long)it.second);
+        }
+    }
+}
+
 void CountMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
     VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
 }
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 1d8e42b..d9f2c4c 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -67,7 +67,7 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
-    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+    void dumpStatesLocked(FILE* out, bool verbose) const override;
 
     void dropDataLocked(const uint64_t dropTimeNs) override;
 
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index e479e5c..a8f80d9 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -126,6 +126,24 @@
     }
 }
 
+void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+    if (mCurrentSlicedBucket == nullptr ||
+        mCurrentSlicedBucket->size() == 0) {
+        return;
+    }
+
+    fprintf(out, "GaugeMetric %lld dimension size %lu\n", (long long)mMetricId,
+            (unsigned long)mCurrentSlicedBucket->size());
+    if (verbose) {
+        for (const auto& it : *mCurrentSlicedBucket) {
+            fprintf(out, "\t(what)%s\t(condition)%s  %d atoms\n",
+                it.first.getDimensionKeyInWhat().toString().c_str(),
+                it.first.getDimensionKeyInCondition().toString().c_str(),
+                (int)it.second.size());
+        }
+    }
+}
+
 void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
                                              ProtoOutputStream* protoOutput) {
     VLOG("gauge metric %lld report now...", (long long)mMetricId);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index ca8dc75..b9e67de 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -106,7 +106,7 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
-    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+    void dumpStatesLocked(FILE* out, bool verbose) const override;
 
     void dropDataLocked(const uint64_t dropTimeNs) override;
 
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 09913dc..079aea5 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -243,6 +243,23 @@
     }
 }
 
+void ValueMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+    if (mCurrentSlicedBucket.size() == 0) {
+        return;
+    }
+
+    fprintf(out, "ValueMetric %lld dimension size %lu\n", (long long)mMetricId,
+            (unsigned long)mCurrentSlicedBucket.size());
+    if (verbose) {
+        for (const auto& it : mCurrentSlicedBucket) {
+            fprintf(out, "\t(what)%s\t(condition)%s  (value)%lld\n",
+                it.first.getDimensionKeyInWhat().toString().c_str(),
+                it.first.getDimensionKeyInCondition().toString().c_str(),
+                (unsigned long long)it.second.sum);
+        }
+    }
+}
+
 bool ValueMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
     // ===========GuardRail==============
     // 1. Report the tuple count if the tuple count > soft limit
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 5e42bd2..cc2309b 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -99,7 +99,7 @@
     // Internal function to calculate the current used bytes.
     size_t byteSizeLocked() const override;
 
-    void dumpStatesLocked(FILE* out, bool verbose) const override{};
+    void dumpStatesLocked(FILE* out, bool verbose) const override;
 
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& eventTime) override;