func indexHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}
	htmlData := HtmlData{
		Title:       "Golang Web Server",
		Description: "This is a simple golang webserver example with built in logging, tracing, a health check, and graceful shutdown.",
		Keywords:    "golang web server",
		Author:      "",
		CssFiles: []string{
			"https://fonts.googleapis.com/css?family=Open+Sans",
		},
		CssScript: template.HTML(MAIN_CSS_TEMPLATE),
		BodyContent: template.HTML(
			`<div class = "main-content">
			 	<h2>Simple Golang Web Server</h2>
				<p>This is a simple golang web server example with built in logging, tracing, a health check, and graceful shutdown.</p>
				<br>
				<h4>It also includes a few demo web applications, including:</h4>
				<p>An Excel / Spreadsheet application using <a href="https://bossanova.uk/jexcel/v2/">JExcel</a></p>
				<p>A QR Code Generator using <a href="https://developers.google.com/chart">Google Charts API</a></p>
				<p>An SVG drawing example (taken from <a href="https://github.com/adonovan/gopl.io/blob/master/ch3/surface/main.go">The Go Programming Language</a>)</p>
				<p>A 3D sphere example using <a href="https://threejs.org/">THREE.JS</a><p>
			</div>
		`),
	}
	indexTemplate, err := template.New("index").Parse(MAIN_HTML_TEMPLATE)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if err := indexTemplate.Execute(w, htmlData); err != nil {
		fmt.Println(err)
	}
}
Our main index handler. This page displays basic intro text with a description of basic
functionality and the libraries we use to construct our demo applications.
package main
import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"os"
	"os/signal"
	"sync/atomic"
	"syscall"
	"time"
)
const (
	REQUEST_ID_KEY         = 8888
	READ_TIMEOUT           = 10
	WRITE_TIMEOUT          = 10
	IDLE_TIMEOUT           = 30
	LOG_FILE_NAME          = "server_log.log"
	DEFAULT_SERVER_ADDRESS = "8888"
)
var (
	listenAddr string
	healthy    int32
)
func main() {
	flag.StringVar(&listenAddr, "address", ":"+DEFAULT_SERVER_ADDRESS, "http service address")
	flag.Parse()
	logFile, err := os.OpenFile(LOG_FILE_NAME, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalf("Error opening file: %v", err)
	}
	defer logFile.Close()
	logger := log.New(logFile, "http: ", log.LstdFlags)
	nextRequestID := func() string {
		return fmt.Sprintf("%d", time.Now().UnixNano())
	}
	server := &http.Server{
		Addr:         listenAddr,
		Handler:      tracingHandler(nextRequestID)(loggingHandler(logger)(routeHandler())),
		ErrorLog:     logger,
		ReadTimeout:  READ_TIMEOUT * time.Second,
		WriteTimeout: WRITE_TIMEOUT * time.Second,
		IdleTimeout:  IDLE_TIMEOUT * time.Second,
	}
	doneChannel := make(chan bool)
	quitChannel := make(chan os.Signal, 1)
	signal.Notify(quitChannel, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-quitChannel
		logger.Println("Server is shutting down...")
		atomic.StoreInt32(&healthy, 0)
		ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
		defer cancel()
		server.SetKeepAlivesEnabled(false)
		if err := server.Shutdown(ctx); err != nil {
			logger.Fatalf("Could not gracefully shutdown the server: %v\n", err)
		}
		close(doneChannel)
	}()
	logger.Println("Server is ready to handle requests at ", listenAddr)
	atomic.StoreInt32(&healthy, 1)
	if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		logger.Fatalf("Could not listen on %s: %v\n", listenAddr, err)
	}
	<-doneChannel
	logger.Println("Server stopped")
}
func routeHandler() *http.ServeMux {
	router := http.NewServeMux()
	router.HandleFunc("/", indexHandler)
	router.HandleFunc("/excel", excelHandler)
	router.HandleFunc("/qr-code-generator", qrCodeHandler)
	router.HandleFunc("/svg", svgHandler)
	router.HandleFunc("/sphere", sphereHandler)
	router.HandleFunc("/health", healthHandler)
	router.HandleFunc("/log", logHandler)
	return router
}
type HtmlData struct {
	Title       string
	Description string
	Keywords    string
	Author      string
	CssFiles    []string
	JsFiles     []string
	CssScript   template.HTML
	JsScript    template.HTML
	BodyContent template.HTML
}
const MAIN_CSS_TEMPLATE = `
<style>
	nav a {
		text-decoration: none;
		color: #fff;
		font-size: 110%;
		font-family: 'Open Sans', sans-serif;   
	}
	li {
		text-decoration: none;
		display: inline-block;
		margin: 8% 4% -1% 4%;
		padding: 1%;
	}
	.main-nav {
		background: #000000;
		text-align: center;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		opacity: 0.6;
		z-index: 9999;
		margin: -10%;
	}
	a:hover {
		color: #a9a9a9;
	}
	a:active {
		color: #a9a9a9;
	}
	body {
		margin: 0;
		font-family: 'Open Sans', sans-serif; 
		font-weight: 100;
	}
	body, html
	{
		height: 100%;
	}
	#table-container
	{
		display:    table;
		text-align: center;
		width:      100%;
		height:     100%;
	}
	#container
	{
		display:        table-cell;
		vertical-align: middle;
	}
	#main
	{
		display: inline-block;
	}
	#spreadsheet
	{
		margin: 20px;
	}
	.main-content {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		width: 70%;
		height: 60%;
		padding-top: 40px;  
		padding-bottom: 20px;  
		padding-left: 20px;  
		padding-right: 20px;  
		color: black;
		text-align: center;
	}
	form input {
		float:center;
		clear:both;
	}
	form input {
		margin:15px 0;
		padding:15px 10px;
		width:40%;
		text-align: center;
		outline:none;
		border:1px solid #bbb;
		border-radius:20px;
		display:inline-block;
		-webkit-box-sizing:border-box;
		   -moz-box-sizing:border-box;
				box-sizing:border-box;
		-webkit-transition:0.2s ease all;
		   -moz-transition:0.2s ease all;
			-ms-transition:0.2s ease all;
			 -o-transition:0.2s ease all;
				transition:0.2s ease all;
	}
	form input[type=text]:focus {
		border-color:cornflowerblue;
	}
</style>
`
const MAIN_HTML_TEMPLATE = `
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="description" content="{{ .Description }}">
	<meta name="keywords" content="{{ .Keywords }}">
	<meta name="author" content="{{ .Author }}">
	<title>{{ .Title }}</title>
	{{ range $index, $cssFileLocation := .CssFiles }}
	<link rel="stylesheet" type="text/css" href="{{ $cssFileLocation }}">
	{{ end }}
	{{ range $index, $jsFileLocation := .JsFiles }}
	<script src="{{ $jsFileLocation }}"></script>
	{{ end }}
	{{ .CssScript }}
</head>
<header>
    <div class="main-nav">
        <nav>
			<ul>
				<li><a href="/"/>Home</a></li>
				<li><a href="/excel"/>Excel App</a></li>
				<li><a href="/qr-code-generator"/>QR Code Generator</a></li>
				<li><a href="/svg">SVG Example</a></li>
				<li><a href="/sphere"/>Sphere</a></li>
			</ul>
        </nav>
    </div>
</header>
<body>
	{{ .BodyContent }}
</body>
{{ .JsScript }}
</html> 
`