LogbackでログメッセージをJsonで出力(logstash-logback-encoderを使用)する際に、メッセージの内容を一部マスクしてみました。
マスクの方法は、logback.xmlの指定だけで特定フィールドの内容をまるっと置き換えたり、正規表現を使用して柔軟に置き換えたりできるようです。
また、カスタムな実装を用意することで設定ファイルだけでは実現できないような柔軟な置き換えもできるみたいなので色々と試してみます。*1
フィールド名を指定してのマスキング
デフォルトのマスク定義でのマスキング
これは、特定のフィールドの内容をデフォルト定義に従い置き換える方法になります。
LogstashEncoder
にMaskingJsonGeneratorDecorator
を指定することで、マスキングの指定ができるようです。
この例ではmessage
フィールドはすべて「これに置き換わるよ」と出力されます。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
<defaultMask>これに置き換わるよ</defaultMask>
<path>message</path>
</jsonGeneratorDecorator>
</encoder>
</appender>
実行結果
実行してみると、test
とログメッセージを出力したのにlogback.xml
に従い「これに置き換わるよ」と出力されていることが確認できます。
フィールドごとにマスク定義を変えてのマスキング
これは、フィールドごとにマスク内容を定義して置き換える方法になります。
この例ではmessage
フィールドはdefaultMask
の定義が適用されますが、pathMask
配下で定義されているcustom
フィールドは「customはこれにかわるよ」に置き換えられ出力されます。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
<defaultMask>これに置き換わるよ</defaultMask>
<path>message</path>
<pathMask>
<path>custom</path>
<mask>customはこれにかわるよ</mask>
</pathMask>
</jsonGeneratorDecorator>
</encoder>
</appender>
実行結果
実行してみると、message
とcustom
ではlogback.xml
の定義に従い異なる置き換えが行われているのが確認できます。
出力される値をハンドリングしてのマスキング
値をベースのマスキングはすべてのフィールドに対して行われていくので、フィールド名を指定してのマスキングよりもパフォーマンスに与える影響は大ききなってしまいます。
正規表現を使ってのマスキング
これは、出力されるログメッセージの中で指定した正規表現にマッチした部分のみマスキングする方法になります。
loback.xmlの内容
defaultMask
はフィールド指定と同じになっていて、 value
に対して正規表現などを指定してマッチした部分を置き換えることができます。
なお、valueMask
を使うとフィールド名指定のpathMask
と同じようにマスク定義をそれぞれ定義できるようになります。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
<defaultMask>*****</defaultMask>
<value>(sio){2}</value>
</jsonGeneratorDecorator>
</encoder>
</appender>
実行結果
実行してみるといい感じに正規表現にマッチしたいる部分がマスキングできているのがわかりますね。
複数箇所マッチすれば全て置き換えられているのも確認できます。
カスタム実装を使用してマスキングしてみる
カスタム実装を使用すると、特定フィールドの値が特定の正規表現にマッチしたら置き換えなんてことが柔軟にできるようになります。
例えば、message
フィールド内に出力される可能性のあるメールアドレスなどをマスキングするなんてこともできたりします。
カスタム実装
この例では、出力される値のマスキングを行うインタフェースのValueMasker
を使ってログに出力される値のマスキングをしています。
また、余計なフィールドに対しては何も行わないようmessage
フィールドのみを対象にしています。
class ValueMaskerExample: ValueMasker {
override fun mask(context: JsonStreamContext, value: Any?): Any? {
return if (value != null && context.currentName == "message") {
value.toString().replace("siosio", "***")
} else {
value
}
}
}
valueMasker
に、カスタム実装のクラスの完全修飾名を指定してあげます。
これで、すべてのフィールドに対してカスタム実装のマスク処理が呼び出されるようになります。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
<valueMasker class="ValueMaskerExample" />
</jsonGeneratorDecorator>
</encoder>
</appender>
実行結果
実行してみるとmessage
フィールドのみマスキングが行われていることが確認できます。
マスキング対象外のcustom
フィールドはマスキングが行われていないことが確認できます。