Skip to content

Commit

Permalink
Merge pull request #23 from FishGoddess/develop
Browse files Browse the repository at this point in the history
v1.5.4-alpha
  • Loading branch information
FishGoddess authored Dec 18, 2023
2 parents e874f22 + 3cc3695 commit 463e8b6
Show file tree
Hide file tree
Showing 42 changed files with 820 additions and 82 deletions.
3 changes: 2 additions & 1 deletion FUTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
* [x] 完善示例代码
* [x] 增加属性解析器适配功能
* [x] 优化 handler 和 writer 设计
* [ ] 增加一个适合查看的 handler 实现
* [x] 增加一个高可读性且高性能的 handler 实现
* [x] TapeHandler 转义处理
* [ ] 提高单元测试覆盖率到 70%
* [ ] 进一步提高单元测试覆盖率到 80%

Expand Down
13 changes: 10 additions & 3 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@

### v1.5.5-alpha (Coming soon)

> 此版本发布于 2023-12-20
> 此版本发布于 2023-12-25
* 增加一个适合查看的 handler 实现
* 提高单元测试覆盖率到 70%
* 继续优化代码,包括设计和质量
* 完善单元测试,提高覆盖率到 70%

### v1.5.4-alpha

> 此版本发布于 2023-12-18
* 增加一个高可读性且高性能的 handler 实现 —— TapeHandler
* 新的 tape handler 性能提升了 33%,且 print 类函数性能提升了 50%

### v1.5.3-alpha

Expand Down
13 changes: 7 additions & 6 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,19 @@ goos: linux
goarch: amd64
cpu: AMD EPYC 7K62 48-Core Processor

BenchmarkLogitLoggerTextHandler-2 1000000 1089 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 800017 1437 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 751623 1567 ns/op 48 B/op 1 allocs/op
BenchmarkLogitLogger-2 1486184 810 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerTextHandler-2 1000000 1080 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 847864 1393 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 1222302 981 ns/op 48 B/op 1 allocs/op
BenchmarkSlogLoggerTextHandler-2 725522 1629 ns/op 0 B/op 0 allocs/op
BenchmarkSlogLoggerJsonHandler-2 583214 2030 ns/op 120 B/op 3 allocs/op
BenchmarkZeroLogLogger-2 1929276 613 ns/op 0 B/op 0 allocs/op
BenchmarkZapLogger-2 976855 1168 ns/op 216 B/op 2 allocs/op
BenchmarkLogrusLogger-2 231723 4927 ns/op 2080 B/op 32 allocs/op

BenchmarkLogitFile-2 454489 2366 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1038120 1154 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1026002 1179 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFile-2 624774 1935 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1378076 873 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1367479 883 ns/op 0 B/op 0 allocs/op
BenchmarkSlogFile-2 407590 2944 ns/op 0 B/op 0 allocs/op
BenchmarkZeroLogFile-2 634375 1810 ns/op 0 B/op 0 allocs/op
BenchmarkZapFile-2 382790 2641 ns/op 216 B/op 2 allocs/op
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,19 @@ goos: linux
goarch: amd64
cpu: AMD EPYC 7K62 48-Core Processor

BenchmarkLogitLoggerTextHandler-2 1000000 1089 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 800017 1437 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 751623 1567 ns/op 48 B/op 1 allocs/op
BenchmarkLogitLogger-2 1486184 810 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerTextHandler-2 1000000 1080 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 847864 1393 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 1222302 981 ns/op 48 B/op 1 allocs/op
BenchmarkSlogLoggerTextHandler-2 725522 1629 ns/op 0 B/op 0 allocs/op
BenchmarkSlogLoggerJsonHandler-2 583214 2030 ns/op 120 B/op 3 allocs/op
BenchmarkZeroLogLogger-2 1929276 613 ns/op 0 B/op 0 allocs/op
BenchmarkZapLogger-2 976855 1168 ns/op 216 B/op 2 allocs/op
BenchmarkLogrusLogger-2 231723 4927 ns/op 2080 B/op 32 allocs/op

BenchmarkLogitFile-2 454489 2366 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1038120 1154 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1026002 1179 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFile-2 624774 1935 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1378076 873 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1367479 883 ns/op 0 B/op 0 allocs/op
BenchmarkSlogFile-2 407590 2944 ns/op 0 B/op 0 allocs/op
BenchmarkZeroLogFile-2 634375 1810 ns/op 0 B/op 0 allocs/op
BenchmarkZapFile-2 382790 2641 ns/op 216 B/op 2 allocs/op
Expand Down
2 changes: 1 addition & 1 deletion _examples/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package main

import (
"github.com/FishGoddess/logit"
"github.com/FishGoddess/logit/rotate"
"github.com/FishGoddess/logit/core/rotate"
)

func main() {
Expand Down
9 changes: 5 additions & 4 deletions _examples/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@ import (
"log/slog"

"github.com/FishGoddess/logit"
"github.com/FishGoddess/logit/core/handler"
)

func main() {
// By default, logit uses text handler to output logs.
// By default, logit uses tape handler to output logs.
logger := logit.NewLogger()
logger.Info("default handler is text")
logger.Info("default handler logging")

// You can change it to other handlers by options.
// For example, use json handler:
logger = logit.NewLogger(logit.WithJsonHandler())
logger.Info("using json handler")

// Or you want to use customized handlers, try RegisterHandler.
// Or you want to use customized handlers, try Register.
newHandler := func(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return slog.NewTextHandler(w, opts)
}

if err := logit.RegisterHandler("demo", newHandler); err != nil {
if err := handler.Register("demo", newHandler); err != nil {
panic(err)
}

Expand Down
2 changes: 1 addition & 1 deletion _examples/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func main() {

// Change logger handler:
logit.WithHandler("xxx")
logit.WithTapeHandler()
logit.WithTextHandler()
logit.WithJsonHandler()

Expand All @@ -50,7 +51,6 @@ func main() {

// More options can be found in logit package which have prefix "With".
// What's more? We provide a options pack that we think it's useful in production.
// It outputs logs to a rotate file using batch write, so you should call Sync() or Close() when shutdown.
opts := logit.ProductionOptions()

logger = logit.NewLogger(opts...)
Expand Down
37 changes: 27 additions & 10 deletions _examples/performance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,41 @@ goos: linux
goarch: amd64
cpu: AMD EPYC 7K62 48-Core Processor
BenchmarkLogitLoggerTextHandler-2 1000000 1089 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 800017 1437 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 751623 1567 ns/op 48 B/op 1 allocs/op
BenchmarkLogitLogger-2 1486184 810 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerTextHandler-2 1000000 1080 ns/op 0 B/op 0 allocs/op
BenchmarkLogitLoggerJsonHandler-2 847864 1393 ns/op 120 B/op 3 allocs/op
BenchmarkLogitLoggerPrint-2 1222302 981 ns/op 48 B/op 1 allocs/op
BenchmarkSlogLoggerTextHandler-2 725522 1629 ns/op 0 B/op 0 allocs/op
BenchmarkSlogLoggerJsonHandler-2 583214 2030 ns/op 120 B/op 3 allocs/op
BenchmarkZeroLogLogger-2 1929276 613 ns/op 0 B/op 0 allocs/op
BenchmarkZapLogger-2 976855 1168 ns/op 216 B/op 2 allocs/op
BenchmarkLogrusLogger-2 231723 4927 ns/op 2080 B/op 32 allocs/op
BenchmarkLogitFile-2 454489 2366 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1038120 1154 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1026002 1179 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFile-2 624774 1935 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBuffer-2 1378076 873 ns/op 0 B/op 0 allocs/op
BenchmarkLogitFileWithBatch-2 1367479 883 ns/op 0 B/op 0 allocs/op
BenchmarkSlogFile-2 407590 2944 ns/op 0 B/op 0 allocs/op
BenchmarkZeroLogFile-2 634375 1810 ns/op 0 B/op 0 allocs/op
BenchmarkZapFile-2 382790 2641 ns/op 216 B/op 2 allocs/op
BenchmarkLogrusFile-2 174944 6491 ns/op 2080 B/op 32 allocs/op
*/

// go test -v ./_examples/performance_test.go -bench=^BenchmarkLogitLogger$ -benchtime=1s
func BenchmarkLogitLogger(b *testing.B) {
logger := logit.NewLogger(
logit.WithInfoLevel(),
logit.WithTapeHandler(),
logit.WithWriter(io.Discard),
)

b.ReportAllocs()
b.StartTimer()

for i := 0; i < b.N; i++ {
logger.Info("info...", "trace", "xxx", "id", 123, "pi", 3.14)
}
}

// go test -v ./_examples/performance_test.go -bench=^BenchmarkLogitLoggerTextHandler$ -benchtime=1s
func BenchmarkLogitLoggerTextHandler(b *testing.B) {
logger := logit.NewLogger(
Expand Down Expand Up @@ -90,7 +107,7 @@ func BenchmarkLogitLoggerJsonHandler(b *testing.B) {
func BenchmarkLogitLoggerPrint(b *testing.B) {
logger := logit.NewLogger(
logit.WithInfoLevel(),
logit.WithTextHandler(),
logit.WithTapeHandler(),
logit.WithWriter(io.Discard),
)

Expand Down Expand Up @@ -209,7 +226,7 @@ func BenchmarkLogitFile(b *testing.B) {

logger := logit.NewLogger(
logit.WithInfoLevel(),
logit.WithTextHandler(),
logit.WithTapeHandler(),
logit.WithFile(path),
)

Expand All @@ -227,7 +244,7 @@ func BenchmarkLogitFileWithBuffer(b *testing.B) {

logger := logit.NewLogger(
logit.WithInfoLevel(),
logit.WithTextHandler(),
logit.WithTapeHandler(),
logit.WithFile(path),
logit.WithBuffer(65536),
)
Expand All @@ -248,7 +265,7 @@ func BenchmarkLogitFileWithBatch(b *testing.B) {

logger := logit.NewLogger(
logit.WithInfoLevel(),
logit.WithTextHandler(),
logit.WithTapeHandler(),
logit.WithFile(path),
logit.WithBatch(64),
)
Expand Down
4 changes: 2 additions & 2 deletions _icons/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"log/slog"
"os"
"time"

"github.com/FishGoddess/logit/core/handler"
)

type nilSyncer struct{}
Expand Down Expand Up @@ -55,7 +57,7 @@ func newDefaultConfig() *config {

conf := &config{
level: slog.LevelDebug,
handler: handlerText,
handler: handler.Tape,
newWriter: newWriter,
wrapWriter: nil,
replaceAttr: nil,
Expand Down Expand Up @@ -102,7 +104,7 @@ func (c *config) newHandlerOptions() *slog.HandlerOptions {
}

func (c *config) newHandler() (slog.Handler, Syncer, io.Closer, error) {
newHandler, err := getHandlerFunc(c.handler)
newHandler, err := handler.Get(c.handler)
if err != nil {
return nil, nil, nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"log/slog"
"os"
"testing"

"github.com/FishGoddess/logit/core/handler"
)

type testConfigHandler struct {
Expand Down Expand Up @@ -58,7 +60,7 @@ func TestConfigNewHandlerOptions(t *testing.T) {
func TestConfigNewHandler(t *testing.T) {
handlerName := t.Name()

RegisterHandler(handlerName, func(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
handler.Register(handlerName, func(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return &testConfigHandler{
w: w,
opts: *opts,
Expand Down
44 changes: 44 additions & 0 deletions core/handler/buffer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 FishGoddess. All Rights Reserved.
//
// 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 handler

import (
"sync"

"github.com/FishGoddess/logit/defaults"
)

var bufferPool = sync.Pool{
New: func() any {
bs := make([]byte, 0, defaults.MinBufferSize)
return &buffer{bs: bs}
},
}

type buffer struct {
bs []byte
}

func newBuffer() *buffer {
return bufferPool.Get().(*buffer)
}

func freeBuffer(buffer *buffer) {
// Return only smaller buffers for reducing peak allocation.
if cap(buffer.bs) <= defaults.MaxBufferSize {
buffer.bs = buffer.bs[:0]
bufferPool.Put(buffer)
}
}
47 changes: 47 additions & 0 deletions core/handler/buffer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2023 FishGoddess. All Rights Reserved.
//
// 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 handler

import (
"testing"

"github.com/FishGoddess/logit/defaults"
)

// go test -v -cover -count=1 -test.cpu=1 -run=^TestNewBuffer$
func TestBufferPool(t *testing.T) {
for i := 0; i < 100; i++ {
bs := make([]byte, 0, 2*defaults.MaxBufferSize)
buffer := &buffer{bs: bs}
freeBuffer(buffer)
}

for i := 0; i < 100; i++ {
buffer := newBuffer()
bs := buffer.bs

if len(bs) != 0 {
t.Fatalf("len %d of buffer is wrong", len(bs))
}

if cap(bs) < defaults.MinBufferSize {
t.Fatalf("cap %d of buffer too small", cap(bs))
}

if cap(bs) > defaults.MaxBufferSize {
t.Fatalf("cap %d of buffer too large", cap(bs))
}
}
}
Loading

0 comments on commit 463e8b6

Please sign in to comment.