Add a prometheus exporter and some metrics

This commit is contained in:
Björn Busse 2018-03-08 02:40:26 +00:00
parent a3ce9988ff
commit 9a4e42ba8b
2 changed files with 68 additions and 3 deletions

View File

@ -28,6 +28,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/prometheus/client_golang/prometheus"
) )
const ( const (
@ -60,15 +62,20 @@ func GetRoom(name string) (r *Room, found bool) {
return r, found return r, found
} }
func SendLusers(client *Client) { func GetNumberOfRegisteredUsers(client *Client) (nusers float64){
lusers := 0 nusers = 0
clientsM.RLock() clientsM.RLock()
for client := range clients { for client := range clients {
if client.registered { if client.registered {
lusers++ nusers++
} }
} }
clientsM.RUnlock() clientsM.RUnlock()
return nusers
}
func SendLusers(client *Client) {
lusers := GetNumberOfRegisteredUsers(client)
client.ReplyNicknamed("251", fmt.Sprintf("There are %d users and 0 invisible on 1 servers", lusers)) client.ReplyNicknamed("251", fmt.Sprintf("There are %d users and 0 invisible on 1 servers", lusers))
} }
@ -268,6 +275,8 @@ func ClientRegister(client *Client, cmd string, cols []string) {
} }
} }
client.registered = true client.registered = true
clients_irc_total.Inc()
clients_connected.Set(GetNumberOfRegisteredUsers(client))
client.ReplyNicknamed("001", "Hi, welcome to IRC") client.ReplyNicknamed("001", "Hi, welcome to IRC")
client.ReplyNicknamed("002", "Your host is "+*hostname+", running goircd "+version) client.ReplyNicknamed("002", "Your host is "+*hostname+", running goircd "+version)
client.ReplyNicknamed("003", "This server was created sometime") client.ReplyNicknamed("003", "This server was created sometime")
@ -338,17 +347,22 @@ func HandlerJoin(client *Client, cmd string) {
Denied: Denied:
client.ReplyNicknamed("475", room, "Cannot join channel (+k) - bad key") client.ReplyNicknamed("475", room, "Cannot join channel (+k) - bad key")
Joined: Joined:
clients_irc_rooms_total.With(prometheus.Labels{"room":"all"}).Inc()
clients_irc_rooms_total.With(prometheus.Labels{"room":room}).Inc()
} }
} }
func Processor(events chan ClientEvent, finished chan struct{}) { func Processor(events chan ClientEvent, finished chan struct{}) {
var now time.Time var now time.Time
go func() { go func() {
for { for {
time.Sleep(10 * time.Second) time.Sleep(10 * time.Second)
events <- ClientEvent{eventType: EventTick} events <- ClientEvent{eventType: EventTick}
} }
}() }()
for event := range events { for event := range events {
now = time.Now() now = time.Now()
client := event.client client := event.client
@ -618,6 +632,7 @@ func Processor(events chan ClientEvent, finished chan struct{}) {
default: default:
client.ReplyNicknamed("421", cmd, "Unknown command") client.ReplyNicknamed("421", cmd, "Unknown command")
} }
clients_connected.Set(GetNumberOfRegisteredUsers(client))
} }
} }
} }

View File

@ -24,12 +24,15 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net" "net"
"net/http"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
proxyproto "github.com/Freeaqingme/go-proxyproto" proxyproto "github.com/Freeaqingme/go-proxyproto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
) )
const ( const (
@ -47,7 +50,37 @@ var (
tlsBind = flag.String("tlsbind", "", "TLS address to bind to") tlsBind = flag.String("tlsbind", "", "TLS address to bind to")
tlsPEM = flag.String("tlspem", "", "Path to TLS certificat+key PEM file") tlsPEM = flag.String("tlspem", "", "Path to TLS certificat+key PEM file")
proxyTimeout = flag.Uint("proxytimeout", PROXY_TIMEOUT, "Timeout when using proxy protocol") proxyTimeout = flag.Uint("proxytimeout", PROXY_TIMEOUT, "Timeout when using proxy protocol")
metrics = flag.Bool("metrics", false, "Enable metrics export")
verbose = flag.Bool("v", false, "Enable verbose logging.") verbose = flag.Bool("v", false, "Enable verbose logging.")
clients_tls_total = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "clients_tls_connected_total",
Help: "Number of connected clients during the lifetime of the server.",
},
)
clients_irc_total = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "clients_irc_connected_total",
Help: "Number of connected irc clients during the lifetime of the server.",
},
)
clients_irc_rooms_total = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "clients_irc_rooms_connected_total",
Help: "Number of clients joined to rooms during the lifetime of the server.",
},
[]string{"room"},
)
clients_connected = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "clients_connected",
Help: "Number of connected clients.",
},
)
) )
func listenerLoop(sock net.Listener, events chan ClientEvent) { func listenerLoop(sock net.Listener, events chan ClientEvent) {
@ -58,6 +91,7 @@ func listenerLoop(sock net.Listener, events chan ClientEvent) {
continue continue
} }
client := NewClient(conn) client := NewClient(conn)
clients_tls_total.Inc()
go client.Processor(events) go client.Processor(events)
} }
} }
@ -149,9 +183,25 @@ func Run() {
go listenerLoop(listenerTLS, events) go listenerLoop(listenerTLS, events)
} }
// Create endpoint for prometheus metrics export
if *metrics {
go prom_export()
}
Processor(events, make(chan struct{})) Processor(events, make(chan struct{}))
} }
func prom_export() {
prometheus.MustRegister(clients_tls_total)
prometheus.MustRegister(clients_irc_total)
prometheus.MustRegister(clients_irc_rooms_total)
prometheus.MustRegister(clients_connected)
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))
}
func main() { func main() {
flag.Parse() flag.Parse()
Run() Run()