mirror of
https://github.com/Luzifer/ots.git
synced 2025-05-31 03:44:22 -04:00
Implement metrics collection for API server (#143)
This commit is contained in:
parent
1623e09225
commit
5ad6449757
12 changed files with 402 additions and 95 deletions
31
api.go
31
api.go
|
@ -8,13 +8,24 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Luzifer/ots/pkg/metrics"
|
||||
"github.com/Luzifer/ots/pkg/storage"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
errorReasonInvalidJSON = "invalid_json"
|
||||
errorReasonSecretMissing = "secret_missing"
|
||||
errorReasonSecretSize = "secret_size"
|
||||
errorReasonStorageError = "storage_error"
|
||||
errorReasonSecretNotFound = "secret_not_found"
|
||||
)
|
||||
|
||||
type apiServer struct {
|
||||
store storage
|
||||
collector *metrics.Collector
|
||||
store storage.Storage
|
||||
}
|
||||
|
||||
type apiResponse struct {
|
||||
|
@ -29,9 +40,10 @@ type apiRequest struct {
|
|||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
func newAPI(s storage) *apiServer {
|
||||
func newAPI(s storage.Storage, c *metrics.Collector) *apiServer {
|
||||
return &apiServer{
|
||||
store: s,
|
||||
collector: c,
|
||||
store: s,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +69,7 @@ func (a apiServer) handleCreate(res http.ResponseWriter, r *http.Request) {
|
|||
if strings.HasPrefix(r.Header.Get("Content-Type"), "application/json") {
|
||||
tmp := apiRequest{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&tmp); err != nil {
|
||||
a.collector.CountSecretCreateError(errorReasonInvalidJSON)
|
||||
a.errorResponse(res, http.StatusBadRequest, err, "decoding request body")
|
||||
return
|
||||
}
|
||||
|
@ -66,17 +79,20 @@ func (a apiServer) handleCreate(res http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if secret == "" {
|
||||
a.collector.CountSecretCreateError(errorReasonSecretMissing)
|
||||
a.errorResponse(res, http.StatusBadRequest, errors.New("secret missing"), "")
|
||||
return
|
||||
}
|
||||
|
||||
if cust.MaxSecretSize > 0 && len(secret) > int(cust.MaxSecretSize) {
|
||||
a.collector.CountSecretCreateError(errorReasonSecretSize)
|
||||
a.errorResponse(res, http.StatusBadRequest, errors.New("secret size exceeds maximum"), "")
|
||||
return
|
||||
}
|
||||
|
||||
id, err := a.store.Create(secret, time.Duration(expiry)*time.Second)
|
||||
if err != nil {
|
||||
a.collector.CountSecretCreateError(errorReasonStorageError)
|
||||
a.errorResponse(res, http.StatusInternalServerError, err, "creating secret")
|
||||
return
|
||||
}
|
||||
|
@ -86,6 +102,8 @@ func (a apiServer) handleCreate(res http.ResponseWriter, r *http.Request) {
|
|||
expiresAt = func(v time.Time) *time.Time { return &v }(time.Now().UTC().Add(time.Duration(expiry) * time.Second))
|
||||
}
|
||||
|
||||
a.collector.CountSecretCreated()
|
||||
go updateStoredSecretsCount(a.store, a.collector)
|
||||
a.jsonResponse(res, http.StatusCreated, apiResponse{
|
||||
ExpiresAt: expiresAt,
|
||||
Success: true,
|
||||
|
@ -104,13 +122,18 @@ func (a apiServer) handleRead(res http.ResponseWriter, r *http.Request) {
|
|||
secret, err := a.store.ReadAndDestroy(id)
|
||||
if err != nil {
|
||||
status := http.StatusInternalServerError
|
||||
if err == errSecretNotFound {
|
||||
if errors.Is(err, storage.ErrSecretNotFound) {
|
||||
a.collector.CountSecretReadError(errorReasonSecretNotFound)
|
||||
status = http.StatusNotFound
|
||||
} else {
|
||||
a.collector.CountSecretReadError(errorReasonStorageError)
|
||||
}
|
||||
a.errorResponse(res, status, err, "reading & destroying secret")
|
||||
return
|
||||
}
|
||||
|
||||
a.collector.CountSecretRead()
|
||||
go updateStoredSecretsCount(a.store, a.collector)
|
||||
a.jsonResponse(res, http.StatusOK, apiResponse{
|
||||
Success: true,
|
||||
Secret: secret,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue