Add tests for log module

This commit is contained in:
Ming Deng 2020-09-19 23:04:40 +08:00
parent 2539fe3831
commit a1782cc22d
13 changed files with 370 additions and 44 deletions

View File

@ -63,7 +63,17 @@ func disableEscapeHTML(i interface{}) {
// AccessLog - Format and print access log.
func AccessLog(r *AccessLogRecord, format string) {
var msg string
msg := r.format(format)
lm := &LogMsg{
Msg: strings.TrimSpace(msg),
When: time.Now(),
Level: levelLoggerImpl,
}
beeLogger.writeMsg(lm)
}
func (r *AccessLogRecord) format(format string) string {
msg := ""
switch format {
case apacheFormat:
timeFormatted := r.RequestTime.Format("02/Jan/2006 03:04:05")
@ -79,10 +89,5 @@ func AccessLog(r *AccessLogRecord, format string) {
msg = string(jsonData)
}
}
lm := &LogMsg{
Msg: strings.TrimSpace(msg),
When: time.Now(),
Level: levelLoggerImpl,
}
beeLogger.writeMsg(lm)
return msg
}

View File

@ -0,0 +1,38 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestAccessLog_format(t *testing.T) {
alc := &AccessLogRecord{
RequestTime: time.Date(2020, 9, 19, 21, 21, 21, 11, time.UTC),
}
res := alc.format(apacheFormat)
println(res)
assert.Equal(t, " - - [19/Sep/2020 09:21:21] \" 0 0\" 0.000000 ", res)
res = alc.format(jsonFormat)
assert.Equal(t,
"{\"remote_addr\":\"\",\"request_time\":\"2020-09-19T21:21:21.000000011Z\",\"request_method\":\"\",\"request\":\"\",\"server_protocol\":\"\",\"host\":\"\",\"status\":0,\"body_bytes_sent\":0,\"elapsed_time\":0,\"http_referrer\":\"\",\"http_user_agent\":\"\",\"remote_user\":\"\"}\n", res)
AccessLog(alc, jsonFormat)
}

View File

@ -18,6 +18,9 @@ import (
"net"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// ConnTCPListener takes a TCP listener and accepts n TCP connections
@ -45,6 +48,7 @@ func TestConn(t *testing.T) {
log.Informational("informational")
}
// need to rewrite this test, it's not stable
func TestReconnect(t *testing.T) {
// Setup connection listener
newConns := make(chan net.Conn)
@ -77,3 +81,17 @@ func TestReconnect(t *testing.T) {
t.Error("Did not reconnect")
}
}
func TestConnWriter_Format(t *testing.T) {
lg := &LogMsg{
Level: LevelDebug,
Msg: "Hello, world",
When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
FilePath: "/user/home/main.go",
LineNumber: 13,
Prefix: "Cus",
}
cw := NewConn().(*connWriter)
res := cw.Format(lg)
assert.Equal(t, "[D] Cus Hello, world", res)
}

View File

@ -59,7 +59,7 @@ type consoleWriter struct {
func (c *consoleWriter) Format(lm *LogMsg) string {
msg := lm.OldStyleFormat()
if c.Colorful {
msg = strings.Replace(lm.Msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
msg = strings.Replace(msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
}
h, _, _ := formatTimeHeader(lm.When)
bytes := append(append(h, msg...), '\n')
@ -72,6 +72,10 @@ func (c *consoleWriter) SetFormatter(f LogFormatter) {
// NewConsole creates ConsoleWriter returning as LoggerInterface.
func NewConsole() Logger {
return newConsole()
}
func newConsole() *consoleWriter {
cw := &consoleWriter{
lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)),
Level: LevelDebug,

View File

@ -17,6 +17,8 @@ package logs
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// Try each log level in decreasing order of priority.
@ -62,3 +64,19 @@ func TestConsoleAsync(t *testing.T) {
time.Sleep(1 * time.Millisecond)
}
}
func TestFormat(t *testing.T) {
log := newConsole()
lm := &LogMsg{
Level: LevelDebug,
Msg: "Hello, world",
When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
FilePath: "/user/home/main.go",
LineNumber: 13,
Prefix: "Cus",
}
res := log.Format(lm)
assert.Equal(t, "2020/09/19 20:12:37.000 \x1b[1;44m[D]\x1b[0m Cus Hello, world\n", res)
err := log.WriteMsg(lm)
assert.Nil(t, err)
}

View File

@ -22,6 +22,8 @@ import (
"strconv"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestFilePerm(t *testing.T) {
@ -428,3 +430,18 @@ func BenchmarkFileOnGoroutine(b *testing.B) {
}
os.Remove("test4.log")
}
func TestFileLogWriter_Format(t *testing.T) {
lg := &LogMsg{
Level: LevelDebug,
Msg: "Hello, world",
When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
FilePath: "/user/home/main.go",
LineNumber: 13,
Prefix: "Cus",
}
fw := newFileWriter().(*fileLogWriter)
res := fw.Format(lg)
assert.Equal(t, "2020/09/19 20:12:37.000 [D] Cus Hello, world\n", res)
}

View File

@ -1,11 +1,78 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"encoding/json"
"errors"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type CustomFormatter struct{}
func (c *CustomFormatter) Format(lm *LogMsg) string {
return "hello, msg: " + lm.Msg
}
type TestLogger struct {
Formatter string `json:"formatter"`
Expected string
formatter LogFormatter
}
func (t *TestLogger) Init(config string) error {
er := json.Unmarshal([]byte(config), t)
t.formatter, _ = GetFormatter(t.Formatter)
return er
}
func (t *TestLogger) WriteMsg(lm *LogMsg) error {
msg := t.formatter.Format(lm)
if msg != t.Expected {
return errors.New("not equal")
}
return nil
}
func (t *TestLogger) Destroy() {
panic("implement me")
}
func (t *TestLogger) Flush() {
panic("implement me")
}
func (t *TestLogger) SetFormatter(f LogFormatter) {
panic("implement me")
}
func TestCustomFormatter(t *testing.T) {
RegisterFormatter("custom", &CustomFormatter{})
tl := &TestLogger{
Expected: "hello, msg: world",
}
assert.Nil(t, tl.Init(`{"formatter": "custom"}`))
assert.Nil(t, tl.WriteMsg(&LogMsg{
Msg: "world",
}))
}
func TestPatternLogFormatter(t *testing.T) {
tes := &PatternLogFormatter{
Pattern: "%F:%n|%w%t>> %m",
@ -25,4 +92,4 @@ func TestPatternLogFormatter(t *testing.T) {
if got != want {
t.Errorf("want %s, got %s", want, got)
}
}
}

View File

@ -44,7 +44,9 @@ func (s *JLWriter) Init(config string) error {
}
func (s *JLWriter) Format(lm *LogMsg) string {
return lm.OldStyleFormat()
msg := lm.OldStyleFormat()
msg = fmt.Sprintf("%s %s", lm.When.Format("2006-01-02 15:04:05"), msg)
return msg
}
func (s *JLWriter) SetFormatter(f LogFormatter) {

View File

@ -0,0 +1,65 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type TestHttpHandler struct {
}
func (t *TestHttpHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("coming"))
}
func TestJLWriter_WriteMsg(t *testing.T) {
// start sever
http.Handle("/", &TestHttpHandler{})
go http.ListenAndServe(":12124", nil)
jl := newJLWriter()
jl.Init(`{
"webhookurl":"http://localhost:12124/hello",
"redirecturl":"nil",
"imageurl":"a"
}`)
err := jl.WriteMsg(&LogMsg{
Msg: "world",
})
jl.Flush()
jl.Destroy()
assert.Nil(t, err)
}
func TestJLWriter_Format(t *testing.T) {
lg := &LogMsg{
Level: LevelDebug,
Msg: "Hello, world",
When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
FilePath: "/user/home/main.go",
LineNumber: 13,
Prefix: "Cus",
}
jl := newJLWriter().(*JLWriter)
res := jl.Format(lg)
assert.Equal(t, "2020-09-19 20:12:37 [D] Cus Hello, world", res)
}

View File

@ -37,7 +37,6 @@ import (
"fmt"
"log"
"os"
"path"
"runtime"
"strings"
"sync"
@ -135,18 +134,6 @@ type nameLogger struct {
name string
}
type LogMsg struct {
Level int
Msg string
When time.Time
FilePath string
LineNumber int
Args []interface{}
Prefix string
enableFullFilePath bool
enableFuncCallDepth bool
}
var logMsgPool *sync.Pool
// NewLogger returns a new BeeLogger.
@ -187,27 +174,6 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
return bl
}
// OldStyleFormat you should never invoke this
func (lm *LogMsg) OldStyleFormat() string {
msg := lm.Msg
if len(lm.Args) > 0 {
lm.Msg = fmt.Sprintf(lm.Msg, lm.Args...)
}
msg = lm.Prefix + " " + msg
if lm.enableFuncCallDepth {
if !lm.enableFullFilePath {
_, lm.FilePath = path.Split(lm.FilePath)
}
msg = fmt.Sprintf("[%s:%d] %s", lm.FilePath, lm.LineNumber, msg)
}
msg = levelPrefix[lm.Level] + " " + msg
return msg
}
// SetLogger provides a given logger adapter into BeeLogger with config string.
// config must in in JSON format like {"interval":360}}
func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {

View File

@ -0,0 +1,55 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"fmt"
"path"
"time"
)
type LogMsg struct {
Level int
Msg string
When time.Time
FilePath string
LineNumber int
Args []interface{}
Prefix string
enableFullFilePath bool
enableFuncCallDepth bool
}
// OldStyleFormat you should never invoke this
func (lm *LogMsg) OldStyleFormat() string {
msg := lm.Msg
if len(lm.Args) > 0 {
lm.Msg = fmt.Sprintf(lm.Msg, lm.Args...)
}
msg = lm.Prefix + " " + msg
if lm.enableFuncCallDepth {
filePath := lm.FilePath
if !lm.enableFullFilePath {
_, filePath = path.Split(filePath)
}
msg = fmt.Sprintf("[%s:%d] %s", filePath, lm.LineNumber, msg)
}
msg = levelPrefix[lm.Level] + " " + msg
return msg
}

View File

@ -0,0 +1,44 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestLogMsg_OldStyleFormat(t *testing.T) {
lg := &LogMsg{
Level: LevelDebug,
Msg: "Hello, world",
When: time.Date(2020, 9, 19, 20, 12, 37, 9, time.UTC),
FilePath: "/user/home/main.go",
LineNumber: 13,
Prefix: "Cus",
}
res := lg.OldStyleFormat()
assert.Equal(t, "[D] Cus Hello, world", res)
lg.enableFuncCallDepth = true
res = lg.OldStyleFormat()
assert.Equal(t, "[D] [main.go:13] Cus Hello, world", res)
lg.enableFullFilePath = true
res = lg.OldStyleFormat()
assert.Equal(t, "[D] [/user/home/main.go:13] Cus Hello, world", res)
}

View File

@ -0,0 +1,27 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logs
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestBeeLogger_DelLogger(t *testing.T) {
prefix := "My-Cus"
l := GetLogger(prefix)
assert.NotNil(t, l)
}