pfSense python 解释器未读取 json
pfSense python interpreter doen't read json
我摸不着头脑。我的目标是获得 json 的输入并将其输出到 influxdb 中。因为我是从 pfSense 收集数据,所以我的工具是有限的。因此我使用 Python 3.8.
首先在 Debian 机器上开发我写了这段代码:
#!/usr/local/bin/python3.8
import os
import json
from influxdb import InfluxDBClient
from datetime import datetime
INTERFACES = ["igb0", "pppoe0"]
WORKING_FOLDER = "/tmp/json"
NOW = datetime.now()
CLIENT = InfluxDBClient("host", "8086", "user", "pw", "firewall")
for interface in INTERFACES:
stats = {}
os.popen(
"vnstat --json d 2 -i {} > {}/{}_d.json".format(interface, WORKING_FOLDER, interface)
).read()
os.popen(
"vnstat --json m 2 -i {} > {}/{}_m.json".format(interface, WORKING_FOLDER, interface)
).read()
with open(f"{WORKING_FOLDER}/{interface}_d.json", "r") as j:
day = json.loads(j.read())
with open(f"{WORKING_FOLDER}/{interface}_m.json", "r") as k:
month = json.loads(k.read())
if not len(day["interfaces"][0]["traffic"]["day"]) == 2:
stats["yesterday"] = {"rx": 0, "tx": 0}
stats["today"] = {
"rx": day["interfaces"][0]["traffic"]["day"][0]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][0]["tx"],
}
else:
stats["yesterday"] = {
"rx": day["interfaces"][0]["traffic"]["day"][0]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][0]["tx"],
}
stats["today"] = {
"rx": day["interfaces"][0]["traffic"]["day"][1]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][1]["tx"],
}
if not len(month["interfaces"][0]["traffic"]["month"]) == 2:
stats["last_month"] = {"rx": 0, "tx": 0}
stats["this_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][0]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][0]["tx"],
}
else:
stats["last_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][0]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][0]["tx"],
}
stats["this_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][1]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][1]["tx"],
}
json_body = [
{
"measurement": f"stats_{interface}",
"time": NOW,
"fields": {
"yesterday_rx": stats["yesterday"]["rx"],
"yesterday_tx": stats["yesterday"]["tx"],
"yesterday_total": int(stats["yesterday"]["rx"]) + int(stats["yesterday"]["tx"]),
"today_rx": stats["today"]["rx"],
"today_tx": stats["today"]["tx"],
"today_total": int(stats["today"]["rx"]) + int(stats["today"]["tx"]),
"last_month_rx": stats["last_month"]["rx"],
"last_month_tx": stats["last_month"]["tx"],
"last_month_total": int(stats["last_month"]["rx"]) + int(stats["last_month"]["tx"]),
"this_month_rx": stats["this_month"]["rx"],
"this_month_tx": stats["this_month"]["tx"],
"this_month_total": int(stats["this_month"]["rx"]) + int(stats["this_month"]["tx"]),
},
}
]
CLIENT.write_points(json_body)
在我的 Debian 机器上测试它(注释掉第 12 和 13 行以不覆盖我的 json 文件)一切都很顺利。所以我将脚本移到我的 pfSense 中,但出现以下错误:
[2.5.2-RELEASE][admin@pfSense]/usr/local/pythonscripts: ./trafficstats.py
Traceback (most recent call last):
File "./trafficstats.py", line 18, in <module>
month = json.loads(k.read())
File "/usr/local/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/local/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
我问自己为什么。因为看moth文件是有效的json如果我没看错的话:
{"vnstatversion":"2.7","jsonversion":"2","interfaces":[{"name":"igb0","alias":"WAN","created":{"date":{"year":2022,"month":2,"day":4}},"updated":{"date":{"year":2022,"month":2,"day":12},"time":{"hour":9,"minute":30}},"traffic":{"total":{"rx":82416467756,"tx":43825701833},"month":[{"id":88,"date":{"year":2022,"month":2},"rx":82416467756,"tx":43825701833}]}}]}
有人知道发生了什么事吗?
干杯,
加米
“期望值为 char 0”通常意味着您正在尝试 json.loads()
一个空字符串:
>>> import json
>>> json.loads("")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python39\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python39\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
你没有检查那些 vnstat
调用是否成功(无论如何你应该使用 subprocess.check_call()
而不是 os.popen
因为你甚至没有真正使用管道),所以它是可能文件已创建但为空。
总而言之,我可能会重构为这样的东西:
- 使用
subprocess.check_call()
等待进程完成(并检查结果)
- 不要使用基本上被丢弃的
stats
dict
- 重构重复位
#!/usr/local/bin/python3.8
import json
import subprocess
from datetime import datetime
from influxdb import InfluxDBClient
INTERFACES = ["igb0", "pppoe0"]
WORKING_FOLDER = "/tmp/json"
NOW = datetime.now()
CLIENT = InfluxDBClient("host", "8086", "user", "pw", "firewall")
# Process an interfaces.X.traffic.PERIOD dict into a pair of (previous_rx, previous_tx), (current_rx, current_tx)
def process_traffic(traffic):
if len(traffic) != 2:
return ((0, 0), (traffic[0]["rx"], traffic[0]["tx"]))
return ((traffic[0]["rx"], traffic[0]["tx"]), (traffic[1]["rx"], traffic[1]["tx"]))
def process_iface(interface):
day_json = f"{WORKING_FOLDER}/{interface}_d.json"
month_json = f"{WORKING_FOLDER}/{interface}_m.json"
# TODO: consider shlex.quote for safety
subprocess.check_call(
f"vnstat --json d 2 -i {interface} > {day_json}",
shell=True,
)
subprocess.check_call(
f"vnstat --json m 2 -i {interface} > {month_json}",
shell=True,
)
with open(day_json, "r") as j:
day_data = json.loads(j.read())
with open(month_json, "r") as k:
month_data = json.loads(k.read())
(yesterday_rx, yesterday_tx), (today_rx, today_tx) = process_traffic(
day_data["interfaces"][0]["traffic"]["day"]
)
(last_month_rx, last_month_tx), (this_month_rx, this_month_tx) = process_traffic(
month_data["interfaces"][0]["traffic"]["month"]
)
json_body = [
{
"measurement": f"stats_{interface}",
"time": NOW,
"fields": {
"yesterday_rx": yesterday_rx,
"yesterday_tx": yesterday_tx,
"yesterday_total": int(yesterday_rx) + int(yesterday_tx),
"today_rx": today_rx,
"today_tx": today_tx,
"today_total": int(today_rx) + int(today_tx),
"last_month_rx": last_month_rx,
"last_month_tx": last_month_tx,
"last_month_total": int(last_month_rx) + int(last_month_tx),
"this_month_rx": this_month_rx,
"this_month_tx": this_month_tx,
"this_month_total": int(this_month_rx) + int(this_month_tx),
},
}
]
CLIENT.write_points(json_body)
def main():
for interface in INTERFACES:
process_iface(interface)
if __name__ == "__main__":
main()
我摸不着头脑。我的目标是获得 json 的输入并将其输出到 influxdb 中。因为我是从 pfSense 收集数据,所以我的工具是有限的。因此我使用 Python 3.8.
首先在 Debian 机器上开发我写了这段代码:
#!/usr/local/bin/python3.8
import os
import json
from influxdb import InfluxDBClient
from datetime import datetime
INTERFACES = ["igb0", "pppoe0"]
WORKING_FOLDER = "/tmp/json"
NOW = datetime.now()
CLIENT = InfluxDBClient("host", "8086", "user", "pw", "firewall")
for interface in INTERFACES:
stats = {}
os.popen(
"vnstat --json d 2 -i {} > {}/{}_d.json".format(interface, WORKING_FOLDER, interface)
).read()
os.popen(
"vnstat --json m 2 -i {} > {}/{}_m.json".format(interface, WORKING_FOLDER, interface)
).read()
with open(f"{WORKING_FOLDER}/{interface}_d.json", "r") as j:
day = json.loads(j.read())
with open(f"{WORKING_FOLDER}/{interface}_m.json", "r") as k:
month = json.loads(k.read())
if not len(day["interfaces"][0]["traffic"]["day"]) == 2:
stats["yesterday"] = {"rx": 0, "tx": 0}
stats["today"] = {
"rx": day["interfaces"][0]["traffic"]["day"][0]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][0]["tx"],
}
else:
stats["yesterday"] = {
"rx": day["interfaces"][0]["traffic"]["day"][0]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][0]["tx"],
}
stats["today"] = {
"rx": day["interfaces"][0]["traffic"]["day"][1]["rx"],
"tx": day["interfaces"][0]["traffic"]["day"][1]["tx"],
}
if not len(month["interfaces"][0]["traffic"]["month"]) == 2:
stats["last_month"] = {"rx": 0, "tx": 0}
stats["this_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][0]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][0]["tx"],
}
else:
stats["last_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][0]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][0]["tx"],
}
stats["this_month"] = {
"rx": month["interfaces"][0]["traffic"]["month"][1]["rx"],
"tx": month["interfaces"][0]["traffic"]["month"][1]["tx"],
}
json_body = [
{
"measurement": f"stats_{interface}",
"time": NOW,
"fields": {
"yesterday_rx": stats["yesterday"]["rx"],
"yesterday_tx": stats["yesterday"]["tx"],
"yesterday_total": int(stats["yesterday"]["rx"]) + int(stats["yesterday"]["tx"]),
"today_rx": stats["today"]["rx"],
"today_tx": stats["today"]["tx"],
"today_total": int(stats["today"]["rx"]) + int(stats["today"]["tx"]),
"last_month_rx": stats["last_month"]["rx"],
"last_month_tx": stats["last_month"]["tx"],
"last_month_total": int(stats["last_month"]["rx"]) + int(stats["last_month"]["tx"]),
"this_month_rx": stats["this_month"]["rx"],
"this_month_tx": stats["this_month"]["tx"],
"this_month_total": int(stats["this_month"]["rx"]) + int(stats["this_month"]["tx"]),
},
}
]
CLIENT.write_points(json_body)
在我的 Debian 机器上测试它(注释掉第 12 和 13 行以不覆盖我的 json 文件)一切都很顺利。所以我将脚本移到我的 pfSense 中,但出现以下错误:
[2.5.2-RELEASE][admin@pfSense]/usr/local/pythonscripts: ./trafficstats.py
Traceback (most recent call last):
File "./trafficstats.py", line 18, in <module>
month = json.loads(k.read())
File "/usr/local/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/local/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
我问自己为什么。因为看moth文件是有效的json如果我没看错的话:
{"vnstatversion":"2.7","jsonversion":"2","interfaces":[{"name":"igb0","alias":"WAN","created":{"date":{"year":2022,"month":2,"day":4}},"updated":{"date":{"year":2022,"month":2,"day":12},"time":{"hour":9,"minute":30}},"traffic":{"total":{"rx":82416467756,"tx":43825701833},"month":[{"id":88,"date":{"year":2022,"month":2},"rx":82416467756,"tx":43825701833}]}}]}
有人知道发生了什么事吗?
干杯, 加米
“期望值为 char 0”通常意味着您正在尝试 json.loads()
一个空字符串:
>>> import json
>>> json.loads("")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python39\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python39\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
你没有检查那些 vnstat
调用是否成功(无论如何你应该使用 subprocess.check_call()
而不是 os.popen
因为你甚至没有真正使用管道),所以它是可能文件已创建但为空。
总而言之,我可能会重构为这样的东西:
- 使用
subprocess.check_call()
等待进程完成(并检查结果) - 不要使用基本上被丢弃的
stats
dict - 重构重复位
#!/usr/local/bin/python3.8
import json
import subprocess
from datetime import datetime
from influxdb import InfluxDBClient
INTERFACES = ["igb0", "pppoe0"]
WORKING_FOLDER = "/tmp/json"
NOW = datetime.now()
CLIENT = InfluxDBClient("host", "8086", "user", "pw", "firewall")
# Process an interfaces.X.traffic.PERIOD dict into a pair of (previous_rx, previous_tx), (current_rx, current_tx)
def process_traffic(traffic):
if len(traffic) != 2:
return ((0, 0), (traffic[0]["rx"], traffic[0]["tx"]))
return ((traffic[0]["rx"], traffic[0]["tx"]), (traffic[1]["rx"], traffic[1]["tx"]))
def process_iface(interface):
day_json = f"{WORKING_FOLDER}/{interface}_d.json"
month_json = f"{WORKING_FOLDER}/{interface}_m.json"
# TODO: consider shlex.quote for safety
subprocess.check_call(
f"vnstat --json d 2 -i {interface} > {day_json}",
shell=True,
)
subprocess.check_call(
f"vnstat --json m 2 -i {interface} > {month_json}",
shell=True,
)
with open(day_json, "r") as j:
day_data = json.loads(j.read())
with open(month_json, "r") as k:
month_data = json.loads(k.read())
(yesterday_rx, yesterday_tx), (today_rx, today_tx) = process_traffic(
day_data["interfaces"][0]["traffic"]["day"]
)
(last_month_rx, last_month_tx), (this_month_rx, this_month_tx) = process_traffic(
month_data["interfaces"][0]["traffic"]["month"]
)
json_body = [
{
"measurement": f"stats_{interface}",
"time": NOW,
"fields": {
"yesterday_rx": yesterday_rx,
"yesterday_tx": yesterday_tx,
"yesterday_total": int(yesterday_rx) + int(yesterday_tx),
"today_rx": today_rx,
"today_tx": today_tx,
"today_total": int(today_rx) + int(today_tx),
"last_month_rx": last_month_rx,
"last_month_tx": last_month_tx,
"last_month_total": int(last_month_rx) + int(last_month_tx),
"this_month_rx": this_month_rx,
"this_month_tx": this_month_tx,
"this_month_total": int(this_month_rx) + int(this_month_tx),
},
}
]
CLIENT.write_points(json_body)
def main():
for interface in INTERFACES:
process_iface(interface)
if __name__ == "__main__":
main()