commit a3a7668f6b0a395b1a79bfad807b3858d28e6d22 Author: adminer Date: Mon Mar 9 22:03:03 2026 +0300 Добавить Chatgpt.txt diff --git a/Chatgpt.txt b/Chatgpt.txt new file mode 100644 index 0000000..b5d6e18 --- /dev/null +++ b/Chatgpt.txt @@ -0,0 +1,154 @@ +Отличная ошибка! Вы столкнулись с особенностью языка VRL (Vector Remap Language) — он fail-safe (отказоустойчивый). Это значит, что программа не скомпилируется, если в ней есть хотя бы один необработанный потенциальный сбой. Ошибка 103 говорит именно об этом: выражение merge(., parsed) может упасть, и вы должны явно указать, что делать в случае ошибки. + +Вот исправленная секция transforms для вашего vector.yaml, которая учитывает все возможные проблемы: + +```yaml +transforms: + add_nomad_metadata: + type: remap + inputs: ["docker_logs"] + source: |- + # 1. БЕЗОПАСНО добавляем метаданные Nomad (они всегда есть) + .nomad = { + "job_id": "${NOMAD_JOB_ID}", + "job_name": "${NOMAD_JOB_NAME}", + "task_name": "${NOMAD_TASK_NAME}", + "alloc_id": "${NOMAD_ALLOC_ID}", + "node_id": "${NOMAD_NODE_ID}", + "node_name": "${NOMAD_NODE_NAME}", + "datacenter": "${NOMAD_DC}" + } + + # 2. БЕЗОПАСНО парсим JSON, ЕСЛИ поле .message - строка + if is_string(.message) { + # Пытаемся распарсить. В случае ошибки parsed будет null, а err - описанием ошибки. + parsed, err = parse_json(.message) + + if err == null { + # Если парсинг прошел успешно И результат - объект (не массив, не строка) + if is_object(parsed) { + # Используем "паникующий" merge! потому что мы УВЕРЕНЫ в типах на 100% + # . - это объект (весь лог), parsed - тоже объект (результат парсинга) + . = merge!(., parsed) + } else { + # Если внутри .message был валидный JSON, но это массив или строка, + # сохраняем его в отдельное поле, чтобы не сломать структуру. + .parsed_json = parsed + } + } else { + # Логируем ошибку парсинга (опционально, для отладки) + .parse_error = err + } + } + + # 3. (Опционально) Удаляем временное поле с ошибкой, если оно пустое + if is_null(.parse_error) { + del(.parse_error) + } + ``` + + 🔍 Что было исправлено и почему + + 1. Ошибка 103 (Unhandled fallible assignment) — исправлена заменой merge(., parsed) на конструкцию с обработкой ошибки. Теперь программа не "упадет", если parsed окажется не объектом. + 2. Проверка типа parsed — добавлена проверка if is_object(parsed). Функция parse_json может вернуть не только объект ({...}), но и массив ([...]), строку или число, если JSON верхнего уровня — это примитив или массив. Слияние (merge) работает только с объектами. Без этой проверки вы бы получили новую ошибку на этапе выполнения. + 3. Использование merge! — внутри блока if is_object(parsed) мы на 100% уверены, что parsed — это объект, а . (исходный лог) — всегда объект. Поэтому можно использовать "паникующий" вариант merge!, который не требует обработки ошибок (так как их просто не может быть из-за наших проверок). + 4. Обработка краевых случаев: + · Если поле message не строка — JSON не парсится (это нормально для бинарных логов). + · Если внутри message был JSON-массив (например, ["log1", "log2"]), он сохранится в поле .parsed_json, а структура основного события не сломается. + · Если произошла ошибка парсинга, она сохранится в поле .parse_error (потом удаляется для чистоты). + + 📝 Полный исправленный конфиг для вашего шаблона Nomad + + Замените содержимое вашего template в задании Nomad на этот исправленный YAML: + + ```yaml + data_dir: "${NOMAD_ALLOC_DIR}/vector/data" + + api: + enabled: true + address: "0.0.0.0:${NOMAD_PORT_api}" + + sources: + docker_logs: + type: docker_logs + include_containers: ["*"] + + transforms: + add_nomad_metadata: + type: remap + inputs: ["docker_logs"] + source: |- + .nomad = { + "job_id": "${NOMAD_JOB_ID}", + "job_name": "${NOMAD_JOB_NAME}", + "task_name": "${NOMAD_TASK_NAME}", + "alloc_id": "${NOMAD_ALLOC_ID}", + "node_id": "${NOMAD_NODE_ID}", + "node_name": "${NOMAD_NODE_NAME}", + "datacenter": "${NOMAD_DC}" + } + + if is_string(.message) { + parsed, err = parse_json(.message) + + if err == null { + if is_object(parsed) { + . = merge!(., parsed) + } else { + .parsed_json = parsed + } + } else { + .parse_error = err + } + } + + if is_null(.parse_error) { + del(.parse_error) + } + + sinks: + openobserve: + type: http + inputs: ["add_nomad_metadata"] + uri: "http://openobserve.service.consul:5080/api/default/default/_json" + method: "post" + compression: "gzip" + encoding: + codec: "json" + timestamp_format: "rfc3339" + auth: + strategy: "basic" + user: "{{ key "openobserve/user" }}" + password: "{{ key "openobserve/password" }}" + buffer: + type: "disk" + max_size: 268435488 + when_full: "drop_newest" + healthcheck: + enabled: false + ``` + + 🚀 После исправления + + 1. Перезапустите задание: + ```bash + nomad job stop vector + nomad job run vector.nomad + ``` + 2. Проверьте логи: Ошибка компиляции VRL должна исчезнуть. В OpenObserve будут приходить обогащенные логи, а если внутри message был валидный JSON, его поля "поднимутся" на верхний уровень события для удобной фильтрации. + + Такой подход делает трансформацию устойчивой к любым нестандартным данным в логах, что критически важно для production-сред. + } + } + } + } + } + } + } + } + } + } + } + } + } + } \ No newline at end of file