go-micro
go-micro copied to clipboard
How to add value to metadata?
Hello,
I want to add some value to metadata from grpc method, then process in wrapper, however I found since grpc 1.40, we can't modify the context, the proposed solution is to use metadata.NewIncomingContext.
https://github.com/grpc/grpc-go/issues/4363
I don't know how to do it in micro?
func (s *ServerImpl) Location(ctx context.Context, req *pb.LocationRequest, rsp *pb.City) error {
// add value to context
md, _ := metadata.FromContext(ctx)
if md != nil {
md.Set("tag", "value")
}
}
func LogWrapper(fn server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, rsp interface{}) error {
err := fn(ctx, req, rsp)
value, _ := md.Get("tag") // value is empty
}
}
After you modify the metadata, you need to convert back to context, and pass it in your request.
@xpunch
sorry, I don't get you, could you show me the example code? in Location method, ctx only exposed Value, Deadline, Done, Err methods, I don't know how to make the modification take effect.
...
ctx, err = metadata.NewContext(ctx, md)
metadata.Set(ctx, k,v)
@xpunch
This is not working.ctx can't be modified.
As the one mentioned in the issue https://github.com/grpc/grpc-go/issues/4363
func (w *wrappedStream) Context() context.Context {
ctx := w.ServerStream.Context()
md := metadata.FromIncomingContext(ctx)
newMD := md.Copy()
newMD.Append("uuid", id)
newCtx := metadata.NewIncomingContext(ctx, newMD)
return newCtx
}
However I don't find the proper way to do so.
Sorry, I misunderstand your issue. HandlerWrapper As the context cannot be modify, and there is no way to pass the context back to previous wrapper, we cannot pass metadata to log wrapper.
@JeffreyBool
根据grpc最新的设计,outbound的context修改必须用metadata.NewIncomingContext,所以只能从micro框架内部做相应的修改,如果你选择grpc1.38.0,你会发现简单的set,get依然还是可以的。
我的需求很简单,本想统一处理错误码(读取response的code),现在只能通过json解析response了。 等待micro出一个官方的方案吧。
@JeffreyBool 业务层级的错误码,譬如response都有的固定结构,err_code, err_msg这样的。 既然context没法修改,可以尝试在rsp interface{}里面增加对应的临时字段,当然这个只是没有办法的办法。
@JeffreyBool 的确我也正在做接口监控统计的事情,目前遇到的问题是我可以在wrapper里面检测到错误码(err),业务层次的错误码(rsp提取),但是我没办法在wrapper里面上报到influxdb。
我看你用的是monitor.DefaultMetrics(应该是默认的配置吧,我希望能够自定义),如果希望传个对象给wrapper(比如处理上报influxdb的逻辑),有没有办法实现?如果context能存对象,这个就很方便了。
@JeffreyBool 想了一圈,发现还是你的这个接口监控,错误方案比较靠谱。 对了,NewClientWrapper这个怎么使用,似乎client.Wrapper用法说明比较少,我下面这么用server.HandlerWrapper是可以的,但是NewClientWrapper没反应。
service := micro.NewService(
micro.Name(constant.UtilServiceName),
micro.Version("latest"),
micro.RegisterTTL(time.Second*30),
micro.RegisterInterval(time.Second*15),
micro.Server(grpc.NewServer(server.Address(""), server.Name(constant.UtilServiceName))),
micro.Registry(reg),
micro.WrapHandler(NewHandlerWrapper()),
micro.WrapClient(NewClientWrapper()),
)