diff --git a/README.md b/README.md new file mode 100644 index 0000000..291aa0f --- /dev/null +++ b/README.md @@ -0,0 +1,202 @@ +# GO Actuator + +[![GoDoc](https://godoc.org/github.com/sinhashubham95/bleep?status.svg)](https://pkg.go.dev/github.com/sinhashubham95/bleep) +[![Release](https://img.shields.io/github/v/release/sinhashubham95/bleep?sort=semver)](https://github.com/sinhashubham95/bleep/releases) +[![Report](https://goreportcard.com/badge/github.com/sinhashubham95/bleep)](https://goreportcard.com/report/github.com/sinhashubham95/bleep) +[![Coverage Status](https://coveralls.io/repos/github/sinhashubham95/bleep/badge.svg?branch=master)](https://coveralls.io/github/sinhashubham95/bleep?branch=master) +[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#utilities) + +GO actuator configures the set of actuator endpoints for your application. It is compatible with [Fast HTTP](https://github.com/valyala/fasthttp), [GIN](https://github.com/gin-gonic/gin) and [NET/HTTP](https://pkg.go.dev/net/http). + +## Installation + +```shell +go get github.com/sinhashubham95/go-actuator +``` + +## How to Use + +The actuator library is compatible with the most famous web frameworks. This is highly configurable and each endpoint can be enabled or disabled during initialization. You can also specify a prefix path for each of these configured endpoints(with default value `/actuator`). + +### Configuration + +The configuration contains the following:- + +1. **Endpoints** - This is the list of endpoints which will be enabled. This is not a mandatory parameter. If not provided, then all the endpoints will be enabled. The possible endpoints are - `/env`, `/httpTrace`, `/info`, `/metrics`, `/ping`, `/shutdown` and `/threadDump`. You can find the description of each of these endpoints below. + +2. **Prefix** - This is the prefix request path for all the configured endpoints. + +```go +import "github.com/sinhashubham95/go-actuator/models" + +config := &models.Config{ + Endpoints: []int{ + models.Env, models.HTTPTrace, models.Info, models.Metrics, models.Ping, models.Shutdown, models.ThreadDump + }, + Prefix: "/actuator" +} +``` + +### Using with [Fast HTTP](https://github.com/valyala/fasthttp) + +```go +import ( + "github.com/valyala/fasthttp" + actuator "github.com/sinhashubham95/go-actuator" + "github.com/sinhashubham95/go-actuator/models" +) + +actuatorHandler := actuator.GetFastHTTPActuatorHandler(&models.Config{}) +handler := func(ctx *fasthttp.RequestCtx) { + switch(ctx.Path()) { + // your configured paths + default: + actuatorHandler(ctx) + } +} +fasthttp.ListenAndServe(":8080", handler) +``` + +### Using with [GIN](https://github.com/gin-gonic/gin) + +```go +import ( + "github.com/gin-gonic/gin" + actuator "github.com/sinhashubham95/go-actuator" + "github.com/sinhashubham95/go-actuator/models" +) + +engine := gin.Default() +actuator.ConfigureGINActuatorEngine(&models.Config{}, engine) +``` + +### Using with [Net HTTP](https://pkg.go.dev/net/http) + +```go +import ( + actuator "github.com/sinhashubham95/go-actuator" + "github.com/sinhashubham95/go-actuator/models" + "net/http" +) + +mux := &http.ServeMux{} +actuator.ConfigureNetHTTPHandler(&models.Config{}, mux) +``` + +## Endpoints + +### Env - `/actuator/env` + +This is used to get all the environment variables for the runtime where the application is running. Note that to use this, you need to pass the runtime environment as an application flag as follows. + +```shell +go build +./${APPLICATION_NAME} -env=${ENVIRONMENT_NAME} +``` + +```json +{ + "env_key_1": "env_value_1", + "env_key_2": "env_value_2" +} +``` + +### HTTP Trace - `/actuator/httpTrace` + +This is used to get the trace for the last 100 HTTP requests. Now if this has to be used, then the HTTP requests should be wrapped with the trace as follows. + +```go +import ( + actuatorCore "github.com/sinhashubham95/go-actuator/core" + "net/http" + "strings" +) + +request, err := http.NewRequest(http.MethodGet, "https://sample.com", strings.NewReader("sample")) +if err != nil { + // incorrect request +} + +request = actuatorCore.WithClientTrace(request) + +// now use this request with whichever http client you want to use +response, err := http.DefaultClient.Do(request) +``` + +```json +[ + { + "host": "https://sample.com", + "dnsLookupTimeTakenInNanos": 1234, + "tcpConnectionTimeTakenInNanos": 1234, + "connectTimeTakenInNanos": 1234, + "preTransferTimeTakenInNanos": 1234, + "isTLSEnabled": true, + "tlsHandshakeTimeTakenInNanos": 1234, + "serverProcessingTimeTakenInNanos": 1234, + "isConnectionReused": true + } +] +``` + +### Info - `/actuator/info` + +This is used to get the basic information for an application. To get the correct and relevant information for your application you need to change the build script as well as the run script for your application as follows. + +```shell +buildStamp=$(date -u '+%Y-%m-%d_%I:%M:%S%p') +commitId=$(git rev-list -1 HEAD) +commitTime=$(git show -s --format=%ci "$commitId") +commitAuthor=$(git --no-pager show -s --format='%an <%ae>' "$commitId") +gitUrl=$(git config --get remote.origin.url) +userName=$(whoami) +hostName=$(hostname) +go build -ldflags " -X github.com/sinhashubham95/info.BuildStamp=$buildStamp -X github.com/sinhashubham95/info.GitCommitID=$commitId -X github.com/sinhashubham95/info.GitPrimaryBranch=$2 -X github.com/sinhashubham95/info.GitURL=$gitUrl -X github.com/sinhashubham95/info.UserName=$userName -X github.com/sinhashubham95/info.HostName=$hostName -X \"github.com/sinhashubham95/info.GitCommitTime=$commitTime\" -X \"github.com/sinhashubham95/info.GitCommitAuthor=$commitAuthor\"" +./${APPLICATION_NAME} -env=${ENVIRONMENT_NAME} -name=${APPLICATION_NAME} -port=${APPLICATION_PORT} -version=${APPLICATION_VERSION} +``` + +```json +{ + "application": { + "env": "ENVIRONMENT", + "name": "APPLICATION_NAME", + "version": "APPLICATION_VERSION" + }, + "git": { + "username": "s0s01qp", + "hostName": "m-C02WV1L6HTD5", + "buildStamp": "2019-08-22_09:44:04PM", + "commitAuthor": "Shubham Sinha ", + "commitId": "836475215e3ecf0ef26e0d5b65a9db626568ef89", + "commitTime": "2019-08-23 02:27:26 +0530", + "branch": "master", + "url": "https://gecgithub01.walmart.com/RT-Integrated-Fulfillment/gif-ui-bff.git" + }, + "runtime": { + "arch": "", + "os": "", + "port": 8080, + "runtimeVersion": "" + } +} +``` + +### Metrics - `/actuator/metrics` + +This is used to get the runtime memory statistics for your application. You can find the definition of each of the fields [here](./models/memStats.go). + +```json +{} +``` + +### Ping - `/actuator/ping` + +This is the lightweight ping endpoint that can be used along with your load balancer. This is used to know the running status of your application. + +### Shutdown - `/actuator/shutdown` + +This is used to bring the application down. + +### Thread dump - `/actuator/threadDump` + +This is used to get the trace of all the goroutines. diff --git a/commons/constants.go b/commons/constants.go index c2c23c5..b881900 100644 --- a/commons/constants.go +++ b/commons/constants.go @@ -14,7 +14,7 @@ const ( GitCommitAuthor = "commitAuthor" GitCommitID = "commitId" GitCommitTime = "commitTime" - GitPrimaryBranch = "primaryBranch" + GitPrimaryBranch = "branch" GitURL = "url" GoRoutines = "goroutine" HostName = "hostName" diff --git a/controllers/fastHTTP/env.go b/controllers/fastHTTP/env.go index 333eb00..475776b 100644 --- a/controllers/fastHTTP/env.go +++ b/controllers/fastHTTP/env.go @@ -1,10 +1,11 @@ package fastHTTP import ( - "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" "github.com/valyala/fasthttp" "net/http" + + "github.com/sinhashubham95/go-actuator/commons" + "github.com/sinhashubham95/go-actuator/core" ) // HandleEnv is the handler function for the env endpoint diff --git a/controllers/fastHTTP/httpTrace.go b/controllers/fastHTTP/httpTrace.go index d04c2e6..86752dc 100644 --- a/controllers/fastHTTP/httpTrace.go +++ b/controllers/fastHTTP/httpTrace.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleHTTPTrace is used to handle the http trace request diff --git a/controllers/fastHTTP/info.go b/controllers/fastHTTP/info.go index 2b5a250..999514e 100644 --- a/controllers/fastHTTP/info.go +++ b/controllers/fastHTTP/info.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleInfo is the handler function for the info endpoint diff --git a/controllers/fastHTTP/metrics.go b/controllers/fastHTTP/metrics.go index 97f126c..a6e7ec5 100644 --- a/controllers/fastHTTP/metrics.go +++ b/controllers/fastHTTP/metrics.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleMetrics is the handler function for the metrics endpoint diff --git a/controllers/fastHTTP/shutdown.go b/controllers/fastHTTP/shutdown.go index a82425c..0f0b769 100644 --- a/controllers/fastHTTP/shutdown.go +++ b/controllers/fastHTTP/shutdown.go @@ -4,7 +4,7 @@ import ( "github.com/valyala/fasthttp" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleShutdown is the handler function for the shutdown endpoint diff --git a/controllers/fastHTTP/threadDump.go b/controllers/fastHTTP/threadDump.go index 010d8cb..f32741d 100644 --- a/controllers/fastHTTP/threadDump.go +++ b/controllers/fastHTTP/threadDump.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleThreadDump is the handler for getting thread dump diff --git a/controllers/gin/env.go b/controllers/gin/env.go index d8c80d4..a9c9897 100644 --- a/controllers/gin/env.go +++ b/controllers/gin/env.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleEnv is the handler function for the env endpoint diff --git a/controllers/gin/httpTrace.go b/controllers/gin/httpTrace.go index 890f1e1..5a69dff 100644 --- a/controllers/gin/httpTrace.go +++ b/controllers/gin/httpTrace.go @@ -2,8 +2,9 @@ package gin import ( "github.com/gin-gonic/gin" - "github.com/sinhashubham95/go-actuator/controllers/core" "net/http" + + "github.com/sinhashubham95/go-actuator/core" ) // HandleHTTPTrace is used to handle the http trace request diff --git a/controllers/gin/info.go b/controllers/gin/info.go index c30c6c3..96a538f 100644 --- a/controllers/gin/info.go +++ b/controllers/gin/info.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleInfo is the handler function for the info endpoint diff --git a/controllers/gin/metrics.go b/controllers/gin/metrics.go index f1226c5..a008f23 100644 --- a/controllers/gin/metrics.go +++ b/controllers/gin/metrics.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleMetrics is the handler function for the metrics endpoint diff --git a/controllers/gin/shutdown.go b/controllers/gin/shutdown.go index e581e96..ac82408 100644 --- a/controllers/gin/shutdown.go +++ b/controllers/gin/shutdown.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleShutdown is the handler function for the shutdown endpoint diff --git a/controllers/gin/threadDump.go b/controllers/gin/threadDump.go index fae3281..50dbf59 100644 --- a/controllers/gin/threadDump.go +++ b/controllers/gin/threadDump.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleThreadDump is the handler to get the thread dump diff --git a/controllers/netHTTP/env.go b/controllers/netHTTP/env.go index eca0f56..0963f99 100644 --- a/controllers/netHTTP/env.go +++ b/controllers/netHTTP/env.go @@ -4,7 +4,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleEnv is the handler function for the env endpoint diff --git a/controllers/netHTTP/httpTrace.go b/controllers/netHTTP/httpTrace.go index 295c1f3..f0dd1c8 100644 --- a/controllers/netHTTP/httpTrace.go +++ b/controllers/netHTTP/httpTrace.go @@ -4,7 +4,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleHTTPTrace is used to handle the http trace request diff --git a/controllers/netHTTP/info.go b/controllers/netHTTP/info.go index 3ebe690..96753b1 100644 --- a/controllers/netHTTP/info.go +++ b/controllers/netHTTP/info.go @@ -4,7 +4,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleInfo is the handler function for the info endpoint diff --git a/controllers/netHTTP/metrics.go b/controllers/netHTTP/metrics.go index 13b61da..d786039 100644 --- a/controllers/netHTTP/metrics.go +++ b/controllers/netHTTP/metrics.go @@ -4,7 +4,7 @@ import ( "net/http" "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleMetrics is the handler function for the metrics endpoint diff --git a/controllers/netHTTP/shutdown.go b/controllers/netHTTP/shutdown.go index 127cd08..a4e9b2b 100644 --- a/controllers/netHTTP/shutdown.go +++ b/controllers/netHTTP/shutdown.go @@ -3,7 +3,7 @@ package netHTTP import ( "net/http" - "github.com/sinhashubham95/go-actuator/controllers/core" + "github.com/sinhashubham95/go-actuator/core" ) // HandleShutdown is the handler function for the shutdown endpoint diff --git a/controllers/netHTTP/threadDump.go b/controllers/netHTTP/threadDump.go index 9935f9c..498bfda 100644 --- a/controllers/netHTTP/threadDump.go +++ b/controllers/netHTTP/threadDump.go @@ -1,9 +1,10 @@ package netHTTP import ( - "github.com/sinhashubham95/go-actuator/commons" - "github.com/sinhashubham95/go-actuator/controllers/core" "net/http" + + "github.com/sinhashubham95/go-actuator/commons" + "github.com/sinhashubham95/go-actuator/core" ) func HandleThreadDump(writer http.ResponseWriter, request *http.Request) { diff --git a/controllers/core/env.go b/core/env.go similarity index 100% rename from controllers/core/env.go rename to core/env.go diff --git a/controllers/core/httpTrace.go b/core/httpTrace.go similarity index 96% rename from controllers/core/httpTrace.go rename to core/httpTrace.go index ec9a7a9..d1f2866 100644 --- a/controllers/core/httpTrace.go +++ b/core/httpTrace.go @@ -17,7 +17,9 @@ var httpTraceResults []*models.HTTPTraceResult // this is mandatory to populate the trace in the result set func WithClientTrace(request *http.Request) *http.Request { // create a result - result := &models.HTTPTraceResult{} + result := &models.HTTPTraceResult{ + Host: request.Host, + } // set the trace in the request context request.WithContext(httptrace.WithClientTrace(request.Context(), &httptrace.ClientTrace{ @@ -58,7 +60,7 @@ func WithClientTrace(request *http.Request) *http.Request { result.IsReused = true } }, - WroteRequest: func(_ httptrace.WroteRequestInfo) { + WroteRequest: func(info httptrace.WroteRequestInfo) { result.ServerStart = time.Now() // when client does not use dial context or old package diff --git a/controllers/core/info.go b/core/info.go similarity index 100% rename from controllers/core/info.go rename to core/info.go diff --git a/controllers/core/metrics.go b/core/metrics.go similarity index 100% rename from controllers/core/metrics.go rename to core/metrics.go diff --git a/controllers/core/ping.go b/core/ping.go similarity index 100% rename from controllers/core/ping.go rename to core/ping.go diff --git a/controllers/core/shutdown.go b/core/shutdown.go similarity index 100% rename from controllers/core/shutdown.go rename to core/shutdown.go diff --git a/controllers/core/threadDump.go b/core/threadDump.go similarity index 100% rename from controllers/core/threadDump.go rename to core/threadDump.go diff --git a/models/httpTrace.go b/models/httpTrace.go index 54ea84b..00782c7 100644 --- a/models/httpTrace.go +++ b/models/httpTrace.go @@ -4,25 +4,27 @@ import "time" // HTTPTraceResult is the set of useful information to trace the http request type HTTPTraceResult struct { + Host string `json:"host"` + DNSStart time.Time `json:"-"` DNSDone time.Time `json:"-"` - DNSLookup time.Duration `json:"dnsLookupTimeTaken"` + DNSLookup time.Duration `json:"dnsLookupTimeTakenInNanos"` TCPStart time.Time `json:"-"` TCPDone time.Time `json:"-"` - TCPConnection time.Duration `json:"tcpConnectionTimeTaken"` + TCPConnection time.Duration `json:"tcpConnectionTimeTakenInNanos"` - Connect time.Duration `json:"connectTimeTaken"` - PreTransfer time.Duration `json:"preTransferTimeTaken"` + Connect time.Duration `json:"connectTimeTakenInNanos"` + PreTransfer time.Duration `json:"preTransferTimeTakenInNanos"` IsTLS bool `json:"isTLSEnabled"` TLSStart time.Time `json:"-"` TLSDone time.Time `json:"-"` - TLSHandshake time.Duration `json:"tlsHandshakeTimeTaken"` + TLSHandshake time.Duration `json:"tlsHandshakeTimeTakenInNanos"` ServerStart time.Time `json:"-"` ServerDone time.Time `json:"-"` - ServerProcessing time.Duration `json:"serverProcessingTimeTaken"` + ServerProcessing time.Duration `json:"serverProcessingTimeTakenInNanos"` IsReused bool `json:"isConnectionReused"` diff --git a/models/MemStats.go b/models/memStats.go similarity index 100% rename from models/MemStats.go rename to models/memStats.go