/
Praxis/

Определение структуры лога

Контекст

Прежде чем анализировать логи, нужно договориться, как представлять каждую запись в программе. Каждая строка лога — это цифровой отпечаток события: когда произошло, в каком сервисе, что именно случилось, и как связать это событие с другими.

На этом этапе мы создадим структуру данных для хранения записи и функцию для её парсинга из текстовой строки.

Ключевая концепция: Регулярные выражения

— инструмент для поиска текста по шаблону. Вы не знаете точное значение request_id, но знаете, что оно всегда начинается с request_id=. Регулярное выражение описывает шаблон того, как выглядит искомый текст.

re := regexp.MustCompile(`request_id=([a-zA-Z0-9_]+)`) matches := re.FindStringSubmatch(line) if len(matches) > 1 { requestID := matches[1] // Захваченная группа }

MustCompile компилирует шаблон один раз (паникует при ошибке — используйте только для константных шаблонов). FindStringSubmatch возвращает срез: первый элемент — полное совпадение, последующие — захваченные группы в скобках.

💡 Gotcha: Компилируйте регулярные выражения один раз и переиспользуйте. Компиляция на каждую строку — дорогая операция.

Используемые пакеты

ПакетНазначениеКлючевые функции
regexpРегулярные выраженияMustCompile, FindStringSubmatch
timeРабота со временемParse
stringsРабота со строкамиTrimSpace, Contains

Цели этапа

Создать структуру для хранения записи лога и функцию парсинга.

Что необходимо сделать:

  • Структура LogEntry:

    • Поле Timestamp (time.Time) — когда произошло событие
    • Поле Level (string) — INFO, WARN, ERROR
    • Поле Service (string) — какой сервис создал запись
    • Поле Message (string) — текст сообщения
    • Поле RequestID (string) — идентификатор для сопоставления
    • Поле UserID (string) — идентификатор пользователя (опционально)
  • Функция:

    func ParseLogLine(line string) (LogEntry, error)

    Логика:

    1. Разобрать временную метку из формата ISO 8601
    2. Извлечь уровень записи из квадратных скобок [INFO], [ERROR]
    3. Определить имя сервиса
    4. Найти request_id с помощью регулярного выражения
    5. При некорректной строке — вернуть ошибку

Пример работы

$ go run main.go Parsing: 2023-12-25T14:30:15.123Z [INFO] user-service: User authenticated, request_id=req_abc123, user_id=12345 LogEntry{ Timestamp: 2023-12-25 14:30:15.123 +0000 UTC Level: INFO Service: user-service Message: User authenticated, request_id=req_abc123, user_id=12345 RequestID: req_abc123 UserID: 12345 }

Полезные материалы

  • regexp — документация пакета
  • time.Parse — парсинг времени
  • Регулярные выражения — Go by Example
  • Регулярные выражения в Go — на русском

Критерии

не проверялось
  • Структура LogEntry определена с полями Timestamp, Level, Service, Message, RequestID, UserID
  • Функция ParseLogLine(line string) (LogEntry, error) создана
  • Временная метка парсится из формата ISO 8601 через time.Parse
  • Уровень записи извлекается из квадратных скобок
  • RequestID извлекается с помощью regexp
  • При некорректной строке возвращается ошибка
Войдите в аккаунт, чтобы начать проект
Запустите первую проверку