カランのブログ

Kalan 頭像照片,在淡水拍攝,淺藍背景

四零二曜日電子報上線啦!訂閱訂起來

ソフトウェアエンジニア / 台湾人 / 福岡生活
このブログはRSS Feed をサポートしています。RSSリンクをクリックして設定してください。技術に関する記事はコードがあるのでブログで閲覧することをお勧めします。

今のモード ライト

我會把一些不成文的筆記或是最近的生活雜感放在短筆記,如果有興趣的話可以來看看唷!

記事のタイトルや概要は自動翻訳であるため(中身は翻訳されてない場合が多い)、変な言葉が出たり、意味伝わらない場合がございます。空いてる時間で翻訳します。

golangアプリでログを収集して一元化する方法

この記事はHow to collect, standardize, and centralize Golang logs | Datadogを読んでまとめたものです。

ログを使用する際には、次の点に注意する必要があります:

  1. ログを引数として渡し、必要な場合に引数として渡します。
  2. コンテキストを統一的にカプセル化し、必要な場合にコンテキストから取得します。
  3. ロガーをパッケージ化し、他のパッケージが使用できるように公開します。

明らかに、最初の方法はすぐに問題に直面します。例えば:

func (p *Post) CreatePost(name string, content string, logger *log.Logger) {
  ///
  if err != nil {
    logger.Fatal("error!")
  }
}

CreatePostメソッドにはロガーを渡す必要があり、引数が非常に冗長になる可能性があります。また、ロガーの連鎖的な渡しも発生する可能性があります。この方法の最大の利点は、依存関係が透明になることです。関数を介してロガーの使用が明確になり、テストもロガーをモックすることが容易です。

2番目の方法では、main関数内で明示的にcontextを渡し、その中にロガーを格納します。必要な場合はlog.Logger.FromContext(ctx)を使用します。現時点では明らかな欠点は見つかっていません。

const (
  ContextKeyLogger = "logger"
)
func main() {

  ctx := context.Background()
  loggerCtx := context.WithValue(ctx, ContextKeyLogger, log.Logger)
  
}

3番目の方法は、現在の方法です。ロガーをパッケージ化し、他のパッケージが使用できるように公開します。これにより、簡単に使用できるという最大の利点がありますが、テストする際には容易ではありません。パラメータ化されていないため、ロガーをモックするのは困難です。(他の良い解決策もあるかもしれませんが?)

package logging

var Logger *log.Logger

func init() {
  Logger = &log.Logger{
    // your setting
  }
}

次に、この記事での推奨事項を見てみましょう:

  1. logrusの使用をお勧めします。logrusは非常に使いやすいログパッケージであり、ネイティブのlogを完全にサポートしています。フック機構を使用することで、簡単にサードパーティのレポートプラットフォーム(例:datadog、sentryなど)と連携することができます。
  2. ログのフォーマットとしてJSONを使用することをお勧めします。JSONは解析しやすく、主要な言語でサポートされており、サードパーティプラットフォームにとっても解析しやすいです。logrusではSetFormatter(&logrus.JSONFormatter{})を使用して出力を設定できます。
  3. 統一されたインターフェースを使用します。
  4. ゴルーチン内でロガーを呼び出さないようにします。並行性の問題に加えて、ロガーの内部実装にもゴルーチンが実行される可能性があるため、メカニズム全体を制御するのが難しくなります。
  5. ログをローカルファイルに保存します。他のプラットフォームを使用している場合でも、ネットワークの問題によって一部のログが失われることはありませんし、常にログファイルを見つけることができます。
  6. クラスターなどのアーキテクチャを使用している場合、syslogを使用してログを1つのサーバーに集中させる必要があるかもしれません。
  7. Dockerなどのコンテナサービスを使用している場合、DockerのSTDOUTを監視する必要があるかもしれません。

その他

log.Fatal()log.Panic()について、Fatalは暗黙的にos.Exit(1)を呼び出し、Panicは暗黙的にpanicを呼び出します。使用する際には特に注意が必要です。

次の記事

Golang ノート — タイプアサーション

前の記事

より安全なリクエストヘッダー-メタデータの取得リクエストヘッダー

この文章が役に立つと思うなら、下のリンクで応援してくれると大変嬉しいです✨

Buy me a coffee