我想做一个syslog解析器来转换我的syslog,它有一个key=value格式的JSON信息,输出文件是一个.txt文件,我可以导入到FortiSIEM中,这对于兼容的syslog来说是非常挑剔的,而且我无法开始解析"原始的"syslog,因此我的 idea 是在日志(log)到达SIEM之前简化它.

我用PyParsing做了一些测试,但我真的不知道如何使用它,我的输出文件正在创建中,但结果是空白的

我想我不能分享系统日志(log),所以这里有一个非常粗略的例子,说明系统日志(log)是什么样子的:

<140>1 2022-05-02T08:31:22.478Z platform数据导出-syslog_variation-{"key"=值,信息:{"key"=value,"key"=value},info2:{"key"=value,"key"=value},"key"=value}

我想出的 playbook 是:

from pyparsing import Word, Suppress, alphanums, CharsNotIn, ZeroOrMore, Dict

# Define header
priority = Suppress("<") + Word(alphanums) + Suppress(">")
version = Word(alphanums) + Suppress(" ")
timestamp = CharsNotIn(" ") + Suppress(" ")
hostname = CharsNotIn(" ") + Suppress(" ")
appname = CharsNotIn(" ") + Suppress(" ")
procid = CharsNotIn(" ") + Suppress(" ")
msgid = CharsNotIn("\n")
header = priority + version + timestamp + hostname + appname + procid + msgid

# Define key-value pairs
key = Word(alphanums + "_")
value = CharsNotIn("\n")
pair = key + Suppress("=") + value
kv_pairs = Dict(pair + ZeroOrMore(Suppress(",") + pair))

# Define message format
message = header + Suppress(" ") + kv_pairs

# Open input and output files
with open("syslog.txt") as input_file, open("syslog_output.txt", "w") as output_file:
    for line in input_file:
        try:
            # Convert to key-value format
            parsed_message = message.parseString(line.strip())
            kv_message = " ".join([f"{key}={value}" for key, value in parsed_message.items()])

            # Write the message to the output file
            output_file.write(parsed_message + "\n")
        except Exception as e:
            print(f"Failed to parse line: {line} with error: {e}")

            continue

当我运行脚本并打印headermessage输出时,我得到两个异常:

Failed to parse line: "Whole Syslog Text"
 with error: Expected ' ', found '2022'  (at char 7), (line:1, col:8)

Failed to parse line: 
 with error: Expected '<'  (at char 0), (line:1, col:1)

Header:  {Suppress:('<') W:(0-9A-Za-z) Suppress:('>') W:(0-9A-Za-z) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:(
)}

Message:  {Suppress:('<') W:(0-9A-Za-z) Suppress:('>') W:(0-9A-Za-z) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:( ) Suppress:(' ') !W:(
) Suppress:(' ') Dict:({W:(0-9A-Z_a-z) Suppress:('=') !W:(
) [{Suppress:(',') W:(0-9A-Z_a-z) Suppress:('=') !W:(
)}]...})}

我希望我的输出文件如下所示:

<140>1 2022-05-02T08:31:22.478Z platform dataexport - syslog_variation -
key=value
key=value
key=value
...

我需要有标头来识别FortiSIEM上的日志(log)类型.

推荐答案

正如我在 comments 中提到的,默认情况下,pyparsing会跳过空格,因此所有+ Suppress(" ")个术语都应该删除.

CharsNotIn是跳过空格规则的例外,我发现Word(printables)更好.

我将您的timestamphostname等术语替换为Word(printables),如下所示:

timestamp = Word(printables)
hostname = Word(printables)
appname = Word(printables)
procid = Word(printables)
msgid = rest_of_line
header = priority + version + timestamp + hostname + appname + '-' + procid + '-' + msgid

我使用以下代码测试解析器:

header.run_tests("""\
    <140>1 2022-05-02T08:31:22.478Z platform dataexport - syslog_variation - {"key"=value, info:{"key"=value, "key"=value, "key"=value}, info2:{"key"=value, "key"=value},"key"=value}
    """)

结果是这样的:

<140>1 2022-05-02T08:31:22.478Z platform dataexport - syslog_variation - {"key"=value, info:{"key"=value, "key"=value, "key"=value}, info2:{"key"=value, "key"=value},"key"=value}
['140', '1', '2022-05-02T08:31:22.478Z', 'platform', 'dataexport', '-', 'syslog_variation', '-', ' {"key"=value, info:{"key"=value, "key"=value, "key"=value}, info2:{"key"=value, "key"=value},"key"=value}']

您必须改进键-值对的定义.对key使用pyparsing的QuotedString('"'),因为它是用引号括起来的值.对于value,您需要更加小心地只读到下一个逗号或},而不是一直读到行尾的\n.

Python相关问答推荐

如何计算两极打印机中 * 所有列 * 的出现次数?

仿制药的类型铸造

pandas滚动和窗口中有效观察的最大数量

大小为M的第N位_计数(或人口计数)的公式

如何使用pytest来查看Python中是否存在class attribution属性?

Pandas—在数据透视表中占总数的百分比

LocaleError:模块keras._' tf_keras. keras没有属性__internal_'''

在输入行运行时停止代码

ruamel.yaml dump:如何阻止map标量值被移动到一个新的缩进行?

如何在FastAPI中替换Pydantic的constr,以便在BaseModel之外使用?'

提取数组每行的非零元素

用fft计算指数复和代替求和来模拟衍射?

如何使用matplotlib查看并列直方图

如何根据一定条件生成段id

用由数据帧的相应元素形成的列表的函数来替换列的行中的值

类型对象';敌人';没有属性';损害';

文本溢出了Kivy的视区

Numpy`astype(Int)`给出`np.int64`而不是`int`-怎么办?

#将多条一维曲线计算成其二维数组(图像)表示

将标签与山脊线图对齐