Unverified Commit 45f39b58 authored by Ge Jun's avatar Ge Jun Committed by GitHub

Merge pull request #804 from zyearn/customize_brpc_metrics_path

customize brpc metrics path
parents e5279ada 3f46212e
...@@ -92,4 +92,4 @@ process_username : "gejun" ...@@ -92,4 +92,4 @@ process_username : "gejun"
# bvar导出到其它监控系统格式 # bvar导出到其它监控系统格式
bvar已支持的其它监控系统格式有[Prometheus](https://prometheus.io)。将Prometheus的抓取url地址的路径设置为`/metrics`即可,例如brpc server跑在本机的8080端口,则抓取url配置为`127.0.0.1:8080/metrics` bvar已支持的其它监控系统格式有[Prometheus](https://prometheus.io)。将Prometheus的抓取url地址的路径设置为`/brpc_metrics`即可,例如brpc server跑在本机的8080端口,则抓取url配置为`127.0.0.1:8080/brpc_metrics`
...@@ -92,4 +92,4 @@ The monitoring system should combine data on every single machine periodically a ...@@ -92,4 +92,4 @@ The monitoring system should combine data on every single machine periodically a
# Dump to the format of other monitoring system # Dump to the format of other monitoring system
Currently monitoring system supported by bvar is [Prometheus](https://prometheus.io). All you need to do is to set the path in scraping target url to `/metrics`. For example, if brpc server is running in localhost on port 8080, the scraping target should be `127.0.0.1:8080/metrics`. Currently monitoring system supported by bvar is [Prometheus](https://prometheus.io). All you need to do is to set the path in scraping target url to `/brpc_metrics`. For example, if brpc server is running on localhost:8080, the scraping target should be `127.0.0.1:8080/brpc_metrics`.
...@@ -32,6 +32,9 @@ DECLARE_int32(bvar_latency_p3); ...@@ -32,6 +32,9 @@ DECLARE_int32(bvar_latency_p3);
namespace brpc { namespace brpc {
// Defined in server.cpp
extern const char* const g_server_info_prefix;
// This is a class that convert bvar result to prometheus output. // This is a class that convert bvar result to prometheus output.
// Currently the output only includes gauge and summary for two // Currently the output only includes gauge and summary for two
// reasons: // reasons:
...@@ -61,8 +64,8 @@ private: ...@@ -61,8 +64,8 @@ private:
struct SummaryItems { struct SummaryItems {
std::string latency_percentiles[NPERCENTILES]; std::string latency_percentiles[NPERCENTILES];
std::string latency_avg; int64_t latency_avg;
std::string count; int64_t count;
std::string metric_name; std::string metric_name;
bool IsComplete() const { return !metric_name.empty(); } bool IsComplete() const { return !metric_name.empty(); }
...@@ -103,6 +106,7 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece& ...@@ -103,6 +106,7 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece&
"_latency_999", "_latency_9999", "_max_latency" "_latency_999", "_latency_9999", "_max_latency"
}; };
CHECK(NPERCENTILES == arraysize(latency_names)); CHECK(NPERCENTILES == arraysize(latency_names));
const std::string desc_str = desc.as_string();
butil::StringPiece metric_name(name); butil::StringPiece metric_name(name);
for (int i = 0; i < NPERCENTILES; ++i) { for (int i = 0; i < NPERCENTILES; ++i) {
if (!metric_name.ends_with(latency_names[i])) { if (!metric_name.ends_with(latency_names[i])) {
...@@ -110,7 +114,7 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece& ...@@ -110,7 +114,7 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece&
} }
metric_name.remove_suffix(latency_names[i].size()); metric_name.remove_suffix(latency_names[i].size());
SummaryItems* si = &_m[metric_name.as_string()]; SummaryItems* si = &_m[metric_name.as_string()];
si->latency_percentiles[i] = desc.as_string(); si->latency_percentiles[i] = desc_str;
if (i == NPERCENTILES - 1) { if (i == NPERCENTILES - 1) {
// '_max_latency' is the last suffix name that appear in the sorted bvar // '_max_latency' is the last suffix name that appear in the sorted bvar
// list, which means all related percentiles have been gathered and we are // list, which means all related percentiles have been gathered and we are
...@@ -123,13 +127,13 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece& ...@@ -123,13 +127,13 @@ PrometheusMetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece&
if (metric_name.ends_with("_latency")) { if (metric_name.ends_with("_latency")) {
metric_name.remove_suffix(8); metric_name.remove_suffix(8);
SummaryItems* si = &_m[metric_name.as_string()]; SummaryItems* si = &_m[metric_name.as_string()];
si->latency_avg = desc.as_string(); si->latency_avg = strtoll(desc_str.data(), NULL, 10);
return si; return si;
} }
if (metric_name.ends_with("_count")) { if (metric_name.ends_with("_count")) {
metric_name.remove_suffix(6); metric_name.remove_suffix(6);
SummaryItems* si = &_m[metric_name.as_string()]; SummaryItems* si = &_m[metric_name.as_string()];
si->count = desc.as_string(); si->count = strtoll(desc_str.data(), NULL, 10);
return si; return si;
} }
return NULL; return NULL;
...@@ -168,8 +172,7 @@ bool PrometheusMetricsDumper::DumpLatencyRecorderSuffix( ...@@ -168,8 +172,7 @@ bool PrometheusMetricsDumper::DumpLatencyRecorderSuffix(
<< si->metric_name << "_sum " << si->metric_name << "_sum "
// There is no sum of latency in bvar output, just use // There is no sum of latency in bvar output, just use
// average * count as approximation // average * count as approximation
<< strtoll(si->latency_avg.data(), NULL, 10) * << si->latency_avg * si->count << '\n'
strtoll(si->count.data(), NULL, 10) << '\n'
<< si->metric_name << "_count " << si->count << '\n'; << si->metric_name << "_count " << si->count << '\n';
return true; return true;
} }
...@@ -181,14 +184,21 @@ void PrometheusMetricsService::default_method(::google::protobuf::RpcController* ...@@ -181,14 +184,21 @@ void PrometheusMetricsService::default_method(::google::protobuf::RpcController*
ClosureGuard done_guard(done); ClosureGuard done_guard(done);
Controller *cntl = static_cast<Controller*>(cntl_base); Controller *cntl = static_cast<Controller*>(cntl_base);
cntl->http_response().set_content_type("text/plain"); cntl->http_response().set_content_type("text/plain");
if (DumpPrometheusMetricsToIOBuf(&cntl->response_attachment()) != 0) {
cntl->SetFailed("Fail to dump metrics");
return;
}
}
int DumpPrometheusMetricsToIOBuf(butil::IOBuf* output) {
butil::IOBufBuilder os; butil::IOBufBuilder os;
PrometheusMetricsDumper dumper(&os, _server->ServerPrefix()); PrometheusMetricsDumper dumper(&os, g_server_info_prefix);
const int ndump = bvar::Variable::dump_exposed(&dumper, NULL); const int ndump = bvar::Variable::dump_exposed(&dumper, NULL);
if (ndump < 0) { if (ndump < 0) {
cntl->SetFailed("Fail to dump metrics"); return -1;
return;
} }
os.move_to(cntl->response_attachment()); os.move_to(*output);
return 0;
} }
} // namespace brpc } // namespace brpc
...@@ -18,23 +18,19 @@ ...@@ -18,23 +18,19 @@
#define BRPC_PROMETHEUS_METRICS_SERVICE_H #define BRPC_PROMETHEUS_METRICS_SERVICE_H
#include "brpc/builtin_service.pb.h" #include "brpc/builtin_service.pb.h"
#include "brpc/server.h"
namespace brpc { namespace brpc {
class PrometheusMetricsService : public metrics { class PrometheusMetricsService : public brpc_metrics {
public: public:
PrometheusMetricsService(Server* server)
: _server(server) {}
void default_method(::google::protobuf::RpcController* cntl_base, void default_method(::google::protobuf::RpcController* cntl_base,
const ::brpc::MetricsRequest* request, const ::brpc::MetricsRequest* request,
::brpc::MetricsResponse* response, ::brpc::MetricsResponse* response,
::google::protobuf::Closure* done) override; ::google::protobuf::Closure* done) override;
private:
Server* _server;
}; };
int DumpPrometheusMetricsToIOBuf(butil::IOBuf* output);
} // namepace brpc } // namepace brpc
#endif // BRPC_PROMETHEUS_METRICS_SERVICE_H #endif // BRPC_PROMETHEUS_METRICS_SERVICE_H
...@@ -97,7 +97,7 @@ service sockets { ...@@ -97,7 +97,7 @@ service sockets {
rpc default_method(SocketsRequest) returns (SocketsResponse); rpc default_method(SocketsRequest) returns (SocketsResponse);
} }
service metrics { service brpc_metrics {
rpc default_method(MetricsRequest) returns (MetricsResponse); rpc default_method(MetricsRequest) returns (MetricsResponse);
} }
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "brpc/builtin/bad_method_service.h" #include "brpc/builtin/bad_method_service.h"
#include "brpc/restful.h" #include "brpc/restful.h"
namespace brpc { namespace brpc {
// A wrapper to access some private methods/fields of `Server' // A wrapper to access some private methods/fields of `Server'
...@@ -97,7 +96,7 @@ public: ...@@ -97,7 +96,7 @@ public:
RestfulMap* global_restful_map() const RestfulMap* global_restful_map() const
{ return _server->_global_restful_map; } { return _server->_global_restful_map; }
private: private:
const Server* _server; const Server* _server;
}; };
......
...@@ -92,6 +92,8 @@ namespace brpc { ...@@ -92,6 +92,8 @@ namespace brpc {
BAIDU_CASSERT(sizeof(int32_t) == sizeof(butil::subtle::Atomic32), BAIDU_CASSERT(sizeof(int32_t) == sizeof(butil::subtle::Atomic32),
Atomic32_must_be_int32); Atomic32_must_be_int32);
extern const char* const g_server_info_prefix = "rpc_server";
const char* status_str(Server::Status s) { const char* status_str(Server::Status s) {
switch (s) { switch (s) {
case Server::UNINITIALIZED: return "UNINITIALIZED"; case Server::UNINITIALIZED: return "UNINITIALIZED";
...@@ -266,7 +268,7 @@ static bvar::Vector<unsigned, 2> GetSessionLocalDataCount(void* arg) { ...@@ -266,7 +268,7 @@ static bvar::Vector<unsigned, 2> GetSessionLocalDataCount(void* arg) {
} }
std::string Server::ServerPrefix() const { std::string Server::ServerPrefix() const {
return butil::string_printf("rpc_server_%d", listen_address().port); return butil::string_printf("%s_%d", g_server_info_prefix, listen_address().port);
} }
void* Server::UpdateDerivedVars(void* arg) { void* Server::UpdateDerivedVars(void* arg) {
...@@ -484,7 +486,7 @@ int Server::AddBuiltinServices() { ...@@ -484,7 +486,7 @@ int Server::AddBuiltinServices() {
LOG(ERROR) << "Fail to add ListService"; LOG(ERROR) << "Fail to add ListService";
return -1; return -1;
} }
if (AddBuiltinService(new (std::nothrow) PrometheusMetricsService(this))) { if (AddBuiltinService(new (std::nothrow) PrometheusMetricsService)) {
LOG(ERROR) << "Fail to add MetricsService"; LOG(ERROR) << "Fail to add MetricsService";
return -1; return -1;
} }
......
...@@ -40,12 +40,17 @@ TEST(PrometheusMetrics, sanity) { ...@@ -40,12 +40,17 @@ TEST(PrometheusMetrics, sanity) {
ASSERT_EQ(0, server.AddService(&echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE)); ASSERT_EQ(0, server.AddService(&echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
ASSERT_EQ(0, server.Start("127.0.0.1:8614", NULL)); ASSERT_EQ(0, server.Start("127.0.0.1:8614", NULL));
brpc::Server server2;
DummyEchoServiceImpl echo_svc2;
ASSERT_EQ(0, server2.AddService(&echo_svc2, brpc::SERVER_DOESNT_OWN_SERVICE));
ASSERT_EQ(0, server2.Start("127.0.0.1:8615", NULL));
brpc::Channel channel; brpc::Channel channel;
brpc::ChannelOptions channel_opts; brpc::ChannelOptions channel_opts;
channel_opts.protocol = "http"; channel_opts.protocol = "http";
ASSERT_EQ(0, channel.Init("127.0.0.1:8614", &channel_opts)); ASSERT_EQ(0, channel.Init("127.0.0.1:8614", &channel_opts));
brpc::Controller cntl; brpc::Controller cntl;
cntl.http_request().uri() = "/metrics"; cntl.http_request().uri() = "/brpc_metrics";
channel.CallMethod(NULL, &cntl, NULL, NULL, NULL); channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
ASSERT_FALSE(cntl.Failed()); ASSERT_FALSE(cntl.Failed());
std::string res = cntl.response_attachment().to_string(); std::string res = cntl.response_attachment().to_string();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment