178 lines
6.1 KiB
C++
178 lines
6.1 KiB
C++
// Copyright 2022 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef COMPONENTS_METRICS_METRICS_SERVICE_OBSERVER_H_
|
|
#define COMPONENTS_METRICS_METRICS_SERVICE_OBSERVER_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/callback_list.h"
|
|
#include "base/containers/flat_map.h"
|
|
#include "base/files/file_path.h"
|
|
#include "base/strings/string_piece.h"
|
|
#include "components/metrics/metrics_logs_event_manager.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
|
|
namespace metrics {
|
|
|
|
// Observes logs generated by a metrics collection system (UMA and UKM) and
|
|
// stores them in-memory. This class also provides a way to export the logs in a
|
|
// JSON format, which includes metadata, proto data, as well as the events
|
|
// describing the lifecycle of the logs.
|
|
class MetricsServiceObserver : public MetricsLogsEventManager::Observer {
|
|
public:
|
|
// Possible metrics service types.
|
|
enum class MetricsServiceType {
|
|
UMA,
|
|
UKM,
|
|
};
|
|
|
|
// Represents a log and its data. Exposed for testing.
|
|
struct Log {
|
|
// Represents an event that occurred on the log. An optional message may
|
|
// be associated with the event. For example, the event may be
|
|
// |kLogTrimmed|, with |message| being "Log size too large".
|
|
struct Event {
|
|
Event();
|
|
|
|
Event(const Event&);
|
|
Event& operator=(const Event&);
|
|
|
|
~Event();
|
|
|
|
// The type of event.
|
|
MetricsLogsEventManager::LogEvent event;
|
|
|
|
// The timestamp at which the event occurred. This is the number of
|
|
// milliseconds since Epoch.
|
|
double timestampMs;
|
|
|
|
// An optional message associated with the event.
|
|
absl::optional<std::string> message;
|
|
};
|
|
|
|
Log();
|
|
|
|
Log(const Log&);
|
|
Log& operator=(const Log&);
|
|
|
|
~Log();
|
|
|
|
// The SHA1 hash of the log's data, used to uniquely identify it.
|
|
std::string hash;
|
|
|
|
// The time at which the log was closed. This is the number of seconds since
|
|
// Epoch.
|
|
std::string timestamp;
|
|
|
|
// The log's compressed (gzipped) serialized protobuf.
|
|
std::string data;
|
|
|
|
// A list of the events that occurred throughout the log's lifetime.
|
|
std::vector<Event> events;
|
|
|
|
// The type of log (stability, ongoing, independent). This is only set if
|
|
// this log is a UMA log.
|
|
absl::optional<MetricsLog::LogType> type;
|
|
};
|
|
|
|
// |service_type| is the type of service this observer will be observing from.
|
|
explicit MetricsServiceObserver(MetricsServiceType service_type);
|
|
|
|
MetricsServiceObserver(const MetricsServiceObserver&) = delete;
|
|
MetricsServiceObserver& operator=(const MetricsServiceObserver&) = delete;
|
|
|
|
~MetricsServiceObserver() override;
|
|
|
|
// MetricsLogsEventManager::Observer:
|
|
void OnLogCreated(
|
|
base::StringPiece log_hash,
|
|
base::StringPiece log_data,
|
|
base::StringPiece log_timestamp,
|
|
metrics::MetricsLogsEventManager::CreateReason reason) override;
|
|
void OnLogEvent(MetricsLogsEventManager::LogEvent event,
|
|
base::StringPiece log_hash,
|
|
base::StringPiece message) override;
|
|
void OnLogType(absl::optional<MetricsLog::LogType> log_type) override;
|
|
|
|
// Exports |logs_| to a JSON string and writes it to |json_output|. If
|
|
// |include_log_proto_data| is true, the protos of the logs will be included.
|
|
// The format of the JSON object is as follows:
|
|
//
|
|
// {
|
|
// logType: string, // e.g. "UMA" or "UKM"
|
|
// logs: [
|
|
// {
|
|
// type?: string, // e.g. "Ongoing" (set only for UMA logs)
|
|
// hash: string,
|
|
// timestamp: string,
|
|
// data: string, // set if |include_log_proto_data| is true
|
|
// size: number,
|
|
// events: [
|
|
// {
|
|
// event: string, // e.g. "Trimmed"
|
|
// timestamp: number,
|
|
// message?: string
|
|
// },
|
|
// ...
|
|
// ]
|
|
// },
|
|
// ...
|
|
// ]
|
|
// }
|
|
//
|
|
// The "hash" field is the hex representation of the log's hash. The
|
|
// "data" field is a base64 encoding of the log's compressed (gzipped)
|
|
// serialized protobuf. The "size" field is the size (in bytes) of the log.
|
|
bool ExportLogsAsJson(bool include_log_proto_data, std::string* json_output);
|
|
|
|
// Exports logs data (see ExportLogsAsJson() above) to the passed |path|. If
|
|
// the file pointed by |path| does not exist, it will be created. If it
|
|
// already exists, its contents will be overwritten.
|
|
void ExportLogsToFile(const base::FilePath& path);
|
|
|
|
// Registers a callback. This callback will be run every time this observer is
|
|
// notified through OnLogCreated() or OnLogEvent(). When the returned
|
|
// CallbackListSubscription is destroyed, the callback is automatically
|
|
// de-registered.
|
|
[[nodiscard]] base::CallbackListSubscription AddNotifiedCallback(
|
|
base::RepeatingClosure callback);
|
|
|
|
// Returns |logs_|.
|
|
std::vector<std::unique_ptr<Log>>* logs_for_testing() { return &logs_; }
|
|
|
|
private:
|
|
// Returns the Log object from |logs_| with the given |log_hash| if one
|
|
// exists. Returns nullptr otherwise.
|
|
Log* GetLogFromHash(base::StringPiece log_hash);
|
|
|
|
// The type of service this observer is observing. This has no impact on how
|
|
// the logs are stored. This is only used when exporting the logs (see
|
|
// ExportLogsAsJson() above) so that the type of logs is easily identifiable.
|
|
const MetricsServiceType service_type_;
|
|
|
|
// The list of logs that are being kept track of. It is a vector so that we
|
|
// can keep the ordering of the logs as they are inserted.
|
|
std::vector<std::unique_ptr<Log>> logs_;
|
|
|
|
// An overlay on |logs_| that allows for a log to be located based on its
|
|
// hash.
|
|
base::flat_map<base::StringPiece, Log*> indexed_logs_;
|
|
|
|
// Keeps track of the type of UMA logs (ongoing, stability, independent) that
|
|
// are being created. This should only be set for UMA logs, since the concept
|
|
// of log type only exists in UMA.
|
|
absl::optional<MetricsLog::LogType> uma_log_type_;
|
|
|
|
// List of callbacks to run whenever this observer is notified. Note that
|
|
// OnLogType() will not trigger the callbacks.
|
|
base::RepeatingClosureList notified_callbacks_;
|
|
};
|
|
|
|
} // namespace metrics
|
|
|
|
#endif // COMPONENTS_METRICS_METRICS_SERVICE_OBSERVER_H_
|