From f4910fff5119dccacbd1bc03a62c663972da8c12 Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Wed, 16 Dec 2020 13:28:29 -0800 Subject: [PATCH] Starts a refactor (#898) --- .reflex | 2 +- main.go | 17 ++++--- .../__snapshots__/web.snapshot | 0 routes.go => web/routes.go | 47 ++++++++++++++++--- main_test.go => web/routes_test.go | 28 +++++------ 5 files changed, 65 insertions(+), 29 deletions(-) rename __snapshots__/dozzle.snapshot => web/__snapshots__/web.snapshot (100%) rename routes.go => web/routes.go (85%) rename main_test.go => web/routes_test.go (91%) diff --git a/.reflex b/.reflex index 70d7f06f..2ea61568 100644 --- a/.reflex +++ b/.reflex @@ -1 +1 @@ --r '\.go$' -R 'node_modules' -R '^static/' -R '^.cache/' -G '*_test.go' -s -- go run main.go routes.go --level debug +-r '\.go$' -R 'node_modules' -R '^static/' -R '^.cache/' -G '*_test.go' -s -- go run main.go --level debug diff --git a/main.go b/main.go index 00e71a97..40275b7f 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "net/http" "net/url" "os" "os/signal" @@ -10,6 +9,8 @@ import ( "time" "github.com/amir20/dozzle/docker" + "github.com/amir20/dozzle/web" + "github.com/gobuffalo/packr" log "github.com/sirupsen/logrus" "github.com/spf13/pflag" @@ -20,7 +21,6 @@ var ( addr = "" base = "" level = "" - showAll = false tailSize = 300 filters map[string]string version = "dev" @@ -81,11 +81,14 @@ func main() { } box := packr.NewBox("./static") - r := createRoutes(base, &handler{ - client: dockerClient, - box: box, - }) - srv := &http.Server{Addr: addr, Handler: r} + + config := web.Config{ + Addr: addr, + Base: base, + Version: version, + TailSize: tailSize, + } + srv := web.CreateServer(dockerClient, box, config) go func() { log.Infof("Accepting connections on %s", srv.Addr) diff --git a/__snapshots__/dozzle.snapshot b/web/__snapshots__/web.snapshot similarity index 100% rename from __snapshots__/dozzle.snapshot rename to web/__snapshots__/web.snapshot diff --git a/routes.go b/web/routes.go similarity index 85% rename from routes.go rename to web/routes.go index def306db..19148b03 100644 --- a/routes.go +++ b/web/routes.go @@ -1,4 +1,4 @@ -package main +package web import ( "encoding/json" @@ -11,11 +11,37 @@ import ( "time" "github.com/amir20/dozzle/docker" + "github.com/gobuffalo/packr" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" ) -func createRoutes(base string, h *handler) *mux.Router { +// Config is a struct for configuring the web service +type Config struct { + Base string + Addr string + Version string + TailSize int +} + +type handler struct { + client docker.Client + box packr.Box + config *Config +} + +// CreateServer creates a service for http handler +func CreateServer(c docker.Client, b packr.Box, config Config) *http.Server { + handler := &handler{ + client: c, + box: b, + config: &config, + } + return &http.Server{Addr: config.Addr, Handler: createRouter(handler)} +} + +func createRouter(h *handler) *mux.Router { + base := h.config.Base r := mux.NewRouter() r.Use(setCSPHeaders) if base != "/" { @@ -54,14 +80,14 @@ func (h *handler) index(w http.ResponseWriter, req *http.Request) { } path := "" - if base != "/" { - path = base + if h.config.Base != "/" { + path = h.config.Base } data := struct { Base string Version string - }{path, version} + }{path, h.config.Version} err = tmpl.Execute(w, data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -102,7 +128,7 @@ func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) { return } - messages, err := h.client.ContainerLogs(r.Context(), container.ID, tailSize, r.Header.Get("Last-Event-ID")) + messages, err := h.client.ContainerLogs(r.Context(), container.ID, h.config.TailSize, r.Header.Get("Last-Event-ID")) w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") @@ -138,6 +164,13 @@ Loop: } log.WithField("NumGoroutine", runtime.NumGoroutine()).Debug("runtime stats") + + if log.IsLevelEnabled(log.DebugLevel) { + var m runtime.MemStats + runtime.ReadMemStats(&m) + // For info on each, see: https://golang.org/pkg/runtime/#MemStats + log.WithField("Alloc KBs", m.Alloc/1024).WithField("TotalAlloc KBs", m.TotalAlloc/1024).WithField("Sys KBs", m.Sys/1024).Debug("runtime mem stats") + } } func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) { @@ -219,7 +252,7 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) { } func (h *handler) version(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, version) + fmt.Fprintln(w, h.config.Version) } func sendContainersJSON(client docker.Client, w http.ResponseWriter) error { diff --git a/main_test.go b/web/routes_test.go similarity index 91% rename from main_test.go rename to web/routes_test.go index acb8be55..33aa9ca2 100644 --- a/main_test.go +++ b/web/routes_test.go @@ -1,4 +1,4 @@ -package main +package web import ( "context" @@ -92,7 +92,7 @@ func Test_handler_streamLogs_happy(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamLogs) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -119,7 +119,7 @@ func Test_handler_streamLogs_happy_with_id(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamLogs) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -146,7 +146,7 @@ func Test_handler_streamLogs_happy_container_stopped(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamLogs) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -165,7 +165,7 @@ func Test_handler_streamLogs_error_finding_container(t *testing.T) { mockedClient := new(MockedClient) mockedClient.On("FindContainer", id).Return(docker.Container{}, errors.New("error finding container")) - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamLogs) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -192,7 +192,7 @@ func Test_handler_streamLogs_error_reading(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamLogs) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -221,7 +221,7 @@ func Test_handler_streamEvents_happy(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamEvents) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -243,7 +243,7 @@ func Test_handler_streamEvents_error(t *testing.T) { close(messages) }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamEvents) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -269,7 +269,7 @@ func Test_handler_streamEvents_error_request(t *testing.T) { cancel() }() - h := handler{client: mockedClient} + h := handler{client: mockedClient, config: &Config{TailSize: 300}} handler := http.HandlerFunc(h.streamEvents) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) @@ -282,7 +282,7 @@ func Test_createRoutes_index(t *testing.T) { box := packr.NewBox("./virtual") require.NoError(t, box.AddString("index.html", "index page"), "AddString should have no error.") - handler := createRoutes("/", &handler{mockedClient, box}) + handler := createRouter(&handler{mockedClient, box, &Config{Base: "/"}}) req, err := http.NewRequest("GET", "/", nil) require.NoError(t, err, "NewRequest should not return an error.") rr := httptest.NewRecorder() @@ -295,7 +295,7 @@ func Test_createRoutes_redirect(t *testing.T) { mockedClient := new(MockedClient) box := packr.NewBox("./virtual") - handler := createRoutes("/foobar", &handler{mockedClient, box}) + handler := createRouter(&handler{mockedClient, box, &Config{Base: "/foobar"}}) req, err := http.NewRequest("GET", "/foobar", nil) require.NoError(t, err, "NewRequest should not return an error.") rr := httptest.NewRecorder() @@ -309,7 +309,7 @@ func Test_createRoutes_foobar(t *testing.T) { box := packr.NewBox("./virtual") require.NoError(t, box.AddString("index.html", "foo page"), "AddString should have no error.") - handler := createRoutes("/foobar", &handler{mockedClient, box}) + handler := createRouter(&handler{mockedClient, box, &Config{Base: "/foobar"}}) req, err := http.NewRequest("GET", "/foobar/", nil) require.NoError(t, err, "NewRequest should not return an error.") rr := httptest.NewRecorder() @@ -323,7 +323,7 @@ func Test_createRoutes_foobar_file(t *testing.T) { box := packr.NewBox("./virtual") require.NoError(t, box.AddString("/test", "test page"), "AddString should have no error.") - handler := createRoutes("/foobar", &handler{mockedClient, box}) + handler := createRouter(&handler{mockedClient, box, &Config{Base: "/foobar"}}) req, err := http.NewRequest("GET", "/foobar/test", nil) require.NoError(t, err, "NewRequest should not return an error.") rr := httptest.NewRecorder() @@ -336,7 +336,7 @@ func Test_createRoutes_version(t *testing.T) { mockedClient := new(MockedClient) box := packr.NewBox("./virtual") - handler := createRoutes("/", &handler{mockedClient, box}) + handler := createRouter(&handler{mockedClient, box, &Config{Base: "/", Version: "dev"}}) req, err := http.NewRequest("GET", "/version", nil) require.NoError(t, err, "NewRequest should not return an error.") rr := httptest.NewRecorder()