python - 如何解决 Telegraf 中的此错误?

标签 python influxdb telegraf telegraf-inputs-plugin telegraf-plugins

我有一个自定义的 python 插件,用于将数据拉入 Telegraf。它按预期打印出线路协议(protocol)输出。
在我的 Ubuntu 18.04 环境中,当这个插件运行时,我在我的日志中看到一行:

2020-12-28T21:55:00Z E! [inputs.exec] Error in plugin: exec: exit status 1 for command '/my_company/plugins-enabled/plugin-mysystem/poll_mysystem.py': Traceback (most recent call last):...
这就对了。我不知道如何获得实际的回溯。
如果我运行 sudo -u telegraf /usr/bin/telegraf -config /etc/telegraf/telegraf.conf ,插件按预期工作。它完全按照应有的方式轮询和加载数据。
当 Telegraf 自行执行插件时,我不确定如何解决此错误。
我已经重新启动了 Telegraf 服务。我已经验证了权限(我认为上面的执行表明它应该可以工作)。
根据收到的评论和答案提供了一些额外的细节:
  • 该插件位于一个目录中,其中整个结构归 telegraf:telegraf 所有。 .该错误似乎并不表示它无法看到正在执行的文件,而是当 Telegraf 执行插件时文件中的某些内容失败了。
  • 插件代码如下。

  • 插件代码( /my_company/plugins-enabled/plugin-mysystem/poll_mysystem.py ):
    from google.auth.transport.requests import Request
    from google.oauth2 import id_token
    import requests
    import os
    
    RUNTIME_URL = INTERNAL_URL
    MEASUREMENT = "MY_MEASUREMENT"
    CREDENTIALS = "GOOGLE_SERVICE_FILE.json"
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = CREDENTIALS  # ENV VAR REQUIRED BY GOOGLE CODE BELOW
    CLIENT_ID = VALUE_FROM_GOOGLE
    
    exclude_fields = ["name", "version"] # Don't try to put these into influxdb from json response
    
    def make_iap_request(url, client_id, method="GET", **kwargs):
        # Code provided by Google docs
        # Set the default timeout, if missing
        if "timeout" not in kwargs:
            kwargs["timeout"] = 90
    
        # Obtain an OpenID Connect (OIDC) token from metadata server or using service
        # account.
        open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
    
        # Fetch the Identity-Aware Proxy-protected URL, including an
        # Authorization header containing "Bearer " followed by a
        # Google-issued OpenID Connect token for the service account.
        resp = requests.request(method, url, headers={"Authorization": "Bearer {}".format(open_id_connect_token)}, **kwargs)
        if resp.status_code == 403:
            raise Exception("Service account does not have permission to " "access the IAP-protected application.")
        elif resp.status_code != 200:
            raise Exception(
                "Bad response from application: {!r} / {!r} / {!r}".format(resp.status_code, resp.headers, resp.text)
            )
        else:
            return resp.json()
    
    
    def print_results(results):
        """
        Take the results of a Dolores call and print influx line protocol results
        """
        for item in results["workflow"]:
            line_protocol_line_base = f"{MEASUREMENT},name={item['name']}"
            values = ""
            for key, value in item.items():
                if key not in exclude_fields:
                    values = values + f",{key}={value}"
            values = values[1:]
            line_protocol_line = f"{line_protocol_line_base} {values}"
            print(line_protocol_line)
    
    
    def main():
        current_runtime = make_iap_request(URL, CLIENT_ID, timeout=30)
        print_results(current_runtime)
    
    
    if __name__== "__main__":
        main()
    
    telegraf.conf的相关部分文件:
    [[inputs.exec]]
      ## Commands array
      commands = [
        "/my_company/plugins-enabled/plugin-*/poll_*.py",
      ]
    
    配置文件的代理部分
    [agent]
      interval = "60s"
      round_interval = true
      metric_batch_size = 1000
      metric_buffer_limit = 10000
      collection_jitter = "0s"
      flush_interval = "10s"
      flush_jitter = "0s"
      precision = ""
      debug = false
      quiet = false
      logfile = "/var/log/telegraf/telegraf.log"
      hostname = ""
      omit_hostname = true
    
    我接下来该怎么做?

    最佳答案

    exec插件在换行符处截断您的异常消息。如果您结束对 make_iap_request 的调用在 try/except 块中,然后 print(e, file=sys.stderr)与其让异常一直冒泡,不如告诉你更多。

    def main():
        """
        Query URL and print line protocol
        """
        try:
            current_runtime = make_iap_request(URL, CLIENT_ID, timeout=30)
            print_results(current_runtime)
        except Exception as e:
            print(e, file=sys.stderr)
    
    或者,您的脚本可以将错误消息记录到它自己的日志文件中,而不是将它们传回 Telegraf。这将使您更好地控制记录的内容。
    我怀疑您遇到了环境问题,您的运行方式有所不同。如果不是权限,则可能是环境变量差异。

    关于python - 如何解决 Telegraf 中的此错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65484916/

    相关文章:

    InfluxDB如何查询每一个第n个值

    du - 如何通过 Telegraf 监控目录的大小

    json - 如何在 Telegraf 中过滤 JSON 响应

    telegraf - 如何检查 telegraf 中的插件状态?

    python - PyQt 中继承的困难

    unit-testing - 使用 influxdb 的程序的单元测试

    python - 如何在Python正则表达式中使用变量?

    influxdb - 在将它们添加到生产 influxdb 之前测试连续查询的最佳方法?

    python - 带有 python 问题的嵌套 JSON

    python - 将 2010 Q1 转换为日期时间 2010-3-31