众所周知grafana有一个插件用于触发告警的时候给panel截图, 或者用于分享panel的时候截图
同时也支持将这个插件单独部署,作为一个远程服务供grafana调用,
单独部署时,将这个渲染服务的api配置到grafana的配置中,像下面这样即可:
[rendering]
server_url = http://localhost:8081/render ## 用于告诉grafana需要渲染图片的时候调哪个接口
callback_url = http://localhost:3000/ ##
sequenceDiagram
participant grafana
participant render
grafana-->>render: render request
render->>grafana: request render url
render-->>render: do render
render-->>grafana: return render result
grafana请求render的时候的参数是:
http://localhost:8081/render
{
"deviceScaleFactor": "1.000000",
"domain": "localhost",
"encoding": "png",
"height": "500",
"renderKey": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJSZW5kZXJVc2VyIjp7Im9yZ19pZCI6MSwidXNlcl9pZCI6Mywib3JnX3JvbGUiOiJBZG1pbiJ9LCJleHAiOjE3MjE1NTM0NDF9.rE2ag__yTe9SaRQlZCWwmnT9Kpb-1lWKafg3DEhaonBypMgUJnYQ-vIjb90JtOwSC8z90GaO3jfJuVy5RaWZlQ",
"timeout": "60",
"timezone": "",
"url": "http://localhost:3000/d-solo/dds8i1mqqa680e/new-dashboard?panelId=1&orgId=1&render=1",
"width": "1000"
}
Header:
X-Auth-Token:-
其中关键的参数是:
url : 用于告诉渲染服务渲染哪个页面(这个页面就是grafana的一个页面)
renderKey : render访问grafana页面的时候需要带着的一个token
使用grafana的插件或者独立部署render供grafana调用,在结果上区别不大,受限于render对机器性能的要求
即使独立部署了render,受限于渲染时对机器性能的要求,如果如需要同时渲染多张图片,那render也是有瓶颈的
如果可以单独部署一个render,直接调render的渲染接口
http://localhost:8081/render
甚至可以通过部署多个render提高整体的渲染性能
在日常巡检监控面板的时候,
综上,希望可以通过独立调用render,建设一个巡检的平台,实现对监控的记录,以及巡检确认的平台
基于上面的介绍,可以知道能通过直接调render的接口,
传递给render 要 渲染的URL和 访问要渲染的URL时传递的renderKey
http://localhost:3000/d-solo/dds8i1mqqa680e/new-dashboard?panelId=1&orgId=1&render=1
dds8i1mqqa680e todo
new-dashboard 面板的名称
panelId=1 panel 的id
比较关键的就是上面三个参数,替换成对应的就可以了
renderKey 是 grafana生成
传递给 render
render访问grafana的某个panel的时候传递给grafana
renderKey在grafana内部生成并缓存,且有一定随机性,且有过期时间,且在使用后会被删除,所以理论上无法获得并使用
但还是要介绍一下:参考4.7
参考4.8 4.9(终极简单方案)
git clone https://github.com/grafana/grafana-image-renderer.git
yarn install --pure-lockfile
yarn run build
node build/app.js server --port=8081
git clone https://github.com/grafana/grafana.git
前端部分
yarn install --immutable
yarn start
后端部分
make run
都构建好即可打开 浏览器
http://localhost:3000/
可以看到grafana 已经启动了
如果是windows 需要 在WSL中clone 并构建代码
需要注意的是 goland 配置goroot 是wsl中的go
同时安装go 的时候最好使用 下载解压配置环境变量的方式
处理 /render 接口的代码位于
HttpServer.render
可以看到 是从请求参数中 获取 renderKey
在这里打印一下参数
就可以看到renderKey是什么?
然后使用renderKey 直接请求render
http://localhost:8081/render
像上面说的 renderKey 只能用一次
所以这里需要做两件事
pkg/services/rendering/auth.go
func (r *perRequestRenderKeyProvider) get(ctx context.Context, opts AuthOpts) (string, error) {
return generateAndSetRenderKey(r.cache, ctx, opts, 2222222222)
}
pkg/services/rendering/auth.go
func deleteRenderKey(cache *remotecache.RemoteCache, log log.Logger, ctx context.Context, renderKey string) {
//err := cache.Delete(ctx, fmt.Sprintf(renderKeyPrefix, renderKey))
//if err != nil {
// log.Error("Failed to delete render key", "error", err)
//}
return
}
这样就可以直接请求 render了
curl --location --request GET '127.0.0.1:8081/render?url=http://localhost:3000/d-solo/dds8i1mqqa680e/new-dashboard?panelId=1%26orgId=1%26render=1&renderKey=mnJBDk0QxfZ2gpLtG6Lrqtowk6yDiaeV&domain=localhost' \
--header 'X-Auth-Token: -' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)'
可以直接返回渲染的panel的图片
那么有没有更好的方式? 有!!!
给grafana配置jwt,就可以了。
分为两步:
[auth.jwt]
enabled = true
enable_login_token = true
header_name = X-jwt-ttk
email_claim = sub
username_claim = sub
email_attribute_path =
username_attribute_path =
jwk_set_url = https://dev-a6snru0l7etv5rov.us.auth0.com/.well-known/jwks.json
jwk_set_file =
cache_ttl = 60m
expect_claims = {}
key_file =
key_id =
role_attribute_path = role
role_attribute_strict = false
groups_attribute_path =
auto_sign_up = true
url_login = true
allow_assign_grafana_admin = true
skip_org_role_sync = false
其他的直接copy即可,需要注意的是 jwk_set_url 是怎么来的?参考另一篇文章:auth0如何创建jwt
jwk_set_url = https://dev-a6snru0l7etv5rov.us.auth0.com/.well-known/jwks.json
同时可以获得token,以auth_token拼接到要访问的URL后即可,同时不需要传renderKey了,类似:
curl --location --request GET
'127.0.0.1:8081/render?url=http://localhost:3000/d-solo/dds8i1mqqa680e/new-dashboard?panelId=1%26orgId=1%26render=1%26auth_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlhV1dzbnVGclhWT1hUTnZoZE1pUSJ9.eyJpc3MiOiJodHRwczovL2Rldi1hNnNucnUwbDdldHY1cm92LnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJEMHB4bHZLYzFYblYwVHlEcW5zWm1qZkVzejNvOUlmQkBjbGllbnRzIiwiYXVkIjoiZ3JhZmFuYXRlc3QiLCJpYXQiOjE3MjE1NDQyNjQsImV4cCI6MTcyMTYzMDY2NCwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIiwiYXpwIjoiRDBweGx2S2MxWG5WMFR5RHFuc1ptamZFc3ozbzlJZkIifQ.Qk9AEfHANWsZP9PAnvfRcDkDpX3qoIF9tkgMiOMsF9A-JcIzveB5q5CkPCGXhgwfQHdZmjCVp97HYJ3mAmqiWCPoFydkkOTOKThiFYYtXsq-esNTj9VP-bGD3uc4SyIZrNPtr7WEwaganc15UL7nVdaqMGSvNbrUf9HtsW_UYRxIABGwiPOnbnWa1VkkVpmmYZnMQhOaqTR3DScyDPIc_4-pNpHUybeh81eGLiaq1qVoVNQWXQgNpFQLXVa-s-wSLXE7wFxYy-Q6RAb5TjT6cWkare9j8BpxiJiQda1Y02dfq8oDKHGTjFUCjUGLGJgRnXm1tppLii-WL09Ij24SjA%26viewPanel=1&domain=localhost' \
--header 'X-Auth-Token: -' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)'
介绍一下原理,在render 调 grafana的时候在header中传递 grafana的 token 给grafana
按下面步骤获取到token
修改render (grafana-image-render)代码
src/browser/browser.ts
page.setExtraHTTPHeaders({
'Authorization':'Bearer token'
})
// 在这一行上面添加上面的内容 Bearer 后面的就是前面获取到的token
return page.goto(options.url, { waitUntil: 'networkidle0', timeout: options.timeout * 1000 });
重新build
yarn run build
然后重新启动 render
node build/app.js server --port=8081
再调 render渲染接口,这次不传renderKey 也不传jwt token,也可以获取到截图了
curl --location --request GET '127.0.0.1:8081/render?url=http://localhost:3000/d-solo/dds8i1mqqa680e/new-dashboard?panelId=1%26orgId=1%26render=1%26viewPanel=%26from=1721736889194%26to=1721738490788&domain=localhost' \
--header 'X-Auth-Token: -' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)'
完结撒花