Skip to content

Commit

Permalink
added logging middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
devang-gaur committed May 18, 2021
1 parent 07c1e4f commit 88e65c4
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ replace (

require (
github.com/ghodss/yaml v1.0.0
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-getter v1.5.1
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
Expand Down Expand Up @@ -447,6 +449,8 @@ github.com/gophercloud/utils v0.0.0-20200423144003-7c72efc7435d/go.mod h1:ehWUbL
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
Expand Down
12 changes: 11 additions & 1 deletion pkg/http-server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package httpserver

import (
"context"
httputils "github.com/accurics/terrascan/pkg/utils/http"
gorillaHandlers "github.com/gorilla/handlers"
"net/http"
"os"
"os/signal"
Expand Down Expand Up @@ -54,14 +56,20 @@ func (g *APIServer) start(routes []*Route, port, certFile, privateKeyFile string
router = mux.NewRouter() // new router
)

logWriter := logging.GetLogWriter(logger)

logger.Info("registering routes...")

// register all routes
for _, v := range routes {
logger.Info("Route ", v.verb, " - ", v.path)
router.Methods(v.verb).Path(v.path).HandlerFunc(v.fn)
handler := gorillaHandlers.CustomLoggingHandler(logWriter, http.HandlerFunc(v.fn), logging.WriteRequestLog)
router.Methods(v.verb).Path(v.path).Handler(handler)
}

router.NotFoundHandler = gorillaHandlers.CustomLoggingHandler(logWriter, http.HandlerFunc(httputils.NotFound), logging.WriteRequestLog)
router.MethodNotAllowedHandler = gorillaHandlers.CustomLoggingHandler(logWriter, http.HandlerFunc(httputils.NotAllowed), logging.WriteRequestLog)

// Add a route for all static templates / assets. Currently used for the Webhook logs views
// go/terrascan/asset is the path where the assets files are located inside the docker container
router.PathPrefix("/assets/").Handler(http.StripPrefix("/assets/", http.FileServer(http.Dir("/go/terrascan/assets"))))
Expand Down Expand Up @@ -100,3 +108,5 @@ func (g *APIServer) start(routes []*Route, port, certFile, privateKeyFile string
}
logger.Info("server exiting gracefully")
}


76 changes: 76 additions & 0 deletions pkg/logging/logwriter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package logging

import (
gorillaHandlers "github.com/gorilla/handlers"
"go.uber.org/zap"
"io"
"net"
"net/http"
"net/url"
"strconv"
"time"
)

type LogWriter struct {
logger *zap.SugaredLogger
}

func GetLogWriter(logger *zap.SugaredLogger) LogWriter {
return LogWriter{
logger: logger,
}
}

func (l LogWriter) Write(p []byte) (n int, err error) {
l.logger.Info(string(p))
return len(p), nil
}

// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
// ts is the timestamp with which the entry should be logged.
// status and size are used to provide the response HTTP status and size.
func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
username := "-"
if url.User != nil {
if name := url.User.Username(); name != "" {
username = name
}
}

host, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
host = req.RemoteAddr
}

uri := req.RequestURI

// Requests using the CONNECT method over HTTP/2.0 must use
// the authority field (aka r.Host) to identify the target.
// Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
if req.ProtoMajor == 2 && req.Method == "CONNECT" {
uri = req.Host
}
if uri == "" {
uri = url.RequestURI()
}

buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
buf = append(buf, host...)
buf = append(buf, " - "...)
buf = append(buf, username...)
buf = append(buf, ` "`...)
buf = append(buf, req.Method...)
buf = append(buf, " "...)
buf = append(buf, uri...)
buf = append(buf, " "...)
buf = append(buf, req.Proto...)
buf = append(buf, `" `...)
buf = append(buf, strconv.Itoa(status)...)
buf = append(buf, " "...)
buf = append(buf, strconv.Itoa(size)...)
return buf
}

func WriteRequestLog(writer io.Writer, params gorillaHandlers.LogFormatterParams) {
writer.Write(buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size))
}
11 changes: 11 additions & 0 deletions pkg/utils/http/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package httputils

import "net/http"

func NotFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}

func NotAllowed(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
}

0 comments on commit 88e65c4

Please sign in to comment.