Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69007c82 authored by yro's avatar yro
Browse files

Implement a logic to rate limitted flush statsd with by checking the

size of each MetricsProducer's. The implementation of byteSize() method
is still TBD as it depends on migration to ProtoOutputStream.

Test: statsd, statsd_test
Change-Id: I966606044d7cb814dabe94192bacecad91f28177
parent a17d0ac3
Loading
Loading
Loading
Loading
+23 −23
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ void StatsLogProcessor::OnLogEvent(const LogEvent& msg) {
    // pass the event to metrics managers.
    for (auto& pair : mMetricsManagers) {
        pair.second->onLogEvent(msg);
        flushIfNecessary(msg.GetTimestampNs(), pair.first, pair.second);
    }
}

@@ -84,41 +85,40 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
        it->second->finish();
        mMetricsManagers.erase(it);
    }
    auto flushTime = mLastFlushTimes.find(key);
    if (flushTime != mLastFlushTimes.end()) {
        mLastFlushTimes.erase(flushTime);
    }
}

void StatsLogProcessor::addEventMetricData(const EventMetricData& eventMetricData) {
    // TODO: Replace this code when MetricsManager.onDumpReport() is ready to
    // get a list of byte arrays.
    flushIfNecessary(eventMetricData);
    const int numBytes = eventMetricData.ByteSize();
    char buffer[numBytes];
    eventMetricData.SerializeToArray(&buffer[0], numBytes);
    string bufferString(buffer, numBytes);
    mEvents.push_back(bufferString);
    mBufferSize += eventMetricData.ByteSize();
void StatsLogProcessor::flushIfNecessary(uint64_t timestampNs,
                                         const ConfigKey& key,
                                         const unique_ptr<MetricsManager>& metricsManager) {
    auto lastFlushNs = mLastFlushTimes.find(key);
    if (lastFlushNs != mLastFlushTimes.end()) {
        if (timestampNs - lastFlushNs->second < kMinFlushPeriod) {
            return;
        }
    }

void StatsLogProcessor::flushIfNecessary(const EventMetricData& eventMetricData) {
    if (eventMetricData.ByteSize() + mBufferSize > kMaxSerializedBytes) {
    size_t totalBytes = metricsManager->byteSize();
    if (totalBytes > kMaxSerializedBytes) {
        flush();
        mLastFlushTimes[key] = std::move(timestampNs);
    }
}

void StatsLogProcessor::flush() {
    // TODO: Take ConfigKey as an argument and flush metrics related to the
    // ConfigKey. Also, create a wrapper that holds a repeated field of
    // StatsLogReport's.
    /*
    StatsLogReport logReport;
    for (string eventBuffer : mEvents) {
        EventMetricData eventFromBuffer;
        eventFromBuffer.ParseFromString(eventBuffer);
        EventMetricData* newEntry = logReport.mutable_event_metrics()->add_data();
        newEntry->CopyFrom(eventFromBuffer);
    }

    const int numBytes = logReport.ByteSize();
    vector<uint8_t> logReportBuffer(numBytes);
    logReport.SerializeToArray(&logReportBuffer[0], numBytes);
    mPushLog(logReportBuffer);
    mEvents.clear();
    mBufferSize = 0;
    */
}

}  // namespace statsd
+9 −15
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ public:
private:
    std::unordered_map<ConfigKey, std::unique_ptr<MetricsManager>> mMetricsManagers;

    std::unordered_map<ConfigKey, long> mLastFlushTimes;

    sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.

    /* Max *serialized* size of the logs kept in memory before flushing through binder call.
@@ -59,25 +61,17 @@ private:
     */
    static const size_t kMaxSerializedBytes = 16 * 1024;

    /* List of data that was captured for a single metric over a given interval of time. */
    vector<string> mEvents;

    /* Current *serialized* size of the logs kept in memory.
       To save computation, we will not calculate the size of the StatsLogReport every time when a
       new entry is added, which would recursively call ByteSize() on every log entry. Instead, we
       keep the sum of all individual stats log entry sizes. The size of a proto is approximately
       the sum of the size of all member protos.
     */
    size_t mBufferSize = 0;

    /* Check if the buffer size exceeds the max buffer size when the new entry is added, and flush
       the logs to callback clients if true. */
    void flushIfNecessary(const EventMetricData& eventMetricData);

    /* Append event metric data to StatsLogReport. */
    void addEventMetricData(const EventMetricData& eventMetricData);
    void flushIfNecessary(uint64_t timestampNs,
                          const ConfigKey& key,
                          const unique_ptr<MetricsManager>& metricsManager);

    std::function<void(const vector<uint8_t>&)> mPushLog;

    /* Minimum period between two flushes in nanoseconds. Currently set to 10
     * minutes. */
    static const unsigned long long kMinFlushPeriod = 600 * NS_PER_SEC;
};

}  // namespace statsd
+8 −1
Original line number Diff line number Diff line
@@ -203,6 +203,13 @@ void CountMetricProducer::flushCounterIfNeeded(const uint64_t eventTimeNs) {
         (long long)mCurrentBucketStartTimeNs);
}

size_t CountMetricProducer::byteSize() {
// TODO: return actual proto size when ProtoOutputStream is ready for use for
// CountMetricsProducer.
//    return mProto->size();
    return 0;
}

}  // namespace statsd
}  // namespace os
}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public:

    void onSlicedConditionMayChange() override;

    size_t byteSize() override;

    // TODO: Implement this later.
    virtual void notifyAppUpgrade(const string& apk, const int uid, const int version) override{};

+7 −0
Original line number Diff line number Diff line
@@ -349,6 +349,13 @@ void DurationMetricProducer::flushDurationIfNeeded(const uint64_t eventTime) {
    }
}

size_t DurationMetricProducer::byteSize() {
// TODO: return actual proto size when ProtoOutputStream is ready for use for
// DurationMetricsProducer.
//    return mProto->size();
  return 0;
}

}  // namespace statsd
}  // namespace os
}  // namespace android
Loading