Skip to content

Commit

Permalink
Merge pull request #10 from systemli/Add-Prometheus-Metrics
Browse files Browse the repository at this point in the history
🚸 Add Prometheus Metrics
  • Loading branch information
0x46616c6b authored Oct 3, 2024
2 parents 57a6e59 + ce4fb61 commit c5d936b
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 2 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The adapter is configured via environment variables:
- `DOMAIN_LISTEN_ADDR`: The address to listen on for incoming requests. Default: `10002`.
- `MAILBOX_LISTEN_ADDR`: The address to listen on for incoming requests. Default: `10003`.
- `SENDERS_LISTEN_ADDR`: The address to listen on for incoming requests. Default: `10004`.
- `METRICS_LISTEN_ADDR`: The address to listen on for metrics. Default: `10005`.

In Postfix, you can configure the adapter as a transport like this:

Expand All @@ -23,3 +24,44 @@ virtual_mailbox_domains = tcp:localhost:10002
virtual_mailbox_maps = tcp:localhost:10003
smtpd_sender_login_maps = tcp:localhost:10004
```

## Metrics

The adapter exposes metrics in the Prometheus format. You can access them on the `/metrics` endpoint.

```text
# HELP userli_postfix_adapter_request_duration_seconds Duration of requests to userli
# TYPE userli_postfix_adapter_request_duration_seconds histogram
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="0.1"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="0.15000000000000002"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="0.22500000000000003"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="0.3375"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="0.5062500000000001"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="alias",status="success",le="+Inf"} 1
userli_postfix_adapter_request_duration_seconds_sum{handler="alias",status="success"} 0.074540625
userli_postfix_adapter_request_duration_seconds_count{handler="alias",status="success"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="0.1"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="0.15000000000000002"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="0.22500000000000003"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="0.3375"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="0.5062500000000001"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="domain",status="success",le="+Inf"} 3
userli_postfix_adapter_request_duration_seconds_sum{handler="domain",status="success"} 0.246158083
userli_postfix_adapter_request_duration_seconds_count{handler="domain",status="success"} 3
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="0.1"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="0.15000000000000002"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="0.22500000000000003"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="0.3375"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="0.5062500000000001"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="mailbox",status="success",le="+Inf"} 1
userli_postfix_adapter_request_duration_seconds_sum{handler="mailbox",status="success"} 0.097836333
userli_postfix_adapter_request_duration_seconds_count{handler="mailbox",status="success"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="0.1"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="0.15000000000000002"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="0.22500000000000003"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="0.3375"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="0.5062500000000001"} 1
userli_postfix_adapter_request_duration_seconds_bucket{handler="senders",status="success",le="+Inf"} 1
userli_postfix_adapter_request_duration_seconds_sum{handler="senders",status="success"} 0.097870375
userli_postfix_adapter_request_duration_seconds_count{handler="senders",status="success"} 1
```
26 changes: 26 additions & 0 deletions adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"fmt"
"net"
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
)

Expand All @@ -27,26 +29,32 @@ func NewPostfixAdapter(client UserliService) *PostfixAdapter {
func (p *PostfixAdapter) AliasHandler(conn net.Conn) {
defer conn.Close()

now := time.Now()

payload, err := p.payload(conn)
if err != nil {
log.WithError(err).Error("Error getting payload")
_, _ = conn.Write([]byte("400 Error getting payload\n"))
requestDurations.With(prometheus.Labels{"handler": "alias", "status": "error"}).Observe(time.Since(now).Seconds())
return
}
email := strings.TrimSuffix(payload, "\n")
aliases, err := p.client.GetAliases(string(email))
if err != nil {
log.WithError(err).WithField("email", email).Error("Error fetching aliases")
_, _ = conn.Write([]byte("400 Error fetching aliases\n"))
requestDurations.With(prometheus.Labels{"handler": "alias", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

if len(aliases) == 0 {
_, _ = conn.Write([]byte("500 NO%20RESULT\n"))
requestDurations.With(prometheus.Labels{"handler": "alias", "status": "success"}).Observe(time.Since(now).Seconds())
return
}

_, _ = conn.Write([]byte(fmt.Sprintf("200 %s \n", strings.Join(aliases, ","))))
requestDurations.With(prometheus.Labels{"handler": "alias", "status": "success"}).Observe(time.Since(now).Seconds())
}

// DomainHandler handles the get command for domains.
Expand All @@ -55,10 +63,13 @@ func (p *PostfixAdapter) AliasHandler(conn net.Conn) {
func (p *PostfixAdapter) DomainHandler(conn net.Conn) {
defer conn.Close()

now := time.Now()

payload, err := p.payload(conn)
if err != nil {
log.WithError(err).Error("Error getting payload")
_, _ = conn.Write([]byte("400 Error getting payload\n"))
requestDurations.With(prometheus.Labels{"handler": "domain", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

Expand All @@ -67,15 +78,18 @@ func (p *PostfixAdapter) DomainHandler(conn net.Conn) {
if err != nil {
log.WithError(err).WithField("domain", domain).Error("Error fetching domain")
_, _ = conn.Write([]byte("400 Error fetching domain\n"))
requestDurations.With(prometheus.Labels{"handler": "domain", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

if !exists {
_, _ = conn.Write([]byte("500 NO%20RESULT\n"))
requestDurations.With(prometheus.Labels{"handler": "domain", "status": "success"}).Observe(time.Since(now).Seconds())
return
}

_, _ = conn.Write([]byte("200 1\n"))
requestDurations.With(prometheus.Labels{"handler": "domain", "status": "success"}).Observe(time.Since(now).Seconds())
}

// MailboxHandler handles the get command for mailboxes.
Expand All @@ -84,10 +98,13 @@ func (p *PostfixAdapter) DomainHandler(conn net.Conn) {
func (p *PostfixAdapter) MailboxHandler(conn net.Conn) {
defer conn.Close()

now := time.Now()

payload, err := p.payload(conn)
if err != nil {
log.WithError(err).Error("Error getting payload")
_, _ = conn.Write([]byte("400 Error getting payload\n"))
requestDurations.With(prometheus.Labels{"handler": "mailbox", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

Expand All @@ -96,15 +113,18 @@ func (p *PostfixAdapter) MailboxHandler(conn net.Conn) {
if err != nil {
log.WithError(err).WithField("email", email).Error("Error fetching mailbox")
_, _ = conn.Write([]byte("400 Error fetching mailbox\n"))
requestDurations.With(prometheus.Labels{"handler": "mailbox", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

if !exists {
_, _ = conn.Write([]byte("500 NO%20RESULT\n"))
requestDurations.With(prometheus.Labels{"handler": "mailbox", "status": "success"}).Observe(time.Since(now).Seconds())
return
}

_, _ = conn.Write([]byte("200 1\n"))
requestDurations.With(prometheus.Labels{"handler": "mailbox", "status": "success"}).Observe(time.Since(now).Seconds())
}

// SendersHandler handles the get command for senders.
Expand All @@ -113,10 +133,13 @@ func (p *PostfixAdapter) MailboxHandler(conn net.Conn) {
func (p *PostfixAdapter) SendersHandler(conn net.Conn) {
defer conn.Close()

now := time.Now()

payload, err := p.payload(conn)
if err != nil {
log.WithError(err).Error("Error getting payload")
_, _ = conn.Write([]byte("400 Error getting payload\n"))
requestDurations.With(prometheus.Labels{"handler": "senders", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

Expand All @@ -125,15 +148,18 @@ func (p *PostfixAdapter) SendersHandler(conn net.Conn) {
if err != nil {
log.WithError(err).WithField("email", email).Error("Error fetching senders")
_, _ = conn.Write([]byte("400 Error fetching senders\n"))
requestDurations.With(prometheus.Labels{"handler": "senders", "status": "error"}).Observe(time.Since(now).Seconds())
return
}

if len(senders) == 0 {
_, _ = conn.Write([]byte("500 NO%20RESULT\n"))
requestDurations.With(prometheus.Labels{"handler": "senders", "status": "success"}).Observe(time.Since(now).Seconds())
return
}

_, _ = conn.Write([]byte(fmt.Sprintf("200 %s \n", strings.Join(senders, ","))))
requestDurations.With(prometheus.Labels{"handler": "senders", "status": "success"}).Observe(time.Since(now).Seconds())
}

// payload reads the data from the connection. It checks for valid
Expand Down
9 changes: 9 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type Config struct {

// SendersListenAddr is the address to listen for senders requests.
SendersListenAddr string

// MetricsListenAddr is the address to listen for metrics requests.
MetricsListenAddr string
}

// NewConfig creates a new Config with default values.
Expand Down Expand Up @@ -81,12 +84,18 @@ func NewConfig() *Config {
sendersListenAddr = ":10004"
}

metricsListenAddr := os.Getenv("METRICS_LISTEN_ADDR")
if metricsListenAddr == "" {
metricsListenAddr = ":10005"
}

return &Config{
UserliBaseURL: userliBaseURL,
UserliToken: userliToken,
AliasListenAddr: aliasListenAddr,
DomainListenAddr: domainListenAddr,
MailboxListenAddr: mailboxListenAddr,
SendersListenAddr: sendersListenAddr,
MetricsListenAddr: metricsListenAddr,
}
}
8 changes: 8 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"io"
"os"
"testing"

Expand All @@ -13,6 +14,10 @@ type ConfigTestSuite struct {
suite.Suite
}

func (s *ConfigTestSuite) SetupTest() {
log.SetOutput(io.Discard)
}

func (s *ConfigTestSuite) TestNewConfig() {
s.Run("fail when userli token not set", func() {
defer func() { log.StandardLogger().ExitFunc = nil }()
Expand All @@ -35,6 +40,7 @@ func (s *ConfigTestSuite) TestNewConfig() {
s.Equal(":10002", config.DomainListenAddr)
s.Equal(":10003", config.MailboxListenAddr)
s.Equal(":10004", config.SendersListenAddr)
s.Equal(":10005", config.MetricsListenAddr)
})

s.Run("custom config", func() {
Expand All @@ -44,6 +50,7 @@ func (s *ConfigTestSuite) TestNewConfig() {
os.Setenv("DOMAIN_LISTEN_ADDR", ":20002")
os.Setenv("MAILBOX_LISTEN_ADDR", ":20003")
os.Setenv("SENDERS_LISTEN_ADDR", ":20004")
os.Setenv("METRICS_LISTEN_ADDR", ":20005")

config := NewConfig()

Expand All @@ -53,6 +60,7 @@ func (s *ConfigTestSuite) TestNewConfig() {
s.Equal(":20002", config.DomainListenAddr)
s.Equal(":20003", config.MailboxListenAddr)
s.Equal(":20004", config.SendersListenAddr)
s.Equal(":20005", config.MetricsListenAddr)
})
}

Expand Down
12 changes: 11 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@ go 1.23.1

require (
github.com/h2non/gock v1.2.0
github.com/prometheus/client_golang v1.20.4
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
golang.org/x/sys v0.25.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
32 changes: 31 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -20,8 +47,11 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()

go StartMetricsServer(ctx, config.MetricsListenAddr)

var wg sync.WaitGroup

wg.Add(4)
Expand Down
35 changes: 35 additions & 0 deletions prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"context"
"net/http"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"

log "github.com/sirupsen/logrus"
)

var (
requestDurations = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "userli_postfix_adapter_request_duration_seconds",
Help: "Duration of requests to userli",
Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5.0),
}, []string{"handler", "status"})
)

// StartMetricsServer starts a new HTTP server for prometheus metrics.
func StartMetricsServer(ctx context.Context, listenAddr string) {
registry := prometheus.NewRegistry()

registry.MustRegister(
collectors.NewGoCollector(),
requestDurations,
)

http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))

log.Info("Metrics server started on ", listenAddr)
log.Fatal(http.ListenAndServe(listenAddr, nil))
}

0 comments on commit c5d936b

Please sign in to comment.