Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
c8386e9f
Commit
c8386e9f
authored
Dec 03, 2018
by
zhujiashun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimize
parent
70aa6e3d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
75 additions
and
69 deletions
+75
-69
prometheus_metrics_service.cpp
src/brpc/builtin/prometheus_metrics_service.cpp
+63
-62
prometheus_metrics_service.h
src/brpc/builtin/prometheus_metrics_service.h
+5
-5
server.h
src/brpc/server.h
+1
-1
brpc_prometheus_metrics_unittest.cpp
test/brpc_prometheus_metrics_unittest.cpp
+6
-1
No files found.
src/brpc/builtin/metrics_service.cpp
→
src/brpc/builtin/
prometheus_
metrics_service.cpp
View file @
c8386e9f
...
...
@@ -20,7 +20,7 @@
#include "brpc/controller.h" // Controller
#include "brpc/server.h" // Server
#include "brpc/closure_guard.h" // ClosureGuard
#include "brpc/builtin/metrics_service.h"
#include "brpc/builtin/
prometheus_
metrics_service.h"
#include "brpc/builtin/common.h"
#include "bvar/bvar.h"
...
...
@@ -39,9 +39,9 @@ namespace brpc {
// more counter is just another gauge.
// 2) Histogram and summary is equivalent except that histogram
// calculates quantiles in the server side.
class
MetricsDumper
:
public
bvar
::
Dumper
{
class
Prometheus
MetricsDumper
:
public
bvar
::
Dumper
{
public
:
explicit
MetricsDumper
(
butil
::
IOBufBuilder
&
os
,
explicit
Prometheus
MetricsDumper
(
butil
::
IOBufBuilder
&
os
,
const
std
::
string
&
server_prefix
)
:
_os
(
os
)
,
_server_prefix
(
server_prefix
)
{
...
...
@@ -50,7 +50,7 @@ public:
bool
dump
(
const
std
::
string
&
name
,
const
butil
::
StringPiece
&
desc
);
private
:
DISALLOW_COPY_AND_ASSIGN
(
MetricsDumper
);
DISALLOW_COPY_AND_ASSIGN
(
Prometheus
MetricsDumper
);
bool
ProcessLatencyRecorderSuffix
(
const
butil
::
StringPiece
&
name
,
const
butil
::
StringPiece
&
desc
);
...
...
@@ -74,8 +74,8 @@ private:
std
::
map
<
std
::
string
,
SummaryItems
>
_m
;
};
bool
MetricsDumper
::
dump
(
const
std
::
string
&
name
,
const
butil
::
StringPiece
&
desc
)
{
if
(
desc
.
size
()
>
0
&&
desc
[
0
]
==
'"'
)
{
bool
Prometheus
MetricsDumper
::
dump
(
const
std
::
string
&
name
,
const
butil
::
StringPiece
&
desc
)
{
if
(
!
desc
.
empty
()
&&
desc
[
0
]
==
'"'
)
{
// there is no necessary to monitor string in prometheus
return
true
;
}
...
...
@@ -90,8 +90,8 @@ bool MetricsDumper::dump(const std::string& name, const butil::StringPiece& desc
return
true
;
}
bool
MetricsDumper
::
ProcessLatencyRecorderSuffix
(
const
butil
::
StringPiece
&
name
,
const
butil
::
StringPiece
&
desc
)
{
bool
Prometheus
MetricsDumper
::
ProcessLatencyRecorderSuffix
(
const
butil
::
StringPiece
&
name
,
const
butil
::
StringPiece
&
desc
)
{
static
std
::
string
latency_names
[]
=
{
butil
::
string_printf
(
"latency_%d"
,
(
int
)
bvar
::
FLAGS_bvar_latency_p1
),
butil
::
string_printf
(
"latency_%d"
,
(
int
)
bvar
::
FLAGS_bvar_latency_p2
),
...
...
@@ -100,70 +100,71 @@ bool MetricsDumper::ProcessLatencyRecorderSuffix(const butil::StringPiece& name,
};
CHECK
(
NPERCENTILES
==
sizeof
(
latency_names
)
/
sizeof
(
std
::
string
));
int
i
=
0
;
butil
::
StringPiece
key
(
name
);
for
(;
i
<
NPERCENTILES
;
++
i
)
{
if
(
name
.
starts_with
(
_server_prefix
)
&&
name
.
ends_with
(
latency_names
[
i
]))
{
key
.
remove_suffix
(
latency_names
[
i
].
size
()
+
1
);
/* 1 is sizeof('_') */
_m
[
key
.
as_string
()].
latency_percentiles
[
i
]
=
desc
.
as_string
();
break
;
if
(
name
.
starts_with
(
_server_prefix
))
{
int
i
=
0
;
butil
::
StringPiece
key
(
name
);
for
(;
i
<
NPERCENTILES
;
++
i
)
{
if
(
key
.
ends_with
(
latency_names
[
i
]))
{
key
.
remove_suffix
(
latency_names
[
i
].
size
()
+
1
);
/* 1 is sizeof('_') */
_m
[
key
.
as_string
()].
latency_percentiles
[
i
]
=
desc
.
as_string
();
break
;
}
}
}
if
(
i
<
NPERCENTILES
)
{
// '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
// ready to output a Summary.
if
(
latency_names
[
i
]
==
"max_latency"
)
{
const
SummaryItems
&
items
=
_m
[
key
.
as_string
()];
_os
<<
"# HELP "
<<
key
<<
'\n'
<<
"# TYPE "
<<
key
<<
" summary
\n
"
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p1
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
0
]
<<
'\n'
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p2
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
1
]
<<
'\n'
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p3
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
2
]
<<
'\n'
<<
key
<<
"{quantile=
\"
0.999
\"
} "
<<
items
.
latency_percentiles
[
3
]
<<
'\n'
<<
key
<<
"{quantile=
\"
0.9999
\"
} "
<<
items
.
latency_percentiles
[
4
]
<<
'\n'
<<
key
<<
"{quantile=
\"
1
\"
} "
<<
items
.
latency_percentiles
[
5
]
<<
'\n'
<<
key
<<
"_sum "
// There is no sum of latency in bvar output, just use average * count as approximation
<<
strtoll
(
items
.
latency_avg
.
data
(),
NULL
,
10
)
*
strtoll
(
items
.
count
.
data
(),
NULL
,
10
)
<<
'\n'
<<
key
<<
"_count "
<<
items
.
count
<<
'\n'
;
if
(
i
<
NPERCENTILES
)
{
// '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
// ready to output a Summary.
if
(
latency_names
[
i
]
==
"max_latency"
)
{
const
SummaryItems
&
items
=
_m
[
key
.
as_string
()];
_os
<<
"# HELP "
<<
key
<<
'\n'
<<
"# TYPE "
<<
key
<<
" summary
\n
"
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p1
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
0
]
<<
'\n'
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p2
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
1
]
<<
'\n'
<<
key
<<
"{quantile=
\"
"
<<
std
::
setprecision
(
2
)
<<
(
double
)(
bvar
::
FLAGS_bvar_latency_p3
)
/
100
<<
"
\"
} "
<<
items
.
latency_percentiles
[
2
]
<<
'\n'
<<
key
<<
"{quantile=
\"
0.999
\"
} "
<<
items
.
latency_percentiles
[
3
]
<<
'\n'
<<
key
<<
"{quantile=
\"
0.9999
\"
} "
<<
items
.
latency_percentiles
[
4
]
<<
'\n'
<<
key
<<
"{quantile=
\"
1
\"
} "
<<
items
.
latency_percentiles
[
5
]
<<
'\n'
<<
key
<<
"_sum "
// There is no sum of latency in bvar output, just use average * count as approximation
<<
strtoll
(
items
.
latency_avg
.
data
(),
NULL
,
10
)
*
strtoll
(
items
.
count
.
data
(),
NULL
,
10
)
<<
'\n'
<<
key
<<
"_count "
<<
items
.
count
<<
'\n'
;
}
return
true
;
}
// Get the average of latency in recent window size
if
(
key
.
ends_with
(
"latency"
))
{
key
.
remove_suffix
(
8
/* sizeof("latency") + sizeof('_') */
);
_m
[
key
.
as_string
()].
latency_avg
=
desc
.
as_string
();
return
true
;
}
if
(
key
.
ends_with
(
"count"
)
&&
!
key
.
ends_with
(
"builtin_service_count"
)
&&
// 'builtin_service_count' and 'connection_count' is not
// exposed by bvar in LatencyRecorder
!
key
.
ends_with
(
"connection_count"
))
{
key
.
remove_suffix
(
6
/* sizeof("count") + sizeof('_') */
);
_m
[
key
.
as_string
()].
count
=
desc
.
as_string
();
return
true
;
}
return
true
;
}
// Get the average of latency in recent window size
if
(
name
.
starts_with
(
_server_prefix
)
&&
name
.
ends_with
(
"latency"
))
{
key
.
remove_suffix
(
8
/* sizeof("latency") + sizeof('_') */
);
_m
[
key
.
as_string
()].
latency_avg
=
desc
.
as_string
();
return
true
;
}
if
(
name
.
starts_with
(
_server_prefix
)
&&
name
.
ends_with
(
"count"
)
&&
// 'builtin_service_count' and 'connection_count' is not
// exposed by bvar in LatencyRecorder
!
name
.
ends_with
(
"builtin_service_count"
)
&&
!
name
.
ends_with
(
"connection_count"
))
{
key
.
remove_suffix
(
6
/* sizeof("count") + sizeof('_') */
);
_m
[
key
.
as_string
()].
count
=
desc
.
as_string
();
return
true
;
}
return
false
;
}
void
MetricsService
::
default_method
(
::
google
::
protobuf
::
RpcController
*
cntl_base
,
const
::
brpc
::
MetricsRequest
*
,
::
brpc
::
MetricsResponse
*
,
::
google
::
protobuf
::
Closure
*
done
)
{
void
Prometheus
MetricsService
::
default_method
(
::
google
::
protobuf
::
RpcController
*
cntl_base
,
const
::
brpc
::
MetricsRequest
*
,
::
brpc
::
MetricsResponse
*
,
::
google
::
protobuf
::
Closure
*
done
)
{
ClosureGuard
done_guard
(
done
);
Controller
*
cntl
=
static_cast
<
Controller
*>
(
cntl_base
);
cntl
->
http_response
().
set_content_type
(
"text/plain"
);
butil
::
IOBufBuilder
os
;
MetricsDumper
dumper
(
os
,
_server
->
ServerPrefix
());
Prometheus
MetricsDumper
dumper
(
os
,
_server
->
ServerPrefix
());
const
int
ndump
=
bvar
::
Variable
::
dump_exposed
(
&
dumper
,
NULL
);
if
(
ndump
<
0
)
{
cntl
->
SetFailed
(
"Fail to dump metrics"
);
...
...
src/brpc/builtin/metrics_service.h
→
src/brpc/builtin/
prometheus_
metrics_service.h
View file @
c8386e9f
...
...
@@ -14,17 +14,17 @@
// Authors: Jiashun Zhu(zhujiashun@bilibili.com)
#ifndef BRPC_METRICS_SERVICE_H
#define BRPC_METRICS_SERVICE_H
#ifndef BRPC_
PROMETHEUS_
METRICS_SERVICE_H
#define BRPC_
PROMETHEUS_
METRICS_SERVICE_H
#include "brpc/builtin_service.pb.h"
#include "brpc/server.h"
namespace
brpc
{
class
MetricsService
:
public
metrics
{
class
Prometheus
MetricsService
:
public
metrics
{
public
:
MetricsService
(
Server
*
server
)
Prometheus
MetricsService
(
Server
*
server
)
:
_server
(
server
)
{}
void
default_method
(
::
google
::
protobuf
::
RpcController
*
cntl_base
,
...
...
@@ -37,4 +37,4 @@ private:
}
// namepace brpc
#endif // BRPC_METRICS_SERVICE_H
#endif // BRPC_
PROMETHEUS_
METRICS_SERVICE_H
src/brpc/server.h
View file @
c8386e9f
...
...
@@ -522,7 +522,7 @@ friend class ProtobufsService;
friend
class
ConnectionsService
;
friend
class
BadMethodService
;
friend
class
ServerPrivateAccessor
;
friend
class
MetricsService
;
friend
class
Prometheus
MetricsService
;
friend
class
Controller
;
int
AddServiceInternal
(
google
::
protobuf
::
Service
*
service
,
...
...
test/brpc_prometheus_metrics_unittest.cpp
View file @
c8386e9f
...
...
@@ -34,7 +34,7 @@ enum STATE {
SUMMARY
};
TEST
(
P
ROMETHEUS_METRICS
,
sanity
)
{
TEST
(
P
rometheusMetrics
,
sanity
)
{
brpc
::
Server
server
;
DummyEchoServiceImpl
echo_svc
;
ASSERT_EQ
(
0
,
server
.
AddService
(
&
echo_svc
,
brpc
::
SERVER_DOESNT_OWN_SERVICE
));
...
...
@@ -60,6 +60,8 @@ TEST(PROMETHEUS_METRICS, sanity) {
int
gauge_num
=
0
;
bool
summary_sum_gathered
=
false
;
bool
summary_count_gathered
=
false
;
bool
has_ever_summary
=
false
;
bool
has_ever_gauge
=
false
;
while
((
end_pos
=
res
.
find
(
'\n'
,
start_pos
))
!=
butil
::
StringPiece
::
npos
)
{
res
[
end_pos
]
=
'\0'
;
// safe;
...
...
@@ -86,6 +88,7 @@ TEST(PROMETHEUS_METRICS, sanity) {
ASSERT_EQ
(
2
,
matched
);
ASSERT_STREQ
(
name_type
,
name_help
);
state
=
HELP
;
has_ever_gauge
=
true
;
break
;
case
SUMMARY
:
if
(
butil
::
StringPiece
(
res
.
data
()
+
start_pos
,
end_pos
-
start_pos
).
find
(
"quantile="
)
...
...
@@ -106,6 +109,7 @@ TEST(PROMETHEUS_METRICS, sanity) {
state
=
HELP
;
summary_sum_gathered
=
false
;
summary_count_gathered
=
false
;
has_ever_summary
=
true
;
}
}
// else find "quantile=", just break to next line
break
;
...
...
@@ -115,6 +119,7 @@ TEST(PROMETHEUS_METRICS, sanity) {
}
start_pos
=
end_pos
+
1
;
}
ASSERT_TRUE
(
has_ever_gauge
&&
has_ever_summary
);
ASSERT_EQ
(
0
,
server
.
Stop
(
0
));
ASSERT_EQ
(
0
,
server
.
Join
());
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment