func (mx *mux) serverStats(key engine.ServerKey) (*engine.RoundTripStats, error) {
	b, ok := mx.backends[key.BackendKey]
	if !ok {
		return nil, fmt.Errorf("%v not found", key.BackendKey)
	}
	srv, ok := b.findServer(key)
	if !ok {
		return nil, fmt.Errorf("%v not found", key)
	}

	u, err := url.Parse(srv.URL)
	if err != nil {
		return nil, err
	}

	m, err := memmetrics.NewRTMetrics()
	if err != nil {
		return nil, err
	}
	for _, f := range mx.frontends {
		if f.backend.backend.Id != key.BackendKey.Id {
			continue
		}
		if err := f.watcher.collectServerMetrics(m, u); err != nil {
			return nil, err
		}
	}
	return engine.NewRoundTripStats(m)
}
func (mx *mux) topServers(key *engine.BackendKey) ([]engine.Server, error) {
	metrics := map[string]*sval{}
	for _, f := range mx.frontends {
		if key != nil && key.Id != f.backend.backend.Id {
			continue
		}
		for _, s := range f.backend.servers {
			val, ok := metrics[s.URL]
			if !ok {
				sval, err := newSval(s)
				if err != nil {
					return nil, err
				}
				metrics[s.URL] = sval
				val = sval
			}
			if err := f.watcher.collectServerMetrics(val.m, val.u); err != nil {
				return nil, err
			}
		}
	}
	servers := make([]engine.Server, 0, len(metrics))
	for _, v := range metrics {
		stats, err := engine.NewRoundTripStats(v.m)
		if err != nil {
			return nil, err
		}
		v.srv.Stats = stats
		servers = append(servers, *v.srv)
	}
	sort.Stable(&serverSorter{es: servers})
	return servers, nil
}
func (rt *RTWatcher) rtServerStats(u *url.URL) (*engine.RoundTripStats, error) {
	rt.mtx.Lock()
	defer rt.mtx.Unlock()

	sm, ok := rt.srvs[surl{scheme: u.Scheme, host: u.Host}]
	if ok {
		return engine.NewRoundTripStats(sm)
	}
	return nil, fmt.Errorf("watcher: %v not found", u)
}
func (mx *mux) backendStats(key engine.BackendKey) (*engine.RoundTripStats, error) {
	m, err := memmetrics.NewRTMetrics()
	if err != nil {
		return nil, err
	}
	for _, f := range mx.frontends {
		if f.backend.backend.Id != key.Id {
			continue
		}
		if err := f.watcher.collectMetrics(m); err != nil {
			return nil, err
		}
	}
	return engine.NewRoundTripStats(m)
}
func (rt *RTWatcher) rtStats() (*engine.RoundTripStats, error) {
	rt.mtx.Lock()
	defer rt.mtx.Unlock()

	return engine.NewRoundTripStats(rt.m)
}