diff --git a/app/metrics/config.pb.go b/app/metrics/config.pb.go index d62dcef9..b0874b3b 100644 --- a/app/metrics/config.pb.go +++ b/app/metrics/config.pb.go @@ -27,7 +27,8 @@ type Config struct { unknownFields protoimpl.UnknownFields // Tag of the outbound handler that handles metrics http connections. - Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + Listen string `protobuf:"bytes,2,opt,name=listen,proto3" json:"listen,omitempty"` } func (x *Config) Reset() { @@ -67,20 +68,28 @@ func (x *Config) GetTag() string { return "" } +func (x *Config) GetListen() string { + if x != nil { + return x.Listen + } + return "" +} + var File_app_metrics_config_proto protoreflect.FileDescriptor var file_app_metrics_config_proto_rawDesc = []byte{ 0x0a, 0x18, 0x61, 0x70, 0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x1a, 0x0a, 0x06, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x32, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x42, 0x52, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, - 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0xaa, 0x02, 0x10, 0x58, 0x72, 0x61, 0x79, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x42, 0x52, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, + 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0xaa, 0x02, 0x10, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/metrics/config.proto b/app/metrics/config.proto index 5e6880f1..0441df03 100644 --- a/app/metrics/config.proto +++ b/app/metrics/config.proto @@ -10,4 +10,5 @@ option java_multiple_files = true; message Config { // Tag of the outbound handler that handles metrics http connections. string tag = 1; + string listen = 2; } diff --git a/app/metrics/metrics.go b/app/metrics/metrics.go index 757d673d..1dc5b2f5 100644 --- a/app/metrics/metrics.go +++ b/app/metrics/metrics.go @@ -24,12 +24,15 @@ type MetricsHandler struct { statsManager feature_stats.Manager observatory extension.Observatory tag string + listen string + tcpListener net.Listener } // NewMetricsHandler creates a new MetricsHandler based on the given config. func NewMetricsHandler(ctx context.Context, config *Config) (*MetricsHandler, error) { c := &MetricsHandler{ - tag: config.Tag, + tag: config.Tag, + listen: config.Listen, } common.Must(core.RequireFeatures(ctx, func(om outbound.Manager, sm feature_stats.Manager) { c.statsManager = sm @@ -87,6 +90,23 @@ func (p *MetricsHandler) Type() interface{} { } func (p *MetricsHandler) Start() error { + + // direct listen a port if listen is set + if p.listen != "" { + TCPlistener, err := net.Listen("tcp", p.listen) + if err != nil { + return err + } + p.tcpListener = TCPlistener + errors.LogInfo(context.Background(), "Metrics server listening on ", p.listen) + + go func() { + if err := http.Serve(TCPlistener, http.DefaultServeMux); err != nil { + errors.LogErrorInner(context.Background(), err, "failed to start metrics server") + } + }() + } + listener := &OutboundListener{ buffer: make(chan net.Conn, 4), done: done.New(), diff --git a/infra/conf/metrics.go b/infra/conf/metrics.go index 3f550e88..75965206 100644 --- a/infra/conf/metrics.go +++ b/infra/conf/metrics.go @@ -6,15 +6,21 @@ import ( ) type MetricsConfig struct { - Tag string `json:"tag"` + Tag string `json:"tag"` + Listen string `json:"listen"` } func (c *MetricsConfig) Build() (*metrics.Config, error) { + if c.Listen == "" && c.Tag == "" { + return nil, errors.New("Metrics must have a tag or listen address.") + } + // If the tag is empty but have "listen" set a default "Metrics" for compatibility. if c.Tag == "" { - return nil, errors.New("metrics tag can't be empty.") + c.Tag = "Metrics" } return &metrics.Config{ - Tag: c.Tag, + Tag: c.Tag, + Listen: c.Listen, }, nil }