blob: b39d01ad91b981fdbcd6609eccce51e532625705 [file] [log] [blame]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef METRICS_METRICS_WRITER_H_
#define METRICS_METRICS_WRITER_H_
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_refptr.h>
#include <base/task/sequenced_task_runner.h>
#include "metrics/serialization/metric_sample.h"
constexpr char kUMAEventsPath[] = "/var/lib/metrics/uma-events";
// Logs UMA metrics to metrics file.
class MetricsWriter : public base::RefCountedThreadSafe<MetricsWriter> {
public:
MetricsWriter() = default;
MetricsWriter(const MetricsWriter&) = delete;
MetricsWriter& operator=(const MetricsWriter&) = delete;
// Write the metrics to the file.
virtual bool WriteMetrics(std::vector<metrics::MetricSample> samples) = 0;
// Change the output file path.
virtual bool SetOutputFile(const std::string& output_file) = 0;
protected:
friend class base::RefCountedThreadSafe<MetricsWriter>;
virtual ~MetricsWriter() = default;
};
// Write UMA metrics using `metrics::SerializationUtils::WriteMetricsToFile` on
// the caller thread.
//
// It acquires a file lock to write logs so that this may block the thread for
// non-trivial time. This writer can use a nonblocking file lock by setting
// `use_nonblocking_lock` to true. Note that using a nonblocking lock will
// result in dropped metrics if the lock could not be grabbed.
//
// This class is not thread-safe.
class SynchronousMetricsWriter : public MetricsWriter {
public:
explicit SynchronousMetricsWriter(
bool use_nonblocking_lock = false,
base::FilePath uma_events_file = base::FilePath(kUMAEventsPath));
bool WriteMetrics(std::vector<metrics::MetricSample> samples) override;
bool SetOutputFile(const std::string& output_file) override;
private:
friend class CMetricsLibraryTest;
friend class MetricsLibraryTest;
// Whether or not to use a nonblocking lock when calling `WriteMetrics()`.
bool use_nonblocking_lock_;
base::FilePath uma_events_file_;
};
// Write UMA metrics using `metrics::SerializationUtils::WriteMetricsToFile` on
// `base::SequencedTaskRunner` sequentially.
//
// The destructor waits until all metrics requested are written into the file by
// default. You can skip the waiting on the destructor by passing false
// `wait_on_destructor` at constructor and manually waits for all metrics
// flushed by `WaitUntilFlushed()`.
//
// This class is thread-safe.
class AsynchronousMetricsWriter : public MetricsWriter {
public:
// Creates AsynchronousMetricsWriter.
//
// `task_runner` should be passed to specify on which thread will the writer
// be executed. The thread may be blocked for a long time by this writer.
//
// If you explicitly set false to `wait_on_destructor`, you should call
// `WaitUntilFlushed()` after all write are requested. Otherwise enqueued
// metrics can be lost.
//
// `uma_events_file` specifies the metrics output file path.
explicit AsynchronousMetricsWriter(
scoped_refptr<base::SequencedTaskRunner> task_runner,
bool wait_on_destructor = true,
base::FilePath uma_events_file = base::FilePath(kUMAEventsPath));
// Dispatch a request to the background thread to log the metrics to the file.
// Returns false if it fails to dispatch.
bool WriteMetrics(std::vector<metrics::MetricSample> samples) override;
// Change the output file path. Metrics requested before this call are
// written into the previous output file.
bool SetOutputFile(const std::string& output_file) override;
// Wait until all metrics requested before this call are written into the
// output file.
void WaitUntilFlushed();
private:
~AsynchronousMetricsWriter() override;
void WriteMetricsOnThread(std::vector<metrics::MetricSample> samples);
void SetOutputFileOnThread(base::FilePath output_file);
scoped_refptr<base::SequencedTaskRunner> task_runner_;
const bool wait_on_destructor_;
base::FilePath uma_events_file_;
base::WeakPtrFactory<AsynchronousMetricsWriter> weak_ptr_factory_{this};
};
#endif // METRICS_METRICS_WRITER_H_