本项目是PromQL转InfluxQL转译器和适配器,实现了传入原生PromQL查询语句,转成InfluxQL语句,并查询InfluxDB数据库返回结果。
本程序基于以下前置条件开发:
项目结构和核心代码基本稳定,后续开发以新增特性和性能优化为主,尽量兼容旧版本API。v1.0版本之前不建议用于生产环境。
截图中的dashboard来自Go Metrics。有部分PromQL函数和表达式未支持,所以有个别图没有数据。后续版本都会支持到。
原dashboard是针对部署在Kubernetes平台的应用的,作者修改了原dashboard里的查询标签。修改后的dashboard的存放在applications/prom/promethues_influxdb_grafana_stack/grafana/provisioning/dashboards/Go Metrics-1673758370201.json
路径下。
如果你想用InfluxDB作为时序数据的底层存储,同时又希望能继续使用Prometheus的PromQL查询语句做数据分析,可以采用本项目applications
模块下的prom
适配服务替换掉Prometheus的接口服务,仅将Prometheus用作监控数据采集服务。
本项目采用单仓库多模块的项目结构开发。包含:
applications
模块:负责提供适配层RESTful接口服务
prom
模块:负责提供适配Grafana的Prometheus数据源的RESTful接口服务adaptors
模块:负责提供各种适配器和转译器.
├── LICENSE
├── README.md
├── adaptors # 负责提供各种适配器和转译器
│ ├── coverage.out
│ ├── go.mod
│ ├── go.sum
│ ├── prom # PromQL相关适配器和转译器
│ │ ├── influxdb # PromQL转InfluxQL,适配InfluxDB数据源
│ │ ├── influxdbadaptor.go # InfluxDB适配器
│ │ ├── influxdbadaptor_test.go
│ │ └── testdata
│ └── storages # 数据源相关的结构体
│ └── influxdb
├── applications # 负责提供适配层RESTful接口服务
│ ├── constants.go
│ ├── go.mod
│ ├── prom # 适配Grafana的Prometheus数据源的RESTful接口服务
│ │ ├── Dockerfile
│ │ ├── client
│ │ ├── cmd
│ │ ├── config
│ │ ├── db
│ │ ├── docker-compose.yml
│ │ ├── dto
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── helper.go
│ │ ├── prom_openapi3.go
│ │ ├── prom_openapi3.json
│ │ ├── promethues_influxdb_grafana_stack
│ │ ├── svc.go
│ │ ├── svcimpl.go
│ │ ├── svcimpl_test.go
│ │ └── transport
│ └── prom.go # 需要适配器实现的接口
├── architecture.png
├── coverage.out
├── promql2influxql.png
├── screencapture-go-metrics-2023-01-12-16_37_22.png
├── screencapture-node-exporter-full-2023-01-12-16_41_13.pdf
└── uml.png
15 directories, 26 files
# Prometheus metric
example_metric{queue="0:http://example:8086/api/v1/prom/write?db=prometheus",le="0.005"} 308
# Same metric parsed into InfluxDB
measurement
example_metric
tags
queue = "0:http://example:8086/api/v1/prom/write?db=prometheus"
le = "0.005"
job = "prometheus"
instance = "localhost:9090"
__name__ = "example_metric"
fields
value = 308
{
"resultType": "vector",
"result": [
{
"metric": {
"container": "alertmanager",
"endpoint": "web",
"instance": "172.17.0.4:9093",
"job": "alertmanager-main",
"namespace": "monitoring",
"pod": "alertmanager-main-0",
"service": "alertmanager-main"
},
"value": [
1672995857.892,
"8060"
]
}
]
}
本项目有两种使用方式:第三方库、RESTful服务等
直接在你的项目根路径下执行go get
命令即可。
go get -d github.com/wubin1989/promql2influxql/[email protected]
RESTful服务代码在applications/prom
路径下,是一个单独的go模块。已经有了Dockerfile和docker-compose.yml文件。推荐测试环境采用docker方式部署。
go run cmd/main.go
可看到如下命令行日志输出:
➜ rpc git:(main) ✗ go run cmd/main.go
2023/01/12 19:57:18 maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined
_ _
| | | |
__ _ ___ ______ __| | ___ _ _ __| | ___ _ _
/ _` | / _ \ |______| / _` | / _ \ | | | | / _` | / _ \ | | | |
| (_| || (_) | | (_| || (_) || |_| || (_| || (_) || |_| |
\__, | \___/ \__,_| \___/ \__,_| \__,_| \___/ \__,_|
__/ |
|___/
2023-01-12 19:57:18 INF ================ Registered Routes ================
2023-01-12 19:57:18 INF +---------------------------+--------+----------------------------------+
2023-01-12 19:57:18 INF | NAME | METHOD | PATTERN |
2023-01-12 19:57:18 INF +---------------------------+--------+----------------------------------+
2023-01-12 19:57:18 INF | Query | POST | /api/v1/query |
2023-01-12 19:57:18 INF | GetQuery | GET | /api/v1/query |
2023-01-12 19:57:18 INF | Query_range | POST | /api/v1/query_range |
2023-01-12 19:57:18 INF | GetQuery_range | GET | /api/v1/query_range |
2023-01-12 19:57:18 INF | GetLabel_Label_nameValues | GET | /api/v1/label/:label_name/values |
2023-01-12 19:57:18 INF | GetDoc | GET | /go-doudou/doc |
2023-01-12 19:57:18 INF | GetOpenAPI | GET | /go-doudou/openapi.json |
2023-01-12 19:57:18 INF | Prometheus | GET | /go-doudou/prometheus |
2023-01-12 19:57:18 INF | GetConfig | GET | /go-doudou/config |
2023-01-12 19:57:18 INF | GetStatsvizWs | GET | /go-doudou/statsviz/ws |
2023-01-12 19:57:18 INF | GetStatsviz | GET | /go-doudou/statsviz/* |
2023-01-12 19:57:18 INF | GetDebugPprofCmdline | GET | /debug/pprof/cmdline |
2023-01-12 19:57:18 INF | GetDebugPprofProfile | GET | /debug/pprof/profile |
2023-01-12 19:57:18 INF | GetDebugPprofSymbol | GET | /debug/pprof/symbol |
2023-01-12 19:57:18 INF | GetDebugPprofTrace | GET | /debug/pprof/trace |
2023-01-12 19:57:18 INF | GetDebugPprofIndex | GET | /debug/pprof/* |
2023-01-12 19:57:18 INF +---------------------------+--------+----------------------------------+
2023-01-12 19:57:18 INF ===================================================
2023-01-12 19:57:18 INF Http server is listening at :9090
2023-01-12 19:57:18 INF Http server started in 6.225365ms
在线Swagger接口文档地址:http://localhost:9090/go-doudou/doc 接口文档http basic用户名/密码:admin/admin
打包docker镜像
docker build -t promql2influxql_promql2influxql .
启动RESTful服务和基础设施容器
docker-compose -f docker-compose.yml up -d --remove-orphans
可以看到如下命令行日志输出
➜ rpc git:(main) ✗ docker-compose -f docker-compose.yml up -d --remove-orphans
[+] Running 6/6
⠿ Network rpc_default Created 0.1s
⠿ Container promql2influxql_influxdb Started 1.1s
⠿ Container promql2influxql_node_exporter Started 0.3s
⠿ Container promql2influxql_promql2influxql Started 1.0s
⠿ Container promql2influxql_grafana Started 1.0s
⠿ Container promql2influxql_prometheus Started
以下是各服务的请求地址:
http://promql2influxql_promql2influxql:9090
(需要配置到grafana数据源)http://localhost:3000
http://localhost:9090
(仅用作监控数据采集服务)http://promql2influxql_influxdb:8086
如果需要新增其他数据源的PromQL转译和适配,只需在adaptors/prom
路径下复制一套influxdb
包的代码,修改使用即可。比如需要新增对Elasticsearch数据源的适配,只需将influxdb
包的代码复制一套改成elastic
(或随便什么名字)包,在里面实现转译逻辑,然后在prom
包路径下新增一个elasticadaptor.go
文件,把influxdbadaptor.go
文件里的代码复制进去改改就可以了。
如果需要为Grafana新增其他查询语言的适配服务,需要首先在applications
路径下复制一套prom
包的代码改造成一套适配服务,然后在adaptors
路径下复制一套prom
包的代码改造成适配器,再在适配服务里调用即可。比如需求是用Elasticsearch查询语言去查询InfluxDB里的数据,需要首先在applications
路径下复制一套prom
包的代码,命名为elastic
包,然后在adaptors
路径下复制一套prom
包的代码,命名为elastic
包,在applications
模块下的elastic
包里开发适配服务,在adaptors
模块下的elastic
包里开发适配器,最后在适配服务里调用适配器就可以了。
根据官方文档 https://prometheus.io/docs/prometheus/latest/querying/functions/#trigonometric-functions 整理
End
参数@
表达式Evaluation
参数offset
表达式再计算得出最终的结束时间Start
参数因为原生InfluxQL不支持Prometheus的/api/v1/query_range
接口的step
参数和相应的计算机制,例如一段时间范围内,每隔3分钟,计算一次前10分钟的http请求增长速率,原生InfluxQL只能做到利用group by time(3m)
语句实现一段时间范围内每隔3分钟,计算一次前3分钟的http请求增长速率,所以本项目对此的处理方式是:当PromQL查询语句中包含区间向量查询,例如go_gc_duration_seconds_count[5m]
中的[5m]
,同时传了Step
参数,则忽略Step
参数,取区间时间范围的5m
作为group by time(interval)
语句中的interval
参数值。
原生InfluxQL语句实现不了,后续计划通过进行多次InfluxQL查询后在内存中计算实现。
本项目参考了 https://github.com/influxdata/flux 项目的PromQL转Flux转译器的代码。此外,还依赖了很多非常优秀的开源项目。在此向各位开源作者表示感谢!
MIT