Home > Backend Development > Golang > Reuse logging client in interceptor of Golang grpc server method

Reuse logging client in interceptor of Golang grpc server method

PHPz
Release: 2024-02-06 09:03:12
forward
442 people have browsed it

在 Golang grpc 服务器方法的拦截器中重用日志客户端

Question content

I am building a grpc server using go. Currently the server provides three methods:

  • submit homework
  • Cancel job
  • Get job status

I'm using datadog to log some metrics such as request count, duration, etc. The submitjob method looks like this:

func (s *myserver) submitjob(ctx context.context, request *submitjobrequest) (*submitjobresponse, error) {
        s.dd_client.logrequestcount("submitjob")
        start_time := time.now()
        defer s.dd_client.logrequestduration("submitjob", time.since(start_time))

        resp := somefunc()

    return resp, nil
}
Copy after login

The logging code in these three different server methods is almost identical. So I want to know how to avoid this duplication.

I noticed that golang grpc has the concept of interceptor. Basically I can define an interceptor function and use it to do pre/post processing of server method calls.

Following the documentation, I wrote an interceptor as follows:

func unaryInterceptor(ctx context.Context,
    req interface{},
    info *grpc.UnaryServerInfo,
    handler grpc.UnaryHandler,
) (interface{}, error) {
    dd_client := NewDatadogClient()
    defer dd_client.Close()

        dd_client.LogRequestCount(info.FullMethod)

        start_time := time.Now()

    resp, err := handler(ctx, req)

        dd_client.LogRequestDuration(info.FullMethod, time.Since(start_time))

    return resp, err
}
Copy after login

The problem is that every time the interceptor is called, it creates and destroys a new datadog client. I think this is unnecessary. But since unaryinterceptor is just a method and not a class, I don't see a way to create the datadog client once and reuse it later? Is there a way to meet my needs?


Correct answer


Yes, don't create it on the spot, but move it to another file/package, let's call it datadog.go

You need to declare it as a singleton, so it only has 1 pointer in all usages, like...

(I use the type "datadogtype" to refer to the data type returned by the function "newdatadogclient", please specify the package and version to give more precise sample code)

//your package code....


var dataDog DataDogType

//access it through a wrapper, the wrapper will init the var the first time, 
//the remaining times it will be reused

func GetDataDog()(*DataDogType) {

if dataDog == nil {
    dataDog = NewDatadogClient()
}


return dataDog

}
Copy after login

Now, depending on your use case, if you return it as a pointer and close it, you will close all uses of it, so return the pointer itself and omit the part that closes it, or return the value, so it is a copy of the original of

BTW, can you share what datadog version and specific package you are using?

The above is the detailed content of Reuse logging client in interceptor of Golang grpc server method. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template