こんにちは!
LIFULLエンジニアの吉永です。
LIFULL Advent Calendar 2024 10日目の記事です。
先日GoのGORMにてデフォルトロガーが意図しない設定になっていた件の調査と対応を行ったので注意喚起もこめて記事にします。
※この記事の内容はGORM v.1.25.12時点の実装にもとづいたものになります
GORMのデフォルトロガーについて
上記に記載の通りデフォルトでは、スロークエリとエラーをロギング
する設定になっています。
GORMデフォルトロガー初期設定コード
クエリ実行時間200msを超えたらWarnレベル以上のログを残す設定になっています。
ログ出力個所
デフォルトロガーで実装されたTrace関数内で閾値を超えたクエリを標準出力に出しています。
この時、Trace関数の引数で渡されているfc
経由で実行されたSQL全文が渡されており、SQLがそのまま標準出力に出てしまいます。
また、エラー発生時にも同様であり標準出力に意図せずSQLが出力されてしまうこともあります。
SQLがログに出てしまうことについて
会社によってはSQLそのものがログに出てしまうことはセキュリティ要件に抵触してしまうこともあるかと思います。
SQLなので、SELECTする際のWHERE句に秘匿情報が含まれていることもあるかもしれませんし、場合によってはINSERT/UPDATE時に個人情報を暗号化した文字やハッシュ化した文字も含まれるかもしれません。
また、デフォルト設定で一部条件を満たした場合にのみ出力されていることからも、テスト環境で動作確認していた時には開発者が気づいていないこともありそうです。
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
上記のようなデフォルト設定で利用しているとロガーの存在にすら気づいていないこともありそうですね。
対処方法
SQLをそのままログ出力したくない場合、下記2点の対処方法があります。
ログ出力を無効にする
シンプルな対処はこちらです。
ログレベルをSilent
にするとTrace関数から即リターンするようになっています。
先ほどのデフォルト設定の初期化でConfigに以下のようにパラメーターを渡すことでログレベルをSilent
にできます。
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
ロガーを自前で実装する
にもあるように、上記interfaceを実装した構造体を自前で用意して、初期化時のConfigに渡すことで実現できます。
まとめ
- GORMのデフォルトロガーは条件を満たすとSQLを標準出力に出力してしまう
- 避けたい場合はログ出力を無効設定にしてデフォルトロガーを使うか、デフォルトロガー相当の構造体を自前で実装する必要がある
意図せず変なログが残っているのって怖いですよね・・・
GORMが悪いわけではないのですが、ライブラリを利用する場合はどんな設定があって、デフォルトだとどうなっているのか?はちゃんと事前に確認しないといけないなと改めて思いました!
最後まで読んでいただきありがとうございました!
また次の記事でお会いしましょう。