Как сделать grpc middleware для метрики времени коннекта?
Есть двусторонний grpc api. Мне нужно добавить метрику, которая измеряет время жизни коннекта с клиентом. Собираюсь добавить это в миддлвар. Но что-то не могу понять как хендлить отключение коннекта. Ну и вообще с миддлаварами небольшие пробелы есть.
Я с gRPC особо не работал, не уверен, что эту задачу получится решить с помощью middleware.
Если бы у меня стояла такая задача, я бы сначала разобрался как отлавливать connect/disconnect.
Вот тут есть пример https://github.com/grpc/grpc-go/issues/3634, но не уверен на 100%
А после того, как станет понятно как эту информацию получить - станет понятно как эту метрику отдавать.
func (h *Stats) TagRPC(ctx context.Context, _ *stats.RPCTagInfo) context.Context {
return ctx
}
func (h *Stats) HandleRPC(ctx context.Context, s stats.RPCStats) {
if trailer, ok := s.(*stats.OutTrailer); ok {
remoteAddr := string(stats.Tags(ctx))
connInfoInterface, ok := h.connInfo.Load(remoteAddr)
if !ok {
h.logger.Warn(ctx, "start time was not set")
return
}
connInfo := connInfoInterface.(*connInfo)
connInfo.label = trailer.Trailer.Get(remoteAddr)[0]
}
}
func (h *Stats) TagConn(ctx context.Context, s *stats.ConnTagInfo) context.Context {
ctx = stats.SetIncomingTags(ctx, []byte(s.RemoteAddr.String()))
return ctx
}
func (h *Stats) HandleConn(ctx context.Context, s stats.ConnStats) {
remoteAddr := string(stats.Tags(ctx))
switch s.(type) {
case *stats.ConnBegin:
h.connInfo.Store(remoteAddr, &connInfo{beginTime: time.Now()})
case *stats.ConnEnd:
connInfoInterface, ok := h.connInfo.LoadAndDelete(remoteAddr)
if !ok {
h.logger.Warn(ctx, "begin time was not set")
}
connInfo, ok := connInfoInterface.(*connInfo)
if !ok {
h.logger.Warn(ctx, "wrong convertations")
}
h.metrics.ConnectionTime.With(metrics.MakeLabels(connInfo.label)).Observe(time.Since(connInfo.beginTime).Seconds())
}
}
Но мне не очень нравится как выглядит, если честно. Я лейбл для метрики отправляю трейлером из обработчика. По итогу этот трейлер в стриме возвращается клиенту. Сейчас вот думаю над лучшим решением. Кстати, вот вопрос на стаковерфлоу https://stackoverflow.com/questions/70201446/addin...