🔐
Goでログマスキングを実現する方法
Go プログラミング
目次
はじめに
出力やログに機密情報を含めたくないと思ったことはありませんか? Go はシンプルな方法で文字列出力時のマスキングを実現できます。
本記事では「Go の Stringer インターフェースを利用したマスキングの方法」を解説します。
Go と Stringer インターフェース
fmtパッケージの関数は、値がfmt.Stringerを実装している場合、String()メソッドを自動的に呼び出します。これはfmt.Print系だけでなく、fmt.Sprintfやfmt.Errorfの%s、%vなどでも同様です。
type Stringer interface {
String() string
}
この特性を利用してマスキングを実現することができます。
基本例:独自型に String()を実装
例えば、クレジットカード番号を持つ型を定義し、String() を実装すると次のようになります。
type CreditCardNumber string
func (c CreditCardNumber) String() string {
return "****-****-****-****"
}
num := CreditCardNumber("4111-1111-1111-1111")
fmt.Println(num) // ****-****-****-****
fmt.Errorf でも同様にマスキング
エラーメッセージでも同じようにマスキングされます:
num := CreditCardNumber("4111-1111-1111-1111")
err := fmt.Errorf("処理エラー: %s", num)
fmt.Println(err) // 処理エラー: ****-****-****-****
構造体に含めた場合
次は構造体のフィールドにその型を含める例です。
type CreditCardNumber string
func (c CreditCardNumber) String() string {
return "****-****-****-****"
}
type CreditCard struct {
Number CreditCardNumber
UserName string
}
c := CreditCard{
Number: "1999-2123-4531-1124",
UserName: "tanaka",
}
fmt.Println(c) // {****-****-****-**** tanaka}
fmt は構造体の各フィールドを個別に出力する際、各フィールドが Stringer を実装していれば String() を呼び出すのでマスキングできます。
構造体自体に String()を実装する方法
より詳細な出力を控えたい場合は、構造体自体に String() を実装するとよいでしょう。
func (c CreditCard) String() string {
return fmt.Sprintf("num:%s,name:%s", c.Number, c.UserName)
}
fmt.Println(c) // num:****-****-****-****,name:tanaka
まとめ
fmtやlogはStringerを実装した型のString()を自動で呼び出すPrint*系だけでなく、%sや%vを使うSprintf、Errorfでもマスキングされる- マスキングしたい値を含む型に
String()を実装するだけで実現可能 - 構造体自体にも
String()を実装すると、出力を完全に制御できる
これで Go でログマスキングを実現する基本はばっちりです。是非使ってみてください! 🚀