Как записать результаты нескольких выражений в один json_file в python?

есть вот такой код для парсинга апачевского access.log:

import argparse
import json
import re
from collections import Counter


parser = argparse.ArgumentParser(description='Код для анализа логов')
parser.add_argument('-f', dest='logfile', action='store', default='access.log')
args = parser.parse_args()


reg_gen = r'(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[^]]+\s*]\s"(?P<METHOD>GET|POST|PUT|DELETE|HEAD)\s+[^]]+\s*"\s(?P<STATUS>20[0-9]|30[0-9]|40[0-9]|50[0-9])\s[^"]+"(?P<URL>https?:[^"]+)"\s*"[^"]+"\s(?P<REQ_TIME>\d{4})$'
reg_ce = r'(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[^]]+\s*]\s"(?P<METHOD>GET|POST|PUT|DELETE|HEAD)\s+[^]]+\s*"\s(?P<STATUS>40[0-9])\s[^"]+"(?P<URL>https?:[^"]+)"\s*"[^"]+"\s(?P<REQ_TIME>\d{4})$'
reg_se = r'(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[^]]+\s*]\s"(?P<METHOD>GET|POST|PUT|DELETE|HEAD)\s+[^]]+\s*"\s(?P<STATUS>50[0-9])\s[^"]+"(?P<URL>https?:[^"]+)"\s*"[^"]+"\s(?P<REQ_TIME>\d{4})$'


json_data = []


with open(args.logfile) as f:
    try:
        sum_of_all_req = sum(1 for _ in f.readlines())
    except IOError:
        print("Unable to read file")
print(json.dumps((f"Sum of requests = {sum_of_all_req}"), indent=4))


comp_ip = re.compile(reg_gen)
dict_ips_t10 = Counter()
with open(args.logfile) as f:
     for line in f:
         m = comp_ip.match(line)
         if m:
              ip = m.group('IP')
              dict_ips_t10[ip] += 1
print(json.dumps(dict_ips_t10.most_common(10), indent=4))


comp_long = re.compile(reg_gen)
dict_long_t10 = Counter()
with open(args.logfile) as f:
    for line in f:
        m = comp_long.match(line)
        if m:
            long = m.group('IP', 'METHOD', 'URL', 'REQ_TIME')
            dict_long_t10[long] += 1
print(json.dumps(dict_long_t10.most_common(10), indent=4))


comp_clienterror = re.compile(reg_ce)
dict_clienterr_t10 = Counter()
with open(args.logfile) as f:
    for line in f:
        m = comp_clienterror.match(line)
        if m:
            client_err = m.group('IP', 'METHOD', 'STATUS', 'URL')
            dict_clienterr_t10[client_err] += 1
print(json.dumps(dict_clienterr_t10.most_common(10), indent=4))


comp_servererror = re.compile(reg_se)
dict_servererr_t10 = Counter()
with open(args.logfile) as f:
    for line in f:
        m = comp_servererror.match(line)
        if m:
            server_err = m.group('IP', 'METHOD', 'STATUS', 'URL')
            dict_servererr_t10[server_err] += 1
print(json.dumps(dict_servererr_t10.most_common(10), indent=4))


json_data.append({
    sum_of_all_req,
    dict_ips_t10.most_common(10),
    dict_long_t10.most_common(10),
    dict_clienterr_t10.most_common(10),
    dict_servererr_t10.most_common(10)
})

with open("final_log.json", "w") as jsonfile:
   json.dump(json_data, jsonfile, indent=5)

Выполнение кода прерывается ошибкой :

   dict_long_t10.most_common(10),
TypeError: unhashable type: 'list'

При этом если записывать каждый результат отдельно, то все работает. Мне нужно, чтобы результирующий json-файл содержал результаты всех представленных выражений. Как исправить?

Пример записи из access.log:

83.167.113.100 - - [12/Dec/2015:18:31:25 +0100] "POST /administrator/index.php HTTP/1.1" 200 4494 "http://almhuette-raith.at/administrator/" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" 8566

Пример вывода после выполнения кода: вывод


Ответы (1 шт):

Автор решения: Ник

Решение оказалось простым (благодаря помощи опытных коллег). Итак:

json_data.append([
    sum_of_all_req,
    dict_ip,
    dict_ips_t10.most_common(10),
    dict_long_t10.most_common(10),
    dict_clienterr_t10.most_common(10),
    dict_servererr_t10.most_common(10),
])

with open("final_log.json", "w") as jsonfile:
   json.dump(json_data, jsonfile, indent=5)

Все дело в туплах)

→ Ссылка