添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
机灵的盒饭  ·  Run Grafana Docker ...·  1 月前    · 
喝醉的烤面包  ·  Nodejs logging using ...·  1 月前    · 
读研的酱肘子  ·  KubeSphere Enterprise ...·  1 月前    · 
健身的铁链  ·  Using the browser ...·  1 月前    · 
英姿勃勃的勺子  ·  DJI Pocket 2 技術參數·  4 月前    · 
阳光的香槟  ·  Objective C ...·  5 月前    · 

Repository files navigation

promql2influxql

  • Prometheus v2.41.0:Docker镜像 prom/prometheus:v2.41.0
  • InfluxDB v1.8.10:Docker镜像 influxdb:1.8.10
  • Prometheus数据写入方式:
  • Prometheus Remote Write机制
  • InfluxDB的/api/v1/prom/write接口
  • 项目结构和核心代码基本稳定,后续开发以新增特性和性能优化为主,尽量兼容旧版本API。v1.0版本之前不建议用于生产环境。

  • 支持Prometheus四种指标类型:Counter、Gauge、Histogram和Summary。
  • 支持PromQL的7种选择器表达式、10种聚合操作表达式、13种二元操作表达式、24种内置函数转译到InfluxQL查询语句。
  • 支持作为Prometheus数据源的适配器服务接入Grafana,输入PromQL查询语句实际由适配器服务向InfluxDB实例发起查询请求和返回结果。
  • 既可以作为第三方库在你的项目中依赖,也可以作为微服务单独部署。
  • 遵循SOLID软件设计原则,采用面向微服务架构的代码组织结构,易扩展。
  • 截图中的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

    UML类图

    Prometheus数据写入InfluxDB格式转换

    # 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
      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服务

    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 

    以下是各服务的请求地址:

  • promql2influxql服务: http://promql2influxql_promql2influxql:9090 (需要配置到grafana数据源)
  • promql2influxql服务在线Swagger接口文档地址: http://localhost:9091/go-doudou/doc
    接口文档http basic用户名/密码:admin/admin
  • Grafana: http://localhost:3000
  • Prometheus: http://localhost:9090 (仅用作监控数据采集服务)
  • Influxdb: 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 包里开发适配器,最后在适配服务里调用适配器就可以了。

  • Counter:计数器
  • Gauge:仪表盘
  • Histogram:直方图
  • Summary:摘要
  • 选择器(8个)

  • =:相等匹配器
  • !=:不相等匹配器
  • =~:正则表达式匹配器
  • !~:正则表达式相反匹配器
  • {}:瞬时向量选择器
  • {}[]:区间向量选择器
    - [ ] {}[:]:子查询 (原生influxql不支持)
  • offset:偏移量修改器
  • 聚合操作(13个)

  • by:相当于InfluxQL的group by语句
    - [ ] without:忽略指定标签,by的相反操作 (原生influxql不支持)
  • sum:求和
  • min:最小值
  • max:最大值
  • avg:平均值
  • stddev:标准差
    - [ ] stdvar:标准差异 (原生influxql不支持)
  • count:统计结果行数
    - [ ] count_values:按值分组,统计每组的结果行数 (原生influxql不支持)
  • bottomk:样本值最小的k个元素
  • topk:样本值最大的k个元素
  • quantile:分布统计
  • 二元操作符(20个)

  • and:且
  • - [ ] unless:排除 (原生influxql不支持)
    - [ ] ==:等于 (原生influxql不支持)
  • !=:不等于
  • >=:大于等于
  • <=:小于等于
    - [ ] bool:0表示false,1表示true (原生influxql不支持)
    - [ ] ignoring:忽略标签 (原生influxql不支持)
    - [ ] on:与ignoring相反,类似by (原生influxql不支持)
    - [ ] group_left:多对一,类似sql的左连接 (原生influxql不支持)
    - [ ] group_right:一对多,类似sql的右连接 (原生influxql不支持)
  • 内置函数(共70个,已支持24个)

    根据官方文档 https://prometheus.io/docs/prometheus/latest/querying/functions/#trigonometric-functions 整理

  • abs()
    - [ ] absent() (原生influxql不支持) - [ ] absent_over_time() (原生influxql不支持)
  • ceil()
    - [ ] changes() (原生influxql不支持)
  • clamp():按最大值、最小值区间范围筛选
  • clamp_max():按最大值筛选
  • clamp_min():按最小值筛选
    - [ ] day_of_month() (原生influxql不支持)
    - [ ] day_of_week() (原生influxql不支持)
    - [ ] day_of_year() (原生influxql不支持)
    - [ ] days_in_month() (原生influxql不支持)
    - [ ] delta() (原生influxql不支持)
  • deriv()
  • exp()
  • floor()
    - [ ] histogram_count() (原生influxql不支持)
    - [ ] histogram_sum() (原生influxql不支持)
    - [ ] histogram_fraction() (原生influxql不支持)
    - [ ] histogram_quantile() (原生influxql不支持)
  • holt_winters()
    - [ ] hour() (原生influxql不支持)
  • idelta()
  • increase()
  • irate()
  • label_join()
  • label_replace()
  • log2()
  • log10()
    - [ ] minute() (原生influxql不支持)
    - [ ] month() (原生influxql不支持)
  • predict_linear()
  • rate()
  • resets()
  • round()
  • scalar()
  • sgn()
    - [ ] sort() :InfluxDB只支持order by time,Prometheus只支持order by value
    - [ ] sort_desc() :InfluxDB只支持order by time,Prometheus只支持order by value
  • sqrt()
  • time()
  • timestamp()
  • vector()
    - [ ] year() (原生influxql不支持)
  • avg_over_time()
  • min_over_time()
  • max_over_time()
  • sum_over_time()
  • count_over_time()
  • quantile_over_time()
  • stddev_over_time()
    - [ ] stdvar_over_time() (原生influxql不支持)
  • last_over_time()
    - [ ] present_over_time() (原生influxql不支持)
  • acos()
    - [ ] acosh() (原生influxql不支持)
  • asin()
    - [ ] asinh() (原生influxql不支持)
  • atan()
    - [ ] atanh() (原生influxql不支持)
  • cos()
    - [ ] cosh() (原生influxql不支持)
  • sin()
    - [ ] sinh() (原生influxql不支持)
  • tan()
    - [ ] tanh() (原生influxql不支持)
    - [ ] deg() (原生influxql不支持)
    - [ ] pi() (原生influxql不支持)
    - [ ] rad() (原生influxql不支持)
  • 关于查询时间范围

  • 结束时间取值优先级从最高到最低依次是:
  • End 参数
  • PromQL查询命令中的 @ 表达式
  • Evaluation 参数
  • 以上的结果会跟PromQL查询命令中的 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 参数值。

    暂不支持PromQL多measurement查询和二元操作符两边同时为VectorSelector或MatrixSelector表达式查询

    原生InfluxQL语句实现不了,后续计划通过进行多次InfluxQL查询后在内存中计算实现。

    Credits

    本项目参考了 https://github.com/influxdata/flux 项目的PromQL转Flux转译器的代码。此外,还依赖了很多非常优秀的开源项目。在此向各位开源作者表示感谢!

    License