Last active
August 4, 2023 21:23
-
-
Save josue/7c70d7b1f3d0e374a465a0718ac82aff to your computer and use it in GitHub Desktop.
Revisions
-
josue revised this gist
May 12, 2018 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ go build for linux: env GOOS=linux go build -o /tmp/server server.go run with docker: docker run -it --rm --name test -v /tmp/server:/server -p 3000:80 -p 3001:6060 alpine /server run pprof debugger: go get github.com/google/pprof -
josue revised this gist
May 12, 2018 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,13 +1,13 @@ /* go build for linux: env GOOS=linux go build -o /tmp/server server.go run with docker: docker run -it --rm --name test -v /tmp/server:/tmp/server -p 3000:80 -p 3001:6060 alpine /server run pprof debugger: go get github.com/google/pprof pprof --seconds 30 -http=:4444 /tmp/server http://localhost:3001/debug/pprof/profile benchmarking with wrk: brew install wrk @@ -159,7 +159,7 @@ func initApiServer() { http.HandleFunc(route, errorHandler(routeHandler)) } port := "80" // default port if os.Getenv("SERVER_PORT") != "" { port = os.Getenv("SERVER_PORT") } -
josue revised this gist
May 12, 2018 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -56,15 +56,18 @@ func routeHandler(w http.ResponseWriter, r *http.Request) error { } // route methods // root/index path func apiRoot(w http.ResponseWriter, r *http.Request) error { data := map[string]string{"hello": "welcome"} return outputJSON(w, data) } // simple health check func apiHealthz(w http.ResponseWriter, r *http.Request) error { data := map[string]interface{}{"alive": time.Now().Unix()} return outputJSON(w, data) } // simulate error with 1 second delay func apiError(w http.ResponseWriter, r *http.Request) error { defer timeTrack(time.Now(), "/error endpoint bug taking too long") time.Sleep(1 * time.Second) -
josue revised this gist
May 12, 2018 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,7 +26,7 @@ import ( "syscall" "time" _ "net/http/pprof" ) // http routes -
josue revised this gist
May 12, 2018 . No changes.There are no files selected for viewing
-
josue revised this gist
May 12, 2018 . 1 changed file with 35 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,19 @@ /* go build for linux: env GOOS=linux go build -o /tmp/server-linux server.go run with docker: docker run -it --rm --name test -v /tmp:/app -p 3000:80 -p 3001:6060 -e SERVER_PORT=80 alpine /app/server-linux run pprof debugger: go get github.com/google/pprof pprof --seconds 30 -http=:4444 /tmp/server-linux http://localhost:3001/debug/pprof/profile benchmarking with wrk: brew install wrk wrk -d 5s http://localhost:3000/ */ package main import ( @@ -9,6 +25,8 @@ import ( "os/signal" "syscall" "time" _ "net/http/pprof" // NOTE: temp debugger ) // http routes @@ -121,25 +139,38 @@ func initSignals() { signalHandler(<-captureSignal) } // initialize PPROF debugger func initPprofDebugger() { port := "6060" // default port if os.Getenv("PPROF_PORT") != "" { port = os.Getenv("PPROF_PORT") } log.Println("Running pprof debugger on :" + port) log.Println(fmt.Sprint(http.ListenAndServe(":"+port, nil).Error())) } // initialize server listener func initApiServer() { // initialize routes for route, _ := range routes { http.HandleFunc(route, errorHandler(routeHandler)) } port := "3000" // default port if os.Getenv("SERVER_PORT") != "" { port = os.Getenv("SERVER_PORT") } log.Println("Running api server on port :" + port) err := http.ListenAndServe(":"+port, nil) if err != nil { log.Printf("[Error] ListenAndServe: %v", err) } } func main() { // start PPROF debugger go initPprofDebugger() // capture signals go initSignals() -
josue revised this gist
May 12, 2018 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -48,6 +48,7 @@ func apiHealthz(w http.ResponseWriter, r *http.Request) error { return outputJSON(w, data) } func apiError(w http.ResponseWriter, r *http.Request) error { defer timeTrack(time.Now(), "/error endpoint bug taking too long") time.Sleep(1 * time.Second) return fmt.Errorf("some error") } @@ -61,10 +62,10 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler if err != nil { errMsg := fmt.Sprintf("{ \"error:\": \"%s\" }", err.Error()) http.Error(w, errMsg, http.StatusInternalServerError) log.Printf("[latency: %s] %d Error - Path: %s -- err: %v", time.Since(startTime), http.StatusInternalServerError, r.RequestURI, err) return } log.Printf("[latency: %s] %d OK - Path: %s", time.Since(startTime), http.StatusOK, r.RequestURI) } } -
josue revised this gist
May 12, 2018 . 1 changed file with 17 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,7 @@ package main import ( "encoding/json" "fmt" "log" "net/http" @@ -38,13 +39,13 @@ func routeHandler(w http.ResponseWriter, r *http.Request) error { // route methods func apiRoot(w http.ResponseWriter, r *http.Request) error { data := map[string]string{"hello": "welcome"} return outputJSON(w, data) } func apiHealthz(w http.ResponseWriter, r *http.Request) error { data := map[string]interface{}{"alive": time.Now().Unix()} return outputJSON(w, data) } func apiError(w http.ResponseWriter, r *http.Request) error { time.Sleep(1 * time.Second) @@ -67,6 +68,17 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler } } // map to json string func outputJSON(w http.ResponseWriter, data interface{}) error { jsonString, err := json.Marshal(data) if err != nil { log.Fatalf("[Internal Error] Unable to stringify map argument, err: %v", err) return fmt.Errorf("[Internal Error] JSON data") } fmt.Fprint(w, string(jsonString)) return nil } // time track func timeTrack(start time.Time, name string) { elapsed := time.Since(start) @@ -132,4 +144,4 @@ func main() { // start HTTP server initApiServer() } -
josue revised this gist
May 12, 2018 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,7 +20,6 @@ var routes = map[string]string{ // handle route paths with methods func routeHandler(w http.ResponseWriter, r *http.Request) error { route, ok := routes[r.RequestURI] if !ok { return fmt.Errorf("Route %s path does not exist", r.RequestURI) } -
josue revised this gist
May 12, 2018 . 1 changed file with 54 additions and 36 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,6 +10,33 @@ import ( "time" ) // http routes var routes = map[string]string{ "/": "apiRoot", "/healthz": "apiHealthz", "/error": "apiError", } // handle route paths with methods func routeHandler(w http.ResponseWriter, r *http.Request) error { route, ok := routes[r.RequestURI] if !ok { return fmt.Errorf("Route %s path does not exist", r.RequestURI) } switch route { case "apiRoot": return apiRoot(w, r) case "apiHealthz": return apiHealthz(w, r) case "apiError": return apiError(w, r) default: return fmt.Errorf("Route %s method not exist", r.RequestURI) } } // route methods func apiRoot(w http.ResponseWriter, r *http.Request) error { fmt.Fprint(w, "{ \"test\": 123123 }") @@ -25,43 +52,28 @@ func apiError(w http.ResponseWriter, r *http.Request) error { return fmt.Errorf("some error") } // capture errors func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { startTime := time.Now() w.Header().Set("Content-Type", "application/json") err := f(w, r) if err != nil { errMsg := fmt.Sprintf("{ \"error:\": \"%s\" }", err.Error()) http.Error(w, errMsg, http.StatusInternalServerError) timeTrack(startTime, fmt.Sprintf("%d [Error] Path: %q -- err: %v", http.StatusInternalServerError, r.RequestURI, err)) return } timeTrack(startTime, fmt.Sprintf("%d [OK] Path: %s", http.StatusOK, r.RequestURI)) } } // time track func timeTrack(start time.Time, name string) { elapsed := time.Since(start) log.Printf("TimeTrack (%s) -> %s", elapsed, name) } // signal handler func signalHandler(signal os.Signal) { fmt.Printf("\nCaught signal: %+v", signal) @@ -90,22 +102,20 @@ func signalHandler(signal os.Signal) { os.Exit(0) } // initialize signal handler func initSignals() { var captureSignal = make(chan os.Signal, 1) signal.Notify(captureSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT) signalHandler(<-captureSignal) } // initialize server listener func initApiServer() { // initialize routes for route, _ := range routes { http.HandleFunc(route, errorHandler(routeHandler)) } serverPort := "3000" // default port if os.Getenv("SERVER_PORT") != "" { serverPort = os.Getenv("SERVER_PORT") @@ -115,4 +125,12 @@ func main() { if err != nil { log.Printf("[Error] ListenAndServe: %v", err) } } func main() { // capture signals go initSignals() // start HTTP server initApiServer() } -
josue revised this gist
May 12, 2018 . 1 changed file with 67 additions and 67 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,30 +10,55 @@ import ( "time" ) // route methods func apiRoot(w http.ResponseWriter, r *http.Request) error { fmt.Fprint(w, "{ \"test\": 123123 }") return nil } func apiHealthz(w http.ResponseWriter, r *http.Request) error { fmt.Fprintf(w, "{ \"alive:\": %d }", time.Now().Unix()) return nil } func apiError(w http.ResponseWriter, r *http.Request) error { time.Sleep(1 * time.Second) return fmt.Errorf("some error") } // handle route paths with methods func routeHandler(w http.ResponseWriter, r *http.Request) error { defer timeTrack(time.Now(), "Path: " + r.RequestURI) switch r.RequestURI { case "/": return apiRoot(w, r) case "/healthz": return apiHealthz(w, r) case "/error": return apiError(w, r) } return nil } // time track func timeTrack(start time.Time, name string) { elapsed := time.Since(start) log.Printf("TimeTrack (%s) -> %s", elapsed, name) } // capture errors func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") err := f(w, r) if err != nil { log.Printf("[Error] %q: %v", r.RequestURI, err) errMsg := fmt.Sprintf("{ \"error:\": \"%s\" }", err.Error()) http.Error(w, errMsg, http.StatusInternalServerError) return } log.Printf("[OK] %q", r.RequestURI) } } @@ -65,54 +90,29 @@ func signalHandler(signal os.Signal) { os.Exit(0) } func main() { // capture signals go func() { var captureSignal = make(chan os.Signal, 1) signal.Notify(captureSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT) signalHandler(<-captureSignal) }() // http routes routes := []string{"/", "/healthz", "/error"} for _, route := range routes { http.HandleFunc(route, errorHandler(routeHandler)) } // start HTTP server serverPort := "3000" // default port if os.Getenv("SERVER_PORT") != "" { serverPort = os.Getenv("SERVER_PORT") } fmt.Println("Running api server on port :" + serverPort) err := http.ListenAndServe(":"+serverPort, nil) if err != nil { log.Printf("[Error] ListenAndServe: %v", err) } } -
josue revised this gist
May 11, 2018 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -88,8 +88,7 @@ func TimeTrack(start time.Time, name string) { // handle routes func routeHandler(w http.ResponseWriter, r *http.Request) error { defer TimeTrack(time.Now(), "Path: " + r.RequestURI) switch r.RequestURI { case "/": @@ -99,6 +98,7 @@ func routeHandler(w http.ResponseWriter, r *http.Request) error { case "/error": return apiError(w, r) } return nil } @@ -113,5 +113,6 @@ func apiHealthz(w http.ResponseWriter, r *http.Request) error { return nil } func apiError(w http.ResponseWriter, r *http.Request) error { time.Sleep(1 * time.Second) return fmt.Errorf("some error") } -
josue revised this gist
May 11, 2018 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -88,7 +88,8 @@ func TimeTrack(start time.Time, name string) { // handle routes func routeHandler(w http.ResponseWriter, r *http.Request) error { startTime := time.Now() defer TimeTrack(startTime, "Path: " + r.RequestURI) switch r.RequestURI { case "/": -
josue revised this gist
May 11, 2018 . 1 changed file with 7 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -80,10 +80,15 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler } } // time track func TimeTrack(start time.Time, name string) { elapsed := time.Since(start) log.Printf("TimeTrack (%s) -> %s", elapsed, name) } // handle routes func routeHandler(w http.ResponseWriter, r *http.Request) error { defer TimeTrack(time.Now(), "Path: " + r.RequestURI) switch r.RequestURI { case "/": -
josue revised this gist
May 11, 2018 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -82,6 +82,9 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler // handle routes func routeHandler(w http.ResponseWriter, r *http.Request) error { start := time.Now() defer log.Printf("TimeTrack (%s) -> %s", time.Since(start), r.RequestURI) switch r.RequestURI { case "/": return apiRoot(w, r) -
josue revised this gist
May 4, 2018 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,7 +31,10 @@ func main() { serverPort = os.Getenv("SERVER_PORT") } fmt.Println("Running api server on port :" + serverPort) err := http.ListenAndServe(":"+serverPort, nil) if err != nil { log.Printf("[Error] ListenAndServe: %v", err) } } // signal handler -
josue revised this gist
May 4, 2018 . 1 changed file with 12 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,12 +26,12 @@ func main() { } // start HTTP server serverPort := "3000" // default port if os.Getenv("SERVER_PORT") != "" { serverPort = os.Getenv("SERVER_PORT") } fmt.Println("Running api server on port :" + serverPort) http.ListenAndServe(":"+serverPort, nil) } // signal handler @@ -69,8 +69,8 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler err := f(w, r) if err != nil { log.Printf("[Error] %q: %v", r.RequestURI, err) errMsg := fmt.Sprintf("{ \"error:\": \"%s\" }", err.Error()) http.Error(w, errMsg, http.StatusInternalServerError) return } log.Printf("[OK] %q", r.RequestURI) @@ -81,25 +81,25 @@ func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.Handler func routeHandler(w http.ResponseWriter, r *http.Request) error { switch r.RequestURI { case "/": return apiRoot(w, r) case "/healthz": return apiHealthz(w, r) case "/error": return apiError(w, r) } return nil } // routes methods func apiRoot(w http.ResponseWriter, r *http.Request) error { fmt.Fprint(w, "{ \"test\": 123123 }") return nil } func apiHealthz(w http.ResponseWriter, r *http.Request) error { fmt.Fprintf(w, "{ \"alive:\": %d }", time.Now().Unix()) return nil } func apiError(w http.ResponseWriter, r *http.Request) error { return fmt.Errorf("some error") } -
josue revised this gist
May 4, 2018 . 1 changed file with 5 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,9 +19,11 @@ func main() { }() // http routes routes := []string{"/", "/healthz", "/error"} for _, route := range routes { http.HandleFunc(route, errorHandler(routeHandler)) } // start HTTP server SERVER_PORT := "3000" // default port -
josue created this gist
May 4, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,103 @@ package main import ( "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" ) func main() { // capture signals go func() { var captureSignal = make(chan os.Signal, 1) signal.Notify(captureSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT) signalHandler(<-captureSignal) }() // http routes http.HandleFunc("/", errorHandler(routeHandler)) http.HandleFunc("/healthz", errorHandler(routeHandler)) http.HandleFunc("/error", errorHandler(routeHandler)) // start HTTP server SERVER_PORT := "3000" // default port if os.Getenv("SERVER_PORT") != "" { SERVER_PORT = os.Getenv("SERVER_PORT") } fmt.Println("Running api server on port :" + SERVER_PORT) http.ListenAndServe(":"+SERVER_PORT, nil) } // signal handler func signalHandler(signal os.Signal) { fmt.Printf("\nCaught signal: %+v", signal) fmt.Println("\nWait for 1 second to finish processing") time.Sleep(1 * time.Second) switch signal { case syscall.SIGHUP: // kill -SIGHUP XXXX fmt.Println("- got hungup") case syscall.SIGINT: // kill -SIGINT XXXX or Ctrl+c fmt.Println("- got ctrl+c") case syscall.SIGTERM: // kill -SIGTERM XXXX fmt.Println("- got force stop") case syscall.SIGQUIT: // kill -SIGQUIT XXXX fmt.Println("- stop and core dump") default: fmt.Println("- unknown signal") } fmt.Println("\nFinished server cleanup") os.Exit(0) } // capture errors func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") err := f(w, r) if err != nil { log.Printf("[Error] %q: %v", r.RequestURI, err) err_msg := fmt.Sprintf("{ \"error:\": \"%s\" }", err.Error()) http.Error(w, err_msg, http.StatusInternalServerError) return } log.Printf("[OK] %q", r.RequestURI) } } // handle routes func routeHandler(w http.ResponseWriter, r *http.Request) error { switch r.RequestURI { case "/": return ApiRoot(w, r) case "/healthz": return ApiHealthz(w, r) case "/error": return ApiError(w, r) } return nil } // routes methods func ApiRoot(w http.ResponseWriter, r *http.Request) error { fmt.Fprint(w, "{ \"test\": 123123 }") return nil } func ApiHealthz(w http.ResponseWriter, r *http.Request) error { fmt.Fprintf(w, "{ \"alive:\": %d }", time.Now().Unix()) return nil } func ApiError(w http.ResponseWriter, r *http.Request) error { return fmt.Errorf("some error") }