還原序列化偵錯 Proto 表示法

如何在 Protocol Buffers 中記錄偵錯資訊。

從 30.x 版開始,Protobuf DebugString API (Message::DebugStringMessage::ShortDebugStringMessage::Utf8DebugString)、其他 Protobuf API (proto2::ShortFormatproto2::Utf8Format)、Abseil 字串函式 (例如 absl::StrCatabsl::StrFormatabsl::StrAppendabsl::Substitute) 以及 Abseil 記錄 API 將開始自動將 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 與用於記錄訊息的人工可讀偵錯格式分開。

這是故意的,目的是讓您的 proto 的「偵錯表示法」(例如,由記錄產生) 與 TextFormat 不相容。我們希望防止任何人依賴偵錯機制在程式之間傳輸資料。從歷史上看,偵錯格式 (由 DebugString API 產生) 和 TextFormat 一直被錯誤地以可互換的方式使用。我們希望這種刻意的努力能夠防止未來再次發生這種情況。

我們有意選擇連結,而不是不太明顯的格式變更,以便有機會提供背景資訊。這可能會在 UI 中脫穎而出,例如,如果您在網頁的表格上顯示狀態資訊。您可以改用 TextFormat::PrintToString,這樣就不會編輯任何資訊,並保留格式。但是,請謹慎使用此 API – 沒有內建的保護措施。根據經驗法則,如果您要將資料寫入偵錯記錄或產生狀態訊息,則應繼續使用帶有連結的偵錯格式。即使您目前沒有處理敏感資料,也要記住系統可能會變更,而且程式碼會被重複使用。

我嘗試將這個訊息轉換為 TextFormat,但我注意到每次重新啟動程序時,格式都會變更。

這是故意的。請勿嘗試剖析此偵錯格式的輸出。我們保留在不另行通知的情況下變更語法的權利。偵錯格式語法會針對每個程序隨機變更,以防止意外的相依性。如果偵錯格式中的語法變更會破壞您的系統,那麼您應該使用 TextFormat API,而不是使用 proto 的偵錯表示法。

常見問題

我可以到處都使用 TextFormat 嗎?

請勿使用 TextFormat 來產生記錄訊息。這會繞過所有內建的保護措施,而且您可能會意外記錄敏感資訊。即使您的系統目前沒有處理任何敏感資料,未來也可能會變更。

區分記錄與其他系統進一步處理的資訊,方法是視情況使用偵錯表示法或 TextFormat。

我想要撰寫需要同時具備人類可讀和機器可讀性的組態檔

對於這種使用案例,您可以明確使用 TextFormat。您有責任確保您的組態檔不包含任何 PII。

我正在撰寫單元測試,並想要在測試判斷提示中比較 Debugstring

如果您想要比較 protobuf 值,請使用 MessageDifferencer,如下所示

using google::protobuf::util::MessageDifferencer;
...
MessageDifferencer diff;
...
diff.Compare(foo, bar);

除了忽略格式和欄位順序差異之外,您還會獲得更好的錯誤訊息。