# #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 собираются в промежуточном программном обеспечении. Как я могу это сделать? Как перехватить закрытие соединения в промежуточном программном обеспечении?