diff --git a/api.go b/api.go index dd93144..ce5f99a 100644 --- a/api.go +++ b/api.go @@ -12,6 +12,7 @@ import ( "github.com/franela/play-with-docker/services" "github.com/franela/play-with-docker/templates" "github.com/gorilla/mux" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/urfave/negroni" ) @@ -71,6 +72,7 @@ func main() { })) r.Handle("/sessions/{sessionId}/ws/", server) + r.Handle("/metrics", promhttp.Handler()) n := negroni.Classic() n.UseHandler(r) diff --git a/services/client.go b/services/client.go index e2550d9..d2d9d5c 100644 --- a/services/client.go +++ b/services/client.go @@ -4,8 +4,20 @@ import ( "log" "github.com/googollee/go-socket.io" + "github.com/prometheus/client_golang/prometheus" ) +var ( + clientsGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "clients", + Help: "Clients", + }) +) + +func init() { + prometheus.MustRegister(clientsGauge) +} + type ViewPort struct { Rows uint Cols uint @@ -23,6 +35,7 @@ func (c *Client) ResizeViewPort(cols, rows uint) { } func NewClient(so socketio.Socket, session *Session) *Client { + clientsGauge.Inc() so.Join(session.Id) c := &Client{so: so, Id: so.Id()} @@ -52,7 +65,9 @@ func NewClient(so socketio.Socket, session *Session) *Client { } } }) + so.On("disconnection", func() { + clientsGauge.Dec() // Client has disconnected. Remove from session and recheck terminal sizes. for i, cl := range session.clients { if cl.Id == c.Id { @@ -69,6 +84,5 @@ func NewClient(so socketio.Socket, session *Session) *Client { } } }) - return c } diff --git a/services/instance.go b/services/instance.go index 2342449..142f44c 100644 --- a/services/instance.go +++ b/services/instance.go @@ -11,10 +11,22 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" + "github.com/prometheus/client_golang/prometheus" ) var rw sync.Mutex +var ( + instancesGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "instances", + Help: "Instances", + }) +) + +func init() { + prometheus.MustRegister(instancesGauge) +} + type Instance struct { session *Session `json:"-"` Name string `json:"name"` @@ -90,6 +102,8 @@ func NewInstance(session *Session) (*Instance, error) { wsServer.BroadcastTo(session.Id, "new instance", instance.Name, instance.IP, instance.Hostname) + instancesGauge.Inc() + return instance, nil } @@ -142,5 +156,7 @@ func DeleteInstance(session *Session, instance *Instance) error { wsServer.BroadcastTo(session.Id, "delete instance", instance.Name) + instancesGauge.Dec() + return err } diff --git a/services/session.go b/services/session.go index 57405ad..033f370 100644 --- a/services/session.go +++ b/services/session.go @@ -14,9 +14,21 @@ import ( "github.com/docker/docker/client" "github.com/googollee/go-socket.io" + "github.com/prometheus/client_golang/prometheus" "github.com/twinj/uuid" ) +var ( + sessionsGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "sessions", + Help: "Sessions", + }) +) + +func init() { + prometheus.MustRegister(sessionsGauge) +} + var wsServer *socketio.Server type Session struct { @@ -129,10 +141,15 @@ func CloseSession(s *Session) error { s.rw.Lock() defer s.rw.Unlock() + sessionsGauge.Dec() if s.ticker != nil { s.ticker.Stop() } wsServer.BroadcastTo(s.Id, "session end") + for _, c := range s.clients { + c.so.Emit("disconnect") + clientsGauge.Dec() + } log.Printf("Starting clean up of session [%s]\n", s.Id) for _, i := range s.Instances { if i.conn != nil { @@ -207,6 +224,8 @@ func NewSession() (*Session, error) { if err := saveSessionsToDisk(); err != nil { return nil, err } + + sessionsGauge.Inc() return s, nil } @@ -236,6 +255,7 @@ func LoadSessionsFromDisk() error { // schedule session expiration for _, s := range sessions { + sessionsGauge.Inc() timeLeft := s.ExpiresAt.Sub(time.Now()) CloseSessionAfter(s, timeLeft) @@ -243,7 +263,7 @@ func LoadSessionsFromDisk() error { for _, i := range s.Instances { // wire the session back to the instance i.session = s - + instancesGauge.Inc() } // Connect PWD daemon to the new network