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