Added profile purge endpoint

This commit is contained in:
Peter Grlica
2023-01-16 13:52:44 +01:00
parent 352865b4fb
commit a64f4c18b3
8 changed files with 203 additions and 0 deletions
+11
View File
@@ -63,6 +63,17 @@ func (p *Profiler) Hits(s Sort) Hits {
return ll
}
func (p *Profiler) Purge(f *PurgeFilter) {
if f.RouteID == 0 {
p.l = make(Hits, 0)
return
}
p.l = p.l.Filter(func(k string, v *Hit) bool {
return v.Route != f.RouteID
})
}
func (p *Profiler) id(r *h.Request) string {
return r.URL.Path
}
@@ -111,3 +111,53 @@ func Test_ApigwProfiler_filterHit(t *testing.T) {
req.True(found)
req.Len(list[id], 1)
}
func Test_ApigwProfiler_purgeAll(t *testing.T) {
var (
pp = New()
req = require.New(t)
now = time.Date(2022, time.March, 1, 1, 1, 1, 0, time.UTC)
then = now.Add(-1 * day)
later = now.Add(day)
hr, _ = h.NewRequest(httptest.NewRequest("POST", "/foo", strings.NewReader(`foo`)))
hr2, _ = h.NewRequest(httptest.NewRequest("GET", "/bar", strings.NewReader(`foo`)))
)
pp.Push(&Hit{R: hr, Ts: &then})
pp.Push(&Hit{R: hr, Ts: &now})
pp.Push(&Hit{R: hr2, Ts: &now})
pp.Push(&Hit{R: hr2, Ts: &later})
pp.Push(&Hit{R: hr2, Ts: &later})
req.Len(pp.l, 2)
pp.Purge(&PurgeFilter{})
req.Len(pp.l, 0)
}
func Test_ApigwProfiler_purgeRoute(t *testing.T) {
var (
pp = New()
req = require.New(t)
now = time.Date(2022, time.March, 1, 1, 1, 1, 0, time.UTC)
then = now.Add(-1 * day)
later = now.Add(day)
hr, _ = h.NewRequest(httptest.NewRequest("POST", "/foo", strings.NewReader(`foo`)))
hr2, _ = h.NewRequest(httptest.NewRequest("GET", "/bar", strings.NewReader(`foo`)))
)
pp.Push(&Hit{Route: 1, R: hr, Ts: &then})
pp.Push(&Hit{Route: 1, R: hr, Ts: &now})
pp.Push(&Hit{Route: 2, R: hr2, Ts: &now})
pp.Push(&Hit{Route: 2, R: hr2, Ts: &later})
pp.Push(&Hit{Route: 2, R: hr2, Ts: &later})
req.Len(pp.l, 2)
pp.Purge(&PurgeFilter{RouteID: 2})
req.Len(pp.l, 1)
}
+7
View File
@@ -0,0 +1,7 @@
package profiler
type (
PurgeFilter struct {
RouteID uint64
}
)
+9
View File
@@ -2084,6 +2084,15 @@ endpoints:
title: Hit details
path: "/hit/{hitID}"
parameters: { path: [ { name: hitID, type: string, required: true, title: "Hit ID" } ] }
- name: purge all
method: POST
title: Purge all profiler hits
path: "/purge"
- name: purge
method: POST
title: Purge route profiler hits
path: "/purge/{routeID}"
parameters: { path: [ { name: routeID, type: "uint64", title: "Route ID", required: true } ] }
- title: Locale
entrypoint: locale
+22
View File
@@ -3,6 +3,7 @@ package rest
import (
"context"
"github.com/cortezaproject/corteza/server/pkg/apigw/profiler"
"github.com/cortezaproject/corteza/server/pkg/filter"
"github.com/cortezaproject/corteza/server/system/rest/request"
"github.com/cortezaproject/corteza/server/system/service"
@@ -13,6 +14,7 @@ type (
profilerService interface {
Hits(context.Context, types.ApigwProfilerFilter) (types.ApigwProfilerHitSet, types.ApigwProfilerFilter, error)
HitsAggregated(context.Context, types.ApigwProfilerFilter) (types.ApigwProfilerAggregationSet, types.ApigwProfilerFilter, error)
Purge(context.Context, *profiler.PurgeFilter)
}
ApigwProfiler struct {
@@ -109,6 +111,26 @@ func (ctrl *ApigwProfiler) Hit(ctx context.Context, r *request.ApigwProfilerHit)
return ctrl.makeRoutePayload(ctx, set[0], err)
}
func (ctrl *ApigwProfiler) PurgeAll(ctx context.Context, r *request.ApigwProfilerPurgeAll) (_ interface{}, _ error) {
var (
f = &profiler.PurgeFilter{}
)
ctrl.svc.Purge(ctx, f)
return
}
func (ctrl *ApigwProfiler) Purge(ctx context.Context, r *request.ApigwProfilerPurge) (_ interface{}, _ error) {
var (
f = &profiler.PurgeFilter{
RouteID: r.RouteID,
}
)
ctrl.svc.Purge(ctx, f)
return
}
func (ctrl *ApigwProfiler) makePayload(ctx context.Context, q *types.ApigwProfilerAggregation, err error) (*profilerHitPayload, error) {
if err != nil || q == nil {
return nil, err
@@ -22,6 +22,8 @@ type (
Aggregation(context.Context, *request.ApigwProfilerAggregation) (interface{}, error)
Route(context.Context, *request.ApigwProfilerRoute) (interface{}, error)
Hit(context.Context, *request.ApigwProfilerHit) (interface{}, error)
PurgeAll(context.Context, *request.ApigwProfilerPurgeAll) (interface{}, error)
Purge(context.Context, *request.ApigwProfilerPurge) (interface{}, error)
}
// HTTP API interface
@@ -29,6 +31,8 @@ type (
Aggregation func(http.ResponseWriter, *http.Request)
Route func(http.ResponseWriter, *http.Request)
Hit func(http.ResponseWriter, *http.Request)
PurgeAll func(http.ResponseWriter, *http.Request)
Purge func(http.ResponseWriter, *http.Request)
}
)
@@ -80,6 +84,38 @@ func NewApigwProfiler(h ApigwProfilerAPI) *ApigwProfiler {
return
}
api.Send(w, r, value)
},
PurgeAll: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewApigwProfilerPurgeAll()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.PurgeAll(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Purge: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewApigwProfilerPurge()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Purge(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
@@ -91,5 +127,7 @@ func (h ApigwProfiler) MountRoutes(r chi.Router, middlewares ...func(http.Handle
r.Get("/apigw/profiler/", h.Aggregation)
r.Get("/apigw/profiler/route/{routeID}", h.Route)
r.Get("/apigw/profiler/hit/{hitID}", h.Hit)
r.Post("/apigw/profiler/purge", h.PurgeAll)
r.Post("/apigw/profiler/purge/{routeID}", h.Purge)
})
}
@@ -88,6 +88,16 @@ type (
// Hit ID
HitID string
}
ApigwProfilerPurgeAll struct {
}
ApigwProfilerPurge struct {
// RouteID PATH parameter
//
// Route ID
RouteID uint64 `json:",string"`
}
)
// NewApigwProfilerAggregation request
@@ -284,3 +294,54 @@ func (r *ApigwProfilerHit) Fill(req *http.Request) (err error) {
return err
}
// NewApigwProfilerPurgeAll request
func NewApigwProfilerPurgeAll() *ApigwProfilerPurgeAll {
return &ApigwProfilerPurgeAll{}
}
// Auditable returns all auditable/loggable parameters
func (r ApigwProfilerPurgeAll) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *ApigwProfilerPurgeAll) Fill(req *http.Request) (err error) {
return err
}
// NewApigwProfilerPurge request
func NewApigwProfilerPurge() *ApigwProfilerPurge {
return &ApigwProfilerPurge{}
}
// Auditable returns all auditable/loggable parameters
func (r ApigwProfilerPurge) Auditable() map[string]interface{} {
return map[string]interface{}{
"routeID": r.RouteID,
}
}
// Auditable returns all auditable/loggable parameters
func (r ApigwProfilerPurge) GetRouteID() uint64 {
return r.RouteID
}
// Fill processes request and fills internal variables
func (r *ApigwProfilerPurge) Fill(req *http.Request) (err error) {
{
var val string
// path params
val = chi.URLParam(req, "routeID")
r.RouteID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}
+5
View File
@@ -192,6 +192,11 @@ func (svc *apigwProfiler) HitsAggregated(ctx context.Context, filter types.Apigw
return
}
func (svc *apigwProfiler) Purge(ctx context.Context, f *profiler.PurgeFilter) {
apigw.Service().Profiler().Purge(f)
return
}
func sortAggregation(list *types.ApigwProfilerAggregationSet, filter *types.ApigwProfilerFilter) {
for _, ff := range sortAggFields {
fe := filter.Sort.Get(ff)