log4j2
ロギングに問題があります。
(groovy-all 4.0.0、org.apache.logging.log4j 2.17.1、gmavenplus-plugin 1.13.0)
大きなネストされた Map オブジェクトがあります (10 個のキーと 1 つの値が 100 の長さのマップのリストです)。
そして、ログを次のように呼び出します。
Map myNestedMap = (1..1500).collectEntries{ ["key-$it", "value-$it"] }
log.debug("Some message, $myNestedMap")
そして、この行は10秒以上機能します...
デバッグ中に、これが呼び出されることがわかりました:
//org.apache.logging.log4j.message.ReusableSimpleMessage
@Override
public void formatTo(final StringBuilder buffer) {
buffer.append(charSequence);
}
インスタンスはどこにcharSequence
ありますかGString
。
パフォーマンスをチェックするためにいくつかのコードを追加しました。
Map myNestedMap = ...
Closure measure = { String message, Closure cl ->
long start = Calendar.getInstance().getTimeInMillis()
cl.call()
long end = Calendar.getInstance().getTimeInMillis()
println("$message ${(end-start)/1000} sec")
}
measure('StringBuilder:(GString, but no cast)') {
new StringBuilder().append("$myNestedMap")
}
measure('StringBuilder:(cast to String)') {
new StringBuilder().append((String)"$myNestedMap")
}
measure('StringBuilder:(cast to CharSequence)') {
new StringBuilder().append((CharSequence)"$myNestedMap")
}
measure('StringBuilder:(cast to GString)') {
new StringBuilder().append((GString)"$myNestedMap")
}
出力:
StringBuilder:(GString, but no cast) 0.354 sec
StringBuilder:(cast to String) 0.296 sec
StringBuilder:(cast to CharSequence) 13.479 sec
StringBuilder:(cast to GString) 12.937 sec
そこで、どう対処したらよいかアドバイスをいただきたいです。
できます:
Map myNestedMap = ...
log.debug("Some message, $myNestedMap" as String)
しかし、プロジェクト全体ですべてのログ レコードを String にキャストしたくありません。