"policy-opa-pdp/pkg/log"
"policy-opa-pdp/pkg/metrics"
"policy-opa-pdp/pkg/opasdk"
+ "time"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
)
// RegisterHandlers registers the HTTP handlers for the service.
// Handler for OPA decision making
opaDecisionHandler := http.HandlerFunc(decision.OpaDecision)
- http.Handle("/policy/pdpo/v1/decision", basicAuth(opaDecisionHandler))
+ http.Handle("/policy/pdpo/v1/decision", basicAuth(trackDecisionResponseTime(opaDecisionHandler)))
// Handler for kubernetes readiness probe
readinessProbeHandler := http.HandlerFunc(readinessProbe)
http.Handle("/opa/listpolicies", listPoliciesHandler)
dataHandler := http.HandlerFunc(data.DataHandler)
- http.Handle("/policy/pdpo/v1/data/", basicAuth(dataHandler))
+ http.Handle("/policy/pdpo/v1/data/", basicAuth(trackDataResponseTime(dataHandler)))
- http.Handle("/policy/pdpo/v1/data", basicAuth(dataHandler))
+ http.Handle("/policy/pdpo/v1/data", basicAuth(trackDataResponseTime(dataHandler)))
+ //Handler for prometheus
+ http.Handle("/metrics", promhttp.Handler())
+
+}
+
+//Track Decision response time metrics
+func trackDecisionResponseTime(next http.HandlerFunc) http.HandlerFunc {
+ return trackResponseTime(metrics.DecisionResponseTime, next)
+}
+
+//Track Data response time metrics
+func trackDataResponseTime(next http.HandlerFunc) http.HandlerFunc {
+ return trackResponseTime(metrics.DataResponseTime, next)
+}
+
+func trackResponseTime(metricCollector prometheus.Observer, next http.HandlerFunc) http.HandlerFunc {
+ return func(res http.ResponseWriter, req *http.Request) {
+ start := time.Now()
+ next(res, req)
+ duration := time.Since(start).Seconds()
+ metricCollector.Observe(duration)
+ }
}
// handles authentication
"policy-opa-pdp/pkg/decision"
"policy-opa-pdp/pkg/healthcheck"
"testing"
+ "time"
+ "github.com/stretchr/testify/assert"
)
// Mock configuration
t.Errorf("readinessProbe returned unexpected body: got %v want %v", rr.Body.String(), expected)
}
}
+
+
+type mockObserver struct {
+ observedDuration float64
+}
+
+func (m *mockObserver) Observe(duration float64) {
+ m.observedDuration = duration
+}
+
+// Test trackDecisionResponseTime function
+func TestTrackDecisionResponseTime(t *testing.T) {
+ observer := &mockObserver{}
+ handler := trackDecisionResponseTime(func(res http.ResponseWriter, req *http.Request) {
+ time.Sleep(50 * time.Millisecond)
+ res.WriteHeader(http.StatusOK)
+ })
+
+ req := httptest.NewRequest("GET", "/decision", nil)
+ res := httptest.NewRecorder()
+
+ handler(res, req)
+
+ assert.NotNil(t, observer.observedDuration)
+}
+
+// Test trackDataResponseTime function
+func TestTrackDataResponseTime(t *testing.T) {
+ observer := &mockObserver{}
+ handler := trackDataResponseTime(func(res http.ResponseWriter, req *http.Request) {
+ time.Sleep(30 * time.Millisecond)
+ res.WriteHeader(http.StatusOK)
+ })
+
+ req := httptest.NewRequest("GET", "/data", nil)
+ res := httptest.NewRecorder()
+
+ handler(res, req)
+
+ assert.NotNil(t, observer.observedDuration)
+}
+
+// Test trackResponseTime function
+func TestTrackResponseTime(t *testing.T) {
+ observer := &mockObserver{}
+
+ handler := trackResponseTime(observer, func(res http.ResponseWriter, req *http.Request) {
+ time.Sleep(20 * time.Millisecond)
+ res.WriteHeader(http.StatusOK)
+ })
+
+ req := httptest.NewRequest("GET", "/response", nil)
+ res := httptest.NewRecorder()
+ handler(res, req)
+ assert.NotNil(t, observer.observedDuration)
+}
package metrics
-import "sync"
-
+import (
+ "sync"
+ "github.com/prometheus/client_golang/prometheus"
+)
// global counter variables
var TotalErrorCount int64
var DecisionSuccessCount int64
var TotalPoliciesCount int64
var mu sync.Mutex
+//Decision and Data counters to be used in prometheus
+var (
+ DecisionResponseTime = prometheus.NewSummary(prometheus.SummaryOpts{
+ Name: "opa_decision_response_time_seconds",
+ Help: "Response time of OPA decision handler",
+ })
+ DataResponseTime = prometheus.NewSummary(prometheus.SummaryOpts{
+ Name: "opa_data_response_time_seconds",
+ Help: "Response time of OPA data handler",
+ })
+)
+
+//register counters in init
+func init() {
+ prometheus.MustRegister(DecisionResponseTime)
+ prometheus.MustRegister(DataResponseTime)
+}
+
// Increment counter
func IncrementTotalErrorCount() {
mu.Lock()