LoginSignup
5
3

More than 3 years have passed since last update.

マイクロサービスにおけるロギングについて

Posted at

マイクロサービスにおけるロギングMEMO

リクエストにユニークなIDを付与し、紐付けができるようにする

マイクロサービスでは、あるサービスAがサービスBを呼びさらにサービスCを呼ぶといった形になるので、呼び出しチェーンにユニークなIDを与えることで調査の見通しが良くなります。

なるほど。

ログは一箇所に集める

各サービスが出力するユニークID付きのログを横断的に調査するために、各サービスのログを一箇所に集中させることが次に重要になります。

こんな感じらしい

ログデータを構造化する

  • jsonがおすすめ

ログに有益な情報を持たせる

どのサービスでも共通で持つのが望ましいフィールド

  • 日時(タイムスタンプ)
  • 対象のサービス名
  • スタックトレース
  • エラー発生源である外部サービス名やミドルウェア名

リクエストのエントリーポイントとなるサービスで持つのが望ましいフィールド

  • リクエスト元のIPアドレス
  • ユーザが利用したブラウザ名またはモバイルのOS名
  • HTTPレスポンスコード
{
   "level":"error",
   "msg":"SearchSample panic!",
   "request-id":"00A-abcdef-99B",
   "service-name":"MicroService01",
   "stack":"goroutine 6 [running]...スタックトレースが続く...",
   "time":"2020-03-15T23:39:58+09:00"
}

package logger

import (
    "github.com/sirupsen/logrus"
)

const (
    // XTransactionID はユニークIDのためのHTTPヘッダーのキー名です。
    XTransactionID = "X-Transaction-ID"
)

var (
    // Log は本パッケージのグローバルインスタンスです。
    Log = defaultLogger()

    // ServiceName は各アプリケーションのビルド時に ldflags を利用して埋め込まれます。
    // 下記はビルドの例です。
    // go build -ldflags "-X path/microservice-logging/logger.ServiceName=MicroService01"
    ServiceName = "not-set"
)

// Logger は公開インターフェースです。
type Logger interface {
    Debug(xTxID interface{}, msg string, fields ...Field)
    Info(xTxID interface{}, msg string, fields ...Field)
    Error(xTxID interface{}, msg string, fields ...Field)
}

// NewLogger は Logger インターフェースのコンストラクタです。
// 基本として、マイクロサービスのアプリケーションはこれを利用せずに Log インスタンスを利用することがルールです。
// 開発をする場合や調査をする場合などで Config を設定しこのメソッドを呼び出す。
func NewLogger(conf *Config) Logger {
    return newLogger(conf)
}

func defaultLogger() Logger {
    return newLogger(NewConfig()) //NewConfig() で共通ルールに基づくデフォルト設定がされる。
}

type logger struct {
    *logrus.Logger
    config *Config
}

func newLogger(config *Config) Logger {
    var l = logrus.New()
    {
        l.Level, _ = logrus.ParseLevel(config.minLevel.String())
        l.Formatter = config.formatter
        l.Out = config.out
    }
    return &logger{
        Logger: l,
        config: config,
    }
}

func (l *logger) Debug(xTxID interface{}, msg string, fields ...Field) {
    ...
}

func (l *logger) Info(xTxID interface{}, msg string, fields ...Field) {
    ...
}

func (l *logger) Error(xTxID interface{}, msg string, fields ...Field) {
    ...
}
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3