промежуточное ПО grpc(перехватчики) для метрики

# #go #middleware #metrics

#Вперед #промежуточный слой #метрика

Вопрос:

Я хочу посчитать время подключения. grpc/stats.Handler Это мой вариант сервера grpc. Этот обработчик улавливает начало и конец соединения

 type connInfo struct {  beginTime time.Time  label string }  type Stats struct {  rmu sync.RWMutex  connInfo map[string]*connInfo   metrics *metrics.Metrics  logger *log.Logger }  func New(metrics *metrics.Metrics, logger *log.Logger) *Stats {  return amp;Stats{  connInfo: make(map[string]*connInfo),   metrics: metrics,  logger: logger,  } }  func (h *Stats) TagRPC(ctx context.Context, s *stats.RPCTagInfo) context.Context {  label, err := h.getLabel(s.FullMethodName)  if err != nil {  h.logger.Errore(ctx, "error getting label", err)  }  remoteAddr := stats.Tags(ctx)   h.rmu.Lock()  connInfo := h.connInfo[string(remoteAddr)]  connInfo.label = label  h.rmu.Unlock()  return ctx }  func (h *Stats) HandleRPC(ctx context.Context, s stats.RPCStats) {}  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.rmu.Lock()  h.connInfo[remoteAddr] = amp;connInfo{beginTime: time.Now()}  h.rmu.Unlock()   case *stats.ConnEnd:  h.rmu.RLock()  connInfo, ok := h.connInfo[remoteAddr]  h.rmu.RUnlock()  if !ok {  h.logger.Error(ctx, "Begin time was not set")  return  }  h.rmu.Lock()  delete(h.connInfo, remoteAddr)  h.rmu.Unlock()   h.metrics.ConnectionTime.With(metrics.MakeLabels(connInfo.label)).Observe(time.Since(connInfo.beginTime).Seconds())  } }  func (h *Stats) getLabel(methodName string) (string, error) {  label, ok := metricLabels[methodName]  if !ok {  return "", errors.New("method name not found")  }  return label, nil }  

Это работает, но я хочу добавить эту логику в промежуточное программное обеспечение, потому что метрики http собираются в промежуточном программном обеспечении. Как я могу это сделать? Как перехватить закрытие соединения в промежуточном программном обеспечении?