[解決済み] Go パッケージは log.Fatal を使うべきですか、そしてそれはいつですか?
2022-02-19 10:03:19
質問内容
これまで、私は
log.Fatal
が、最近偶然にもこんな質問を発見しました。
コードカバレッジ
と
テスト使用ログ致命的
.
コードカバレッジ100問のコメントの1つにこうあります。
... 大半の場合
log.Fatal
は、main関数やinit関数(あるいは、そこから直接呼び出されることを意図したいくつかの関数)でのみ使用されるべきです。
そこで、Goに付属する標準ライブラリのコードを見てみたんです。 多くの例で
テスト
のコードは
log.Fatal
というのは、問題なさそうです。 テストコード以外でも、例えば
net/http
以下に示す。
// net/http/transport.go
func (t *Transport) putIdleConn(pconn *persistConn) bool {
...
for _, exist := range t.idleConn[key] {
if exist == pconn {
log.Fatalf("dup idle pconn %p in freelist", pconn)
}
}
...
}
を使用しないことがベストプラクティスである場合、その
log.Fatal
なぜ標準ライブラリで使われているのでしょうか? ライブラリの利用者にとっては
os.Exit
が呼び出され、アプリケーションがクリーンアップする機会を提供しません。
私の考えは甘いかもしれませんので、私の質問は、より良い実践として
log.Panic
その結果、私の理論上の長期安定稼働アプリケーションは、灰の中から立ち上がるチャンスを得ることができるかもしれません。
では、どのような場合にlog.Fatalを使うべきか、Goのベストプラクティスはどうなっているのでしょうか?
どのように解決するのか?
私だけかもしれませんが、私は以下のように使っています。
log.Fatal
. UNIX の慣習として、エラーが発生したプロセスはできるだけ早く 0 ではない終了コードで失敗する必要があります。そのため、私は以下のようなガイドラインで
log.Fatal
というときに
-
のいずれかにエラーが発生しました。
func init()
これらはそれぞれ、importが処理されるとき、またはmain funcが呼ばれる前に発生するからです。逆に、私はライブラリやコマンドの行うべき作業単位に直接影響を与えないようなことだけを行います。例えば、ログの設定や、環境とパラメータが正常かどうかのチェックなどです。無効なフラグがあったらmainを実行する必要はないでしょう?そして、もし適切なフィードバックができないのであれば、それを早めに伝えるべきです。 - ...回復不可能なエラーが発生しました。コマンドラインで指定された画像ファイルのサムネイルを作成するプログラムがあるとします。このファイルが存在しないか、パーミッションが不十分で読めない場合、処理を続ける理由はなく、このエラーから回復することはできない。そこで、規約を守り、失敗する。
-
...処理中にエラーが発生し、元に戻せない可能性がある。これはちょっとソフトな定義ですね。説明しましょう。の実装があるとします。
cp
そして、それは非対話的で再帰的にディレクトリをコピーするように開始されました。ここで,コピー先のディレクトリで,コピーするファイルと同じ名前(ただし内容は異なる)を持つファイルに遭遇したとする.ユーザーにどうするか決めてもらうことができず、このファイルをコピーすることができないので、問題が発生します。終了コード0で終了すると、ユーザーはコピー元とコピー先のディレクトリが完全にコピーされていると判断してしまうので、問題のファイルを単純にスキップすることはできないのです。しかし、情報を破壊する可能性があるため、単純に上書きすることもできません。これはユーザーからの明示的な要求がないと回復できない状況なので、私はlog.Fatal
を使用して状況を説明し、できるだけ早い段階で失敗する原則に従います。
関連
-
[解決済み】Weird PHP error: 'Can't use function return value in write context'.
-
[解決済み] ParseFormはいつ使うべきで、FormValueとPostFormValueはいつ使うべきですか?
-
[解決済み] インポート "google/api/annotations.proto" が見つからないか、エラーが発生しました。依存関係として追加するにはどうすればよいですか?
-
[解決済み] SETNXでシングルインスタンスのRedisをロックする
-
[解決済み] gofmtの使い方を教えてください。
-
[解決済み] パラメータと戻り値におけるポインタと値の比較
-
[解決済み] GOPATHとGOROOTの値はどうすればよいですか?
-
[解決済み】Goのタグはどのような用途に使われますか?
-
[解決済み】マップからキーのスライスを取得する
-
[解決済み] メインパッケージに複数のファイルがあるプロジェクトを「go run」するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】golangでデータ構造をディープコピーする
-
[解決済み] Goプロセスをフォークする方法を教えてください。
-
[解決済み] 関数呼び出しで「値として使用」される
-
コンパイル: バージョン "" は go ツールのバージョン "" と一致しません。
-
runnerw.exe: CreateProcess はエラー 216 で失敗しました。プロセスが終了し、終了コード 216 が表示された 実行するプロジェクトがこの例外をスローする
-
[解決済み] "宣言されているが使用されていない "という迷惑なエラーを回避する方法
-
[解決済み] スライスのメソッドを含む
-
[解決済み】init()関数はいつ実行されるのですか?
-
[解決済み】指定したファイル内のテストケースを実行するには?
-
[解決済み】インターフェースのスライスを変換するタイプ