Browse Source

Add more metrics

pull/91/head
Kegan Dougal 8 years ago
parent
commit
b4b0a661c4
  1. 9
      src/github.com/matrix-org/go-neb/api.go
  2. 62
      src/github.com/matrix-org/go-neb/metrics/metrics.go
  3. 1
      src/github.com/matrix-org/go-neb/plugin/plugin.go
  4. 19
      src/github.com/matrix-org/go-neb/services/guggy/guggy.go
  5. 16
      src/github.com/matrix-org/go-neb/services/rssbot/rssbot.go

9
src/github.com/matrix-org/go-neb/api.go

@ -8,6 +8,7 @@ import (
"github.com/matrix-org/go-neb/clients"
"github.com/matrix-org/go-neb/database"
"github.com/matrix-org/go-neb/errors"
"github.com/matrix-org/go-neb/metrics"
"github.com/matrix-org/go-neb/polling"
"github.com/matrix-org/go-neb/types"
"net/http"
@ -180,7 +181,6 @@ func (wh *webhookHandler) handle(w http.ResponseWriter, req *http.Request) {
// but we've base64d it.
base64srvID := segments[len(segments)-1]
bytesSrvID, err := base64.RawURLEncoding.DecodeString(base64srvID)
srvID := string(bytesSrvID)
if err != nil {
log.WithError(err).WithField("base64_service_id", base64srvID).Print(
"Not a b64 encoded string",
@ -188,6 +188,7 @@ func (wh *webhookHandler) handle(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(400)
return
}
srvID := string(bytesSrvID)
service, err := wh.db.LoadService(srvID)
if err != nil {
@ -203,9 +204,10 @@ func (wh *webhookHandler) handle(w http.ResponseWriter, req *http.Request) {
return
}
log.WithFields(log.Fields{
"service_id": service.ServiceID(),
"service_typ": service.ServiceType(),
"service_id": service.ServiceID(),
"service_type": service.ServiceType(),
}).Print("Incoming webhook for service")
metrics.IncrementWebhook(service.ServiceType())
service.OnReceiveWebhook(w, req, cli)
}
@ -319,6 +321,7 @@ func (s *configureServiceHandler) OnIncomingRequest(req *http.Request) (interfac
}
service.PostRegister(old)
metrics.IncrementConfigureService(service.ServiceType())
return &struct {
ID string

62
src/github.com/matrix-org/go-neb/metrics/metrics.go

@ -4,45 +4,47 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
// CommandStatus is the status of a incoming command
type CommandStatus int
// Status is the status of a measurable metric (incoming commands, outgoing polls, etc)
type Status string
// The command status values
// Common status values
const (
StatusPending CommandStatus = iota
StatusSuccess
StatusFailure
StatusSuccess = "success"
StatusFailure = "failure"
)
var (
numIncomingCmds = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "num_incoming_commands_total",
cmdCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "goneb_pling_cmd_total",
Help: "The number of incoming commands from matrix clients",
}, []string{"cmd"})
numSuccessCmds = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "num_success_commands_total",
Help: "The number of incoming commands from matrix clients which were successful",
}, []string{"cmd"})
numErrorCmds = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "num_error_commands_total",
Help: "The number of incoming commands from matrix clients which failed",
}, []string{"cmd"})
}, []string{"cmd", "status"})
configureServicesCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "goneb_configure_services_total",
Help: "The total number of configured services requests",
}, []string{"service_type"})
webhookCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "goneb_webhook_total",
Help: "The total number of recognised incoming webhook requests",
}, []string{"service_type"})
)
// IncrementCommand increments the incoming command counter
func IncrementCommand(cmdName string, st CommandStatus) {
switch st {
case StatusPending:
numIncomingCmds.With(prometheus.Labels{"cmd": cmdName}).Inc()
case StatusSuccess:
numSuccessCmds.With(prometheus.Labels{"cmd": cmdName}).Inc()
case StatusFailure:
numErrorCmds.With(prometheus.Labels{"cmd": cmdName}).Inc()
}
// IncrementCommand increments the pling command counter
func IncrementCommand(cmdName string, st Status) {
cmdCounter.With(prometheus.Labels{"cmd": cmdName, "status": string(st)}).Inc()
}
// IncrementConfigureService increments the /configureService counter
func IncrementConfigureService(serviceType string) {
configureServicesCounter.With(prometheus.Labels{"service_type": serviceType}).Inc()
}
// IncrementWebhook increments the incoming webhook request counter
func IncrementWebhook(serviceType string) {
webhookCounter.With(prometheus.Labels{"service_type": serviceType}).Inc()
}
func init() {
prometheus.MustRegister(numIncomingCmds)
prometheus.MustRegister(numSuccessCmds)
prometheus.MustRegister(numErrorCmds)
prometheus.MustRegister(cmdCounter)
prometheus.MustRegister(configureServicesCounter)
prometheus.MustRegister(webhookCounter)
}

1
src/github.com/matrix-org/go-neb/plugin/plugin.go

@ -72,7 +72,6 @@ func runCommandForPlugin(plugin Plugin, event *matrix.Event, arguments []string)
"user_id": event.Sender,
"command": bestMatch.Path,
}).Info("Executing command")
metrics.IncrementCommand(bestMatch.Path[0], metrics.StatusPending)
content, err := bestMatch.Command(event.RoomID, event.Sender, cmdArgs)
if err != nil {
if content != nil {

19
src/github.com/matrix-org/go-neb/services/guggy/guggy.go

@ -3,10 +3,12 @@ package services
import (
"bytes"
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/matrix-org/go-neb/matrix"
"github.com/matrix-org/go-neb/plugin"
"github.com/matrix-org/go-neb/types"
"io/ioutil"
"math"
"net/http"
"strings"
@ -54,7 +56,7 @@ func (s *guggyService) cmdGuggy(client *matrix.Client, roomID, userID string, ar
querySentence := strings.Join(args, " ")
gifResult, err := s.text2gifGuggy(querySentence)
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to query Guggy: %s", err.Error())
}
if gifResult.GIF == "" {
@ -66,7 +68,7 @@ func (s *guggyService) cmdGuggy(client *matrix.Client, roomID, userID string, ar
mxc, err := client.UploadLink(gifResult.GIF)
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to upload Guggy image to matrix: %s", err.Error())
}
return matrix.ImageMessage{
@ -114,9 +116,20 @@ func (s *guggyService) text2gifGuggy(querySentence string) (*guggyGifResult, err
log.Error(err)
return nil, err
}
if res.StatusCode < 200 || res.StatusCode >= 300 {
resBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
log.WithError(err).Error("Failed to decode Guggy response body")
}
log.WithFields(log.Fields{
"code": res.StatusCode,
"body": string(resBytes),
}).Error("Failed to query Guggy")
return nil, fmt.Errorf("Failed to decode response (HTTP %d)", res.StatusCode)
}
var result guggyGifResult
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, err
return nil, fmt.Errorf("Failed to decode response (HTTP %d): %s", res.StatusCode, err.Error())
}
return &result, nil

16
src/github.com/matrix-org/go-neb/services/rssbot/rssbot.go

@ -11,6 +11,7 @@ import (
"github.com/matrix-org/go-neb/polling"
"github.com/matrix-org/go-neb/types"
"github.com/mmcdole/gofeed"
"github.com/prometheus/client_golang/prometheus"
"html"
"net/http"
"time"
@ -18,6 +19,13 @@ import (
var cachingClient *http.Client
var (
pollCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "goneb_rss_polls_total",
Help: "The number of feed polls from RSS services",
}, []string{"url", "http_status"})
)
const minPollingIntervalSeconds = 60 * 5 // 5 min (News feeds can be genuinely spammy)
type rssBotService struct {
@ -127,8 +135,15 @@ func (s *rssBotService) OnPoll(cli *matrix.Client) time.Time {
feed, items, err := s.queryFeed(u)
if err != nil {
logger.WithField("feed_url", u).WithError(err).Error("Failed to query feed")
herr, ok := err.(gofeed.HTTPError)
statusCode := 0 // e.g. network timeout
if ok {
statusCode = herr.StatusCode
}
pollCounter.With(prometheus.Labels{"url": u, "http_status": string(statusCode)}).Inc()
continue
}
pollCounter.With(prometheus.Labels{"url": u, "http_status": "200"}).Inc() // technically 2xx but gofeed doesn't tell us which
// Loop backwards since [0] is the most recent and we want to send in chronological order
for i := len(items) - 1; i >= 0; i-- {
item := items[i]
@ -285,4 +300,5 @@ func init() {
}
return r
})
prometheus.MustRegister(pollCounter)
}
Loading…
Cancel
Save