File: metrics_service_observer.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (177 lines) | stat: -rw-r--r-- 6,264 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 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_