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  }