将列表输出设置为字典格式



我编写了一个megacli prometheus导出程序,它需要以下数据:固件状态、错误、机柜id、插槽和适配器。

脚本的输出如下所示:

['Adapter #0', 'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up', 'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Adapter #1', 'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up', 'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Adapter #2', 'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up', 'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up']

为了把它变成普罗米修斯可以查询的东西,我试图将上面的列表重新格式化为这样的东西:

{
"Adapter #0": {
1: {
"Enclosure Device ID": "252",
"Slot Number": "0",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
},
2: {
"Enclosure Device ID": "252",
"Slot Number": "1",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
}
}
},
{
"Adapter #1": {
1: {
"Enclosure Device ID": "252",
"Slot Number": "0",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
},
2: {
"Enclosure Device ID": "252",
"Slot Number": "1",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
}
}
},
{
"Adapter #2": {
1: {
"Enclosure Device ID": "252",
"Slot Number": "0",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
},
2: {
"Enclosure Device ID": "252",
"Slot Number": "1",
"Media Error Count": "0",
"Other Error Count": "0",
"Firmware State": "Online, Spun Up"
}
}
}

最终,每个驱动器的最终查询将变成以下内容

"megacli_query";{'enclosure_id'='enclosure Device id','adapter_#'='adapter','slot_number'='slot number','media_error'='media error Count','other_error'='other error Count'','state'='Firmware state'}

因此,我正试图弄清楚以下几个步骤:

  1. 将变量适当分组到其中一个适配器
  2. 将这些变量(表示为字符串(转换为字典
  3. 进一步将这些变量分组到表示单个驱动器的嵌套字典中(在这个粗略的示例中,每个适配器有2个驱动器(

步骤2可以通过在":"并添加到一本空字典中,但我很难构思如何将其拼凑在一起。

我现在唯一拥有的是将变量分组为5组:

from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)

def get_drive_health():
t = grouper(drives, 5)
for i in t:
print(i)
get_drive_health()

但这只对列表中的每5个元素进行分组;适配器";这是不应该的。

这可能有点脆弱,但我希望这个概念能让你走上一条适合你的道路。答案是基于将数据转换为可迭代数据,以便我们可以方便地调用next()

data = [
'Adapter #0',
'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Adapter #1',
'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Adapter #2',
'Enclosure Device ID: 252', 'Slot Number: 0', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up',
'Enclosure Device ID: 252', 'Slot Number: 1', 'Media Error Count: 0', 'Other Error Count: 0', 'Firmware state: Online, Spun Up'
]
## ----------------------
## turn your data into an iterable so that we can call next()
## we could also have done this with a generator expression.
## ----------------------
data = iter(data)
## ----------------------
data_out = {}
## ----------------------
## Start by assuming/anticipating that the first item in data
## is the initial Adapter element. If it is not things should fail "ok-ish"
## ----------------------
adapter = next(data, None)
## ----------------------
while adapter and adapter.startswith("Adapter"):
## ----------------------
## Set the adapter id as the key of our output dictionary and
## initialize the value to be an empty dictionary if needs be
## ----------------------
adapter_data = data_out.setdefault(adapter, {})
## ----------------------
## ----------------------
## fetch the next item in the list. We will anticipate that this is an
## enclosure but that is not strictly needed
## ----------------------
next_data_point = next(data, None)
## ----------------------
i = 0
while next_data_point and next_data_point.startswith("Enclosure"):
## ----------------------
## next_data_point is an enclosure so add it to the dictionary
## ----------------------
i += 1
adapter_data[i] = {
"enclosure_device_id": next_data_point.split(": ")[1],
"slot_number": next(data).split(": ")[1],
"media_error_count": next(data).split(": ")[1],
"other_error_count": next(data).split(": ")[1],
"firmware_state": next(data).split(": ")[1],
}
## ----------------------
## ----------------------
## get the next value from the list
## if it is an Enclosure we keep in the inner loop
## ----------------------
next_data_point = next(data, None)
## ----------------------
## ----------------------
## It was not an enclosure so pre-suppose it is an Adapter
## ----------------------
adapter = next_data_point
## ----------------------
import json
print(json.dumps(data_out, indent=4))

这应该会给你:

{
"Adapter #0": {
"1": {
"enclosure_device_id": "252",
"slot_number": "0",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
},
"2": {
"enclosure_device_id": "252",
"slot_number": "1",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
}
},
"Adapter #1": {
"1": {
"enclosure_device_id": "252",
"slot_number": "0",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
},
"2": {
"enclosure_device_id": "252",
"slot_number": "1",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
}
},
"Adapter #2": {
"1": {
"enclosure_device_id": "252",
"slot_number": "0",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
},
"2": {
"enclosure_device_id": "252",
"slot_number": "1",
"media_error_count": "0",
"other_error_count": "0",
"firmware_state": "Online, Spun Up"
}
}
}

最新更新