6个版本 (3个重大更改)

0.7.1 2024年6月20日
0.7.0 2023年3月13日
0.6.1 2022年9月21日
0.5.0 2022年8月17日
0.4.0 2022年1月25日

#185 in HTTP服务器

Download history 148/week @ 2024-06-17

每月307次下载

Unlicense

16KB
206

tailsrv

tailsrv 监视单个文件,并在文件增长时将其内容流式传输到多个客户端。它就像 tail -f,但作为一个服务器。

  • 当客户端连接时,tailsrv 会向它发送文件数据。
  • 如果没有新数据要发送,tailsrv 会等待文件增长。
  • 如果套接字已满,tailsrv 会等待客户端消耗一些数据后再发送更多。
  • 客户端可以在连接时指定一个初始字节偏移量。

一些实现细节

  • 所有数据都是通过 sendfile 发送的。这意味着数据是直接由内核从页缓存发送到网卡。从不将数据复制到用户空间。这使 tailsrv 具有很好的吞吐量。然而,这也意味着 tailsrv 只能在 Linux 上运行。
  • 我们使用 inotify 跟踪文件的修改。这意味着如果文件没有增长(并且没有新的客户端连接),tailsrv 不会做任何工作。
  • 我们为每个客户端启动一个线程。这意味着缓慢的客户端可以以自己的速度接收数据,而不会影响其他客户端。

如果您想了解 tailsrv 与 Kafka 的比较,请参阅 这里 的比较。

使用示例

假设您有一台名为 webserver 的机器。选择一个端口号并启动 tailsrv

$ tailsrv -p 4321 /var/log/nginx/access.log

tailsrv 现在正在监视 access.log。您可以从您的笔记本电脑连接到 tailsrv 并流式传输文件的内容

$ echo "1000" | nc webserver 4321

您将立即看到 access.log 的内容,从字节 1000 开始,到文件末尾。连接保持打开,等待新数据。一旦 nginx 将一行写入 access.log,它就会出现在您的笔记本电脑上。这大致与这样做相同

$ ssh webserver -- tail -f -c+1000 /var/log/nginx/access.log

然而,您可能希望直接从您的日志消耗应用程序连接到 tailsrv。

let sock = TcpStream::connect("webserver:4321")?;
writeln!(sock, "{}", 1000)?;
for line in BufReader::new(sock).lines() {
    /* handle log data */
}

上面的示例是用 rust 编写的,但如您所见,它非常简单:您可以从任何编程语言中这样做,而无需特殊的客户端库。

协议

步骤 1:客户端向 tailsrv 发送头部信息

头部信息是一个 ASCII 码整数,以换行符结束。如果整数是正数,它表示初始字节数偏移量。如果整数是负数,它表示“从文件末尾开始计数”。示例

  • 0\n - 从文件开头开始
  • 1000\n - 从第 1000 个字节开始
  • -1000\n - 发送最后 1000 个字节

步骤 2:tailsrv 向客户端发送数据

一旦它收到头部信息,tailsrv 将开始向您发送文件数据。

...这就是整个协议的内容。tailsrv 将忽略您在换行符之后发送的任何内容。当您完成时,只需关闭连接即可。除非 tailsrv 正在关闭,否则它不会终止连接。

没有内带会话控制:如果您想跳转到文件中的不同位置,请关闭连接并打开一个新的连接。

文件

tailsrv 期望一个将被附加的文件。如果被监视的文件被删除或移动,tailsrv 将退出。如果您修改了文件的中间部分 - 嗯,不会发生灾难性的事情,但您的客户端可能会感到困惑。

功能

tracing-journald

启用对 tracing-journald 库的依赖,并添加了一个新的 --journald 命令行标志。这将把所有跟踪输出重定向到系统 journald,它比默认输出格式化程序提供的信息更丰富。如果您计划以 tailsrv 作为 systemd 服务运行,特别有用。

sd-notify

启用对 sd-notify 库的依赖。《tt class="src-rs">tailsrv 将在开始接受客户端连接后发送 systemd 准备就绪通知。这与 notify systemd 服务类型结合使用时很有用。

许可

本软件属于公共领域。有关详细信息,请参阅 UNLICENSE。

依赖项

~8–18MB
~238K SLoC