了解 Prometheus HTTP API 结果类型

问题描述 投票:0回答:1

当我调用 HTTP API 时,我得到了很大的不同:

1/ 通过 bash/curl 调用

2/通过nodejs/https GET 调用

任何帮助表示赞赏

谢谢

1/

这是通过 bash+curl 的调用:

#!/bin/bash
APIKEY="xxx-xxx"

curl https://<server>/prometheus-api/query \
-H "x-api-key: $APIKEY" \
-H "content-type: application/x-www-form-urlencoded" \
--data-urlencode \
query='ifHCInOctets{instance="MYROUTER.xxx"} and ifHCInOctets{ifName=~"et-1/1/1"}'

这是结果:结果类型是“向量”,结果“值”是字符串形式的数字,16 位(??帮助)

$ jq '.' result
{
  "status": "success",
  "data": {
    "resultType": "vector",
    "result": [
      {
        "metric": {
          "__name__": "ifHCInOctets",
          "ifAlias": "--- Lien vers ...",
          "ifDescr": "et-1/1/1",
          "ifIndex": "682",
          "ifName": "et-1/1/1",
          "instance": "MYROUTER.xxx",
          "job": "ifmibsnmp"
        },
        "value": [
          1725001024.046,
          "1975177966081341"
        ]
      }
    ]
  }
}

2/

现在这是通过nodejs+https的调用:

var request = '/prometheus-api/query?query=\"ifHCInOctets{instance=\'MYROUTER.xxx\'} and ifHCInOctets{ifName=~\'et-1/1/1\'}\"'

  var erequest = encodeURI(request)

  var options = {
      host:host,
      port: 443,
      method: "GET",
      path: erequest,
      headers: {
        'x-api-key': 'xxxxx',
        'content-type': 'application/x-www-form-urlencoded',
      },
      rejectUnauthorized: false,
  }
  https.get(options,function(resp) {
    resp.setEncoding('utf8');
    console.log('statusCode',resp.statusCode)
    if(resp.statusCode!=200) {
      console.log('-----------------')
    }
    //console.log('headers:', resp.headers);
    let data = '';
    resp.on('data',function(chunk) {
      data += chunk;
    });
    resp.on('end', () => {
      exec.emit('data',data)
    });
  }).on('error', (err) => {
    console.log('Error: ' + err.message);
  });

这是通过nodejs+https调用时的结果:resultType是“string”,result[1]是NaN

{ statusCode 200
data {
  status: 'success',
  data: {
    resultType: 'string',
    result: [
      1725001330.179,
      "ifHCInOctets{instance='MYROUTER.xxx'} and ifHCInOctets{ifName=~'et-1/1/1'}"
    ]
  }
}
node.js curl https prometheus
1个回答
0
投票

问题在于您将查询编写为查询字符串而不是请求正文。

尝试看看使用curl发出的请求与使用nodejs发出的请求之间的区别。我使用一个简单的服务器来打印请求中的标头/正文。

调试服务器.js

const server = http.createServer((req, res) => {
    const { rawHeaders, httpVersion, method, socket, url } = req;
    const { remoteAddress, remoteFamily } = socket;

    let body = '';
    req.on('data', (chunk) => {
        body += chunk;
    });
    req.on('end', () => {
        const data = JSON.stringify({
            timestamp: Date.now(),
            rawHeaders,
            httpVersion,
            method,
            remoteAddress,
            remoteFamily,
            url,
            body
        }, null, 4);
        console.info('---------------');
        console.info(data);
        res.end(data);
    });

});

console.info('App started');
server.listen(3000);

通过 Nodejs 响应

{
    "timestamp": 1725632661944,
    "rawHeaders": [
        "content-type",
        "application/x-www-form-urlencoded",
        "Host",
        "localhost:3000",
        "Connection",
        "keep-alive"
    ],
    "httpVersion": "1.1",
    "method": "GET",
    "remoteAddress": "::1",
    "remoteFamily": "IPv6",
    "url": "/api/v1/query?query=%22ifHCInOctets%7Benv='test'%7D%20and%20ifHCInOctets%7BifName=~'et-1/1/1'%7D%22",
    "body": ""
}

**response via curl**

```json
{
    "timestamp": 1725632707931,
    "rawHeaders": [
        "Host",
        "localhost:3000",
        "User-Agent",
        "curl/7.87.0",
        "Accept",
        "*/*",
        "content-type",
        "application/x-www-form-urlencoded",
        "Content-Length",
        "91"
    ],
    "httpVersion": "1.1",
    "method": "POST",
    "remoteAddress": "::ffff:127.0.0.1",
    "remoteFamily": "IPv6",
    "url": "/api/v1/query",
    "body": "query=ifHCInOctets%7Benv%3D%22test%22%7D+and+ifHCInOctets%7BifName%3D~%22et-1%2F1%2F1%22%7D"
}

© www.soinside.com 2019 - 2024. All rights reserved.