mv metrics/service to x

This commit is contained in:
ginuerzh
2022-09-28 11:46:32 +08:00
parent 41ff9835a6
commit 6e7a8f4619
5 changed files with 3 additions and 240 deletions

View File

@ -26,6 +26,7 @@ type Route interface {
Nodes() []*Node Nodes() []*Node
} }
// route is a Route without nodes.
type route struct{} type route struct{}
func (*route) Dial(ctx context.Context, network, address string, opts ...DialOption) (net.Conn, error) { func (*route) Dial(ctx context.Context, network, address string, opts ...DialOption) (net.Conn, error) {

View File

@ -18,10 +18,10 @@ type SockOpts struct {
} }
type RouterOptions struct { type RouterOptions struct {
Retries int
Timeout time.Duration
IfceName string IfceName string
SockOpts *SockOpts SockOpts *SockOpts
Timeout time.Duration
Retries int
Chain Chainer Chain Chainer
Resolver resolver.Resolver Resolver resolver.Resolver
HostMapper hosts.HostMapper HostMapper hosts.HostMapper

View File

@ -2,45 +2,8 @@ package metrics
type MetricName string type MetricName string
const (
// Number of services. Labels: host.
MetricServicesGauge MetricName = "gost_services"
// Total service requests. Labels: host, service.
MetricServiceRequestsCounter MetricName = "gost_service_requests_total"
// Number of in-flight requests. Labels: host, service.
MetricServiceRequestsInFlightGauge MetricName = "gost_service_requests_in_flight"
// Request duration historgram. Labels: host, service.
MetricServiceRequestsDurationObserver MetricName = "gost_service_request_duration_seconds"
// Total service input data transfer size in bytes. Labels: host, service.
MetricServiceTransferInputBytesCounter MetricName = "gost_service_transfer_input_bytes_total"
// Total service output data transfer size in bytes. Labels: host, service.
MetricServiceTransferOutputBytesCounter MetricName = "gost_service_transfer_output_bytes_total"
// Chain node connect duration histogram. Labels: host, chain, node.
MetricNodeConnectDurationObserver MetricName = "gost_chain_node_connect_duration_seconds"
// Total service handler errors. Labels: host, service.
MetricServiceHandlerErrorsCounter MetricName = "gost_service_handler_errors_total"
// Total chain connect errors. Labels: host, chain, node.
MetricChainErrorsCounter MetricName = "gost_chain_errors_total"
)
type Labels map[string]string type Labels map[string]string
var (
global Metrics = Noop()
)
func Init(m Metrics) {
if m != nil {
global = m
} else {
global = Noop()
}
}
func IsEnabled() bool {
return global != Noop()
}
type Gauge interface { type Gauge interface {
Inc() Inc()
Dec() Dec()
@ -62,15 +25,3 @@ type Metrics interface {
Gauge(name MetricName, labels Labels) Gauge Gauge(name MetricName, labels Labels) Gauge
Observer(name MetricName, labels Labels) Observer Observer(name MetricName, labels Labels) Observer
} }
func GetCounter(name MetricName, labels Labels) Counter {
return global.Counter(name, labels)
}
func GetGauge(name MetricName, labels Labels) Gauge {
return global.Gauge(name, labels)
}
func GetObserver(name MetricName, labels Labels) Observer {
return global.Observer(name, labels)
}

View File

@ -1,43 +0,0 @@
package metrics
var (
nopGauge = &noopGauge{}
nopCounter = &noopCounter{}
nopObserver = &noopObserver{}
noop Metrics = &noopMetrics{}
)
type noopMetrics struct{}
func Noop() Metrics {
return noop
}
func (m *noopMetrics) Counter(name MetricName, labels Labels) Counter {
return nopCounter
}
func (m *noopMetrics) Gauge(name MetricName, labels Labels) Gauge {
return nopGauge
}
func (m *noopMetrics) Observer(name MetricName, labels Labels) Observer {
return nopObserver
}
type noopGauge struct{}
func (*noopGauge) Inc() {}
func (*noopGauge) Dec() {}
func (*noopGauge) Add(v float64) {}
func (*noopGauge) Set(v float64) {}
type noopCounter struct{}
func (*noopCounter) Inc() {}
func (*noopCounter) Add(v float64) {}
type noopObserver struct{}
func (*noopObserver) Observe(v float64) {}

View File

@ -1,157 +1,11 @@
package service package service
import ( import (
"context"
"net" "net"
"time"
"github.com/go-gost/core/admission"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/metrics"
"github.com/go-gost/core/recorder"
) )
type options struct {
admission admission.Admission
recorders []recorder.RecorderObject
logger logger.Logger
}
type Option func(opts *options)
func AdmissionOption(admission admission.Admission) Option {
return func(opts *options) {
opts.admission = admission
}
}
func RecordersOption(recorders ...recorder.RecorderObject) Option {
return func(opts *options) {
opts.recorders = recorders
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
}
}
type Service interface { type Service interface {
Serve() error Serve() error
Addr() net.Addr Addr() net.Addr
Close() error Close() error
} }
type service struct {
name string
listener listener.Listener
handler handler.Handler
options options
}
func NewService(name string, ln listener.Listener, h handler.Handler, opts ...Option) Service {
var options options
for _, opt := range opts {
opt(&options)
}
return &service{
name: name,
listener: ln,
handler: h,
options: options,
}
}
func (s *service) Addr() net.Addr {
return s.listener.Addr()
}
func (s *service) Close() error {
return s.listener.Close()
}
func (s *service) Serve() error {
if v := metrics.GetGauge(
metrics.MetricServicesGauge,
metrics.Labels{}); v != nil {
v.Inc()
defer v.Dec()
}
var tempDelay time.Duration
for {
conn, e := s.listener.Accept()
if e != nil {
// TODO: remove Temporary checking
if ne, ok := e.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 1 * time.Second
} else {
tempDelay *= 2
}
if max := 5 * time.Second; tempDelay > max {
tempDelay = max
}
s.options.logger.Warnf("accept: %v, retrying in %v", e, tempDelay)
time.Sleep(tempDelay)
continue
}
s.options.logger.Errorf("accept: %v", e)
return e
}
tempDelay = 0
for _, rec := range s.options.recorders {
host := conn.RemoteAddr().String()
if h, _, _ := net.SplitHostPort(host); h != "" {
host = h
}
if rec.Record == recorder.RecorderServiceClientAddress {
if err := rec.Recorder.Record(context.Background(), []byte(host)); err != nil {
s.options.logger.Errorf("record %s: %v", rec.Record, err)
}
}
}
if s.options.admission != nil &&
!s.options.admission.Admit(conn.RemoteAddr().String()) {
conn.Close()
s.options.logger.Debugf("admission: %s is denied", conn.RemoteAddr())
continue
}
go func() {
if v := metrics.GetCounter(metrics.MetricServiceRequestsCounter,
metrics.Labels{"service": s.name}); v != nil {
v.Inc()
}
if v := metrics.GetGauge(metrics.MetricServiceRequestsInFlightGauge,
metrics.Labels{"service": s.name}); v != nil {
v.Inc()
defer v.Dec()
}
start := time.Now()
if v := metrics.GetObserver(metrics.MetricServiceRequestsDurationObserver,
metrics.Labels{"service": s.name}); v != nil {
defer func() {
v.Observe(float64(time.Since(start).Seconds()))
}()
}
if err := s.handler.Handle(
context.Background(),
conn,
); err != nil {
s.options.logger.Error(err)
if v := metrics.GetCounter(metrics.MetricServiceHandlerErrorsCounter,
metrics.Labels{"service": s.name}); v != nil {
v.Inc()
}
}
}()
}
}