Fluentd tcp 连接通过 netcat 工具成功。但通过基本 Python 3.7 失败。为什么?
Fluentd tcp contact succeeds via netcat tool. But fails via basic Python 3.7. Why?
所以我开发了一个基于 docker 的 fluentd TCP 日志收集器。
按照此处的示例,https://docs.fluentd.org/input/tcp 成功地从我的主机 Win 10 WSL (Debian) 发送了一条线
echo "my_service: 08:03:10 INFO [my_py_file:343]: My valuable log info." | netcat 127.0.0.1 5170
正如所希望的那样,它作为一个不错的 JSON 到达了流利的状态。但我想从 python 3.7 开始!所以:
import socket
def netcat(hn: str, p: int, content: bytes):
"""https://www.instructables.com/id/Netcat-in-Python/"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((hn, p))
sock.sendall(content)
sock.close()
msg_raw = "my_service: 08:03:10 INFO [my_py_file:343]: My valuable log info."
netcat('127.0.0.1', 5170, bytes(msg_raw, 'utf-8'))
WSL or no:这个python脚本贯穿,没有异常。流利的也没有任何反应,我无法解释。 你们中有人愿意吗?
以防万一:这是我 fluentd.conf
的相关部分。
<source>
@type tcp
@label mainstream
@id pawc_tcp
tag paws.tcp
port 5170
bind 0.0.0.0
# https://docs.fluentd.org/parser/regexp
<parse>
@type regexp
expression /^(?<service_uuid>[a-zA-Z0-9_-]+): (?<logtime>[^\s]+) (?<loglvl>[^\s]+) \[(?<file>[^\]:]+):(?<line>\d+)\]: (?<msg>.*)$/
time_key logtime
time_format %H:%M:%S
types line:integer
</parse>
</source>
<label mainstream>
<match paws.tcp>
@type file
@id output_tcp
path /fluentd/log/tcp.*.log
symlink_path /fluentd/log/tcp.log
</match>
</label>
尝试在消息末尾发送 \r\n
或 [=11=]
。消息以字节形式通过网络发送,因此它可能存储在缓冲区中,读取缓冲区的代码需要一种方法来知道消息已结束。正则表达式也在行终止符上匹配,所以我认为这也是必要的。
如上文 Alex W 所述,我使用的流利正则表达式接受的 TCP 行需要 \n
。我想添加第二个答案来改进原始问题的 python 代码。
居然还有一个readily-implementedlogging.handler.SocketHandler
class!但是,它会查看 python 日志服务器来处理其输出。使用 fluentd 这意味着必须覆盖 emit
函数才能使用它。之后一切正常。
import logging, logging.handlers
class SocketHandlerBytes(logging.handlers.SocketHandler):
def emit(self, record):
try:
msg = bytes(self.format(record) + "\n", 'utf-8')
self.send(msg)
except Exception:
self.handleError(record)
sh = SocketHandlerBytes(host, port)
sh.setFormatter(logger_format_appropriate_for_your_fluentd_tcp_regex)
logging.root.addHandler(sh)
所以我开发了一个基于 docker 的 fluentd TCP 日志收集器。
按照此处的示例,https://docs.fluentd.org/input/tcp 成功地从我的主机 Win 10 WSL (Debian) 发送了一条线
echo "my_service: 08:03:10 INFO [my_py_file:343]: My valuable log info." | netcat 127.0.0.1 5170
正如所希望的那样,它作为一个不错的 JSON 到达了流利的状态。但我想从 python 3.7 开始!所以:
import socket
def netcat(hn: str, p: int, content: bytes):
"""https://www.instructables.com/id/Netcat-in-Python/"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((hn, p))
sock.sendall(content)
sock.close()
msg_raw = "my_service: 08:03:10 INFO [my_py_file:343]: My valuable log info."
netcat('127.0.0.1', 5170, bytes(msg_raw, 'utf-8'))
WSL or no:这个python脚本贯穿,没有异常。流利的也没有任何反应,我无法解释。 你们中有人愿意吗?
以防万一:这是我 fluentd.conf
的相关部分。
<source>
@type tcp
@label mainstream
@id pawc_tcp
tag paws.tcp
port 5170
bind 0.0.0.0
# https://docs.fluentd.org/parser/regexp
<parse>
@type regexp
expression /^(?<service_uuid>[a-zA-Z0-9_-]+): (?<logtime>[^\s]+) (?<loglvl>[^\s]+) \[(?<file>[^\]:]+):(?<line>\d+)\]: (?<msg>.*)$/
time_key logtime
time_format %H:%M:%S
types line:integer
</parse>
</source>
<label mainstream>
<match paws.tcp>
@type file
@id output_tcp
path /fluentd/log/tcp.*.log
symlink_path /fluentd/log/tcp.log
</match>
</label>
尝试在消息末尾发送 \r\n
或 [=11=]
。消息以字节形式通过网络发送,因此它可能存储在缓冲区中,读取缓冲区的代码需要一种方法来知道消息已结束。正则表达式也在行终止符上匹配,所以我认为这也是必要的。
如上文 Alex W 所述,我使用的流利正则表达式接受的 TCP 行需要 \n
。我想添加第二个答案来改进原始问题的 python 代码。
居然还有一个readily-implementedlogging.handler.SocketHandler
class!但是,它会查看 python 日志服务器来处理其输出。使用 fluentd 这意味着必须覆盖 emit
函数才能使用它。之后一切正常。
import logging, logging.handlers
class SocketHandlerBytes(logging.handlers.SocketHandler):
def emit(self, record):
try:
msg = bytes(self.format(record) + "\n", 'utf-8')
self.send(msg)
except Exception:
self.handleError(record)
sh = SocketHandlerBytes(host, port)
sh.setFormatter(logger_format_appropriate_for_your_fluentd_tcp_regex)
logging.root.addHandler(sh)