我的 grpc 服务器有一个日志拦截器,并且想要向元数据添加一个值(我想在整个生命周期中跟踪请求):
func (m *middleware) loggingInterceptor(srv interface{},
ss grpc.ServerStream,
info *grpc.StreamServerInfo,
handler grpc.StreamHandler)
md, ok := metadata.FromIncomingContext(ss.Context())
if !ok {
return errors.New("could not get metadata from incoming stream context")
}
// add the transaction id to the metadata so that business logic can track it
md.Append("trans-id", "some-transaction-id")
// call the handler func
return handler(srv, ss)
}
Run Code Online (Sandbox Code Playgroud)
但文档指出FromIncomingContext:
// FromIncomingContext returns the incoming metadata in ctx if it exists. The
// returned MD should not be modified. Writing to it may cause races.
// Modification should be made to copies of the returned MD.
Run Code Online (Sandbox Code Playgroud)
好的,那么我看一下复制函数并复制元数据:
mdCopy := md.Copy()
mdCopy.Append("trans-id", "some-transaction-id")
Run Code Online (Sandbox Code Playgroud)
并思考“如何将此元数据附加回上下文ServerStream?”,然后我检查是否有一些元数据ss.SetContext(newCtx),但我没有看到任何此类内容。我是否从错误的角度思考这个问题,或者我错过了其他什么?
小智 6
您需要使用NewIncomingContext在流中创建当前上下文的副本。
然后,您必须创建一个wrappedStream覆盖Context方法的类型ServerStream以返回修改后的context. 您需要将其传递wrappedStream给handler您在拦截器中收到的。
您可以在这里看到一个示例(它在这里覆盖其他方法,但想法是相同的): https ://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main .go#L106-L124
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
2106 次 |
| 最近记录: |