You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by to...@apache.org on 2016/06/03 14:08:53 UTC
[3/3] incubator-kudu git commit: KUDU-1444. Get resource metrics of a
scan.
KUDU-1444. Get resource metrics of a scan.
This patch supports to get the resource metrics of a scan in client side. The
resource metrics will be sent back to client in every scan RPC response. This
is useful for impala to show these stats in a query profile.
For now, the resource metrics only contains cfile_cache_miss_bytes and
cfile_cache_hit_bytes. We may add more in the future as needed.
Change-Id: Iedaf570a7601651c93275ae0a8565f1e33da842d
Reviewed-on: http://gerrit.cloudera.org:8080/3013
Tested-by: Kudu Jenkins
Reviewed-by: Todd Lipcon <to...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kudu/commit/ece7b565
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kudu/tree/ece7b565
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kudu/diff/ece7b565
Branch: refs/heads/master
Commit: ece7b5653998db318e4baa5d57f27ba3a836731d
Parents: 6034b85
Author: zhangzhen <zh...@xiaomi.com>
Authored: Tue May 10 19:35:36 2016 +0800
Committer: Todd Lipcon <to...@apache.org>
Committed: Fri Jun 3 13:49:55 2016 +0000
----------------------------------------------------------------------
src/kudu/cfile/cfile_reader.cc | 9 ++-
src/kudu/client/CMakeLists.txt | 2 +
src/kudu/client/client-test.cc | 40 +++++++++++--
src/kudu/client/client.cc | 4 ++
src/kudu/client/client.h | 4 ++
src/kudu/client/resource_metrics-internal.h | 53 ++++++++++++++++++
src/kudu/client/resource_metrics.cc | 71 ++++++++++++++++++++++++
src/kudu/client/resource_metrics.h | 53 ++++++++++++++++++
src/kudu/client/scanner-internal.cc | 24 +++++++-
src/kudu/client/scanner-internal.h | 6 ++
src/kudu/tserver/tablet_service.cc | 12 +++-
src/kudu/tserver/tserver.proto | 10 ++++
src/kudu/util/trace_metrics.h | 12 ++++
13 files changed, 289 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/cfile/cfile_reader.cc
----------------------------------------------------------------------
diff --git a/src/kudu/cfile/cfile_reader.cc b/src/kudu/cfile/cfile_reader.cc
index d05e1d7..0644f1c 100644
--- a/src/kudu/cfile/cfile_reader.cc
+++ b/src/kudu/cfile/cfile_reader.cc
@@ -54,6 +54,9 @@ using strings::Substitute;
namespace kudu {
namespace cfile {
+const char* CFILE_CACHE_MISS_BYTES_METRIC_NAME = "cfile_cache_miss_bytes";
+const char* CFILE_CACHE_HIT_BYTES_METRIC_NAME = "cfile_cache_hit_bytes";
+
// Magic+Length: 8-byte magic, followed by 4-byte header size
static const size_t kMagicAndLengthSize = 12;
static const size_t kMaxHeaderFooterPBSize = 64*1024;
@@ -318,7 +321,7 @@ Status CFileReader::ReadBlock(const BlockPointer &ptr, CacheControl cache_contro
BlockCache::CacheKey key(block_->id(), ptr.offset());
if (cache->Lookup(key, cache_behavior, &bc_handle)) {
TRACE_COUNTER_INCREMENT("cfile_cache_hit", 1);
- TRACE_COUNTER_INCREMENT("cfile_cache_hit_bytes", ptr.size());
+ TRACE_COUNTER_INCREMENT(CFILE_CACHE_HIT_BYTES_METRIC_NAME, ptr.size());
*ret = BlockHandle::WithDataFromCache(&bc_handle);
// Cache hit
return Status::OK();
@@ -331,9 +334,9 @@ Status CFileReader::ReadBlock(const BlockPointer &ptr, CacheControl cache_contro
TRACE_EVENT1("io", "CFileReader::ReadBlock(cache miss)",
"cfile", ToString());
TRACE_COUNTER_INCREMENT("cfile_cache_miss", 1);
- TRACE_COUNTER_INCREMENT("cfile_cache_miss_bytes", ptr.size());
- ScratchMemory scratch;
+ TRACE_COUNTER_INCREMENT(CFILE_CACHE_MISS_BYTES_METRIC_NAME, ptr.size());
+ ScratchMemory scratch;
// If we are reading uncompressed data and plan to cache the result,
// then we should allocate our scratch memory directly from the cache.
// This avoids an extra memory copy in the case of an NVM cache.
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/client/CMakeLists.txt b/src/kudu/client/CMakeLists.txt
index 8c56e9b..eb38862 100644
--- a/src/kudu/client/CMakeLists.txt
+++ b/src/kudu/client/CMakeLists.txt
@@ -40,6 +40,7 @@ set(CLIENT_SRCS
scan_predicate.cc
scan_token-internal.cc
scanner-internal.cc
+ resource_metrics.cc
schema.cc
session-internal.cc
table-internal.cc
@@ -176,6 +177,7 @@ install(FILES
stubs.h
value.h
write_op.h
+ resource_metrics.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/kudu/client)
# Headers: common
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/client-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/client-test.cc b/src/kudu/client/client-test.cc
index 1aae285..9f4e3d8 100644
--- a/src/kudu/client/client-test.cc
+++ b/src/kudu/client/client-test.cc
@@ -20,6 +20,7 @@
#include <glog/stl_logging.h>
#include <algorithm>
+#include <map>
#include <memory>
#include <vector>
@@ -36,6 +37,7 @@
#include "kudu/common/wire_protocol.h"
#include "kudu/consensus/consensus.proxy.h"
#include "kudu/gutil/atomicops.h"
+#include "kudu/gutil/map-util.h"
#include "kudu/gutil/stl_util.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/integration-tests/mini_cluster.h"
@@ -82,6 +84,7 @@ using std::set;
using std::string;
using std::unique_ptr;
using std::vector;
+using std::map;
namespace kudu {
namespace client {
@@ -172,6 +175,15 @@ class ClientTest : public KuduTest {
return resp.tablet_locations(0).tablet_id();
}
+ void FlushTablet(const string& tablet_id) {
+ for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
+ scoped_refptr<TabletPeer> tablet_peer;
+ ASSERT_TRUE(cluster_->mini_tablet_server(i)->server()->tablet_manager()->LookupTablet(
+ tablet_id, &tablet_peer));
+ ASSERT_OK(tablet_peer->tablet()->Flush());
+ }
+ }
+
void CheckNoRpcOverflow() {
for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
MiniTabletServer* server = cluster_->mini_tablet_server(i);
@@ -264,6 +276,26 @@ class ClientTest : public KuduTest {
return std::move(del);
}
+ void DoTestScanResourceMetrics() {
+ KuduScanner scanner(client_table_.get());
+ string tablet_id = GetFirstTabletId(client_table_.get());
+ // flush to ensure we scan disk later
+ FlushTablet(tablet_id);
+ ASSERT_OK(scanner.SetProjectedColumns({ "key" }));
+ LOG_TIMING(INFO, "Scanning disk with no predicates") {
+ ASSERT_OK(scanner.Open());
+ ASSERT_TRUE(scanner.HasMoreRows());
+ KuduScanBatch batch;
+ while (scanner.HasMoreRows()) {
+ ASSERT_OK(scanner.NextBatch(&batch));
+ }
+ std::map<std::string, int64_t> metrics = scanner.GetResourceMetrics().Get();
+ ASSERT_TRUE(ContainsKey(metrics, "cfile_cache_miss_bytes"));
+ ASSERT_TRUE(ContainsKey(metrics, "cfile_cache_hit_bytes"));
+ ASSERT_GT(metrics["cfile_cache_miss_bytes"] + metrics["cfile_cache_hit_bytes"], 0);
+ }
+ }
+
void DoTestScanWithoutPredicates() {
KuduScanner scanner(client_table_.get());
ASSERT_OK(scanner.SetProjectedColumns({ "key" }));
@@ -521,6 +553,7 @@ TEST_F(ClientTest, TestScan) {
// Scan after insert
DoTestScanWithoutPredicates();
+ DoTestScanResourceMetrics();
DoTestScanWithStringPredicate();
DoTestScanWithKeyPredicate();
@@ -989,12 +1022,7 @@ TEST_F(ClientTest, TestScanFaultTolerance) {
// disk.
if (with_flush) {
string tablet_id = GetFirstTabletId(table.get());
- for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
- scoped_refptr<TabletPeer> tablet_peer;
- ASSERT_TRUE(cluster_->mini_tablet_server(i)->server()->tablet_manager()->LookupTablet(
- tablet_id, &tablet_peer));
- ASSERT_OK(tablet_peer->tablet()->Flush());
- }
+ FlushTablet(tablet_id);
}
// Test a few different recoverable server-side error conditions.
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/client.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/client.cc b/src/kudu/client/client.cc
index 781e917..e605b9b 100644
--- a/src/kudu/client/client.cc
+++ b/src/kudu/client/client.cc
@@ -993,6 +993,10 @@ KuduSchema KuduScanner::GetProjectionSchema() const {
return KuduSchema(*data_->configuration().projection());
}
+const ResourceMetrics& KuduScanner::GetResourceMetrics() const {
+ return data_->resource_metrics_;
+}
+
namespace {
// Callback for the RPC sent by Close().
// We can't use the KuduScanner response and RPC controller members for this
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/client.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/client.h b/src/kudu/client/client.h
index f7f3702..93edad7 100644
--- a/src/kudu/client/client.h
+++ b/src/kudu/client/client.h
@@ -21,6 +21,7 @@
#include <string>
#include <vector>
+#include "kudu/client/resource_metrics.h"
#include "kudu/client/row_result.h"
#include "kudu/client/scan_batch.h"
#include "kudu/client/scan_predicate.h"
@@ -1024,6 +1025,9 @@ class KUDU_EXPORT KuduScanner {
// RPC made by the server.
Status GetCurrentServer(KuduTabletServer** server);
+ // Returns the cumulative resource metrics since the scan was started.
+ const ResourceMetrics& GetResourceMetrics() const;
+
// Set the hint for the size of the next batch in bytes.
// If setting to 0 before calling Open(), it means that the first call
// to the tablet server won't return data.
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/resource_metrics-internal.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/resource_metrics-internal.h b/src/kudu/client/resource_metrics-internal.h
new file mode 100644
index 0000000..d9a522d
--- /dev/null
+++ b/src/kudu/client/resource_metrics-internal.h
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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 KUDU_CLIENT_RESOURCE_METRICS_INTERNAL_H
+#define KUDU_CLIENT_RESOURCE_METRICS_INTERNAL_H
+
+#include <map>
+#include <mutex>
+#include <stdint.h>
+#include <string>
+
+#include "kudu/util/locks.h"
+
+namespace kudu {
+
+namespace client {
+
+class ResourceMetrics::Data {
+ public:
+ Data();
+ ~Data();
+
+ // Return a copy of the current counter map.
+ std::map<std::string, int64_t> Get() const;
+
+ // Increment the given counter.
+ void Increment(const std::string& name, int64_t amount);
+
+ // Return metric's current value.
+ int64_t GetMetric(const std::string& name) const;
+
+ private:
+ mutable simple_spinlock lock_;
+ std::map<std::string, int64_t> counters_;
+};
+
+} // namespace client
+} // namespace kudu
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/resource_metrics.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/resource_metrics.cc b/src/kudu/client/resource_metrics.cc
new file mode 100644
index 0000000..f8ccc2a
--- /dev/null
+++ b/src/kudu/client/resource_metrics.cc
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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 "kudu/client/resource_metrics.h"
+#include "kudu/client/resource_metrics-internal.h"
+
+#include <map>
+#include <mutex>
+#include <stdint.h>
+#include <string>
+
+#include "kudu/gutil/map-util.h"
+
+namespace kudu {
+
+namespace client {
+
+ResourceMetrics::ResourceMetrics() :
+ data_(new Data) {}
+
+ResourceMetrics::~ResourceMetrics() {
+ delete data_;
+}
+
+void ResourceMetrics::Increment(const std::string& name, int64_t amount) {
+ data_->Increment(name, amount);
+}
+
+std::map<std::string, int64_t> ResourceMetrics::Get() const {
+ return data_->Get();
+}
+
+int64_t ResourceMetrics::GetMetric(const std::string& name) const {
+ return data_->GetMetric(name);
+}
+
+ResourceMetrics::Data::Data() {}
+
+ResourceMetrics::Data::~Data() {}
+
+void ResourceMetrics::Data::Increment(const std::string& name, int64_t amount) {
+ std::lock_guard<simple_spinlock> l(lock_);
+ counters_[name] += amount;
+}
+
+std::map<std::string, int64_t> ResourceMetrics::Data::Get() const {
+ std::lock_guard<simple_spinlock> l(lock_);
+ return counters_;
+}
+
+int64_t ResourceMetrics::Data::GetMetric(const std::string& name) const {
+ std::lock_guard<simple_spinlock> l(lock_);
+ return FindWithDefault(counters_, name, 0);
+}
+
+} // namespace client
+} // namespace kudu
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/resource_metrics.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/resource_metrics.h b/src/kudu/client/resource_metrics.h
new file mode 100644
index 0000000..d31edaf
--- /dev/null
+++ b/src/kudu/client/resource_metrics.h
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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 KUDU_CLIENT_RESOURCE_METRICS_H
+#define KUDU_CLIENT_RESOURCE_METRICS_H
+
+#include <map>
+#include <stdint.h>
+#include <string>
+
+#include "kudu/util/kudu_export.h"
+
+namespace kudu {
+namespace client {
+
+class KUDU_EXPORT ResourceMetrics {
+ public:
+ ResourceMetrics();
+
+ ~ResourceMetrics();
+
+ // Return a map that contains all metrics, its key is the metric name
+ // and its value is corresponding metric count.
+ std::map<std::string, int64_t> Get() const;
+
+ // Increment the given metric.
+ void Increment(const std::string& name, int64_t amount);
+
+ // Return the metric's current count.
+ int64_t GetMetric(const std::string& name) const;
+
+ private:
+ class KUDU_NO_EXPORT Data;
+ Data* data_;
+};
+
+} // namespace client
+} // namespace kudu
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/scanner-internal.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/scanner-internal.cc b/src/kudu/client/scanner-internal.cc
index afb9316..c52e1c5 100644
--- a/src/kudu/client/scanner-internal.cc
+++ b/src/kudu/client/scanner-internal.cc
@@ -33,6 +33,9 @@
#include "kudu/rpc/rpc_controller.h"
#include "kudu/util/hexdump.h"
+using google::protobuf::FieldDescriptor;
+using google::protobuf::Reflection;
+
using std::set;
using std::string;
@@ -142,6 +145,21 @@ Status KuduScanner::Data::HandleError(const ScanRpcStatus& err,
return err.status;
}
+void KuduScanner::Data::UpdateResourceMetrics() {
+ if (last_response_.has_resource_metrics()) {
+ tserver::ResourceMetricsPB resource_metrics = last_response_.resource_metrics();
+ const Reflection* reflection = resource_metrics.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(resource_metrics, &fields);
+ for (const FieldDescriptor* field : fields) {
+ if (reflection->HasField(resource_metrics, field) &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_INT64) {
+ resource_metrics_.Increment(field->name(), reflection->GetInt64(resource_metrics, field));
+ }
+ }
+ }
+}
+
ScanRpcStatus KuduScanner::Data::AnalyzeResponse(const Status& rpc_status,
const MonoTime& overall_deadline,
const MonoTime& deadline) {
@@ -227,11 +245,15 @@ ScanRpcStatus KuduScanner::Data::SendScanRpc(const MonoTime& overall_deadline,
if (!configuration_.spec().predicates().empty()) {
controller_.RequireServerFeature(TabletServerFeatures::COLUMN_PREDICATES);
}
- return AnalyzeResponse(
+ ScanRpcStatus scan_status = AnalyzeResponse(
proxy_->Scan(next_req_,
&last_response_,
&controller_),
rpc_deadline, overall_deadline);
+ if (scan_status.result == ScanRpcStatus::OK) {
+ UpdateResourceMetrics();
+ }
+ return scan_status;
}
Status KuduScanner::Data::OpenTablet(const string& partition_key,
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/client/scanner-internal.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/scanner-internal.h b/src/kudu/client/scanner-internal.h
index f5657c7..e3a8ef5 100644
--- a/src/kudu/client/scanner-internal.h
+++ b/src/kudu/client/scanner-internal.h
@@ -22,6 +22,7 @@
#include <vector>
#include "kudu/client/client.h"
+#include "kudu/client/resource_metrics.h"
#include "kudu/client/row_result.h"
#include "kudu/client/scan_configuration.h"
#include "kudu/common/partition_pruner.h"
@@ -206,6 +207,9 @@ class KuduScanner::Data {
// TODO: This and the overall scan retry logic duplicates much of RpcRetrier.
Status last_error_;
+ // The scanner's cumulative resource metrics since the scan was started.
+ ResourceMetrics resource_metrics_;
+
private:
// Analyze the response of the last Scan RPC made by this scanner.
//
@@ -223,6 +227,8 @@ class KuduScanner::Data {
const MonoTime& overall_deadline,
const MonoTime& rpc_deadline);
+ void UpdateResourceMetrics();
+
DISALLOW_COPY_AND_ASSIGN(Data);
};
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/tserver/tablet_service.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tablet_service.cc b/src/kudu/tserver/tablet_service.cc
index adb5149..bed74b8 100644
--- a/src/kudu/tserver/tablet_service.cc
+++ b/src/kudu/tserver/tablet_service.cc
@@ -84,6 +84,13 @@ TAG_FLAG(scanner_inject_latency_on_each_batch_ms, unsafe);
DECLARE_int32(memory_limit_warn_threshold_percentage);
namespace kudu {
+namespace cfile {
+extern const char* CFILE_CACHE_MISS_BYTES_METRIC_NAME;
+extern const char* CFILE_CACHE_HIT_BYTES_METRIC_NAME;
+}
+}
+
+namespace kudu {
namespace tserver {
using consensus::ChangeConfigRequestPB;
@@ -1082,7 +1089,10 @@ void TabletServiceImpl::Scan(const ScanRequestPB* req,
resp->set_last_primary_key(last.ToString());
}
}
-
+ resp->mutable_resource_metrics()->set_cfile_cache_miss_bytes(
+ context->trace()->metrics()->GetMetric(cfile::CFILE_CACHE_MISS_BYTES_METRIC_NAME));
+ resp->mutable_resource_metrics()->set_cfile_cache_hit_bytes(
+ context->trace()->metrics()->GetMetric(cfile::CFILE_CACHE_HIT_BYTES_METRIC_NAME));
context->RespondSuccess();
}
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/tserver/tserver.proto
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tserver.proto b/src/kudu/tserver/tserver.proto
index 93850a5..9df226a 100644
--- a/src/kudu/tserver/tserver.proto
+++ b/src/kudu/tserver/tserver.proto
@@ -298,6 +298,13 @@ message ScanRequestPB {
optional bool close_scanner = 5;
}
+// RPC's resource metrics.
+message ResourceMetricsPB {
+ // all metrics MUST be the type of int64.
+ optional int64 cfile_cache_miss_bytes = 1;
+ optional int64 cfile_cache_hit_bytes = 2;
+}
+
message ScanResponsePB {
// The error, if an error occurred with this request.
optional TabletServerErrorPB error = 1;
@@ -330,6 +337,9 @@ message ScanResponsePB {
// If this is a fault-tolerant scanner, this is set to the encoded primary
// key of the last row returned in the response.
optional bytes last_primary_key = 7;
+
+ // The resource usage of this RPC.
+ optional ResourceMetricsPB resource_metrics = 8;
}
// A scanner keep-alive request.
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/ece7b565/src/kudu/util/trace_metrics.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/trace_metrics.h b/src/kudu/util/trace_metrics.h
index fbe1774..a230821 100644
--- a/src/kudu/util/trace_metrics.h
+++ b/src/kudu/util/trace_metrics.h
@@ -17,6 +17,7 @@
#pragma once
#include "kudu/gutil/macros.h"
+#include "kudu/gutil/map-util.h"
#include "kudu/util/atomic.h"
#include "kudu/util/locks.h"
@@ -65,6 +66,12 @@ class TraceMetrics {
tcmalloc_contention_cycles_.IncrementBy(cycles);
}
+ // Return metric's current value.
+ //
+ // NOTE: the 'name' MUST be the same const char* which is used for
+ // insertion. This is because we do pointer-wise comparison internally.
+ int64_t GetMetric(const char* name) const;
+
private:
mutable simple_spinlock lock_;
std::map<const char*, int64_t> counters_;
@@ -90,4 +97,9 @@ inline std::map<const char*, int64_t> TraceMetrics::Get() const {
return m;
}
+inline int64_t TraceMetrics::GetMetric(const char* name) const {
+ std::lock_guard<simple_spinlock> l(lock_);
+ return FindWithDefault(counters_, name, 0);
+}
+
} // namespace kudu