aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/lib/monitoring
diff options
context:
space:
mode:
authorGravatar Vinu Rajashekhar <vinuraja@google.com>2016-07-28 17:05:02 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-07-28 18:17:53 -0700
commit3aaeb88b29bcb7703df7bc23fb1d3b2a11ffc8ec (patch)
treeb4a831f7a0780f12567c63605e50b85fb50efba0 /tensorflow/core/lib/monitoring
parentf1acb3bd828a73b15670fc8019f06a5cd51bd564 (diff)
Metric definition for the monitoring API.
- Implements MetricDef, and AbstractMetricDef. - A metric is defined by its kind, name, description and the description of its labels. - Moves CounterCell's implementation from cc file to header to allow inlining. Change: 128763990
Diffstat (limited to 'tensorflow/core/lib/monitoring')
-rw-r--r--tensorflow/core/lib/monitoring/counter.cc31
-rw-r--r--tensorflow/core/lib/monitoring/counter.h18
-rw-r--r--tensorflow/core/lib/monitoring/counter_test.cc28
-rw-r--r--tensorflow/core/lib/monitoring/metric_def.h128
4 files changed, 162 insertions, 43 deletions
diff --git a/tensorflow/core/lib/monitoring/counter.cc b/tensorflow/core/lib/monitoring/counter.cc
deleted file mode 100644
index 37960a4acd..0000000000
--- a/tensorflow/core/lib/monitoring/counter.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-==============================================================================*/
-
-#include "tensorflow/core/lib/monitoring/counter.h"
-
-#include "tensorflow/core/platform/logging.h"
-
-namespace tensorflow {
-namespace monitoring {
-
-void CounterCell::IncrementBy(const int64 step) {
- DCHECK_LE(0, step) << "Must not decrement cumulative metrics.";
- value_ += step;
-}
-
-int64 CounterCell::value() const { return value_; }
-
-} // namespace monitoring
-} // namespace tensorflow
diff --git a/tensorflow/core/lib/monitoring/counter.h b/tensorflow/core/lib/monitoring/counter.h
index af76884012..7de85b75cb 100644
--- a/tensorflow/core/lib/monitoring/counter.h
+++ b/tensorflow/core/lib/monitoring/counter.h
@@ -20,6 +20,8 @@ limitations under the License.
#include <atomic>
#include <map>
+#include "tensorflow/core/lib/monitoring/metric_def.h"
+#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/mutex.h"
#include "tensorflow/core/platform/thread_annotations.h"
@@ -71,9 +73,12 @@ class CounterCell {
template <int NumLabels>
class Counter {
public:
- Counter() {}
~Counter() {}
+ explicit Counter(
+ const MetricDef<MetricKind::CUMULATIVE, int64, NumLabels>& metric_def)
+ : metric_def_(metric_def) {}
+
// Retrieves the cell for the specified labels, creating it on demand if
// not already present.
template <typename... Labels>
@@ -82,6 +87,10 @@ class Counter {
private:
mutable mutex mu_;
+ // The metric definition. This will be used to identify the metric when we
+ // register it for exporting.
+ const MetricDef<MetricKind::CUMULATIVE, int64, NumLabels> metric_def_;
+
using LabelArray = std::array<string, NumLabels>;
std::map<LabelArray, CounterCell> cells_ GUARDED_BY(mu_);
@@ -92,6 +101,13 @@ class Counter {
// Implementation details follow. API readers may skip.
////
+inline void CounterCell::IncrementBy(const int64 step) {
+ DCHECK_LE(0, step) << "Must not decrement cumulative metrics.";
+ value_ += step;
+}
+
+inline int64 CounterCell::value() const { return value_; }
+
template <int NumLabels>
template <typename... Labels>
CounterCell* Counter<NumLabels>::GetCell(const Labels&... labels)
diff --git a/tensorflow/core/lib/monitoring/counter_test.cc b/tensorflow/core/lib/monitoring/counter_test.cc
index 0010662e26..0e42aed794 100644
--- a/tensorflow/core/lib/monitoring/counter_test.cc
+++ b/tensorflow/core/lib/monitoring/counter_test.cc
@@ -19,26 +19,28 @@ limitations under the License.
namespace tensorflow {
namespace monitoring {
+namespace {
class LabeledCounterTest : public ::testing::Test {
protected:
LabeledCounterTest() {}
- Counter<1> counter_;
+ Counter<1> counter_with_labels_{{"/tensorflow/test/counter_with_labels_",
+ "Counter with one label.", "One label"}};
};
TEST_F(LabeledCounterTest, InitializedWithZero) {
- EXPECT_EQ(0, counter_.GetCell("Empty")->value());
+ EXPECT_EQ(0, counter_with_labels_.GetCell("Empty")->value());
}
TEST_F(LabeledCounterTest, GetCell) {
- auto* cell = counter_.GetCell("GetCellOp");
+ auto* cell = counter_with_labels_.GetCell("GetCellOp");
EXPECT_EQ(0, cell->value());
cell->IncrementBy(42);
EXPECT_EQ(42, cell->value());
- auto* same_cell = counter_.GetCell("GetCellOp");
+ auto* same_cell = counter_with_labels_.GetCell("GetCellOp");
EXPECT_EQ(42, same_cell->value());
same_cell->IncrementBy(58);
@@ -49,29 +51,31 @@ TEST_F(LabeledCounterTest, GetCell) {
using LabeledCounterDeathTest = LabeledCounterTest;
TEST_F(LabeledCounterDeathTest, DiesOnDecrement) {
- EXPECT_DEBUG_DEATH({ counter_.GetCell("DyingOp")->IncrementBy(-1); },
- "decrement");
+ EXPECT_DEBUG_DEATH(
+ { counter_with_labels_.GetCell("DyingOp")->IncrementBy(-1); },
+ "decrement");
}
class UnlabeledCounterTest : public ::testing::Test {
protected:
UnlabeledCounterTest() {}
- Counter<0> counter_;
+ Counter<0> counter_without_labels_{
+ {"/tensorflow/test/counter0", "Counter without any labels."}};
};
TEST_F(UnlabeledCounterTest, InitializedWithZero) {
- EXPECT_EQ(0, counter_.GetCell()->value());
+ EXPECT_EQ(0, counter_without_labels_.GetCell()->value());
}
TEST_F(UnlabeledCounterTest, GetCell) {
- auto* cell = counter_.GetCell();
+ auto* cell = counter_without_labels_.GetCell();
EXPECT_EQ(0, cell->value());
cell->IncrementBy(42);
EXPECT_EQ(42, cell->value());
- auto* same_cell = counter_.GetCell();
+ auto* same_cell = counter_without_labels_.GetCell();
EXPECT_EQ(42, same_cell->value());
same_cell->IncrementBy(58);
@@ -82,8 +86,10 @@ TEST_F(UnlabeledCounterTest, GetCell) {
using UnlabeledCounterDeathTest = UnlabeledCounterTest;
TEST_F(UnlabeledCounterDeathTest, DiesOnDecrement) {
- EXPECT_DEBUG_DEATH({ counter_.GetCell()->IncrementBy(-1); }, "decrement");
+ EXPECT_DEBUG_DEATH({ counter_without_labels_.GetCell()->IncrementBy(-1); },
+ "decrement");
}
+} // namespace
} // namespace monitoring
} // namespace tensorflow
diff --git a/tensorflow/core/lib/monitoring/metric_def.h b/tensorflow/core/lib/monitoring/metric_def.h
new file mode 100644
index 0000000000..f7037359eb
--- /dev/null
+++ b/tensorflow/core/lib/monitoring/metric_def.h
@@ -0,0 +1,128 @@
+/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef THIRD_PARTY_TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_
+#define THIRD_PARTY_TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_
+
+#include <array>
+#include <vector>
+
+#include "tensorflow/core/lib/core/stringpiece.h"
+
+namespace tensorflow {
+namespace monitoring {
+
+// Everything in the internal namespace is implementation details. Do not depend
+// on this.
+namespace internal {
+
+// Ensures that the string is a compile-time string literal.
+class StringLiteral {
+ public:
+ // We allow implicit conversions here on purpose.
+ template <int N>
+ StringLiteral(const char (&data)[N]) : literal_(data, N) {}
+
+ // This ctor will be called for non-literals, causing compile-time failure.
+ template <typename NotStringLiteral>
+ StringLiteral(const NotStringLiteral& not_string_literal) = delete;
+
+ // Implicit conversion to StringPiece.
+ operator StringPiece() const { return literal_; }
+
+ private:
+ const StringPiece literal_;
+};
+
+} // namespace internal
+
+// The different metric kinds available.
+//
+// Gauge indicates that the metric's values are instantaneous measurements of a
+// (typically) continuously varying quantity. Examples: a process's current heap
+// size, a queue's current length.
+//
+// Cumulative indicates that the metric's values represent non-negative changes
+// over specified time periods. Example: the number of rpc calls to a service.
+enum MetricKind { GAUGE, CUMULATIVE };
+
+// Abstract base class for a metric definition.
+//
+// Unlike MetricDef, this class is non-templatized and allows storing and
+// accessing metric definitions without the full type information.
+//
+// Everything except the value type of a metric is stored here. Please read
+// MetricDef class comments for more details.
+class AbstractMetricDef {
+ public:
+ MetricKind kind() const { return kind_; }
+
+ StringPiece name() const { return name_; }
+
+ StringPiece description() const { return description_; }
+
+ const std::vector<StringPiece> label_descriptions() const {
+ return label_descriptions_;
+ }
+
+ private:
+ template <MetricKind kind, typename Value, int NumLabels>
+ friend class MetricDef;
+
+ AbstractMetricDef(
+ const MetricKind kind, const internal::StringLiteral name,
+ const internal::StringLiteral description,
+ const std::vector<internal::StringLiteral>& label_descriptions)
+ : kind_(kind),
+ name_(name),
+ description_(description),
+ label_descriptions_(
+ {label_descriptions.begin(), label_descriptions.end()}) {}
+
+ const MetricKind kind_;
+ const StringPiece name_;
+ const StringPiece description_;
+ const std::vector<StringPiece> label_descriptions_;
+};
+
+// Metric definition.
+//
+// A metric is defined by its kind, value-type, name, description and the
+// description of its labels.
+//
+// NOTE: We allow only string literals for the name, description and label
+// descriptions because these should be fixed at compile-time and shouldn't be
+// dynamic.
+template <MetricKind metric_kind, typename Value, int NumLabels>
+class MetricDef : public AbstractMetricDef {
+ public:
+ using value_type = Value;
+
+ template <typename... LabelDesc>
+ MetricDef(const internal::StringLiteral name,
+ const internal::StringLiteral description,
+ const LabelDesc&... label_descriptions)
+ : AbstractMetricDef(metric_kind, name, description,
+ {label_descriptions...}) {
+ static_assert(sizeof...(LabelDesc) == NumLabels,
+ "Mismatch between Counter<NumLabels> and number of label "
+ "descriptions.");
+ }
+};
+
+} // namespace monitoring
+} // namespace tensorflow
+
+#endif // THIRD_PARTY_TENSORFLOW_CORE_LIB_MONITORING_METRIC_DEF_H_