mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 00:00:54 +00:00
commit
b027968c0b
@ -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
|
||||
}
|
38
pkg/infrastructure/logs/access_log_test.go
Normal file
38
pkg/infrastructure/logs/access_log_test.go
Normal 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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
36
pkg/infrastructure/logs/jianliao_test.go
Normal file
36
pkg/infrastructure/logs/jianliao_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
// 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 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)
|
||||
}
|
@ -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 {
|
||||
|
55
pkg/infrastructure/logs/log_msg.go
Normal file
55
pkg/infrastructure/logs/log_msg.go
Normal 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
|
||||
}
|
44
pkg/infrastructure/logs/log_msg_test.go
Normal file
44
pkg/infrastructure/logs/log_msg_test.go
Normal 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)
|
||||
}
|
27
pkg/infrastructure/logs/log_test.go
Normal file
27
pkg/infrastructure/logs/log_test.go
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user