| // 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. |
| |
| #include <fs/metrics.h> |
| |
| #include <utility> |
| |
| namespace fs { |
| |
| namespace { |
| |
| // Mirrors ids defined in cobalt metric definitions for Filesystems. |
| struct VnodeCobalt { |
| // Maps a vnode operation to a metric_id in filesystem cobalt configuration. |
| enum class MetricId : uint32_t { |
| kUnknown = 0, |
| kLink = 1, |
| kClose = 2, |
| kRead = 3, |
| kWrite = 4, |
| kAppend = 5, |
| kTruncate = 6, |
| kSetAttr = 7, |
| kGetAttr = 8, |
| kSync = 9, |
| kReadDir = 10, |
| kLookUp = 11, |
| kCreate = 12, |
| kUnlink = 13, |
| }; |
| |
| // Enum of Vnode related event codes. |
| enum class EventCode : uint32_t { |
| kUnknown = 0, |
| }; |
| }; |
| |
| const char* GetMetricName(uint32_t metric_id) { |
| switch (static_cast<VnodeCobalt::MetricId>(metric_id)) { |
| case VnodeCobalt::MetricId::kClose: |
| return "Vnode.Close"; |
| case VnodeCobalt::MetricId::kRead: |
| return "Vnode.Read"; |
| case VnodeCobalt::MetricId::kWrite: |
| return "Vnode.Write"; |
| case VnodeCobalt::MetricId::kAppend: |
| return "Vnode.Append"; |
| case VnodeCobalt::MetricId::kTruncate: |
| return "Vnode.Truncate"; |
| case VnodeCobalt::MetricId::kSetAttr: |
| return "Vnode.SetAttribute"; |
| case VnodeCobalt::MetricId::kGetAttr: |
| return "Vnoode.GetAttribute"; |
| case VnodeCobalt::MetricId::kReadDir: |
| return "Vnode.ReadDir"; |
| case VnodeCobalt::MetricId::kSync: |
| return "Vnode.Sync"; |
| case VnodeCobalt::MetricId::kLookUp: |
| return "Vnode.LookUp"; |
| case VnodeCobalt::MetricId::kCreate: |
| return "Vnode.Create"; |
| case VnodeCobalt::MetricId::kUnlink: |
| return "Vnode.Unlink"; |
| case VnodeCobalt::MetricId::kLink: |
| return "Vnode.Link"; |
| default: |
| return "kUnknown"; |
| }; |
| } |
| |
| // Default options for VnodeMetrics that are in tens of nanoseconds precision. |
| const cobalt_client::HistogramOptions kVnodeOptionsNanoOp = |
| cobalt_client::HistogramOptions::Exponential(VnodeMetrics::kHistogramBuckets, 10 * (1024 - 1)); |
| |
| // Default options for VnodeMetrics that are in microseconds precision. |
| const cobalt_client::HistogramOptions kVnodeOptionsMicroOp = |
| cobalt_client::HistogramOptions::Exponential(VnodeMetrics::kHistogramBuckets, |
| 10000 * (1024 - 1)); |
| |
| cobalt_client::HistogramOptions MakeHistogramOptions(const cobalt_client::HistogramOptions& base, |
| VnodeCobalt::MetricId metric_id, |
| VnodeCobalt::EventCode event_code) { |
| cobalt_client::HistogramOptions options = base; |
| options.metric_id = static_cast<uint32_t>(metric_id); |
| options.event_code = static_cast<uint32_t>(event_code); |
| options.get_metric_name = GetMetricName; |
| // TODO(gevalentino): Provide functions that translates event codes to names, for every metric, |
| // or share an event_code enum for all metrics. |
| options.get_event_name = nullptr; |
| return options; |
| } |
| |
| } // namespace |
| |
| VnodeMetrics::VnodeMetrics(cobalt_client::Collector* collector, const fbl::String& fs_name, |
| bool local_metrics) { |
| // Initialize all the metrics for the collector. |
| cobalt_client::HistogramOptions nano_base = kVnodeOptionsNanoOp; |
| cobalt_client::HistogramOptions micro_base = kVnodeOptionsMicroOp; |
| nano_base.component = fs_name; |
| micro_base.component = fs_name; |
| if (local_metrics) { |
| nano_base.SetMode(cobalt_client::MetricOptions::Mode::kRemoteAndLocal); |
| micro_base.SetMode(cobalt_client::MetricOptions::Mode::kRemoteAndLocal); |
| } else { |
| nano_base.SetMode(cobalt_client::MetricOptions::Mode::kRemote); |
| micro_base.SetMode(cobalt_client::MetricOptions::Mode::kRemote); |
| } |
| |
| close.Initialize(MakeHistogramOptions(nano_base, VnodeCobalt::MetricId::kClose, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| read.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kRead, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| write.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kWrite, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| append.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kAppend, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| truncate.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kTruncate, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| set_attr.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kSetAttr, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| get_attr.Initialize(MakeHistogramOptions(nano_base, VnodeCobalt::MetricId::kGetAttr, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| sync.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kSync, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| read_dir.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kReadDir, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| look_up.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kLookUp, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| create.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kCreate, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| unlink.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kUnlink, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| link.Initialize(MakeHistogramOptions(micro_base, VnodeCobalt::MetricId::kLink, |
| VnodeCobalt::EventCode::kUnknown), |
| collector); |
| } |
| |
| Metrics::Metrics(cobalt_client::CollectorOptions options, bool local_metrics, |
| const fbl::String& fs_name) |
| : collector_(std::move(options)), vnode_metrics_(&collector_, fs_name, local_metrics), |
| is_enabled_(false) {} |
| |
| const VnodeMetrics& Metrics::vnode_metrics() const { |
| return vnode_metrics_; |
| } |
| |
| VnodeMetrics* Metrics::mutable_vnode_metrics() { |
| return &vnode_metrics_; |
| } |
| |
| void Metrics::EnableMetrics(bool should_enable) { |
| is_enabled_ = should_enable; |
| vnode_metrics_.metrics_enabled = should_enable; |
| } |
| |
| bool Metrics::IsEnabled() const { |
| return is_enabled_; |
| } |
| |
| } // namespace fs |