diff --git a/spanner/client.go b/spanner/client.go index a3f282cee6f9..9259bc2020dc 100644 --- a/spanner/client.go +++ b/spanner/client.go @@ -134,6 +134,15 @@ type ClientConfig struct { // override the default values. CallOptions *vkit.CallOptions + // UserAgent is the prefix to the user agent header. This is used to supply information + // such as application name or partner tool. + // + // Internal Use Only: This field is for internal tracking purpose only, + // setting the value for this config is not required. + // + // Recommended format: ``application-or-tool-ID/major.minor.version``. + UserAgent string + // logger is the logger to use for this client. If it is nil, all logging // will be directed to the standard logger. logger *log.Logger @@ -211,7 +220,7 @@ func NewClientWithConfig(ctx context.Context, database string, config ClientConf config.incStep = DefaultSessionPoolConfig.incStep } // Create a session client. - sc := newSessionClient(pool, database, sessionLabels, metadata.Pairs(resourcePrefixHeader, database), config.logger, config.CallOptions) + sc := newSessionClient(pool, database, config.UserAgent, sessionLabels, metadata.Pairs(resourcePrefixHeader, database), config.logger, config.CallOptions) // Create a session pool. config.SessionPoolConfig.sessionLabels = sessionLabels sp, err := newSessionPool(sc, config.SessionPoolConfig) diff --git a/spanner/sessionclient.go b/spanner/sessionclient.go index 559c104e92b3..a55c0e370eb6 100644 --- a/spanner/sessionclient.go +++ b/spanner/sessionclient.go @@ -21,6 +21,7 @@ import ( "fmt" "log" "reflect" + "strings" "sync" "time" @@ -90,6 +91,7 @@ type sessionClient struct { connPool gtransport.ConnPool database string id string + userAgent string sessionLabels map[string]string md metadata.MD batchTimeout time.Duration @@ -98,10 +100,11 @@ type sessionClient struct { } // newSessionClient creates a session client to use for a database. -func newSessionClient(connPool gtransport.ConnPool, database string, sessionLabels map[string]string, md metadata.MD, logger *log.Logger, callOptions *vkit.CallOptions) *sessionClient { +func newSessionClient(connPool gtransport.ConnPool, database, userAgent string, sessionLabels map[string]string, md metadata.MD, logger *log.Logger, callOptions *vkit.CallOptions) *sessionClient { return &sessionClient{ connPool: connPool, database: database, + userAgent: userAgent, id: cidGen.nextID(database), sessionLabels: sessionLabels, md: md, @@ -322,7 +325,14 @@ func (sc *sessionClient) nextClient() (*vkit.Client, error) { if err != nil { return nil, err } - client.SetGoogleClientInfo("gccl", internal.Version) + clientInfo := []string{"gccl", internal.Version} + if sc.userAgent != "" { + agentWithVersion := strings.SplitN(sc.userAgent, "/", 2) + if len(agentWithVersion) == 2 { + clientInfo = append(clientInfo, agentWithVersion[0], agentWithVersion[1]) + } + } + client.SetGoogleClientInfo(clientInfo...) if sc.callOptions != nil { client.CallOptions = mergeCallOptions(client.CallOptions, sc.callOptions) }