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 #include <cobalt-client/cpp/collector.h> 6 #include <cobalt-client/cpp/counter-internal.h> 7 #include <cobalt-client/cpp/histogram-internal.h> 8 #include <cobalt-client/cpp/metric-options.h> 9 #include <cobalt-client/cpp/types-internal.h> 10 11 #ifdef __Fuchsia__ 12 #include <cobalt-client/cpp/collector-internal.h> 13 14 #include <fuchsia/cobalt/c/fidl.h> 15 #include <lib/fdio/util.h> 16 #include <lib/fidl/cpp/vector_view.h> 17 #include <lib/zx/channel.h> 18 #endif 19 20 #include <utility> 21 22 namespace cobalt_client { 23 namespace internal { 24 namespace { 25 26 #ifdef __Fuchsia__ MakeCobaltOptions(CollectorOptions options)27internal::CobaltOptions MakeCobaltOptions(CollectorOptions options) { 28 ZX_DEBUG_ASSERT_MSG(options.load_config, "Must define a load_config function."); 29 internal::CobaltOptions cobalt_options; 30 cobalt_options.logger_deadline_first_attempt = options.initial_response_deadline; 31 cobalt_options.logger_deadline = options.response_deadline; 32 cobalt_options.config_reader = std::move(options.load_config); 33 cobalt_options.service_connect = [](const char* service_path, 34 zx::channel service) -> zx_status_t { 35 return fdio_service_connect(service_path, service.release()); 36 }; 37 cobalt_options.service_path.AppendPrintf("/svc/%s", fuchsia_cobalt_LoggerFactory_Name); 38 cobalt_options.release_stage = static_cast<internal::ReleaseStage>(options.release_stage); 39 return cobalt_options; 40 } 41 #else 42 // Host side implementation, which does nothing, just provides safety that all methods wont 43 // fault. 44 class HostLogger : public internal::Logger { 45 public: 46 ~HostLogger() override = default; 47 48 bool Log(const RemoteMetricInfo& remote_info, const HistogramBucket* buckets, 49 size_t num_buckets) override { 50 return true; 51 }; 52 53 bool Log(const RemoteMetricInfo& remote_info, int64_t count) override { return true; }; 54 }; 55 #endif // __Fuchsia__ 56 } // namespace 57 } // namespace internal 58 59 #ifdef __Fuchsia__ Collector(CollectorOptions options)60Collector::Collector(CollectorOptions options) 61 : logger_(std::make_unique<internal::CobaltLogger>( 62 internal::MakeCobaltOptions(std::move(options)))) { 63 flushing_.store(false); 64 } 65 #else Collector(CollectorOptions options)66Collector::Collector(CollectorOptions options) : logger_(std::make_unique<internal::HostLogger>()) { 67 flushing_.store(false); 68 } 69 #endif // __Fuchsia__ 70 Collector(std::unique_ptr<internal::Logger> logger)71Collector::Collector(std::unique_ptr<internal::Logger> logger) : logger_(std::move(logger)) { 72 flushing_.store(false); 73 } 74 ~Collector()75Collector::~Collector() { 76 if (logger_ != nullptr) { 77 Flush(); 78 } 79 }; 80 Flush()81void Collector::Flush() { 82 // If we are already flushing we just return and do nothing. 83 // First come first serve. 84 if (flushing_.exchange(true)) { 85 return; 86 } 87 88 for (internal::FlushInterface* flushable : flushables_) { 89 if (!flushable->Flush(logger_.get())) { 90 flushable->UndoFlush(); 91 } 92 } 93 94 // Once we are finished we allow flushing again. 95 flushing_.store(false); 96 } 97 UnSubscribe(internal::FlushInterface * flushable)98void Collector::UnSubscribe(internal::FlushInterface* flushable) { 99 // TODO(gevalentino): Replace the vector for an unordered_map/hash_map. 100 for (size_t i = 0; i < flushables_.size(); ++i) { 101 if (flushable == flushables_[i]) { 102 flushables_.erase(i); 103 break; 104 } 105 } 106 } 107 GeneralAvailability()108CollectorOptions CollectorOptions::GeneralAvailability() { 109 CollectorOptions options; 110 options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kGa); 111 return options; 112 } 113 Dogfood()114CollectorOptions CollectorOptions::Dogfood() { 115 CollectorOptions options; 116 options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kDogfood); 117 return options; 118 } 119 Fishfood()120CollectorOptions CollectorOptions::Fishfood() { 121 CollectorOptions options; 122 options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kFishfood); 123 return options; 124 } 125 Debug()126CollectorOptions CollectorOptions::Debug() { 127 CollectorOptions options; 128 options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kDebug); 129 return options; 130 } 131 132 } // namespace cobalt_client 133