![Linux:如何将日志文件中的新行发送到远程系统日志?](https://linux22.com/image/804911/Linux%EF%BC%9A%E5%A6%82%E4%BD%95%E5%B0%86%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%96%B0%E8%A1%8C%E5%8F%91%E9%80%81%E5%88%B0%E8%BF%9C%E7%A8%8B%E7%B3%BB%E7%BB%9F%E6%97%A5%E5%BF%97%EF%BC%9F.png)
我们有几个应用程序正在生成自己的纯文本日志文件,我想将这些文件转发到远程系统日志服务器进行集中日志记录。我无法访问root
这些计算机,也无法重新配置syslog
以将输出重定向到远程计算机。
我在网上找到了一些解决方案,但它们大多是人们自制的 bash 脚本,而我正在寻找更强大的、适合在潜在的大容量生产环境中实施的解决方案。
最好是设计时考虑到占用空间小、后台守护进程持续运行、可以跟上很多线路等。- 目前有哪些解决方案可用?
答案1
你已经拒绝了“其他人的 bash 脚本”,但这是一个非常常见的解决方案——一些创造性地使用logger
命令可以跟踪文件并将其内容发送到其他地方。
但我个人不会在生产环境中这样做。
一个更好的选择是使用更少的脚本黑客技术rsyslogd
,并且文本文件输入模块喜欢yoonix 提到-- 这是一个相当不错的解决方案,尽管在文件轮换期间可能会丢失一些行,但如果您使用的是 Linux 系统并将其作为rsyslog
syslog 守护程序,则不需要做太多额外的工作。
syslog-ng
也支持文件输入源rsyslog
其功能与 类似。
恕我直言最好的解决方案——尽管需要修改生成这些日志的应用程序——是直接记录到 syslog。您不想经历中间步骤、文件等——syslog
是 SYStem LOGger,以及在 Unix 平台上写入日志的东西应该将它们发送到 syslog。
遗憾的是,实现这一点留给读者(和应用程序开发人员)作为练习,如果您的开发人员不存在、懒惰或能力不足,则可能无法实现。...
答案2
例如,使用您想要监控的文件(或多个文件)和您的系统日志服务器信息创建一个配置。
文件到syslog.conf:
input { file { path => "/var/log/kern.log" } }
output {
syslog {
facility => "kernel"
host => "syslog.example.com"
port => 514
severity => "informational"
}
}
使用以下命令启动 logstash
java -jar logstash-1.2.2-flatjar.jar agent -f file-to-syslog.conf
答案3
我将它们组合tail.c
成logger.c
一个单一的、占用空间小的编译程序(二进制),该程序轻量、快速且稳定。只要它具有对日志文件的读取权限,它就可以工作,而无需 root 权限。
我还对本机记录器做了一些改进,并添加了一项新的(可选)功能,即在将日志发送到日志服务器之前在每个日志行的开头插入一个文本字符串。结果是程序可以自行运行,而无需使用 shell 管道(即不需要tail logfile | logger
)。它将永远运行,直到明确终止或在写入网络套接字时遇到错误。即使日志文件被旋转甚至消失,它也会继续运行(它只会继续查看文件是否重新出现。)
它使用起来很简单:只需给它一个或多个日志文件进行监控,每次将新行写入文件时,它都会将该行的副本发送到您指定的本地或远程系统日志服务器。如果您使用该选项,还会添加额外的文本字符串。
我实际上在 12 月就完成了这个程序,但当时正在等待雅虎取得版权并开放,现在他们已经取得了版权。(这是我在雅虎工作的一部分,所以我编写了这个程序)。
filelogger程序信息及下载链接:
答案4
我正在回答我自己的问题。
swatch 可能已经起作用,但是我无法让 perl 的 Sys::Syslog 模块在主机上工作,并且安装在主机上的 /usr/bin/logger 不支持记录到远程服务器(util-linux-ng-2.17.2)。
因此,我做的第一件事就是下载 util-linux-2.20.1 的源代码,其中的记录器程序支持远程日志记录。经过测试,很明显日志行允许的字符数是有限制的。深入研究源代码后,我发现了一个硬编码的 400 个字符的限制。(如果您不相信我,请在任何 Linux 系统上运行“strings /usr/bin/logger | grep 400”)。
此限制对于 apache 类型的日志记录(包括 nodejs)来说是不可接受的,因此我修改了代码并将限制增加到 4096。在此过程中,我还添加了一个新的命令行选项,允许在每个日志行的开头插入一个可选的文本字符串。我这样做是因为 nodejs 日志不包含主机名,而 apache 中可能会看到主机名。
此时,我可以使用“tail -F -n 0 [logfile] | ./modified_logger ....”运行 shell 脚本,并且成功了。但我对从 supervise (daemontools) 甚至在后台运行此脚本有些担心,因为如果管道的一端或另一端终止,则存在整个管道终止的风险。我还担心(尽管未经测试)性能。
所以我决定将 tail 功能与 logger 功能合并为一个可执行二进制文件,这样就无需使用 Unix 管道或外部程序。我通过破解 gnu coreutils 中的 tail.c 并将我需要的功能合并到修改后的 logger 程序中来实现这一点。
结果是一个新的二进制文件(117k 大小),我将其称为“filelogger”,它持续监视一个或多个文件,并通过 UDP 或 TCP 将每行新内容记录到本地或远程系统日志中。它工作得很好。我做了一点基准测试,它在大约 3 秒内跨子网(带有一个 vlan 和它们之间的几个物理交换机)记录了大约 17,000 行(1.8MB),记录到运行 syslog-ng 的远程服务器。
要运行该程序,请执行以下操作(在前台、后台或使用 daemontools 监督):
./filelogger -t 'access' -d -p local1.info -n [远程日志主机] -u /tmp/ignored -a $(主机名) /tmp/myfile1 /tmp/myfile2 ...
/tmp/myfile1 和 /tmp/myfile2 是正在监视的文件。
“-a” 是我添加的新选项。在本例中,我在每行日志的开头插入本地主机名。
这个解决方案正是我提出问题时所寻找的解决方案类型,而且事实证明,在我自己做出来之前,它并不存在。:)