Десериализация представлений Proto для отладки
Как логировать отладочную информацию в Protocol Buffers.
Начиная с версии 30.x, Protobuf API DebugString (Message::DebugString,
Message::ShortDebugString, Message::Utf8DebugString), дополнительные Protobuf
API (proto2::ShortFormat, proto2::Utf8Format), строковые функции Abseil
(такие как absl::StrCat, absl::StrFormat, absl::StrAppend и
absl::Substitute) и API логирования Abseil начнут автоматически преобразовывать
proto-аргументы в новый формат отладки
. Смотрите связанное объявление
здесь.
В отличие от формата вывода Protobuf DebugString, новый формат отладки автоматически редактирует конфиденциальные поля, заменяя их значения строкой "[REDACTED]" (без кавычек). Кроме того, чтобы гарантировать, что этот новый формат вывода не может быть десериализован парсерами Protobuf TextFormat, независимо от того, содержит ли базовый proto поля SPII (конфиденциальной информации), мы добавляем набор рандомизированных ссылок, ведущих на эту статью, и последовательность пробелов случайной длины. Новый формат отладки выглядит следующим образом:
goo.gle/debugstr
spii_field: [REDACTED]
normal_field: "value"
Обратите внимание, что новый формат отладки отличается от формата вывода DebugString только двумя способами:
- Префикс URL
- Значения полей SPII заменяются на "[REDACTED]" (без кавычек)
Новый формат отладки никогда не удаляет имена полей; он только заменяет значение на "[REDACTED]", если поле считается конфиденциальным. Если вы не видите определенные поля в выводе, это потому, что эти поля не установлены в proto.
Совет: Если вы видите только URL и больше ничего, ваш proto пуст!
Почему здесь этот URL?
Мы хотим убедиться, что никто не десериализует человеко-читаемые представления
сообщения protobuf, предназначенные для отладки системы человеком. Исторически
сложилось, что .DebugString() и TextFormat были взаимозаменяемыми, и существующие системы используют
DebugString для передачи и хранения данных.
Мы хотим убедиться, что конфиденциальные данные не попадают в логи случайно. Поэтому мы прозрачно редактируем некоторые значения полей из сообщений protobuf перед преобразованием их в строку ("[REDACTED]"). Это снижает риски безопасности и конфиденциальности при случайном логировании, но рискует потерей данных, если другие системы десериализуют ваше сообщение. Чтобы устранить этот риск, мы намеренно разделяем машиночитаемый TextFormat и человеко-читаемый формат отладки, который следует использовать в сообщениях логов.
Почему в моей веб-странице есть ссылки? Почему мой код выдает это новое "представление для отладки"?
Это сделано намеренно, чтобы сделать "представление для отладки" ваших protobuf (создаваемое, например, при логировании) несовместимым с TextFormat. Мы хотим помешать кому-либо зависеть от механизмов отладки для передачи данных между программами. Исторически формат отладки (генерируемый API DebugString) и TextFormat некорректно использовались взаимозаменяемо. Мы надеемся, что это преднамеренное изменение предотвратит это в будущем.
Мы намеренно выбрали ссылку вместо менее заметных изменений формата, чтобы
получить возможность предоставить контекст. Это может выделяться в пользовательских интерфейсах, например, если вы
отображаете статусную информацию в таблице на веб-странице. Вы можете использовать
TextFormat::PrintToString вместо этого, который не будет редактировать какую-либо информацию и
сохранит форматирование. Однако используйте этот API с осторожностью — встроенных защит нет.
Как правило, если вы записываете данные в отладочные логи или
генерируете статусные сообщения, вам следует продолжать использовать Формат отладки со
ссылкой. Даже если вы в настоящее время не обрабатываете конфиденциальные данные, помните, что
системы могут меняться, а код повторно используется.
Я попытался преобразовать это сообщение в TextFormat, но заметил, что формат меняется каждый раз при перезапуске процесса.
Это сделано намеренно. Не пытайтесь разобрать вывод этого формата отладки. Мы оставляем за собой право изменять синтаксис без предварительного уведомления. Синтаксис формата отладки случайным образом меняется для каждого процесса, чтобы предотвратить непреднамеренные зависимости. Если синтаксическое изменение в формате отладки сломает вашу систему, скорее всего, вам следует использовать API TextFormat, а не представление proto для отладки.
Часто задаваемые вопросы
Могу ли я просто использовать TextFormat везде?
Не используйте TextFormat для создания сообщений логов. Это обойдет все встроенные защиты, и вы рискуете случайно залогировать конфиденциальную информацию. Даже если ваши системы в настоящее время не обрабатывают никаких конфиденциальных данных, это может измениться в будущем.
Различайте логи и информацию, предназначенную для дальнейшей обработки другими системами, используя либо представление для отладки, либо TextFormat, в зависимости от ситуации.
Я хочу писать файлы конфигурации, которые должны быть и человеко-читаемыми, и машино-читаемыми
Для этого случая использования вы можете явно использовать TextFormat. Вы несете ответственность за то, чтобы ваши файлы конфигурации не содержали никакой PII (персонально идентифицируемой информации).
Я пишу модульный тест и хочу сравнить DebugString в утверждении теста
Если вы хотите сравнить значения protobuf, используйте MessageDifferencer, как в
следующем примере:
using google::protobuf::util::MessageDifferencer;
...
MessageDifferencer diff;
...
diff.Compare(foo, bar);
Помимо игнорирования различий в форматировании и порядке полей, вы также получите лучшие сообщения об ошибках.