github.com/Cloud-Foundations/Dominator@v0.3.4/lib/html/header.go (about) 1 package html 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "runtime" 8 "strings" 9 "time" 10 11 "github.com/Cloud-Foundations/Dominator/lib/format" 12 "github.com/Cloud-Foundations/Dominator/lib/wsyscall" 13 ) 14 15 type cpuStats struct { 16 realTime time.Time 17 userTime time.Time 18 sysTime time.Time 19 } 20 21 var ( 22 startCpuStats *cpuStats = getCpuStats() 23 lastCpuStats *cpuStats = startCpuStats 24 ) 25 26 func handleFunc(serveMux *http.ServeMux, pattern string, 27 handler func(w http.ResponseWriter, req *http.Request)) { 28 serveMux.HandleFunc(pattern, 29 func(w http.ResponseWriter, req *http.Request) { 30 SetSecurityHeaders(w) // Compliance checkbox. 31 handler(w, req) 32 }) 33 } 34 35 func setSecurityHeaders(w http.ResponseWriter) { 36 w.Header().Set("X-Frame-Options", "DENY") 37 w.Header().Set("X-XSS-Protection", "1") 38 w.Header().Set("Content-Security-Policy", 39 "default-src 'self' ;style-src 'self' 'unsafe-inline'") 40 w.Header().Set("X-Content-Type-Options", "nosniff") 41 } 42 43 func writeCpuStats(writer io.Writer, prefix string, start, current *cpuStats) { 44 userCpuTime := current.userTime.Sub(start.userTime) 45 sysCpuTime := current.sysTime.Sub(start.sysTime) 46 realTime := current.realTime.Sub(start.realTime) 47 cpuTime := userCpuTime + sysCpuTime 48 fmt.Fprintf(writer, 49 " <td>%s CPU Time: %.1f%% (User: %s Sys: %s)</td>\n", 50 prefix, float64(cpuTime*100)/float64(realTime), userCpuTime, sysCpuTime) 51 } 52 53 func writeHeader(writer io.Writer, req *http.Request, noGC bool) { 54 currentCpuStats := getCpuStats() 55 fmt.Fprintln(writer, 56 `<table border="1" bordercolor=#e0e0e0 style="border-collapse: collapse">`) 57 fmt.Fprintf(writer, " <tr>\n") 58 fmt.Fprintf(writer, " <td>Start time: %s</td>\n", 59 startCpuStats.realTime.Format(format.TimeFormatSeconds)) 60 uptime := currentCpuStats.realTime.Sub(startCpuStats.realTime) 61 uptime += time.Millisecond * 50 62 uptime = (uptime / time.Millisecond / 100) * time.Millisecond * 100 63 fmt.Fprintf(writer, " <td>Uptime: %s</td>\n", format.Duration(uptime)) 64 fmt.Fprintf(writer, " </tr>\n") 65 fmt.Fprintf(writer, " <tr>\n") 66 writeCpuStats(writer, "Total", startCpuStats, currentCpuStats) 67 writeCpuStats(writer, "Recent", lastCpuStats, currentCpuStats) 68 lastCpuStats = currentCpuStats 69 fmt.Fprintf(writer, " </tr>\n") 70 fmt.Fprintf(writer, " <tr>\n") 71 var memStatsBeforeGC runtime.MemStats 72 runtime.ReadMemStats(&memStatsBeforeGC) 73 if noGC { 74 fmt.Fprintf(writer, " <td>Allocated memory: %s</td>\n", 75 format.FormatBytes(memStatsBeforeGC.Alloc)) 76 fmt.Fprintf(writer, " <td>System memory: %s</td>\n", 77 format.FormatBytes( 78 memStatsBeforeGC.Sys-memStatsBeforeGC.HeapReleased)) 79 } else { 80 var memStatsAfterGC runtime.MemStats 81 startTime := time.Now() 82 runtime.GC() 83 runtime.ReadMemStats(&memStatsAfterGC) 84 fmt.Fprintf(writer, " <td>Allocated memory: %s (%s after GC, took %s)</td>\n", 85 format.FormatBytes(memStatsBeforeGC.Alloc), 86 format.FormatBytes(memStatsAfterGC.Alloc), 87 format.Duration(time.Since(startTime))) 88 fmt.Fprintf(writer, " <td>System memory: %s (%s after GC)</td>\n", 89 format.FormatBytes( 90 memStatsBeforeGC.Sys-memStatsBeforeGC.HeapReleased), 91 format.FormatBytes( 92 memStatsAfterGC.Sys-memStatsAfterGC.HeapReleased)) 93 } 94 fmt.Fprintf(writer, " </tr>\n") 95 fmt.Fprintf(writer, "</table>\n") 96 fmt.Fprintln(writer, "Raw <a href=\"metrics\">metrics</a><br>") 97 if req != nil { 98 protocol := "http" 99 if req.TLS != nil { 100 protocol = "https" 101 } 102 host := strings.Split(req.Host, ":")[0] 103 fmt.Fprintf(writer, 104 "Local <a href=\"%s://%s:6910/\">system health agent</a>", 105 protocol, host) 106 } 107 } 108 109 func getCpuStats() *cpuStats { 110 uTime, sTime := getRusage() 111 return &cpuStats{ 112 realTime: time.Now(), 113 userTime: uTime, 114 sysTime: sTime, 115 } 116 } 117 118 func getRusage() (time.Time, time.Time) { 119 var rusage wsyscall.Rusage 120 wsyscall.Getrusage(wsyscall.RUSAGE_SELF, &rusage) 121 return time.Unix(int64(rusage.Utime.Sec), int64(rusage.Utime.Usec)*1000), 122 time.Unix(int64(rusage.Stime.Sec), int64(rusage.Stime.Usec)*1000) 123 }