github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/syz-verifier/monitoring_api.go (about) 1 // Copyright 2021 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 // TODO: switch syz-verifier to use syz-fuzzer. 5 6 //go:build ignore 7 8 package main 9 10 import ( 11 "encoding/json" 12 "net/http" 13 "time" 14 ) 15 16 // Monitor provides http based data for the syz-verifier monitoring. 17 // TODO: Add tests to monitoring_api. 18 type Monitor struct { 19 externalStats *Stats 20 } 21 22 // MakeMonitor creates the Monitor instance. 23 func MakeMonitor() *Monitor { 24 instance := &Monitor{} 25 instance.initHTTPHandlers() 26 return instance 27 } 28 29 // ListenAndServe starts the server. 30 func (monitor *Monitor) ListenAndServe(addr string) error { 31 return http.ListenAndServe(addr, nil) 32 } 33 34 // SetStatsTracking points Monitor to the Stats object to monitor. 35 func (monitor *Monitor) SetStatsTracking(s *Stats) { 36 monitor.externalStats = s 37 } 38 39 // InitHTTPHandlers initializes the API routing. 40 func (monitor *Monitor) initHTTPHandlers() { 41 http.Handle("/api/stats.json", jsonResponse(monitor.renderStats)) 42 43 http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { 44 writer.Write([]byte("<a href='api/stats.json'>stats_json</a>")) 45 }) 46 } 47 48 // statsJSON provides information for the "/api/stats.json" render. 49 type statsJSON struct { 50 StartTime time.Time 51 TotalCallMismatches uint64 52 TotalProgs uint64 53 ExecErrorProgs uint64 54 FlakyProgs uint64 55 MismatchingProgs uint64 56 AverExecSpeed uint64 57 } 58 59 // renderStats renders the statsJSON object. 60 func (monitor *Monitor) renderStats() interface{} { 61 stats := monitor.externalStats 62 63 return &statsJSON{ 64 StartTime: stats.StartTime.Get(), 65 TotalCallMismatches: stats.TotalCallMismatches.Get(), 66 TotalProgs: stats.TotalProgs.Get(), 67 ExecErrorProgs: stats.ExecErrorProgs.Get(), 68 FlakyProgs: stats.FlakyProgs.Get(), 69 MismatchingProgs: stats.MismatchingProgs.Get(), 70 AverExecSpeed: 60 * stats.TotalProgs.Get() / uint64(1+time.Since(stats.StartTime.Get()).Seconds()), 71 } 72 } 73 74 // jsonResponse provides general response forming logic. 75 func jsonResponse(getData func() interface{}) http.Handler { 76 return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { 77 w.Header().Set("Content-Type", "application/json") 78 79 data := getData() 80 json, err := json.MarshalIndent( 81 data, 82 "", 83 "\t", 84 ) 85 if err != nil { 86 http.Error(w, err.Error(), 500) // Internal Server Error. 87 return 88 } 89 90 w.Write(json) 91 }) 92 }