1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <stdint.h>
8 #include <unistd.h>
9 
10 #include <cobalt-client/cpp/metric-options.h>
11 #include <cobalt-client/cpp/types-internal.h>
12 
13 #include <fbl/function.h>
14 #include <fbl/string.h>
15 #include <fbl/vector.h>
16 #ifdef __Fuchsia__
17 #include <lib/zx/time.h>
18 #include <lib/zx/vmo.h>
19 #endif
20 
21 #include <atomic>
22 #include <memory>
23 
24 namespace cobalt_client {
25 
26 // Defines the options for initializing the Collector.
27 struct CollectorOptions {
28     // Returns a |Collector| whose data will be logged for GA release stage.
29     static CollectorOptions GeneralAvailability();
30 
31     // Returns a |Collector| whose data will be logged for Dogfood release stage.
32     static CollectorOptions Dogfood();
33 
34     // Returns a |Collector| whose data will be logged for Fishfood release stage.
35     static CollectorOptions Fishfood();
36 
37     // Returns a |Collector| whose data will be logged for Debug release stage.
38     static CollectorOptions Debug();
39 
40 #ifdef __Fuchsia__
41     // Callback used when reading the config to create a cobalt logger.
42     // Returns true when the write was successful. The VMO will be transferred
43     // to the cobalt service.
44     fbl::Function<bool(zx::vmo*, size_t*)> load_config = nullptr;
45 
46     // Configuration for RPC behavior for remote metrics.
47     // Only set if you plan to interact with cobalt service.
48 
49     // When registering with cobalt, will block for this amount of time, each
50     // time we need to reach cobalt, until the response is received.
51     zx::duration response_deadline = zx::duration(0);
52 
53     // When registering with cobalt, will block for this amount of time, the first
54     // time we need to wait for a response.
55     zx::duration initial_response_deadline = zx::duration(0);
56 #endif
57     // This is set internally by factory functions.
58     uint32_t release_stage = 0;
59 };
60 
61 // This class acts as a peer for instantiating Histograms and Counters. All
62 // objects instantiated through this class act as a view, which means that
63 // their lifetime is coupled to this object's lifetime. This class does require
64 // the number of different configurations on construction.
65 //
66 // The Sink provides an API for persisting the supported data types. This is
67 // exposed to simplify testing.
68 //
69 // This class is not moveable, copyable or assignable.
70 // This class is thread-compatible.
71 class Collector {
72 public:
73     Collector(CollectorOptions options);
74     Collector(std::unique_ptr<internal::Logger> logger);
75     Collector(const Collector&) = delete;
76     Collector(Collector&&) = delete;
77     Collector& operator=(const Collector&) = delete;
78     Collector& operator=(Collector&&) = delete;
79     ~Collector();
80 
81     // Allows classes implementing |internal::FlushInterface| to subscribe for Flush events.
Subscribe(internal::FlushInterface * flushable)82     void Subscribe(internal::FlushInterface* flushable) { flushables_.push_back(flushable); }
83 
84     // Allows classes implementing |internal::FlushInterface| to UnSubscribe for Flush events.
85     void UnSubscribe(internal::FlushInterface* flushable);
86 
87     // Flushes the content of all flushable metrics into |logger_|. The |logger_| is
88     // in charge of persisting the data.
89     void Flush();
90 
91 private:
92     // Convert this into a HashTable.
93     fbl::Vector<internal::FlushInterface*> flushables_;
94 
95     std::unique_ptr<internal::Logger> logger_ = nullptr;
96     std::atomic<bool> flushing_ = false;
97 };
98 
99 } // namespace cobalt_client
100