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 <vector>
21 
22 #include "tensorflow/core/framework/summary.pb.h"
23 #include "tensorflow/core/lib/monitoring/types.h"
24 #include "tensorflow/core/platform/stringpiece.h"
25 #include "tensorflow/core/platform/types.h"
26 
27 namespace tensorflow {
28 namespace monitoring {
29 
30 // The different metric kinds available.
31 //
32 // Gauge indicates that the metric's values are instantaneous measurements of a
33 // (typically) continuously varying value. Examples: a process's current heap
34 // size, a queue's current length, the name of the binary used by a process,
35 // whether a task is complete.
36 //
37 // Cumulative indicates that the metric's values represent non-negative changes
38 // over specified time periods. Example: the number of rpc calls to a service.
39 enum class MetricKind : int { kGauge = 0, kCumulative };
40 
41 // The type of the metric values.
42 enum class ValueType : int {
43   kInt64 = 0,
44   kHistogram,
45   kString,
46   kBool,
47   kPercentiles
48 };
49 
50 // Everything in the internal namespace is implementation details. Do not depend
51 // on this.
52 namespace internal {
53 
54 template <typename Value>
55 ValueType GetValueType();
56 
57 template <>
58 inline ValueType GetValueType<int64>() {
59   return ValueType::kInt64;
60 }
61 
62 template <>
63 inline ValueType GetValueType<HistogramProto>() {
64   return ValueType::kHistogram;
65 }
66 
67 template <>
68 inline ValueType GetValueType<Percentiles>() {
69   return ValueType::kPercentiles;
70 }
71 
72 template <>
73 inline ValueType GetValueType<string>() {
74   return ValueType::kString;
75 }
76 
77 template <>
78 inline ValueType GetValueType<bool>() {
79   return ValueType::kBool;
80 }
81 
82 }  // namespace internal
83 
84 // Abstract base class for a metric definition.
85 //
86 // Unlike MetricDef, this class is non-templatized and allows storing and
87 // accessing metric definitions without the full type information.
88 //
89 // Everything except the value type of a metric is stored here. Please read
90 // MetricDef class comments for more details.
91 class AbstractMetricDef {
92  public:
kind()93   MetricKind kind() const { return kind_; }
94 
value_type()95   ValueType value_type() const { return value_type_; }
96 
name()97   StringPiece name() const { return name_; }
98 
description()99   StringPiece description() const { return description_; }
100 
label_descriptions()101   const std::vector<string>& label_descriptions() const {
102     return label_descriptions_;
103   }
104 
105  private:
106   template <MetricKind kind, typename Value, int NumLabels>
107   friend class MetricDef;
108 
AbstractMetricDef(const MetricKind kind,const ValueType value_type,const StringPiece name,const StringPiece description,const std::vector<string> & label_descriptions)109   AbstractMetricDef(const MetricKind kind, const ValueType value_type,
110                     const StringPiece name, const StringPiece description,
111                     const std::vector<string>& label_descriptions)
112       : kind_(kind),
113         value_type_(value_type),
114         name_(name),
115         description_(description),
116         label_descriptions_(std::vector<string>(label_descriptions.begin(),
117                                                 label_descriptions.end())) {}
118 
119   const MetricKind kind_;
120   const ValueType value_type_;
121   const string name_;
122   const string description_;
123   const std::vector<string> label_descriptions_;
124 };
125 
126 // Metric definition.
127 //
128 // A metric is defined by its kind, value-type, name, description and the
129 // description of its labels.
130 //
131 // NOTE: Name, description, and label descriptions should be logically static,
132 // but do not have to live for the lifetime of the MetricDef.
133 //
134 // By "logically static", we mean that they should never contain dynamic
135 // information, but is static for the lifetime of the MetricDef, and
136 // in-turn the metric; they do not need to be compile-time constants.
137 // This allows for e.g. prefixed metrics in a CLIF wrapped environment.
138 template <MetricKind metric_kind, typename Value, int NumLabels>
139 class MetricDef : public AbstractMetricDef {
140  public:
141   template <typename... LabelDesc>
MetricDef(const StringPiece name,const StringPiece description,const LabelDesc &...label_descriptions)142   MetricDef(const StringPiece name, const StringPiece description,
143             const LabelDesc&... label_descriptions)
144       : AbstractMetricDef(metric_kind, internal::GetValueType<Value>(), name,
145                           description, {label_descriptions...}) {
146     static_assert(sizeof...(LabelDesc) == NumLabels,
147                   "Mismatch between Counter<NumLabels> and number of label "
148                   "descriptions.");
149   }
150 };
151 
152 }  // namespace monitoring
153 }  // namespace tensorflow
154 
155 #endif  // TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_
156