Telegraf Socket Listener 输入插件

导航至

Telegraf 最大的优势之一是它提供了大量的插件集合,可以立即用于开始从各种应用程序收集数据。这涵盖了很多常见的基础设施组件,如数据库和 Web 服务器,但如果您想使用自己的脚本或应用程序将数据导入 Telegraf,您还可以使用各种更通用的输入插件。有一个文件插件,可以从磁盘上的文件读取或跟踪文件,一个 exec 插件,可以执行您自己的脚本或命令并解析它们的输出,以及通过 HTTP 监听数据或轮询外部端点(http_listener_v2 和 http)的插件。

我最终最常用的插件之一是 socket_listener 插件,它允许您使用 UDP、TCP 或 Unix 套接字将数据发送到 Telegraf。InfluxDB 行协议的简单性以及使用大多数编程语言写入套接字的简易性使其成为快速原型设计和更长期解决方案的强大工具。

让我们看看该插件在实际应用中的一些示例。我们将使用运行 Ubuntu 的主机系统,其中 TelegrafInfluxDB 是从官方 InfluxData 存储库安装的。

UDP:用户数据报协议

对于第一个示例,让我们配置 socket_listener 插件以接受 UDP 数据包。UDP 协议是一种无连接、尽力而为的服务:消息被发送到它们的接收者,但不保证它们会被接收。这样做的一个好处是,相对于像 TCP 这样更可靠的协议,UDP 的处理开销更少。这使得 UDP 非常适合进程间通信或一些数据丢失是可以接受的情况。

为了设置 Telegraf 以接收 UDP 消息,首先在您的 telegraf.conf 中配置此块

[[inputs.socket_listener]]
  service_address = "udp://:8094"
  data_format = "influx"

这会将 Telegraf 配置为在 UDP 端口 8094 上以 InfluxDB 行协议格式侦听数据。快速重启 Telegraf,它应该就可以接收数据了

sudo systemctl restart telegraf

现在我们可以开始通过 UDP 向 Telegraf 写入一些数据了。为了发送数据,我们将使用两个常见的命令行实用程序,echo 和 nc 或 netcat。在您的终端中输入以下命令

$ echo "m1,tag1=tag_value value=1" | nc -u -4 -q localhost 8094
$ echo "m1,tag1=tag_value value=2" | nc -u -4 -q localhost 8094
$ echo "m1,tag1=tag_value value=3" | nc -u -4 -q localhost 8094

InfluxDB 行协议是一种纯文本格式,这意味着我们可以使用 echo 命令以该格式直接将消息打印到 stdout,并使用 | 字符将该文本“管道”到 nc 中,这将通过网络连接传输数据(在我们的例子中,通过环回接口在同一台机器上)。我们为 nc 提供了几个参数:-u、-4 和 -q。第一个参数告诉 nc 使用 UDP 发送数据;第二个参数表示我们应该使用 IPv4,第三个参数告诉 nc 在数据发送完毕后退出。

由于 UDP 不保证消息是否会被传递,让我们使用 Influx CLI 验证数据是否实际到达数据库

$ influx
Connected to http://localhost:8086 version 1.7.4
InfluxDB shell version: unknown
Enter an InfluxQL query
> use database telegraf
> SELECT * FROM mymeasurement WHERE time > now()-5m
name: socketwriter
time                host           tag1       value
----                ----           ----       --------
1562602580414360000 noah-mbp.local tag_value  1
1562602581418350000 noah-mbp.local tag_value  2
1562602582420300000 noah-mbp.local tag_value  3

成功!我们的三个数据点已写入数据库。

Unix 套接字

虽然 UDP 和 TCP 是网络协议,但 socket_listener 插件还具有侦听 Unix 套接字的能力,这提供了一种通过内核在同一主机上的两个进程之间交换数据的方法。即使在同一主机上通信时,像 TCP 和 UDP 这样的 IP 套接字也会通过环回网络接口发送数据。另一方面,Unix 套接字可以避免这种额外的工作,并将数据直接发送到接收套接字缓冲区,这在本地发送数据时使其具有性能优势。您可以在这篇题为 unix domain sockets vs. internet sockets 的邮件列表帖子中阅读更多关于 Unix 套接字和网络套接字之间差异的信息。

这一次,我们将编写一个小型 Python 脚本,而不是使用命令行工具,该脚本将通过 Unix 套接字向 Telegraf 发送一维 随机游走 数据。首先,我们将 Telegraf 配置如下(完整配置在此

[[inputs.socket_listener]]
  service_address = "unixgram:///tmp/telegraf.sock"

然后我们将使用新配置运行 Telegraf

$ telegraf --config socket-telegraf.conf --debug

我们可以通过列出 /tmp 目录的内容来看到 Telegraf 已经创建了套接字

$ ls /tmp
telegraf.sock

接下来我们将创建我们的 Python 脚本。完整的脚本可以在 此处 找到。在导入语句和一个中断处理程序之后,当我们使用 Ctrl+C 退出我们的脚本时,它将关闭套接字,我们将创建一个套接字对象并连接到 Telegraf 已打开的套接字。

# The file handler for the Telegraf process.
telegraf_socket = "/tmp/telegraf.sock"

# Connection to Telegraf, over a network socket.
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)

sock.connect(telegraf_socket)

然后我们创建一个循环,该循环首先将当前数据点发送到 InfluxDB,然后再更新位置变量以进行下一次循环,并休眠一秒钟,以便限制我们发送的点数

while True:
    message = "socketwriter position=%d\n" % x
    print(message)
    sock.send(message.encode('utf8'))
    x = x + random.randint(-1, 1)
    time.sleep(1)

在 Telegraf 运行的情况下,让我们启动我们的脚本

$ python3 unix_socket_writer.py 
socketwriter position=0

socketwriter position=0

socketwriter position=1

socketwriter position=0

再一次,我们可以打开 InfluxDB CLI 并验证我们的数据是否已写入

$ influx
Connected to http://localhost:8086 version 1.7.4
InfluxDB shell version: unknown
Enter an InfluxQL query
> use database telegraf
> SELECT * FROM socketwriter WHERE time > now()-1m
name: socketwriter
time                host           position
----                ----           --------
1562602580414360000 noah-mbp.local 0
1562602581418350000 noah-mbp.local 0
1562602582420300000 noah-mbp.local 1
1562602583422080000 noah-mbp.local 0

看起来不错!

在您自己的项目中使用它!

无论您是使用 Unix 套接字来获得其本地性能,还是使用 TCP 套接字来获得其网络健壮性,Telegraf 的 socket_listener 插件都提供了一种最简单的方法,可以从您的脚本和应用程序中获取数据并将其导入 Telegraf。如果这不适合您,请查看 Telegraf 提供的其他通用插件 - 您一定会找到适合您需求的东西。

如果您有关于设置 socket_listener 插件的问题或需要帮助,请查看我们的一些社区资源,例如我们的公共 Slack 或 Discourse 论坛,或者直接在 Twitter 上联系我 @noahcrowley