@@ -156,7 +156,34 @@ mod handlers {
156156 let mut stats = Vec :: new ( ) ;
157157 let sm = rm. stat_manager ( ) ;
158158 let sm = sm. read ( ) . await ;
159- for c in sm. counters . iter ( ) {
159+ for c in sm. counters . values ( ) {
160+ stats. push ( models:: Stat {
161+ network : c. sess . network . to_string ( ) ,
162+ inbound_tag : c. sess . inbound_tag . to_owned ( ) ,
163+ forwarded_source : c. sess . forwarded_source . map ( |x| x. to_string ( ) ) ,
164+ source : c. sess . source . to_string ( ) ,
165+ destination : c. sess . destination . to_string ( ) ,
166+ outbound_tag : c. sess . outbound_tag . to_owned ( ) ,
167+ bytes_sent : c. bytes_sent ( ) ,
168+ bytes_recvd : c. bytes_recvd ( ) ,
169+ send_completed : c. send_completed ( ) ,
170+ recv_completed : c. recv_completed ( ) ,
171+ start_time : c. start_time ( ) ,
172+ dns_sniffed_domain : c. sess . dns_sniffed_domain . clone ( ) ,
173+ tls_sniffed_domain : c. sess . tls_sniffed_domain . clone ( ) ,
174+ http_sniffed_domain : c. sess . http_sniffed_domain . clone ( ) ,
175+ } ) ;
176+ }
177+ Ok ( Json ( stats) )
178+ }
179+
180+ pub async fn stat_recent_json (
181+ State ( rm) : State < Arc < RuntimeManager > > ,
182+ ) -> Result < Json < Vec < models:: Stat > > , Infallible > {
183+ let mut stats = Vec :: new ( ) ;
184+ let sm = rm. stat_manager ( ) ;
185+ let sm = sm. read ( ) . await ;
186+ for c in sm. recent_counters . iter ( ) {
160187 stats. push ( models:: Stat {
161188 network : c. sess . network . to_string ( ) ,
162189 inbound_tag : c. sess . inbound_tag . to_owned ( ) ,
@@ -202,19 +229,19 @@ table, th, td {
202229 let total_counters = sm. counters . len ( ) ;
203230 let active_counters = sm
204231 . counters
205- . iter ( )
232+ . values ( )
206233 . filter ( |x| !x. send_completed ( ) || !x. recv_completed ( ) )
207234 . count ( ) ;
208235 let active_sources = HashSet :: < IpAddr > :: from_iter (
209236 sm. counters
210- . iter ( )
237+ . values ( )
211238 . filter ( |x| !x. send_completed ( ) || !x. recv_completed ( ) )
212239 . map ( |c| c. sess . source . ip ( ) ) ,
213240 )
214241 . len ( ) ;
215242 let active_forwarded_source = HashSet :: < IpAddr > :: from_iter (
216243 sm. counters
217- . iter ( )
244+ . values ( )
218245 . filter ( |x| !x. send_completed ( ) || !x. recv_completed ( ) )
219246 . filter_map ( |c| c. sess . forwarded_source ) ,
220247 )
@@ -224,7 +251,55 @@ table, th, td {
224251 total_counters, active_counters, active_sources, active_forwarded_source,
225252 ) ) ;
226253 body. push_str ( "<tr><td>Network</td><td>Inbound</td><td>Forwarded</td><td>Source</td><td>Destination</td><td>Outbound</td><td>SentBytes</td><td>RecvdBytes</td><td>SendFin</td><td>RecvFin</td><td>StartTime</td></tr>" ) ;
227- for c in sm. counters . iter ( ) {
254+ for c in sm. counters . values ( ) {
255+ body. push_str ( & format ! (
256+ "<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>" ,
257+ & c. sess. network,
258+ & c. sess. inbound_tag,
259+ & c. sess. forwarded_source. map( |x|x. to_string( ) ) . unwrap_or( "None" . to_string( ) ) ,
260+ & c. sess. source,
261+ & c. sess. destination,
262+ & c. sess. outbound_tag,
263+ c. bytes_sent( ) ,
264+ c. bytes_recvd( ) ,
265+ c. send_completed( ) ,
266+ c. recv_completed( ) ,
267+ Local
268+ . timestamp_opt( c. start_time( ) as i64 , 0 )
269+ . unwrap( )
270+ . format( "%H:%M:%S" )
271+ . to_string( ) ,
272+ ) ) ;
273+ }
274+ body. push_str ( "</table></html>" ) ;
275+ Ok ( Html ( body) )
276+ }
277+
278+ pub async fn stat_recent_html (
279+ State ( rm) : State < Arc < RuntimeManager > > ,
280+ ) -> Result < Html < String > , Infallible > {
281+ let mut body = String :: from (
282+ r#"<html>
283+ <head><style>
284+ table, th, td {
285+ border: 1px solid black;
286+ border-collapse: collapse;
287+ text-align: right;
288+ padding: 4;
289+ font-size: small;
290+ }
291+ .highlight {
292+ font-weight: bold;
293+ }
294+ </style></head>
295+ <table style="border=4px solid">
296+ "# ,
297+ ) ;
298+ let sm = rm. stat_manager ( ) ;
299+ let sm = sm. read ( ) . await ;
300+ body. push_str ( & format ! ( "Recent {}<br><br>" , sm. recent_counters. len( ) , ) ) ;
301+ body. push_str ( "<tr><td>Network</td><td>Inbound</td><td>Forwarded</td><td>Source</td><td>Destination</td><td>Outbound</td><td>SentBytes</td><td>RecvdBytes</td><td>SendFin</td><td>RecvFin</td><td>StartTime</td></tr>" ) ;
302+ for c in sm. recent_counters . iter ( ) {
228303 body. push_str ( & format ! (
229304 "<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>" ,
230305 & c. sess. network,
@@ -314,6 +389,14 @@ impl ApiServer {
314389 app = app
315390 . route ( "/api/v1/runtime/stat/html" , get ( handlers:: stat_html) )
316391 . route ( "/api/v1/runtime/stat/json" , get ( handlers:: stat_json) )
392+ . route (
393+ "/api/v1/runtime/stat/recent/html" ,
394+ get ( handlers:: stat_recent_html) ,
395+ )
396+ . route (
397+ "/api/v1/runtime/stat/recent/json" ,
398+ get ( handlers:: stat_recent_json) ,
399+ )
317400 . route (
318401 "/api/v1/runtime/outbound/{tag}/last_peer_active" ,
319402 get ( handlers:: last_peer_active) ,
0 commit comments