You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在TimescaleDB中创建规则并触发POST告警?附温度监测示例

在TimescaleDB中实现规则触发的POST告警

完全没问题!这种基于时序数据的阈值告警需求,在TimescaleDB里实现起来非常顺畅——毕竟它本身就是为时序场景设计的,还能借助PostgreSQL的扩展能力轻松对接POST通知。下面我给你一步步拆解实现方案:

1. 先搞定基础数据存储

假设你还没建温度存储表,先整个TimescaleDB专属的时序表(hypertables),比普通PostgreSQL表性能高得多:

CREATE TABLE device_temperatures (
    time TIMESTAMPTZ NOT NULL,
    device_id TEXT NOT NULL,
    temperature NUMERIC NOT NULL
);

-- 把普通表转成时序表
SELECT create_hypertable('device_temperatures', 'time');

2. 用连续聚合高效计算5分钟均值(推荐)

要实时算设备D过去5分钟的平均温度,直接查原始表会慢,整个连续聚合视图自动帮你预计算,性能拉满:

CREATE MATERIALIZED VIEW device_temp_5min_avg
WITH (timescaledb.continuous) AS
SELECT
    time_bucket('5 minutes', time) AS bucket,
    device_id,
    AVG(temperature) AS avg_temperature
FROM device_temperatures
GROUP BY bucket, device_id;

-- 设置自动刷新策略,比如每分钟刷新一次最新数据
SELECT add_continuous_aggregate_policy('device_temp_5min_avg',
    start_offset => INTERVAL '10 minutes',
    end_offset => INTERVAL '0 minutes',
    schedule_interval => INTERVAL '1 minute');

3. 实现告警触发+POST通知的两种方案

方案一:用PostgreSQL触发器+外部脚本(自定义性强)

如果你需要高度自定义的逻辑,比如额外加一些判断条件,可以用触发器结合外部脚本发送POST请求:

3.1 先整个触发函数

CREATE OR REPLACE FUNCTION check_temp_threshold()
RETURNS TRIGGER AS $$
DECLARE
    threshold NUMERIC := 30; -- 这里替换成你的阈值X
    webhook_url TEXT := 'https://your-alert-endpoint.com'; -- 替换成你的POST接口地址
BEGIN
    -- 只监测设备D,且均值超过阈值时触发
    IF NEW.avg_temperature > threshold AND NEW.device_id = 'D' THEN
        -- 用plsh扩展调用bash脚本发POST请求(需要先装plsh)
        PERFORM plsh.execute('curl -X POST ' || webhook_url || 
            ' -H "Content-Type: application/json" ' ||
            ' -d ''{"device_id": "' || NEW.device_id || '", "avg_temperature": ' || NEW.avg_temperature || ', "alert_time": "' || NEW.bucket || '"}''');
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

3.2 启用plsh扩展(用来调用外部脚本)

CREATE EXTENSION IF NOT EXISTS plsh;

3.3 给聚合视图加触发器

CREATE TRIGGER temp_threshold_alert_trigger
AFTER INSERT ON device_temp_5min_avg
FOR EACH ROW
EXECUTE FUNCTION check_temp_threshold();

方案二:用TimescaleDB官方Alerting(省心首选)

TimescaleDB自带了告警功能,不用写复杂的触发器,配置一下就能搞定:

3.1 先启用告警扩展

CREATE EXTENSION IF NOT EXISTS timescaledb_alerting;

3.2 创建告警规则

-- 定义规则:监测设备D过去5分钟的平均温度是否超过阈值
CREATE ALERT RULE temp_exceeds_threshold
WITH (
    description = '当设备D的5分钟平均温度超过阈值X时触发告警',
    severity = 'critical'
)
AS SELECT
    device_id,
    avg_temperature,
    bucket AS alert_time
FROM device_temp_5min_avg
WHERE device_id = 'D' AND avg_temperature > 30 -- 替换成你的阈值X
AND bucket >= NOW() - INTERVAL '5 minutes';

3.3 配置POST通知渠道

CREATE NOTIFICATION CHANNEL temp_alert_webhook
WITH (
    type = 'webhook',
    config = '{
        "url": "https://your-alert-endpoint.com",
        "method": "POST",
        "headers": {"Content-Type": "application/json"},
        "template": "{\"device_id\": \"{{.device_id}}\", \"avg_temperature\": {{.avg_temperature}}, \"alert_time\": \"{{.alert_time}}\"}"
    }'
);

3.4 关联规则和通知渠道,设置检查频率

-- 让告警触发时自动发POST通知
ALTER ALERT RULE temp_exceeds_threshold
SET NOTIFICATION CHANNEL = temp_alert_webhook;

-- 设置每分钟检查一次告警条件
ALTER ALERT RULE temp_exceeds_threshold
SET SCHEDULE INTERVAL = '1 minute';

4. 测试验证

手动插点测试数据,看看告警能不能正常触发:

INSERT INTO device_temperatures (time, device_id, temperature)
VALUES (NOW(), 'D', 35), (NOW() - INTERVAL '2 minutes', 'D', 36);

等个1-2分钟,去你的POST接口后台看看有没有收到通知就行啦。

内容的提问来源于stack exchange,提问作者David Ferreira

火山引擎 最新活动