| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // The cobalt system metrics collection daemon uses cobalt to log system metrics |
| // on a regular basis. |
| |
| #ifndef SRC_COBALT_BIN_SYSTEM_METRICS_SYSTEM_METRICS_DAEMON_H_ |
| #define SRC_COBALT_BIN_SYSTEM_METRICS_SYSTEM_METRICS_DAEMON_H_ |
| |
| #include <fuchsia/cobalt/cpp/fidl.h> |
| #include <lib/async/dispatcher.h> |
| #include <lib/sys/cpp/component_context.h> |
| |
| #include <chrono> |
| #include <memory> |
| #include <thread> |
| #include <vector> |
| |
| #include "src/cobalt/bin/system-metrics/cpu_stats_fetcher.h" |
| #include "src/cobalt/bin/system-metrics/memory_stats_fetcher.h" |
| #include "src/cobalt/bin/system-metrics/metrics_registry.cb.h" |
| #include "src/cobalt/bin/utils/clock.h" |
| |
| // A daemon to send system metrics to Cobalt. |
| // |
| // Usage: |
| // |
| // async::Loop loop(&kAsyncLoopConfigAttachToThread); |
| // std::unique_ptr<sys::ComponentContext> context( |
| // sys::ComponentContext::Create()); |
| // SystemMetricsDaemon daemon(loop.dispatcher(), context.get()); |
| // daemon.StartLogging(); |
| // loop.Run(); |
| class SystemMetricsDaemon { |
| public: |
| // Constructor |
| // |
| // |dispatcher|. This is used to schedule future work. |
| // |
| // |context|. The Cobalt LoggerFactory interface is fetched from this context. |
| SystemMetricsDaemon(async_dispatcher_t* dispatcher, |
| sys::ComponentContext* context); |
| |
| // Starts asynchronously logging all system metrics. |
| void StartLogging(); |
| |
| private: |
| friend class SystemMetricsDaemonTest; |
| |
| // This private constructor is intended for use in tests. |context| may |
| // be null because InitializeLogger() will not be invoked. Instead, |
| // pass a non-null |logger| which may be a local mock that does not use FIDL. |
| SystemMetricsDaemon( |
| async_dispatcher_t* dispatcher, sys::ComponentContext* context, |
| fuchsia::cobalt::Logger_Sync* logger, |
| std::unique_ptr<cobalt::SteadyClock> clock, |
| std::unique_ptr<cobalt::MemoryStatsFetcher> memory_stats_fetcher, |
| std::unique_ptr<cobalt::CpuStatsFetcher> cpu_stats_fetcher); |
| |
| void InitializeLogger(); |
| |
| void InitializeRootResourceHandle(); |
| |
| // Calls LogUpTimeAndLifeTimeEvents, |
| // and then uses the |dispatcher| passed to the constructor to |
| // schedule the next round. |
| void RepeatedlyLogUpTimeAndLifeTimeEvents(); |
| |
| // Calls LogMemoryUsage, |
| // then uses the |dispatcher| passed to the constructor to schedule |
| // the next round. |
| void RepeatedlyLogMemoryUsage(); |
| |
| // Calls LogCpuUsage, |
| // then uses the |dispatcher| passed to the constructor to schedule |
| // the next round. |
| void RepeatedlyLogCpuUsage(); |
| |
| // Returns the amount of time since SystemMetricsDaemon started. |
| std::chrono::seconds GetUpTime(); |
| |
| // Calls LogFuchsiaUpPing and LogFuchsiaLifetimeEvents. |
| // |
| // Returns the amount of time before this method needs to be invoked again. |
| std::chrono::seconds LogUpTimeAndLifeTimeEvents(); |
| |
| // Logs one or more UpPing events depending on how long the device has been |
| // up. |
| // |
| // |uptime| An estimate of how long since device boot time. |
| // |
| // First the "Up" event is logged indicating only that the device is up. |
| // |
| // If the device has been up for at least a minute then "UpOneMinute" is also |
| // logged. |
| // |
| // If the device has been up for at least 10 minutes, then "UpTenMinutes" is |
| // also logged. Etc. |
| // |
| // Returns the amount of time before this method needs to be invoked again. |
| std::chrono::seconds LogFuchsiaUpPing(std::chrono::seconds uptime); |
| |
| // Logs one FuchsiaLifetimeEvent event of type "Boot" the first time it |
| // is invoked and does nothing on subsequent invocations. |
| // |
| // Returns the amount of time before this method needs to be invoked again. |
| // Currently returns std::chrono::seconds::max(). |
| std::chrono::seconds LogFuchsiaLifetimeEvents(); |
| |
| // Logs several different measurements of system-wide memory usage. |
| // |
| // Returns the amount of time before this method needs to be invoked again. |
| std::chrono::seconds LogMemoryUsage(); |
| |
| // Helper function to call Cobalt logger's LogCobaltEvent to log |
| // information in one zx_info_kmem_stats_t stats data point. |
| void LogMemoryUsageToCobalt(const zx_info_kmem_stats_t& stats, |
| const std::chrono::seconds& uptime); |
| |
| // Helper function to translate uptime in seconds to |
| // corresponding cobalt event code. |
| fuchsia_system_metrics::FuchsiaMemoryExperimental2MetricDimensionTimeSinceBoot |
| GetUpTimeEventCode(const std::chrono::seconds& uptime); |
| |
| // TODO(PT-128) To be removed after we start populating |
| // fuchsia_memory_experimental_2. |
| // Helper function to call Cobalt logger's LogCobaltEvent to log |
| // information in one zx_info_kmem_stats_t stats data point. |
| void LogMemoryUsageToCobalt(const zx_info_kmem_stats_t& stats); |
| |
| // Fetches and logs system-wide CPU usage. |
| // |
| // Returns the amount of time before this method needs to be invoked again. |
| std::chrono::seconds LogCpuUsage(); |
| |
| // Helper function to call Cobalt logger's LogCobaltEvent to log |
| // a vector of cpu percentages taken in one minute into Cobalt. |
| void LogCpuPercentagesToCobalt(); |
| |
| bool boot_reported_ = false; |
| async_dispatcher_t* const dispatcher_; |
| sys::ComponentContext* context_; |
| fuchsia::cobalt::LoggerFactorySyncPtr factory_; |
| fuchsia::cobalt::LoggerSyncPtr logger_fidl_proxy_; |
| fuchsia::cobalt::Logger_Sync* logger_; |
| std::chrono::steady_clock::time_point start_time_; |
| std::unique_ptr<cobalt::SteadyClock> clock_; |
| std::unique_ptr<cobalt::MemoryStatsFetcher> memory_stats_fetcher_; |
| std::unique_ptr<cobalt::CpuStatsFetcher> cpu_stats_fetcher_; |
| std::vector<double> cpu_percentages_; |
| }; |
| |
| #endif // SRC_COBALT_BIN_SYSTEM_METRICS_SYSTEM_METRICS_DAEMON_H_ |