• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_METRICS_STRUCTURED_FLUSHED_MAP_H_
6 #define COMPONENTS_METRICS_STRUCTURED_FLUSHED_MAP_H_
7 
8 #include <cstdint>
9 #include <functional>
10 #include <optional>
11 #include <string>
12 #include <vector>
13 
14 #include "base/memory/scoped_refptr.h"
15 #include "base/timer/timer.h"
16 #include "base/types/expected.h"
17 #include "components/metrics/structured/lib/event_buffer.h"  // EventBuffer and FlushError
18 #include "components/metrics/structured/lib/resource_info.h"
19 #include "components/metrics/structured/proto/event_storage.pb.h"
20 #include "third_party/metrics_proto/structured_data.pb.h"
21 
22 namespace base {
23 class FilePath;
24 class SequencedTaskRunner;
25 }  // namespace base
26 
27 namespace metrics::structured {
28 
29 // Manages the reading and writing of events written to disk. All write
30 // operations are enqueued to the same task runner.
31 //
32 // Writing a flushed file is performed asynchronously while reading is performed
33 // synchronously. This is because the Flush API is designed to be called from
34 // the UI thread where blocking operations are not allowed. The Read API
35 // is intended to be called from an IO task while final logs are prepared.
36 //
37 // When an EventBuffer is flushed, a FlushedKey is used to represent the on-disk
38 // data and provide some metadata about what is stored. This key is then used to
39 // read or delete the events.
40 //
41 // All events that have been flushed to disk are considered ready to be
42 // uploaded.
43 class FlushedMap {
44  public:
45   FlushedMap(const base::FilePath& flushed_dir, uint64_t max_size_bytes);
46 
47   ~FlushedMap();
48 
49   // Deletes all flushed events from disk.
50   void Purge();
51 
52   // Flushes |buffer| to disk. A key is returned that is used to identify the
53   // on-disk events.
54   //
55   // |buffer| defines how the flushing occurs.
56   void Flush(EventBuffer<StructuredEventProto>& buffer,
57              FlushedCallback callback);
58 
59   // Reads the events stored at |key|.
60   std::optional<EventsProto> ReadKey(const FlushedKey& key) const;
61 
62   // Deletes the events of |key|.
63   void DeleteKey(const FlushedKey& key);
64 
65   void DeleteKeys(const std::vector<FlushedKey>& keys);
66 
keys()67   const std::vector<FlushedKey>& keys() const { return keys_; }
68 
resource_info()69   const ResourceInfo& resource_info() const { return resource_info_; }
70 
empty()71   bool empty() const { return keys().empty(); }
72 
73  private:
74   // Generates a new path under |flushed_dir_| to store the events. The
75   // filename is generated using UUID.
76   base::FilePath GenerateFilePath() const;
77 
78   // Starts a task that builds the list of in-memory keys.
79   void LoadKeysFromDir(const base::FilePath& dir);
80 
81   // Traverses |dir| building a list of keys.
82   //
83   // It is assumed that all of the files in |dir| store serialized EventsProtos.
84   void BuildKeysFromDir(const base::FilePath& dir);
85 
86   // Flushed map operations that need to be handled post flush.
87   void OnFlushed(FlushedCallback callback,
88                  base::expected<FlushedKey, FlushError> key);
89 
90   // The directory where events are flushed.
91   base::FilePath flushed_dir_;
92 
93   // List of all the keys for flushed events.
94   std::vector<FlushedKey> keys_;
95 
96   // Manages the amount of resource used by |this|.
97   ResourceInfo resource_info_;
98 
99   scoped_refptr<base::SequencedTaskRunner> task_runner_;
100 
101   base::WeakPtrFactory<FlushedMap> weak_factory_{this};
102 };
103 }  // namespace metrics::structured
104 
105 #endif  // COMPONENTS_METRICS_STRUCTURED_FLUSHED_MAP_H_
106