使用Postgres数据源和BIGINT列作为时间的Grafana中的图形

时间:2019-02-14 19:14:12

标签: postgresql grafana metrics

我正在尝试构建一个非常简单的图表,显示一段时间内(例如,每5分钟一次)我有多少次访问。 我的5.4.0版的GrafanaPostgres的9.6版的完整数据配对得很好。 我的下表:

CREATE TABLE visit (
    id                    serial CONSTRAINT visit_primary_key PRIMARY KEY,
    user_credit_id        INTEGER NOT NULL REFERENCES user_credit(id),
    visit_date            bigint NOT NULL,
    visit_path            varchar(128),
    method                varchar(8) NOT NULL DEFAULT 'GET'
);

其中有一些数据:

 id | user_credit_id |  visit_date   |                 visit_path                  | method 
----+----------------+---------------+---------------------------------------------+--------
  1 |              1 | 1550094818029 | /                                           | GET
  2 |              1 | 1550094949537 | /mortgage/restapi/credit/{userId}/decrement | POST
  3 |              1 | 1550094968651 | /mortgage/restapi/credit/{userId}/decrement | POST
  4 |              1 | 1550094988557 | /mortgage/restapi/credit/{userId}/decrement | POST
  5 |              1 | 1550094990820 | /index/UGiBGp0V                             | GET
  6 |              1 | 1550094990929 | /                                           | GET
  7 |              2 | 1550095986310 | /                                           | GET
...

所以我尝试了这3个变体(实际上,很多其他变体都没有运气)没有成功:

  1. 解决方案A:
SELECT
  visit_date as "time",
  count(user_credit_id) AS "user_credit_id"
FROM visit
WHERE $__timeFilter(visit_date)
ORDER BY visit_date ASC

图形上没有数据。错误:pq:整数的无效输入语法:“ 2019-02-14T13:16:50Z”

  1. 解决方案B
SELECT
  $__unixEpochFrom(visit_date),
  count(user_credit_id) AS "user_credit_id"
FROM visit
GROUP BY time
ORDER BY user_credit_id

Series ASELECT
  $__time(visit_date/1000,10m,previous),
  count(user_credit_id) AS "user_credit_id A"
FROM
  visit
WHERE
 visit_date >= $__unixEpochFrom()::bigint*1000 and
 visit_date <= $__unixEpochTo()::bigint*1000
GROUP BY 1
ORDER BY 1

图形上没有数据。没有错误。

  1. 解决方案C
SELECT
  $__timeGroup(visit_date, '1h'),
  count(user_credit_id) AS "user_credit_id"
FROM visit
GROUP BY time
ORDER BY time

图形上没有数据。错误:pq:函数pg_catalog.date_part(未知,bigint)不存在

有人可以帮我解决这个简单的问题,因为我认为查询应该紧凑,天真和简单。.但是Grafana文档演示了其语法和功能,使我有些困惑。 / p>

No success with graph query

2 个答案:

答案 0 :(得分:1)

使用此查询,如果visit_datetimestamptz,该查询将起作用:

SELECT
  $__timeGroupAlias(visit_date,5m,0),
  count(*) AS "count"
FROM visit
WHERE
  $__timeFilter(visit_date)
GROUP BY 1
ORDER BY 1

但是您的visit_datebigint,因此您需要将其转换为timestamp(可能是TO_TIMESTAMP()),否则,您将需要找到其他如何与{ {1}}。使用查询检查器进行调试,您将看到Grafana生成的SQL。

答案 1 :(得分:0)

Jan Garaj,非常感谢!我应该承认您的摘录以及更有价值的建议(建议改用SQL调试)可以极大地帮助我取得突破。 因此,结果查询解决了以下问题:

SELECT
  $__unixEpochGroup(visit_date/1000, '5m') AS "time",
  count(user_credit_id) AS "Total Visits"
FROM visit
WHERE
  '1970-01-01 00:00:00 GMT'::timestamp + ((visit_date/1000)::text)::interval BETWEEN
  $__timeFrom()::timestamp
  AND
  $__timeTo()::timestamp
GROUP BY 1
ORDER BY 1

解密所有这些Grafana魔术的评论:

  1. Grafana有有限的DSL来制作可配置的图形,这组函数转换为一些有意义的SQL(在这里,看到“已编译”的SQL对我很有帮助,非常感谢再次)。
  2. 要使我的BIGINT列适用于预定义的Grafana函数,我们只需将其从UNIX纪元转换为秒,因此在数学语言中-除以1000。
  3. 现在,WHERE语句似乎不是那么简单和可预测的,Grafana DSL在不同的地方工作并且简单的划分并不能解决问题,我通过使用另一个Grafana函数来获取FROM来解决了这个问题和TO的时间点(应绘制Graph的时间段),但是当我们在列中确实有BIGINT时,这些函数会生成时间戳记类型。因此,感谢Postgres,我们有了很多转换器工具来将其设为时间戳记('1970-01-01 00:00:00 GMT':: timestamp +((visit_date / 1000):: text):: interval-为您生成一个BIGINT值,该值已转换为Postgres处理得很好的TIMESTAMP Grafana

debugging_result_sql

P.S。如果您不介意,我已将问题文本更改为更加准确和详细。