【问题标题】:Parse Nagios / Icinga Config with Python Regex使用 Python 正则表达式解析 Nagios / Icinga 配置
【发布时间】:2017-08-08 14:10:25
【问题描述】:

我正在尝试解析 Nagios / Icinga 配置,以便可以使用 Python 对其进行进一步处理。由于我找不到一个工作库来执行此操作(pynag 似乎根本不起作用),我正在尝试使用正则表达式编写一个简单的 Python 脚本来执行此操作。

基本上我想从这个配置文件中获取(它使用制表符进行缩进):

define host {
    address 123.123.123.123
    passive_checks_enabled  1
    }

define service {
    service_description Crondaemon
    check_command   check_nrpe_1arg!check_crondaemon
    }

像这样的 Python 元组:

(
 ('host', ('address', '123.123.123.123'), ('passive_checks_enabled', '1')), 
 ('service', ('service_description', 'Crondaemon'), ('check_command', 'check_nrpe_1arg!check_crondaemon'))
)

这是我的完整脚本,带有解析逻辑,包括一个测试示例:

import re

# white spaces are tabs!
TEST_STR = """
define host {
    address 123.123.123.123
    passive_checks_enabled  1
    }

define service {
    service_description Crondaemon
    check_command   check_nrpe_1arg!check_crondaemon
    }
"""

cfg_all_regex = re.compile(
    r'define\s+(\w+)\s*\{'
    '(.*?)'
    '\t}',
    re.DOTALL
)
# basic regex works
print(re.findall(cfg_all_regex, TEST_STR))

cfg_all_regex = re.compile(
    r'define\s+(\w+)\s*{\n'
    '(\t(.*)?\t(.*)?\n)*'
    '\t}',
    re.DOTALL
)
# more specific regex to extract all key values fails
print(re.findall(cfg_all_regex, TEST_STR))

不幸的是,我无法进行完整的解析,它总是匹配所有内容或不匹配。 你能告诉我如何修复我的正则表达式,以便我可以从我的 Icinga 配置中提取所有键值对吗?

【问题讨论】:

  • pynag 实际上正在工作,但您链接的 page 似乎已过时且未维护。它链接到github repo,您可以在其中获取最新版本。

标签: python regex nagios icinga


【解决方案1】:

re模块不支持重复捕获,所以

'(\t(.*)?\t(.*)?\n)*'

仅保留最后一次组捕获。

同样,我会这样改造

'\t(\w+)\s+([^\n]*)\n\'

因此,考虑到您的数据结构,一个可能的解决方案是创建一个匹配任一模式的正则表达式:

regex = r'define\s+(\w+)\s+\{\n|\t(\w+)\s+([^\n]*)\n|\t\}'
matches = re.finditer(regex, TEST_STR, re.DOTALL)

使用 for 循环,您可以遍历组

for match in matches:
    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1
        if match.group(groupNum):
            print("Group {}: {}".format(groupNum, match.group(groupNum)))

返回:

Group 1: host
Group 2: address
Group 3: 123.123.123.123
Group 2: passive_checks_enabled
Group 3: 1
Group 1: service
Group 2: service_description
Group 3: Crondaemon
Group 2: check_command
Group 3: check_nrpe_1arg!check_crondaemon

【讨论】:

  • 哇没想到这不能用一个简单的正则表达式来解决。但是您的解决方案就像一个魅力,我可以完成我的解析器。最终逻辑可以在这里找到:gist.github.com/ifischer/6e8aa105c5f644fd3803f8b41dcbe4f3 非常感谢您的帮助,为我节省了很多时间摆弄!
  • 刚发现regex支持重复抓包。也许这样解决方案可以简化很多。但暂时不值得努力
  • 你是对的。如果在您的项目中安装第三方库是可行的,那么正则表达式模块是一个更好的选择。
猜你喜欢
  • 2011-10-05
  • 2010-10-23
  • 2014-06-26
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
相关资源
最近更新 更多