Add instrumentation with prometheus
This commit is contained in:
parent
2a72154308
commit
f4ca9e2dbc
6 changed files with 138 additions and 32 deletions
70
lib/stats.go
70
lib/stats.go
|
@ -5,14 +5,15 @@ import (
|
|||
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"gitlab.com/trantor/trantor/lib/database"
|
||||
"gitlab.com/trantor/trantor/lib/instrument"
|
||||
"gitlab.com/trantor/trantor/lib/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
stats_version = 2
|
||||
statsChanSize = 100
|
||||
)
|
||||
|
||||
|
@ -28,22 +29,26 @@ type handler struct {
|
|||
}
|
||||
|
||||
type StatsGatherer struct {
|
||||
db database.DB
|
||||
store storage.Store
|
||||
template *Template
|
||||
hostname string
|
||||
channel chan statsRequest
|
||||
ro bool
|
||||
db database.DB
|
||||
store storage.Store
|
||||
template *Template
|
||||
instrument instrument.Instrument
|
||||
hostname string
|
||||
channel chan statsRequest
|
||||
ro bool
|
||||
}
|
||||
|
||||
func InitStats(database database.DB, store storage.Store, hostname string, template *Template, ro bool) *StatsGatherer {
|
||||
in := instrument.Init()
|
||||
|
||||
sg := StatsGatherer{
|
||||
channel: make(chan statsRequest, statsChanSize),
|
||||
db: database,
|
||||
store: store,
|
||||
template: template,
|
||||
hostname: hostname,
|
||||
ro: ro,
|
||||
channel: make(chan statsRequest, statsChanSize),
|
||||
db: database,
|
||||
store: store,
|
||||
instrument: in,
|
||||
template: template,
|
||||
hostname: hostname,
|
||||
ro: ro,
|
||||
}
|
||||
|
||||
go sg.worker()
|
||||
|
@ -65,33 +70,42 @@ func (sg StatsGatherer) Gather(function func(handler)) func(http.ResponseWriter,
|
|||
ro: sg.ro,
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
function(h)
|
||||
sg.channel <- statsRequest{r}
|
||||
t1 := time.Now()
|
||||
sg.channel <- statsRequest{r, t1.Sub(t0)}
|
||||
}
|
||||
}
|
||||
|
||||
type statsRequest struct {
|
||||
r *http.Request
|
||||
r *http.Request
|
||||
duration time.Duration
|
||||
}
|
||||
|
||||
func (sg StatsGatherer) worker() {
|
||||
for req := range sg.channel {
|
||||
var err error
|
||||
pattern := strings.Split(req.r.URL.Path, "/")
|
||||
id := mux.Vars(req.r)["id"]
|
||||
if len(pattern) > 1 && pattern[1] != "" && id != "" {
|
||||
switch pattern[1] {
|
||||
case "download":
|
||||
id := mux.Vars(req.r)["id"]
|
||||
err = sg.db.IncDownloads(id)
|
||||
case "book":
|
||||
id := mux.Vars(req.r)["id"]
|
||||
err = sg.db.IncViews(id)
|
||||
case "read":
|
||||
id := mux.Vars(req.r)["id"]
|
||||
err = sg.db.IncViews(id)
|
||||
}
|
||||
search := strings.Join(req.r.Form["q"], " ")
|
||||
fmt := req.r.FormValue("fmt")
|
||||
pattern := strings.Split(req.r.URL.Path, "/")
|
||||
|
||||
section := "/"
|
||||
if len(pattern) > 1 && pattern[1] != "" {
|
||||
section = pattern[1]
|
||||
}
|
||||
|
||||
sg.instrument.Visit(section, id, search, fmt)
|
||||
sg.instrument.Duration(section, req.duration*time.Microsecond)
|
||||
switch section {
|
||||
case "download":
|
||||
err = sg.db.IncDownloads(id)
|
||||
case "book":
|
||||
err = sg.db.IncViews(id)
|
||||
case "read":
|
||||
err = sg.db.IncViews(id)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Warn("Problem incrementing visits: ", err)
|
||||
}
|
||||
|
|
Reference in a new issue