Open6

go-agent/v3/integrations/nrmysql のコードリーディングメモ

budougumi0617budougumi0617

driverはこんな感じで初期化されているので
https://github.com/newrelic/go-agent/blob/4b46fc5b40e5398695413097b5c461679a74eafd/v3/newrelic/sql_driver.go#L31-L33

func InstrumentSQLDriver(d driver.Driver, bld SQLDriverSegmentBuilder) driver.Driver {
	return optionalMethodsDriver(&wrapDriver{bld: bld, original: d})
}

実際はここに処理が移譲されている。
https://github.com/newrelic/go-agent/blob/v3.15.2/v3/integrations/nrmysql/nrmysql.go#L61-L67

var (
	baseBuilder = newrelic.SQLDriverSegmentBuilder{
		BaseSegment: newrelic.DatastoreSegment{
			Product: newrelic.DatastoreMySQL,
		},
		ParseQuery: sqlparse.ParseQuery,
		ParseDSN:   parseDSN,
	}
)
budougumi0617budougumi0617

あとは wrapDriver がいろいろメソッドをラップしている。
https://github.com/newrelic/go-agent/blob/4b46fc5b40e5398695413097b5c461679a74eafd/v3/newrelic/sql_driver.go#L69

このへんで BEGIN されるが何もTxにNewrelicの情報を埋め込んでいない。
https://github.com/newrelic/go-agent/blob/4b46fc5b40e5398695413097b5c461679a74eafd/v3/newrelic/sql_driver.go#L155-L162

func (w *wrapConn) Begin() (driver.Tx, error) {
	return w.original.Begin()
}

// BeginTx implements ConnBeginTx.
func (w *wrapConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
	return w.original.(driver.ConnBeginTx).BeginTx(ctx, opts)
}
budougumi0617budougumi0617

理想はこんな感じだけどunexportなので真似できない。
https://github.com/newrelic/go-agent/blob/4b46fc5b40e5398695413097b5c461679a74eafd/v3/newrelic/sql_driver.go#L194-L203

// QueryContext implements QueryerContext.
func (w *wrapConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
	startTime := time.Now()
	rows, err := w.original.(driver.QueryerContext).QueryContext(ctx, query, args)
	if err != driver.ErrSkip {
		seg := w.bld.useQuery(query).startSegmentAt(ctx, startTime)
		seg.End()
	}
	return rows, err
}