This repository has been archived on 2025-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
trantor/lib/stats.go

133 lines
2.8 KiB
Go
Raw Normal View History

2016-05-02 21:36:49 -04:00
package trantor
2013-04-22 23:28:00 +02:00
import (
2014-08-30 13:17:50 -05:00
log "github.com/cihub/seelog"
2013-04-22 23:28:00 +02:00
"net/http"
"strings"
2017-06-05 16:17:14 +00:00
"time"
"github.com/gorilla/mux"
2016-05-02 21:36:49 -04:00
"gitlab.com/trantor/trantor/lib/database"
2017-06-05 16:17:14 +00:00
"gitlab.com/trantor/trantor/lib/instrument"
2016-05-02 21:36:49 -04:00
"gitlab.com/trantor/trantor/lib/storage"
2013-04-22 23:28:00 +02:00
)
2014-08-21 19:24:23 -05:00
const (
statsChanSize = 100
2014-08-21 19:24:23 -05:00
)
type handler struct {
w http.ResponseWriter
r *http.Request
sess *Session
2017-05-21 10:16:16 +00:00
db database.DB
store storage.Store
template *Template
hostname string
2017-05-21 10:16:16 +00:00
ro bool
}
func (h handler) load(tmpl string, data interface{}) {
var err error
fmt := h.r.FormValue("fmt")
switch fmt {
case "rss":
err = h.template.rss.ExecuteTemplate(h.w, tmpl+".rss", data)
case "opds":
err = h.template.opds.ExecuteTemplate(h.w, tmpl+".opds", data)
case "json":
err = loadJson(h.w, tmpl, data)
default:
err = h.template.html.ExecuteTemplate(h.w, tmpl+".html", data)
}
if err != nil {
h.template.html.ExecuteTemplate(h.w, "404.html", data)
log.Warn("An error ocurred loading the template ", tmpl, ".", fmt, ": ", err)
}
}
2014-08-21 19:24:23 -05:00
type StatsGatherer struct {
2017-06-05 16:17:14 +00:00
db database.DB
store storage.Store
template *Template
instrument instrument.Instrument
hostname string
channel chan statsRequest
ro bool
2013-04-22 23:28:00 +02:00
}
2017-05-21 10:16:16 +00:00
func InitStats(database database.DB, store storage.Store, hostname string, template *Template, ro bool) *StatsGatherer {
2017-06-05 16:17:14 +00:00
in := instrument.Init()
2016-05-03 10:11:59 -04:00
sg := StatsGatherer{
2017-06-05 16:17:14 +00:00
channel: make(chan statsRequest, statsChanSize),
db: database,
store: store,
instrument: in,
template: template,
hostname: hostname,
ro: ro,
2016-05-03 10:11:59 -04:00
}
2014-08-21 19:24:23 -05:00
go sg.worker()
2016-05-03 10:11:59 -04:00
return &sg
2014-08-21 19:24:23 -05:00
}
func (sg StatsGatherer) Gather(function func(handler)) func(http.ResponseWriter, *http.Request) {
2013-04-22 23:28:00 +02:00
return func(w http.ResponseWriter, r *http.Request) {
2014-02-11 14:41:50 +01:00
log.Info("Query ", r.Method, " ", r.RequestURI)
2016-05-03 10:11:59 -04:00
h := handler{
store: sg.store,
db: sg.db,
2016-05-03 10:11:59 -04:00
template: sg.template,
hostname: sg.hostname,
w: w,
r: r,
sess: GetSession(r, sg.db),
2017-05-21 10:16:16 +00:00
ro: sg.ro,
2016-05-03 10:11:59 -04:00
}
2017-06-05 16:17:14 +00:00
t0 := time.Now()
function(h)
2017-06-05 16:17:14 +00:00
t1 := time.Now()
sg.channel <- statsRequest{r, t1.Sub(t0)}
2013-04-22 23:28:00 +02:00
}
}
type statsRequest struct {
2017-06-05 16:17:14 +00:00
r *http.Request
duration time.Duration
2013-04-22 23:28:00 +02:00
}
2014-08-21 19:24:23 -05:00
func (sg StatsGatherer) worker() {
for req := range sg.channel {
2017-05-30 22:10:21 +00:00
var err error
id := mux.Vars(req.r)["id"]
2017-06-05 16:17:14 +00:00
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]
2013-04-22 23:28:00 +02:00
}
2017-06-05 16:17:14 +00:00
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)
}
2017-05-30 22:10:21 +00:00
if err != nil {
log.Warn("Problem incrementing visits: ", err)
2013-04-22 23:28:00 +02:00
}
}
}