Skip to content

Commit 8c7495d

Browse files
authored
【腾讯犀牛鸟开源课题实战】prometheus插件专项建设 (#193)
* feat: add prometheus authentication
1 parent 9e8abc0 commit 8c7495d

28 files changed

+432
-13
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ include(snappy)
158158
include(lz4)
159159
include(toml11)
160160
include(flatbuffers)
161+
include(jwt_cpp)
161162

162163
#---------------------------------------------------------------------------------------
163164
# Set complie options and include other libs if options are ON

LICENSE

+15
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,21 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
454454
As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into a machine-executable object form of such source code, you may redistribute such embedded portions in such object form without including the above copyright and permission notices.
455455

456456

457+
Open Source Software Licensed under the MIT with exceptions:
458+
--------------------------------------------------------------------
459+
1. jwt-cpp
460+
Copyright (c) 2018 Dominik Thalhammer
461+
462+
463+
Terms of the MIT with exceptions:
464+
--------------------------------------------------------------------
465+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
466+
467+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
468+
469+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
470+
471+
457472
Open Source Software Licensed under the MIT:
458473
--------------------------------------------------------------------
459474
1. murmurhash3

cmake/config/trpc_config.cmake

+4-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ set(INCLUDE_PATHS ${TRPC_ROOT_PATH}
5555
${TRPC_ROOT_PATH}/cmake_third_party/nghttp2/lib/includes
5656
${TRPC_ROOT_PATH}/cmake_third_party/picohttpparser
5757
${TRPC_ROOT_PATH}/cmake_third_party/snappy
58-
${TRPC_ROOT_PATH}/cmake_third_party/lz4)
58+
${TRPC_ROOT_PATH}/cmake_third_party/lz4
59+
${TRPC_ROOT_PATH}/cmake_third_party/jwt_cpp/include)
5960

6061
# When use tRPC as a third-party library, selectively inject the header files at including any-lib.cmake.
6162
set(TARGET_INCLUDE_PATHS ${TRPC_ROOT_PATH})
@@ -117,4 +118,5 @@ set(LIB_SSL ssl crypto)
117118

118119
set(LIB_METRICS_PROMETHEUS prometheus-cpp-core
119120
prometheus-cpp-pull
120-
prometheus-cpp-push)
121+
prometheus-cpp-push
122+
jwt-cpp)

cmake/jwt_cpp.cmake

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
#
3+
# Tencent is pleased to support the open source community by making tRPC available.
4+
#
5+
# Copyright (C) 2023 THL A29 Limited, a Tencent company.
6+
# All rights reserved.
7+
#
8+
# If you have downloaded a copy of the tRPC source code from Tencent,
9+
# please note that tRPC source code is licensed under the Apache 2.0 License,
10+
# A copy of the Apache 2.0 License is included in this file.
11+
#
12+
#
13+
14+
include(FetchContent)
15+
16+
if(NOT DEFINED JWT_VET)
17+
set(JWT_VET 0.7.0)
18+
endif()
19+
20+
set(JWT_URL https://github.com/Thalhammer/jwt-cpp/archive/refs/tags/v${JWT_VET}.tar.gz)
21+
22+
FetchContent_Declare(
23+
jwt_cpp
24+
URL ${JWT_URL}
25+
SOURCE_DIR ${TRPC_ROOT_PATH}/cmake_third_party/jwt_cpp
26+
)
27+
28+
FetchContent_GetProperties(jwt_cpp)
29+
30+
if(NOT jwt_cpp_POPULATED)
31+
FetchContent_Populate(jwt_cpp)
32+
add_subdirectory(${TRPC_ROOT_PATH}/cmake_third_party/jwt_cpp)
33+
add_library(trpc_jwt_cpp ALIAS jwt-cpp)
34+
set(TARGET_INCLUDE_PATHS ${TARGET_INCLUDE_PATHS}
35+
${TRPC_ROOT_PATH}/cmake_third_party/jwt_cpp)
36+
set(TARGET_LINK_LIBS ${TARGET_LINK_LIBS} trpc_jwt_cpp)
37+
endif()
38+

cmake/prometheus.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ ${TRPC_BUILD_BINARY_PATH}/cmake_third_party/prometheus/core/include>"
5151
${prometheus_SOURCE_DIR}/pull/include
5252
${TRPC_BUILD_BINARY_PATH}/cmake_third_party/prometheus/pull/include
5353
${CMAKE_SOURCE_DIR}/build/_deps/prometheus-build/pull/include
54+
${prometheus_SOURCE_DIR}/push/include
55+
${TRPC_BUILD_BINARY_PATH}/cmake_third_party/prometheus/push/include
56+
${CMAKE_SOURCE_DIR}/build/_deps/prometheus-build/push/include
5457
${prometheus_SOURCE_DIR}/core/include
5558
${TRPC_BUILD_BINARY_PATH}/cmake_third_party/prometheus/core/include
5659
${CMAKE_SOURCE_DIR}/build/_deps/prometheus-build/core/include)

docs/en/prometheus_metrics.md

+22
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ By default, tRPC-Cpp framework does not compile related code with prometheus. To
1919

2020
## Bazel
2121

22+
Before compile, please add prometheus deps in your WORKSPACE file.
23+
24+
```python
25+
load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")
26+
27+
prometheus_cpp_repositories()
28+
```
29+
2230
Add the `"trpc_include_prometheus"` compilation option during Bazel compilation.
2331

2432
For example, add it in `.bazelrc` file.
@@ -66,6 +74,20 @@ The description of the configuration item are as follow.
6674
| histogram_module_cfg | Sequences | No, the default value is [1, 10, 100, 1000] | Statistical interval for latency distribution in ModuleReport, measured in milliseconds. |
6775
| const_labels | Mappings | No, the default value is empty. | Default labels attached to each RPC statistical data. |
6876
77+
By default, we use pull mode to report. If you want to use push mode, please add below configuration to your yaml file.
78+
79+
```yaml
80+
plugins:
81+
metrics:
82+
prometheus:
83+
push_mode:
84+
enable: true
85+
gateway_host: 127.0.0.1
86+
gateway_port: 9091
87+
job_name: trpc_prometheus_push_metrics
88+
interval_ms: 10000 # 默认上报间隔是10s
89+
```
90+
6991
## ModuleReport
7092
7193
**ModuleReport refers to reporting metrics data of RPC inter-module calls, including caller reporting (for tracking client-side invocation information) and callee reporting (for tracking server-side invocation information).**

docs/zh/prometheus_metrics.md

+79
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ tRPC-Cpp 框架默认不会编译 Prometheus 相关的代码。若要开启,
1919

2020
## Bazel 启用方式
2121

22+
编译前,需要增加prometheus的依赖在WORKSPACE文件里。
23+
24+
```python
25+
load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")
26+
27+
prometheus_cpp_repositories()
28+
```
29+
2230
bazel 编译时加上`“trpc_include_prometheus”`编译选项。
2331

2432
例如在 `.bazelrc` 中加上:
@@ -59,6 +67,20 @@ plugins:
5967
key2: value2
6068
```
6169
70+
默认采用pull模式,如果需要启用push模式,则需要增加类似如下的配置:
71+
72+
```yaml
73+
plugins:
74+
metrics:
75+
prometheus:
76+
push_mode:
77+
enable: true
78+
gateway_host: 127.0.0.1
79+
gateway_port: 9091
80+
job_name: trpc_prometheus_push_metrics
81+
interval_ms: 10000 # 默认上报间隔是10s
82+
```
83+
6284
配置项说明:
6385
6486
| 参数 | 类型 | 是否必须配置 | 说明 |
@@ -398,3 +420,60 @@ std::vector<::prometheus::MetricFamily> Collect();
398420
## 通过 admin 获取
399421

400422
如果服务开启了 [admin 功能](./admin_service.md),则可以通过访问 `http://admin_ip:admin_port/metrics` 获取序列化为字符串后的 Prometheus 数据。
423+
424+
# 鉴权
425+
426+
Prometheus插件鉴权分为两种模式:pull模式 和 push模式,不同模式下的配置方式有所区别。
427+
428+
## pull模式
429+
430+
在pull模式下,使用Json Web Token(JWT)方式来鉴权。需要同时配置**trpc的Prometheus插件**和**Prometheus服务器**。
431+
432+
### 插件配置
433+
434+
插件配置样例如下:
435+
436+
```yaml
437+
plugins:
438+
metrics:
439+
prometheus:
440+
auth_cfg:
441+
iss: admin # issuer 签发人
442+
sub: prometheus-pull # subject 主题
443+
aud: trpc-server # audience 受众
444+
secret: test # 密钥
445+
```
446+
447+
需要配置**bearer_token**字段,该token可以通过[JWT官方工具](https://jwt.io/)生成。在payload中填写相应的iss,sub和aud字段,verify signature中填写secret字段,加密算法使用默认的 HS256。
448+
449+
## push模式
450+
451+
在push模式下,为了和pushgateway兼容,鉴权使用**username**和**password**的形式。
452+
453+
### 插件配置
454+
455+
插件配置样例如下:
456+
457+
```yaml
458+
plugins:
459+
metrics:
460+
prometheus:
461+
auth_cfg:
462+
username: admin
463+
password: test
464+
```
465+
466+
### Pushgateway服务器配置
467+
468+
需要在Pushgateway服务器启动时,通过带有通过**bcrypt**加密的密文的配置文件启动。Pushgateway启动的配置文件如下:
469+
470+
```yaml
471+
basic_auth_users:
472+
admin: $2y$05$5uq4H5p8JyfQm.e16o3xduW6tkI2bTRpArTK4MF4dEuvncpz/bqy.
473+
```
474+
475+
密码的密文可以通过htpasswd工具生成:
476+
```shell
477+
> htpasswd -nbB admin test
478+
admin:$2y$05$5uq4H5p8JyfQm.e16o3xduW6tkI2bTRpArTK4MF4dEuvncpz/bqy.
479+
```

examples/features/prometheus/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ examples/features/prometheus/
3232

3333
* Compilation
3434

35+
Before compile, please add prometheus deps in your WORKSPACE.
36+
37+
```python
38+
load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")
39+
40+
prometheus_cpp_repositories()
41+
```
42+
3543
We can run the following command to compile the demo.
3644

3745
```shell

examples/features/prometheus/proxy/trpc_cpp_fiber.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ plugins:
4444
const_labels:
4545
const_key1: const_value1
4646
const_key2: const_value2
47+
# push_mode:
48+
# enable: true
49+
# gateway_host: 127.0.0.1
50+
# gateway_port: 9091
51+
# job_name: trpc_prometheus_push_metrics
52+
# interval_ms: 1000
4753
log:
4854
default:
4955
- name: default

examples/features/prometheus/run.sh

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
bazel build //examples/helloworld/...
2+
3+
cat > WORKSPACE <<EOF
4+
workspace(name = "trpc_cpp")
5+
6+
load("//trpc:workspace.bzl", "trpc_workspace")
7+
8+
trpc_workspace()
9+
10+
load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")
11+
12+
prometheus_cpp_repositories()
13+
EOF
14+
215
bazel build //examples/features/prometheus/... --define trpc_include_prometheus=true
316

417
echo "begin"
518
./bazel-bin/examples/helloworld/helloworld_svr --config=examples/helloworld/conf/trpc_cpp_fiber.yaml &
619
sleep 1
720
./bazel-bin/examples/features/prometheus/proxy/forward_server --config=examples/features/prometheus/proxy/trpc_cpp_fiber.yaml &
821
sleep 1
9-
./bazel-bin/examples/features/prometheus/client/client_config --config=examples/features/prometheus/client/trpc_cpp_fiber.yaml
22+
./bazel-bin/examples/features/prometheus/client/client --client_config=examples/features/prometheus/client/trpc_cpp_fiber.yaml
1023

1124
killall helloworld_svr
1225
if [ $? -ne 0 ]; then

third_party/com_github_thalhammer_jwt_cpp/BUILD

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package(
2+
default_visibility = ["//visibility:public"],
3+
)
4+
5+
cc_library(
6+
name = "jwt-cpp",
7+
hdrs = glob(["include/jwt-cpp/**/*.h", "include/picojson/*.h"]),
8+
includes = ["include"],
9+
deps = [
10+
"@com_github_openssl_openssl//:libcrypto",
11+
"@com_github_openssl_openssl//:libssl",
12+
],
13+
)

trpc/admin/BUILD

+10
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,23 @@ cc_library(
354354
":admin_handler",
355355
":base_funcs",
356356
"//trpc/util:prometheus",
357+
"//trpc/common/config:trpc_config",
358+
"//trpc/log:trpc_log",
359+
"//trpc/util/http:base64",
360+
"//trpc/util/string:string_helper",
357361
] + select({
358362
"//conditions:default": [],
359363
"//trpc:trpc_include_prometheus": [
360364
"@com_github_jupp0r_prometheus_cpp//pull",
365+
"@com_github_thalhammer_jwt_cpp//:jwt-cpp",
366+
"//trpc/metrics/prometheus:prometheus_metrics",
367+
"//trpc/metrics/prometheus:prometheus_conf_parser",
361368
],
362369
"//trpc:include_metrics_prometheus": [
363370
"@com_github_jupp0r_prometheus_cpp//pull",
371+
"@com_github_thalhammer_jwt_cpp//:jwt-cpp",
372+
"//trpc/metrics/prometheus:prometheus_metrics",
373+
"//trpc/metrics/prometheus:prometheus_conf_parser",
364374
],
365375
}),
366376
)

trpc/admin/admin_service.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ AdminService::AdminService() {
117117

118118
#ifdef TRPC_BUILD_INCLUDE_PROMETHEUS
119119
// Prometheus metrics.
120-
RegisterCmd(http::OperationType::GET, "/metrics", std::make_shared<admin::PrometheusHandler>());
120+
auto prometheus_handle_ptr = std::make_shared<admin::PrometheusHandler>();
121+
prometheus_handle_ptr->Init();
122+
RegisterCmd(http::OperationType::GET, "/metrics", prometheus_handle_ptr);
121123
#endif
122124

123125
RegisterCmd(http::OperationType::POST, "/client_detach", std::make_shared<admin::ClientDetachHandler>());

0 commit comments

Comments
 (0)