1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 16 #ifndef TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_ 17 #define TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_ 18 19 #include <array> 20 #include <functional> 21 #include <string> 22 #include <vector> 23 24 #include "tensorflow/core/framework/summary.pb.h" 25 #include "tensorflow/core/lib/monitoring/types.h" 26 #include "tensorflow/core/platform/stringpiece.h" 27 #include "tensorflow/core/platform/types.h" 28 29 namespace tensorflow { 30 namespace monitoring { 31 32 // The different metric kinds available. 33 // 34 // Gauge indicates that the metric's values are instantaneous measurements of a 35 // (typically) continuously varying value. Examples: a process's current heap 36 // size, a queue's current length, the name of the binary used by a process, 37 // whether a task is complete. 38 // 39 // Cumulative indicates that the metric's values represent non-negative changes 40 // over specified time periods. Example: the number of rpc calls to a service. 41 enum class MetricKind : int { kGauge = 0, kCumulative }; 42 43 // The type of the metric values. 44 enum class ValueType : int { 45 kInt64 = 0, 46 kHistogram, 47 kString, 48 kBool, 49 kPercentiles 50 }; 51 52 // Everything in the internal namespace is implementation details. Do not depend 53 // on this. 54 namespace internal { 55 56 template <typename Value> 57 ValueType GetValueType(); 58 59 template <> 60 inline ValueType GetValueType<int64_t>() { 61 return ValueType::kInt64; 62 } 63 64 template <> 65 inline ValueType GetValueType<std::function<int64_t()>>() { 66 return ValueType::kInt64; 67 } 68 69 template <> 70 inline ValueType GetValueType<HistogramProto>() { 71 return ValueType::kHistogram; 72 } 73 74 template <> 75 inline ValueType GetValueType<Percentiles>() { 76 return ValueType::kPercentiles; 77 } 78 79 template <> 80 inline ValueType GetValueType<std::string>() { 81 return ValueType::kString; 82 } 83 84 template <> 85 inline ValueType GetValueType<std::function<std::string()>>() { 86 return ValueType::kString; 87 } 88 89 template <> 90 inline ValueType GetValueType<bool>() { 91 return ValueType::kBool; 92 } 93 94 template <> 95 inline ValueType GetValueType<std::function<bool()>>() { 96 return ValueType::kBool; 97 } 98 99 } // namespace internal 100 101 // Abstract base class for a metric definition. 102 // 103 // Unlike MetricDef, this class is non-templatized and allows storing and 104 // accessing metric definitions without the full type information. 105 // 106 // Everything except the value type of a metric is stored here. Please read 107 // MetricDef class comments for more details. 108 class AbstractMetricDef { 109 public: kind()110 MetricKind kind() const { return kind_; } 111 value_type()112 ValueType value_type() const { return value_type_; } 113 name()114 StringPiece name() const { return name_; } 115 description()116 StringPiece description() const { return description_; } 117 label_descriptions()118 const std::vector<string>& label_descriptions() const { 119 return label_descriptions_; 120 } 121 122 private: 123 template <MetricKind kind, typename Value, int NumLabels> 124 friend class MetricDef; 125 AbstractMetricDef(const MetricKind kind,const ValueType value_type,const StringPiece name,const StringPiece description,const std::vector<string> & label_descriptions)126 AbstractMetricDef(const MetricKind kind, const ValueType value_type, 127 const StringPiece name, const StringPiece description, 128 const std::vector<string>& label_descriptions) 129 : kind_(kind), 130 value_type_(value_type), 131 name_(name), 132 description_(description), 133 label_descriptions_(std::vector<string>(label_descriptions.begin(), 134 label_descriptions.end())) {} 135 136 const MetricKind kind_; 137 const ValueType value_type_; 138 const string name_; 139 const string description_; 140 const std::vector<string> label_descriptions_; 141 }; 142 143 // Metric definition. 144 // 145 // A metric is defined by its kind, value-type, name, description and the 146 // description of its labels. 147 // 148 // NOTE: Name, description, and label descriptions should be logically static, 149 // but do not have to live for the lifetime of the MetricDef. 150 // 151 // By "logically static", we mean that they should never contain dynamic 152 // information, but is static for the lifetime of the MetricDef, and 153 // in-turn the metric; they do not need to be compile-time constants. 154 // This allows for e.g. prefixed metrics in a CLIF wrapped environment. 155 template <MetricKind metric_kind, typename Value, int NumLabels> 156 class MetricDef : public AbstractMetricDef { 157 public: 158 template <typename... LabelDesc> MetricDef(const StringPiece name,const StringPiece description,const LabelDesc &...label_descriptions)159 MetricDef(const StringPiece name, const StringPiece description, 160 const LabelDesc&... label_descriptions) 161 : AbstractMetricDef(metric_kind, internal::GetValueType<Value>(), name, 162 description, {label_descriptions...}) { 163 static_assert(sizeof...(LabelDesc) == NumLabels, 164 "Mismatch between Counter<NumLabels> and number of label " 165 "descriptions."); 166 } 167 }; 168 169 } // namespace monitoring 170 } // namespace tensorflow 171 172 #endif // TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_ 173