diff --git a/config/config.go b/config/config.go index 80e2ec3..fec560f 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ import ( "github.com/dezh-tech/immortal/handler" "github.com/dezh-tech/immortal/relay/redis" "github.com/dezh-tech/immortal/server/grpc" + "github.com/dezh-tech/immortal/server/http" "github.com/dezh-tech/immortal/server/websocket" "github.com/joho/godotenv" "gopkg.in/yaml.v3" @@ -21,6 +22,7 @@ type Config struct { Database database.Config `yaml:"database"` RedisConf redis.Config `yaml:"redis"` GRPCServer grpc.Config `yaml:"grpc_server"` + Metrics http.Config `yaml:"metrics"` Handler handler.Config } diff --git a/config/config.yml b/config/config.yml index 1322b54..f05cb90 100644 --- a/config/config.yml +++ b/config/config.yml @@ -11,7 +11,7 @@ environment: "prod" # ws_server contains information about websocket server. ws_server: # bind is the IP address to be bind and listen on. - # default is local host. + # default is 0.0.0.0. bind: "0.0.0.0" # port is websocket port to be listen on. @@ -21,13 +21,27 @@ ws_server: # grpc_server contains information about grpc server. grpc_server: # bind is the IP address to be bind and listen on. - # default is local host. + # default is 0.0.0.0. bind: "0.0.0.0" # port is grpc port to be listen on. # default is 50050. port: 50050 +# metrics contains information about prometheus metrics https server. +metrics: + # bind is the IP address to be bind and listen on. + # default is 0.0.0.0. + bind: "0.0.0.0" + + # port is grpc port to be listen on. + # default is 9090. + port: 9090 + + # enable or disable metrics service. + # default is disabled. + enable: false + # kraken contains information about connection with kraken instance. kraken: # IP address of kraken instance. diff --git a/go.mod b/go.mod index bb62522..69b01c6 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/gorilla/mux v1.8.1 github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/go.sum b/go.sum index 0d82496..e8c4815 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= @@ -43,6 +45,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= diff --git a/relay/relay.go b/relay/relay.go index ea8c57b..f8df8ce 100644 --- a/relay/relay.go +++ b/relay/relay.go @@ -13,6 +13,7 @@ import ( "github.com/dezh-tech/immortal/metrics" "github.com/dezh-tech/immortal/relay/redis" "github.com/dezh-tech/immortal/server/grpc" + "github.com/dezh-tech/immortal/server/http" "github.com/dezh-tech/immortal/server/websocket" ) @@ -21,6 +22,7 @@ type Relay struct { config config.Config websocketServer *websocket.Server grpcServer *grpc.Server + httpServer *http.Server database *database.Database redis *redis.Redis } @@ -73,11 +75,17 @@ func New(cfg *config.Config) (*Relay, error) { gs := grpc.New(&cfg.GRPCServer, r, db, time.Now()) + hs, err := http.New(cfg.Metrics) + if err != nil { + return nil, err + } + return &Relay{ config: *cfg, websocketServer: ws, database: db, redis: r, + httpServer: hs, grpcServer: gs, }, nil } @@ -99,6 +107,14 @@ func (r *Relay) Start() chan error { } }() + if r.config.Metrics.Enable { + go func() { + if err := r.httpServer.Start(); err != nil { + errCh <- err + } + }() + } + return errCh } @@ -114,5 +130,11 @@ func (r *Relay) Stop() error { return err } + if r.config.Metrics.Enable { + if err := r.httpServer.Start(); err != nil { + return err + } + } + return r.database.Stop() } diff --git a/server/http/config.go b/server/http/config.go new file mode 100644 index 0000000..e0d5515 --- /dev/null +++ b/server/http/config.go @@ -0,0 +1,7 @@ +package http + +type Config struct { + Bind string `yaml:"bind"` + Port uint16 `yaml:"port"` + Enable bool `yaml:"enable"` +} diff --git a/server/http/server.go b/server/http/server.go new file mode 100644 index 0000000..d5477c5 --- /dev/null +++ b/server/http/server.go @@ -0,0 +1,33 @@ +package http + +import ( + "net" + "net/http" + "strconv" + + "github.com/gorilla/mux" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +type Server struct { + router *mux.Router + config Config +} + +func New(cfg Config) (*Server, error) { + r := mux.NewRouter() + + s := &Server{ + router: r, + config: cfg, + } + + r.Handle("/metrics", promhttp.Handler()).Methods("GET") + + return s, nil +} + +func (s *Server) Start() error { + return http.ListenAndServe(net.JoinHostPort(s.config.Bind, //nolint + strconv.Itoa(int(s.config.Port))), s.router) +} diff --git a/server/websocket/event_handler.go b/server/websocket/event_handler.go index aa10e7f..b0227cf 100644 --- a/server/websocket/event_handler.go +++ b/server/websocket/event_handler.go @@ -187,7 +187,7 @@ func (s *Server) handleEvent(conn *websocket.Conn, m message.Message) { log.Printf("error: checking bloom filter: %s", err.Error()) } - // todo::: can we run goroutines per client? + // todo::: should we run goroutines per client? for conn, client := range s.conns { client.Lock() for id, filters := range client.subs {