@@ -2,7 +2,7 @@ import express from 'express';
22import { MetricsService } from '../services/metricsService' ;
33import { logger } from '../utils/logger' ;
44
5- const router = express . Router ( ) ;
5+ const router : express . Router = express . Router ( ) ;
66const metricsService = new MetricsService ( ) ;
77
88// Get live requests with policy enforcement data
@@ -23,30 +23,168 @@ router.get('/live-requests', async (req, res) => {
2323 }
2424} ) ;
2525
26- // Get dashboard statistics
27- router . get ( '/dashboard ' , async ( req , res ) => {
26+ // Get detailed request information by ID
27+ router . get ( '/requests/:id ' , async ( req , res ) => {
2828 try {
29- const status = await metricsService . getMetricsStatus ( ) ;
29+ const { id } = req . params ;
3030 const requests = await metricsService . getRealLiveRequests ( ) ;
31+ const request = requests . find ( r => r . id === id ) ;
3132
32- const totalRequests = requests . length ;
33- const acceptedRequests = requests . filter ( r => r . decision === 'accept' ) . length ;
34- const rejectedRequests = requests . filter ( r => r . decision === 'reject' ) . length ;
35- const policyEnforcedRequests = requests . filter ( r => r . policyType && r . policyType !== 'None' ) . length ;
33+ if ( ! request ) {
34+ return res . status ( 404 ) . json ( {
35+ success : false ,
36+ error : 'Request not found'
37+ } ) ;
38+ }
39+
40+ res . json ( {
41+ success : true ,
42+ data : request ,
43+ timestamp : new Date ( ) . toISOString ( )
44+ } ) ;
45+ } catch ( error ) {
46+ logger . error ( 'Failed to fetch request details:' , error ) ;
47+ res . status ( 500 ) . json ( {
48+ success : false ,
49+ error : 'Failed to fetch request details'
50+ } ) ;
51+ }
52+ } ) ;
53+
54+ // Get aggregated policy enforcement statistics
55+ router . get ( '/policy-stats' , async ( req , res ) => {
56+ try {
57+ const requests = await metricsService . getRealLiveRequests ( ) ;
58+
59+ const stats = {
60+ totalRequests : requests . length ,
61+ approvedRequests : requests . filter ( r => r . decision === 'accept' ) . length ,
62+ rejectedRequests : requests . filter ( r => r . decision === 'reject' ) . length ,
63+ policyDecisions : {
64+ authPolicy : {
65+ total : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'AuthPolicy' ) . length , 0 ) ,
66+ allowed : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'AuthPolicy' && p . decision === 'allow' ) . length , 0 ) ,
67+ denied : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'AuthPolicy' && p . decision === 'deny' ) . length , 0 )
68+ } ,
69+ rateLimitPolicy : {
70+ total : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'RateLimitPolicy' ) . length , 0 ) ,
71+ allowed : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'RateLimitPolicy' && p . decision === 'allow' ) . length , 0 ) ,
72+ denied : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . policyType === 'RateLimitPolicy' && p . decision === 'deny' ) . length , 0 )
73+ }
74+ } ,
75+ enforcementPoints : {
76+ authorino : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . enforcementPoint === 'authorino' ) . length , 0 ) ,
77+ limitador : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . enforcementPoint === 'limitador' ) . length , 0 ) ,
78+ envoy : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . enforcementPoint === 'envoy' ) . length , 0 ) ,
79+ opa : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . enforcementPoint === 'opa' ) . length , 0 ) ,
80+ kuadrant : requests . reduce ( ( sum , r ) => sum + r . policyDecisions . filter ( p => p . enforcementPoint === 'kuadrant' ) . length , 0 )
81+ } ,
82+ modelInferences : {
83+ total : requests . filter ( r => r . modelInference ) . length ,
84+ totalTokens : requests . reduce ( ( sum , r ) => sum + ( r . modelInference ?. totalTokens || 0 ) , 0 ) ,
85+ avgResponseTime : requests . filter ( r => r . modelInference ) . reduce ( ( sum , r ) => sum + ( r . modelInference ?. responseTime || 0 ) , 0 ) / Math . max ( 1 , requests . filter ( r => r . modelInference ) . length ) ,
86+ totalCost : requests . reduce ( ( sum , r ) => sum + ( r . estimatedCost || 0 ) , 0 )
87+ } ,
88+ authentication : {
89+ apiKey : requests . filter ( r => r . authentication ?. method === 'api-key' ) . length ,
90+ none : requests . filter ( r => r . authentication ?. method === 'none' ) . length ,
91+ valid : requests . filter ( r => r . authentication ?. isValid ) . length ,
92+ invalid : requests . filter ( r => r . authentication && ! r . authentication . isValid ) . length
93+ }
94+ } ;
3695
96+ res . json ( {
97+ success : true ,
98+ data : stats ,
99+ timestamp : new Date ( ) . toISOString ( )
100+ } ) ;
101+ } catch ( error ) {
102+ logger . error ( 'Failed to fetch policy stats:' , error ) ;
103+ res . status ( 500 ) . json ( {
104+ success : false ,
105+ error : 'Failed to fetch policy statistics'
106+ } ) ;
107+ }
108+ } ) ;
109+
110+ // Get dashboard statistics from real Prometheus metrics
111+ router . get ( '/dashboard' , async ( req , res ) => {
112+ try {
113+ // Get real data from Prometheus sources
114+ const [ istioMetrics , authorinoMetrics , status ] = await Promise . all ( [
115+ metricsService . fetchIstioMetrics ( ) ,
116+ metricsService . fetchAuthorinoMetrics ( ) ,
117+ metricsService . getMetricsStatus ( )
118+ ] ) ;
119+
120+ // Calculate totals from real Prometheus data
121+ let totalRequests = 0 ;
122+ let acceptedRequests = 0 ;
123+ let authFailedRequests = 0 ;
124+ let rateLimitedRequests = 0 ;
125+ let rejectedRequests = 0 ;
126+
127+ if ( istioMetrics ) {
128+ // Use real Istio metrics for accurate counts
129+ acceptedRequests = istioMetrics . successRequests || 0 ;
130+ authFailedRequests = istioMetrics . authFailedRequests || 0 ;
131+ rateLimitedRequests = istioMetrics . rateLimitedRequests || 0 ;
132+ rejectedRequests = authFailedRequests + rateLimitedRequests + ( istioMetrics . notFoundRequests || 0 ) ;
133+ totalRequests = acceptedRequests + rejectedRequests ;
134+ }
135+
136+ // Enhanced status with real metrics sources
137+ const enhancedStatus = {
138+ ...status ,
139+ istioConnected : istioMetrics !== null ,
140+ metricsSource : istioMetrics ? 'istio-prometheus' : 'fallback' ,
141+ realData : totalRequests > 0
142+ } ;
143+
37144 res . json ( {
38145 success : true ,
39146 data : {
147+ // Real metrics from Prometheus
40148 totalRequests,
41149 acceptedRequests,
42150 rejectedRequests,
43- policyEnforcedRequests,
151+ authFailedRequests,
152+ rateLimitedRequests,
153+ policyEnforcedRequests : authFailedRequests + rateLimitedRequests ,
154+
155+ // Enhanced status
44156 kuadrantStatus : {
45- limitadorConnected : status . limitadorConnected ,
46- authorinoConnected : status . authorinoConnected ,
47- hasRealTraffic : status . hasRealTraffic
157+ ...enhancedStatus ,
158+ notFoundRequests : istioMetrics ?. notFoundRequests || 0 ,
159+ debugIstioMetrics : istioMetrics ? {
160+ successRequests : istioMetrics . successRequests ,
161+ authFailedRequests : istioMetrics . authFailedRequests ,
162+ rateLimitedRequests : istioMetrics . rateLimitedRequests ,
163+ notFoundRequests : istioMetrics . notFoundRequests ,
164+ totalRequests : istioMetrics . totalRequests
165+ } : null
166+ } ,
167+
168+ // Real Authorino controller metrics from Prometheus
169+ authorinoStats : authorinoMetrics ? {
170+ authConfigs : Array . from ( authorinoMetrics . authByNamespace ?. keys ( ) || [ ] ) . length ,
171+ totalEvaluations : authorinoMetrics . authRequests || 0 ,
172+ successfulReconciles : authorinoMetrics . authSuccesses || 0 ,
173+ failedReconciles : authorinoMetrics . authFailures || 0 ,
174+ // Additional controller metrics
175+ reconcileOperations : authorinoMetrics . totalReconciles || 0 ,
176+ avgReconcileTime : authorinoMetrics . avgReconcileTime || 0
177+ } : {
178+ authConfigs : 0 ,
179+ totalEvaluations : 0 ,
180+ successfulReconciles : 0 ,
181+ failedReconciles : 0 ,
182+ reconcileOperations : 0 ,
183+ avgReconcileTime : 0
48184 } ,
49- lastUpdate : status . lastUpdate
185+
186+ lastUpdate : new Date ( ) . toISOString ( ) ,
187+ source : 'prometheus-metrics'
50188 }
51189 } ) ;
52190 } catch ( error ) {
0 commit comments