본문 바로가기

GO lang

[GO] Decorator - 심화(log pattern)

 

main.go

 

package main

import (
	"GO/tuckersGo/goWeb/web10/decoHandler"
	"GO/tuckersGo/goWeb/web10/myapp"
	"log"
	"net/http"
	"time"
)

const portNumber = ":3000"

func logger1(w http.ResponseWriter, r *http.Request, h http.Handler) {
	start := time.Now()
	log.Printf("[LOGGER1] Started\n")
	h.ServeHTTP(w, r)
	log.Printf("[LOGGER1] Completed, time: %v ms\n", time.Since(start).Milliseconds())
}

func logger2(w http.ResponseWriter, r *http.Request, h http.Handler) {
	start := time.Now()
	log.Printf("[LOGGER2] Started\n")
	h.ServeHTTP(w, r)
	log.Printf("[LOGGER2] Completed, time: %v ms\n", time.Since(start).Milliseconds())
}

func NewHandler() http.Handler {
	mux := myapp.NewHttpHandler()
	mux = decoHandler.NewDecoHandler(mux, logger1)
	mux = decoHandler.NewDecoHandler(mux, logger2)
	return mux
}

func main() {
	mux := NewHandler()

	http.ListenAndServe(portNumber, mux)
}

 

./myapp/app.go

 

package myapp

import (
	"fmt"
	"net/http"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World")
}

func NewHttpHandler() http.Handler {
	mux := http.NewServeMux()
	mux.HandleFunc("/", indexHandler)
	return mux
}

 

./decoHandler/deco.go - 이해가 가지만 손코딩은 아직.. 이해가 

 

package decoHandler

import "net/http"

type DecoratorFunc func(http.ResponseWriter, *http.Request, http.Handler)

type DecoHandler struct {
	fn DecoratorFunc
	h  http.Handler
}

func (self *DecoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	self.fn(w, r, self.h)
}

func NewDecoHandler(h http.Handler, fn DecoratorFunc) http.Handler {
	return &DecoHandler{
		fn: fn,
		h:  h,
	}
}

 

main_test.go - buffer 에 데이터를 넣고 꺼내기.

 

package main

import (
	"bufio"
	"bytes"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestIndexPage(t *testing.T) {
	assert := assert.New(t)

	ts := httptest.NewServer(NewHandler())
	defer ts.Close()

	resp, err := http.Get(ts.URL)
	assert.NoError(err)
	assert.Equal(http.StatusOK, resp.StatusCode)
	data, _ := ioutil.ReadAll(resp.Body)
	assert.Equal("Hello World", string(data))
}

func TestDecoHandler(t *testing.T) {
	assert := assert.New(t)

	ts := httptest.NewServer(NewHandler())
	defer ts.Close()

	buf := &bytes.Buffer{}
	log.SetOutput(buf)

	resp, err := http.Get(ts.URL)
	assert.NoError(err)
	assert.Equal(http.StatusOK, resp.StatusCode)

	r := bufio.NewReader(buf)
	line, _, err := r.ReadLine()
	assert.NoError(err)
	assert.Contains(string(line), "[LOGGER2] Start")

	line, _, err = r.ReadLine()
	assert.NoError(err)
	assert.Contains(string(line), "[LOGGER1] Start")

	line, _, err = r.ReadLine()
	assert.NoError(err)
	assert.Contains(string(line), "[LOGGER1] Complete")
}

 

PS D:\workspace\GO\tuckersGo\goWeb\web10> go test
2021/11/11 16:22:33 [LOGGER2] Started
2021/11/11 16:22:34 [LOGGER1] Started
2021/11/11 16:22:34 [LOGGER1] Completed, time: 0 ms
2021/11/11 16:22:34 [LOGGER2] Completed, time: 36 ms
PASS
ok      GO/tuckersGo/goWeb/web10        0.157s
PS D:\workspace\GO\tuckersGo\goWeb\web10>

'GO lang' 카테고리의 다른 글

[GO] Decorator 패턴  (0) 2021.11.06
[GO] Scrapping(2) - Echo server  (0) 2021.10.15
[GO] Scrapping(1) - URL checker  (0) 2021.10.07
[GO] channel  (0) 2021.10.07
[GO] 고루틴  (0) 2021.10.07