🍣

connect-go に New Relic を導入する

2023/10/30に公開

connect-go に New Relic を導入する際に結構ハマったので備忘録として置いておく。

とりあえずサーバ初期化時に New Relic のクライアントを作る。

import (
	"github.com/newrelic/go-agent/v3/newrelic"
)

nr, err := newrelic.NewApplication(
	newrelic.ConfigAppName("app-name"),
	newrelic.ConfigLicense("xxxxx"),
	newrelic.ConfigAppLogEnabled(true),
	newrelic.ConfigDistributedTracerEnabled(true),
	func(config *newrelic.Config) {
		config.Labels = map[string]string{
			"Version": "local-xxxx", # フィルタリングのための識別子を追加
		}
	},
)

いつも通り connect-go でハンドラを初期化する。

path, handler := userv1connect.NewUserServiceHandler(userHandler)

通常はこの後 server mux とかにパスとパンドラを渡すんだけど、

m := http.NewServeMux()
m.Handle(path, handler)

今回はここに newrelic.WrapHandle を挟むことで対象のパスに対する。

m.Handle(newrelic.WrapHandle(nr, path, handler))

あとはいつも通り connecto-go でサーバを起動する。

ここまでではエンドポイントごとのトレース情報しかとれないのでそれぞれの関数で Context を引き回しながら以下のコードを追加することで関数ごとのトレースを追加することができます。

defer newrelic.FromContext(ctx).StartSegment("関数名").End()

また、関数内の特定のコードのみでトレース情報を追加したい場合は以下のように関数の前後に segment を生成することで特定の処理のトレースを追加することができます。

s := newrelic.FromContext(ctx).StartSegment("何かの関数")
// 何かの関数
s.End()

あとは、該当のパスにアクセスすることで New Relic で可視化することができます。

ここまでの対応でハンドラごとの分散トレーシングを可視化することはできましたが、 connect-go の同一ハンドラ内のサービスを分けて可視化することができていないため、分ける方法が分かり次第追記します。

Discussion