41.5 nginx拦截prometheus查询请求使用lua脚本做promql的检查替换

本节重点介绍 :

  • 编写lua脚本做promql的检查替换
  • nginx拦截prometheus查询请求使用lua处理

编写lua脚本做promql的检查替换

获取请求参数

shell 复制代码
function replace_work()
    --Nginx服务器中使用lua获取get或post参数

    local request_method = ngx.var.request_method;
    local args = {}
    --获取参数的值

    if "GET" == request_method then
        args = ngx.req.get_uri_args();
    elseif "POST" == request_method then
        ngx.req.read_body();
        args = ngx.req.get_post_args();
    end

    local q_query = args["query"];
    local q_start = args["start"];
    local q_end = args["end"];
    local q_step = args["step"];
end

根据查询的promql算m5d

shell 复制代码
    local md5_str = get_str_md5(q_query)

    if md5_str == null then
        return
    end
function get_str_md5(input_s)
    local resty_md5 = require "resty.md5"
    local md5 = resty_md5:new()
    if not md5 then
        ngx.log(ngx.ERR, "failed to create md5 object")
        return
    end

    local ok = md5:update(input_s)
    if not ok then
        ngx.log(ngx.ERR, "failed to add data")
        return
    end
    local digest = md5:final()

    local str = require "resty.string"
    local md5_str = str.to_hex(digest)
    return md5_str
end

根据md5去redis中query

shell 复制代码
    local redis_query_key = "hke:heavy_expr:" .. md5_str
    --ngx.log(ngx.ERR, "redis_query_key: ",redis_query_key)
    local redis_get_res = redis_get(redis_query_key)
    if redis_get_res == true then
        q_query = redis_query_key
    end
function redis_get(key)
    -- start of redis

    local redis = require "resty.redis"
    local red = redis:new()
    --red:set_timeouts(1000, 1000, 1000)
    local ok, conn_err = red:connect("localhost", 6379)
    if not ok then
        ngx.log(ngx.ERR, "[redis]failed to connect redis server:", conn_err)
        return false
    end

    local res, get_err = red:get(key)
    if get_err then
        ngx.log(ngx.ERR, "[redis]failed to get value by key: ", key, "err:", get_err)
        return false
    end

    red:set_keepalive(30000, 1000)
    if res ~= ngx.null then
        ngx.log(ngx.INFO, "[redis]success  get value by key: ", key, "value: ", res)
        return true
    else
        return false
    end

    -- end of  redis
end

如果redis中有结果,就替换查询语句为聚合后的

shell 复制代码
    if redis_get_res == true then
        q_query = redis_query_key
    end

    local new_args = {}
    new_args["query"] = q_query
    new_args["start"] = q_start
    new_args["end"] = q_end
    new_args["step"] = q_step

    ngx.req.set_uri_args(new_args)
    --ngx.req.set_uri_args("end=" .. q_end)
    --local arg = ngx.req.get_uri_args()
    --for k, v in pairs(arg) do
    --    ngx.say("[GET ] key:", k, " v:", v)
    --end

完整的 prome_redirect.lua

shell 复制代码
function get_str_md5(input_s)
    local resty_md5 = require "resty.md5"
    local md5 = resty_md5:new()
    if not md5 then
        ngx.log(ngx.ERR, "failed to create md5 object")
        return
    end

    local ok = md5:update(input_s)
    if not ok then
        ngx.log(ngx.ERR, "failed to add data")
        return
    end
    local digest = md5:final()

    local str = require "resty.string"
    local md5_str = str.to_hex(digest)
    return md5_str
end

function redis_get(key)
    -- start of redis

    local redis = require "resty.redis"
    local red = redis:new()
    --red:set_timeouts(1000, 1000, 1000)
    local ok, conn_err = red:connect("localhost", 6379)
    if not ok then
        ngx.log(ngx.ERR, "[redis]failed to connect redis server:", conn_err)
        return false
    end

    local res, get_err = red:get(key)
    if get_err then
        ngx.log(ngx.ERR, "[redis]failed to get value by key: ", key, "err:", get_err)
        return false
    end

    red:set_keepalive(30000, 1000)
    if res ~= ngx.null then
        ngx.log(ngx.INFO, "[redis]success  get value by key: ", key, "value: ", res)
        return true
    else
        return false
    end

    -- end of  redis
end

function replace_work()
    --Nginx服务器中使用lua获取get或post参数

    local request_method = ngx.var.request_method;
    local args = {}
    --获取参数的值

    if "GET" == request_method then
        args = ngx.req.get_uri_args();
    elseif "POST" == request_method then
        ngx.req.read_body();
        args = ngx.req.get_post_args();
    end

    local q_query = args["query"];
    local q_start = args["start"];
    local q_end = args["end"];
    local q_step = args["step"];

    local md5_str = get_str_md5(q_query)

    if md5_str == null then
        return
    end
    local redis_query_key = "hke:heavy_expr:" .. md5_str
    --ngx.log(ngx.ERR, "redis_query_key: ",redis_query_key)
    local redis_get_res = redis_get(redis_query_key)
    if redis_get_res == true then
        q_query = redis_query_key
    end

    local new_args = {}
    new_args["query"] = q_query
    new_args["start"] = q_start
    new_args["end"] = q_end
    new_args["step"] = q_step

    ngx.req.set_uri_args(new_args)
    --ngx.req.set_uri_args("end=" .. q_end)
    --local arg = ngx.req.get_uri_args()
    --for k, v in pairs(arg) do
    --    ngx.say("[GET ] key:", k, " v:", v)
    --end

end

return replace_work();

nginx拦截prometheus查询请求使用lua处理

  • ngx_prome_redirect.conf
shell 复制代码
# 真实prometheus后端,使用前请修改
upstream real_prometheus {

       server 1.1.1.1:9090;
       server 2.2.2.2:9090;

}



server{
    listen 9992;
    server_name _;
    location / {  
        proxy_set_header Host $host:$server_port;
        proxy_pass http://real_prometheus;
    } 
    location /api/v1/query_range { 
        access_by_lua_file /usr/local/openresty/nginx/lua_files/prome_redirect.lua;
        proxy_pass http://real_prometheus;
    }
      
    
}
  • grafana发来的请求经过nginx,使用lua脚本处理
  • 然后转发到真实的prometheus 查询

本节重点总结 :

  • 编写lua脚本做promql的检查替换
  • nginx拦截prometheus查询请求使用lua处理
相关推荐
小小的木头人1 天前
CentOS 7 下 Nginx 访问自定义目录报 403 的完整排查:从端口权限到 SELinux
nginx·centos
新时代农民工~1 天前
【双机高可用部署方案-前后端部署】
java·nginx·springboot
运维全栈笔记1 天前
Nginx 模块化多业务站点通用配置模板
linux·运维·nginx
蓝胖的四次元口袋2 天前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
师傅别念了2 天前
Nginx 反向代理配置指南,看完这篇就够了
nginx
bst@微胖子2 天前
Linux环境做LVM快照
lua
迷茫的大专生3 天前
高可用总结
redis·mysql·nginx·高可用
szephyr3 天前
Nginx 反向代理实战:从 502、跨域到 HTTPS,一次打通
运维·nginx·https·部署·反向代理
迷茫的大专生3 天前
服务器部署与 MySQL 运维学习笔记:从 Ansible 到高可用与性能优化
mysql·nginx·ansible·mysql优化·keepalive
A心有千千结3 天前
Nginx网关可观测建设:打通流量入口,加速线上故障诊断
nginx·prometheus·devops