Как разобрать файл журнала с помощью python и сохранить данные в базе данных?

Я пытаюсь проанализировать файл журнала, который содержит структуру, подобную приведенной ниже, я хочу сделать это с помощью python и хочу сохранить извлеченные данные в базе данных, как я могу это сделать?

Я могу разобрать простую пару значений ключа, но столкнулся с некоторой проблемой.

1: Как я могу проанализировать вложенную структуру, например, поле контекста в файле примера вложено в основную группу?

2: Как справиться с условием, если разделитель представляет собой строку. например, для разделителя пары ключ:значение используется двоеточие (:), а в ключе «сайт» есть пара ключ:значение site_url:http://something.com здесь URL-адрес также содержит двоеточие (:), что дает неправильный ответ.

{
        "username": "lavania",
        "host": "10.105.22.32",
        "event_source": "server",
        "event_type": "/courses/XYZ/CS101/2014_T1/xblock
/i4x:;_;_XYZ;_CS101;_video;_d333fa637a074b41996dc2fd5e675818/handler/xmodule_handler/save_user_state",
        "context": {
            "course_id": "XYZ/CS101/2014_T1",
            "course_user_tags": {},
            "user_id": 42,
            "org_id": "XYZ"
        },
        "time": "2014-06-20T05:49:10.468638+00:00",
        "site":"http://something.com",
        "ip": "127.0.0.1",
        "event": "{\"POST\": {\"saved_video_position\": [\"00:02:10\"]}, \"GET\": {}}",
        "agent": "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0",
        "page": null
    }

    {
        "username": "rihana",
        "host": "10.105.22.32",
        "event_source": "server",
        "event_type": "problem_check",
        "context": {
            "course_id": "XYZ/CS101/2014_T1",
            "course_user_tags": {},
            "user_id": 40,
            "org_id": "XYZ",
            "module": {
                "display_name": ""
            }
        },
        "time": "2014-06-20T06:43:52.716455+00:00",
        "ip": "127.0.0.1",
        "event": {
            "submission": {
                "i4x-XYZ-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                    "input_type": "choicegroup",
                    "question": "",
                    "response_type": "multiplechoiceresponse",
                    "answer": "MenuInflater.inflate()",
                    "variant": "",
                    "correct": true
                }
            },
            "success": "correct",
            "grade": 1,
            "correct_map": {
                "i4x-XYZ-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                    "hint": "",
                    "hintmode": null,
                    "correctness": "correct",
                    "npoints": null,
                    "msg": "",
                    "queuestate": null
                }
            },
            "state": {
                "student_answers": {},
                "seed": 1,
                "done": null,
                "correct_map": {},
                "input_state": {
                    "i4x-XYZ-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {}
                }
            },
            "answers": {
                "i4x-XYZ-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": "choice_0"
            },
            "attempts": 1,
            "max_grade": 1,
            "problem_id": "i4x://XYZ/CS101/problem/33e4aac93dc84f368c93b1d08fa984fc"
        },
        "agent": "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:29.0) Gecko/20100101 Firefox/29.0",
        "page": "x_module"
    }


    {
        "username": "troysa",
        "host": "localhost",
        "event_source": "server",
        "event_type": "/courses/XYZ/CS101/2014_T1/instructor_dashboard/api/list_instructor_tasks",
        "context": {
            "course_id": "XYZ/CS101/2014_T1",
            "course_user_tags": {},
            "user_id": 6,
            "org_id": "XYZ"
        },
        "time": "2014-06-20T05:49:26.780244+00:00",
        "ip": "127.0.0.1",
        "event": "{\"POST\": {}, \"GET\": {}}",
        "agent": "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:29.0) Gecko/20100101 Firefox/29.0",
        "page": null
    }

person rajsinghaniaful    schedule 04.09.2014    source источник


Ответы (2)


Как уже отмечалось, это структура данных JSON. Я написал некоторый быстрый код, который будет читать ваш файл журнала построчно и пытаться найти полные многострочные объекты json. Как только все строки будут прочитаны, все будет готово. Я использую pprint для объектов, чтобы вывод был удобочитаемым для человека, чтобы гарантировать, что возвращаемый dict выглядит правильно.

import json
import pprint

with open("log.txt") as infile:
    # Loop until we have parsed all the lines.
    for line in infile:
        # Read lines until we find a complete object
        while (True):
            try:
                json_data = json.loads(line)
                # We have a complete onject here
                pprint.pprint(json_data)
                # Try and find a new JSON object
                break
            except ValueError:
                # We don't have a complete JSON object
                # read another line and try again
                line += next(infile)

Этот код немного тупиковый. Он читает строку и проверяет, есть ли у нас полный анализируемый объект. Если нет, он читает следующую строку и объединяет ее с последней. Это продолжается до тех пор, пока не будет загружен анализируемый объект. Затем он делает это снова и снова, пока все линии не будут использованы и все объекты не будут найдены.

На этом этапе кода вы прочитали полный объект JSON в json_data:

pprint.pprint(json_data)

Я распечатываю словарь, но это стандартный словарь Python, который можно обрабатывать для данных, как при обычном обходе словаря. Например, вы можете получить course_id с помощью чего-то вроде:

json_data['context']['course_id']

или host через:

json_data['host']
person Michael Petch    schedule 04.09.2014
comment
Спасибо за ваше предложение, Майкл. У вас есть идеи, как мы можем ввести эти значения в базу данных? - person rajsinghaniaful; 04.09.2014

Ваши данные представлены в формате JSON. Используйте модуль json в стандартной библиотеке для его анализа.

Однако ваши данные представляют собой несколько объединенных вместе JSON-дикторов. Надеюсь, вы только что вставили данные из нескольких отдельных записей, иначе вам придется выполнить некоторую очистку данных, прежде чем вы начнете анализировать их в мельчайших деталях.

Предположим, что это отдельные файлы, приведу пример набора "username": "raeha", загруженного в переменную data:

>>> import json
>>> newdata = json.loads(data)
>>> print(newdata["context"])
{'course_id': 'XYZ/CS101/2014_T1', 'course_user_tags': {}, 'org_id': 'XYZ', 'user_id': 40, 'module': {'display_name': ''}}
>>> print(newdata["context"]["user_id"])
40

Метод json.loads() принимает необработанные данные JSON (в виде строки) и форматирует их в типы данных Python. Как правило, самым внешним типом является словарь, каждый ключ которого является строкой, а каждое значение может быть строкой, списком, словарем, числовым значением или элементом, например True, False или None. Они соответствуют true, false и null в JSON.

person MattDMo    schedule 04.09.2014