feat: 日志简化,改用 zap 库

This commit is contained in:
tiglog 2023-08-12 20:03:19 +08:00
parent 9742dccdfa
commit 29151e240d
15 changed files with 367 additions and 385 deletions

13
go.mod
View File

@ -9,18 +9,19 @@ require (
github.com/go-sql-driver/mysql v1.7.1
github.com/hibiken/asynq v0.24.1
github.com/jmoiron/sqlx v1.3.5
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lib/pq v1.10.9
github.com/mattn/go-runewidth v0.0.14
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/pkg/errors v0.9.1
github.com/rs/xid v1.5.0
github.com/rs/zerolog v1.29.1
go.mongodb.org/mongo-driver v1.11.7
go.uber.org/zap v1.25.0
golang.org/x/crypto v0.10.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
@ -35,17 +36,17 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/redis/go-redis/v9 v9.0.3 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
@ -56,6 +57,7 @@ require (
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
@ -63,6 +65,5 @@ require (
golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

31
go.sum
View File

@ -1,7 +1,6 @@
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
@ -16,7 +15,6 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -43,7 +41,6 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@ -62,6 +59,8 @@ github.com/hibiken/asynq v0.24.1 h1:+5iIEAyA9K/lcSPvx3qoPtsKJeKI5u9aOIvUmSsazEw=
github.com/hibiken/asynq v0.24.1/go.mod h1:u5qVeSbrnfT+vtG5Mq8ZPzQu/BmCKMHvTGb91uy9Tts=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
@ -72,16 +71,19 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
@ -95,8 +97,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
@ -112,11 +112,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -149,8 +146,12 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@ -178,8 +179,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -1,53 +0,0 @@
//
// access.go
// Copyright (C) 2022 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"os"
"sync"
"github.com/natefinch/lumberjack"
"github.com/rs/zerolog"
)
var access_once sync.Once
var access_log *zerolog.Logger
var access_log_path = "./var/log/access.log"
func SetupAccessLogFile(path string) {
access_log_path = path
}
func Access() *zerolog.Logger {
access_once.Do(func() {
fileLogger := &lumberjack.Logger{
Filename: access_log_path,
MaxSize: 5, //
MaxBackups: 10,
MaxAge: 14,
Compress: true,
}
output := zerolog.MultiLevelWriter(os.Stderr, fileLogger)
l := zerolog.New(output).
Level(loggerLevel).
With().
Timestamp().
Stack().
CallerWithSkipFrameCount(2).
Logger()
access_log = &l
})
return access_log
}

View File

@ -1,53 +0,0 @@
//
// console.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"os"
"sync"
"github.com/natefinch/lumberjack"
"github.com/rs/zerolog"
)
var console_once sync.Once
var console_log *zerolog.Logger
var console_log_path = "./var/log/console.log"
func SetupConsoleLogFile(path string) {
access_log_path = path
}
func Console() *zerolog.Logger {
console_once.Do(func() {
fileLogger := &lumberjack.Logger{
Filename: console_log_path,
MaxSize: 5, //
MaxBackups: 10,
MaxAge: 14,
Compress: true,
}
output := zerolog.MultiLevelWriter(os.Stderr, fileLogger)
l := zerolog.New(output).
Level(loggerLevel).
With().
Timestamp().
Stack().
CallerWithSkipFrameCount(2).
Logger()
console_log = &l
})
return console_log
}

62
logger/field.go Normal file
View File

@ -0,0 +1,62 @@
//
// field.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import "go.uber.org/zap"
var (
Skip = zap.Skip
Binary = zap.Binary
Bool = zap.Bool
Boolp = zap.Boolp
ByteString = zap.ByteString
Complex128 = zap.Complex128
Complex128p = zap.Complex128p
Complex64 = zap.Complex64
Complex64p = zap.Complex64p
Float64 = zap.Float64
Float64p = zap.Float64p
Float32 = zap.Float32
Float32p = zap.Float32p
Int = zap.Int
Intp = zap.Intp
Int64 = zap.Int64
Int64p = zap.Int64p
Int32 = zap.Int32
Int32p = zap.Int32p
Int16 = zap.Int16
Int16p = zap.Int16p
Int8 = zap.Int8
Int8p = zap.Int8p
String = zap.String
Stringp = zap.Stringp
Uint = zap.Uint
Uintp = zap.Uintp
Uint64 = zap.Uint64
Uint64p = zap.Uint64p
Uint32 = zap.Uint32
Uint32p = zap.Uint32p
Uint16 = zap.Uint16
Uint16p = zap.Uint16p
Uint8 = zap.Uint8
Uint8p = zap.Uint8p
Uintptr = zap.Uintptr
Uintptrp = zap.Uintptrp
Reflect = zap.Reflect
Namespace = zap.Namespace
Stringer = zap.Stringer
Time = zap.Time
Timep = zap.Timep
Stack = zap.Stack
StackSkip = zap.StackSkip
Duration = zap.Duration
Durationp = zap.Durationp
Object = zap.Object
Inline = zap.Inline
Any = zap.Any
)

View File

@ -1,46 +0,0 @@
//
// init.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"path/filepath"
"strconv"
"strings"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/pkgerrors"
)
var loggerLevel = zerolog.InfoLevel
func init() {
// zerolog.ErrorStackMarshaler = func(err error) interface{} {
// return pkgerrors.MarshalStack(errors.Wrap(err, "wrap"))
// }
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
zerolog.TimeFieldFormat = time.RFC3339
zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
new_files := strings.Split(file, "/")
l := len(new_files)
pos := 0
var new_file string
if l-3 > 0 {
pos = l - 3
new_file = strings.Join(new_files[pos:], "/")
} else {
new_file = filepath.Base(file)
}
return new_file + ":" + strconv.Itoa(line)
}
}
func SetLevel(level zerolog.Level) {
loggerLevel = level
}

View File

@ -8,70 +8,98 @@
package logger
import (
"io"
"os"
"sync"
"github.com/natefinch/lumberjack"
"github.com/rs/zerolog"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var once sync.Once
type Level = zapcore.Level
var log_path = "./var/log/app.log"
const (
DebugLevel = zapcore.DebugLevel
InfoLevel = zapcore.InfoLevel
WarnLevel = zapcore.WarnLevel
ErrorLevel = zapcore.ErrorLevel
PanicLevel = zapcore.PanicLevel
FatalLevel = zapcore.FatalLevel
)
func SetLogPath(path string) {
log_path = path
type Logger struct {
l *zap.Logger
// https://pkg.go.dev/go.uber.org/zap#example-AtomicLevel
al *zap.AtomicLevel
}
var log *zerolog.Logger
func New(out io.Writer, level Level, opts ...Option) *Logger {
if out == nil {
out = os.Stderr
}
func Get() *zerolog.Logger {
once.Do(func() {
al := zap.NewAtomicLevelAt(level)
cfg := zap.NewProductionEncoderConfig()
cfg.EncodeTime = zapcore.RFC3339TimeEncoder
fileLogger := &lumberjack.Logger{
Filename: log_path,
MaxSize: 5, //
MaxBackups: 10,
MaxAge: 14,
Compress: true,
}
output := zerolog.MultiLevelWriter(os.Stderr, fileLogger)
l := zerolog.New(output).
Level(loggerLevel).
With().
Timestamp().
Stack().
CallerWithSkipFrameCount(2).
Logger()
log = &l
})
return log
core := zapcore.NewCore(
zapcore.NewJSONEncoder(cfg),
zapcore.AddSync(out),
al,
)
return &Logger{l: zap.New(core, opts...), al: &al}
}
func Debug(msg string) {
Get().Debug().Msg(msg)
// SetLevel 动态更改日志级别
// 对于使用 NewTee 创建的 Logger 无效,因为 NewTee 本意是根据不同日志级别
// 创建的多个 zap.Core不应该通过 SetLevel 将多个 zap.Core 日志级别统一
func (l *Logger) SetLevel(level Level) {
if l.al != nil {
l.al.SetLevel(level)
}
}
func Debugf(format string, v ...interface{}) {
Get().Debug().Msgf(format, v...)
type Field = zap.Field
func (l *Logger) Debug(msg string, fields ...Field) {
l.l.Debug(msg, fields...)
}
func Info(msg string) {
Get().Info().Msg(msg)
func (l *Logger) Info(msg string, fields ...Field) {
l.l.Info(msg, fields...)
}
func Infof(format string, v ...interface{}) {
Get().Info().Msgf(format, v...)
func (l *Logger) Warn(msg string, fields ...Field) {
l.l.Warn(msg, fields...)
}
func Warn(msg string) {
Get().Warn().Msg(msg)
func (l *Logger) Error(msg string, fields ...Field) {
l.l.Error(msg, fields...)
}
func Warnf(format string, v ...interface{}) {
Get().Warn().Msgf(format, v...)
func (l *Logger) Panic(msg string, fields ...Field) {
l.l.Panic(msg, fields...)
}
func Error(msg string) {
Get().Error().Msg(msg)
func (l *Logger) Fatal(msg string, fields ...Field) {
l.l.Fatal(msg, fields...)
}
func Errorf(format string, v ...interface{}) {
Get().Error().Msgf(format, v...)
func (l *Logger) Sync() error {
return l.l.Sync()
}
var std = New(os.Stderr, InfoLevel)
func Default() *Logger { return std }
func ReplaceDefault(l *Logger) { std = l }
func SetLevel(level Level) { std.SetLevel(level) }
func Debug(msg string, fields ...Field) { std.Debug(msg, fields...) }
func Info(msg string, fields ...Field) { std.Info(msg, fields...) }
func Warn(msg string, fields ...Field) { std.Warn(msg, fields...) }
func Error(msg string, fields ...Field) { std.Error(msg, fields...) }
func Panic(msg string, fields ...Field) { std.Panic(msg, fields...) }
func Fatal(msg string, fields ...Field) { std.Fatal(msg, fields...) }
func Sync() error { return std.Sync() }

View File

@ -36,10 +36,10 @@ func outer() error {
}
func TestLogToFile(t *testing.T) {
// logger.SetupLog("./var/log/test.log", zerolog.DebugLevel)
var log = logger.Get()
gtest.NotNil(t, log)
log := logger.New(logger.NewProductionRotateBySize("./var/log/test.log"), logger.DebugLevel)
defer log.Sync()
gtest.NotNil(t, logger.Default())
err := outer()
log.Error().Err(err).Msg("hello world")
log.Info().Msg("中华人民共和国")
log.Error("hello world", logger.Any("err", err))
log.Info("中华人民共和国")
}

27
logger/options.go Normal file
View File

@ -0,0 +1,27 @@
//
// options.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import "go.uber.org/zap"
type Option = zap.Option
var (
WrapCore = zap.WrapCore
Hooks = zap.Hooks
Fields = zap.Fields
ErrorOutput = zap.ErrorOutput
Development = zap.Development
AddCaller = zap.AddCaller
WithCaller = zap.WithCaller
AddCallerSkip = zap.AddCallerSkip
AddStacktrace = zap.AddStacktrace
IncreaseLevel = zap.IncreaseLevel
WithFatalHook = zap.WithFatalHook
WithClock = zap.WithClock
)

View File

@ -1,53 +0,0 @@
//
// recover.go
// Copyright (C) 2022 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"os"
"sync"
"github.com/natefinch/lumberjack"
"github.com/rs/zerolog"
)
var recover_once sync.Once
var recover_log *zerolog.Logger
var recover_log_path = "./var/log/recover.log"
func SetupRecoverLogFile(path string) {
recover_log_path = path
}
func Recover() *zerolog.Logger {
recover_once.Do(func() {
fileLogger := &lumberjack.Logger{
Filename: recover_log_path,
MaxSize: 5, //
MaxBackups: 10,
MaxAge: 14,
Compress: true,
}
output := zerolog.MultiLevelWriter(os.Stderr, fileLogger)
l := zerolog.New(output).
// Level(zerolog.InfoLevel).
With().
Timestamp().
Stack().
CallerWithSkipFrameCount(2).
Logger()
recover_log = &l
})
return recover_log
}

84
logger/rotate.go Normal file
View File

@ -0,0 +1,84 @@
//
// rotate.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"io"
"strings"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"gopkg.in/natefinch/lumberjack.v2"
)
type RotateConfig struct {
// 共用配置
Filename string // 完整文件名
MaxAge int // 保留旧日志文件的最大天数
// 按时间轮转配置
RotationTime time.Duration // 日志文件轮转时间
// 按大小轮转配置
MaxSize int // 日志文件最大大小MB
MaxBackups int // 保留日志文件的最大数量
Compress bool // 是否对日志文件进行压缩归档
LocalTime bool // 是否使用本地时间,默认 UTC 时间
}
// NewProductionRotateByTime 创建按时间轮转的 io.Writer
func NewProductionRotateByTime(filename string) io.Writer {
return NewRotateByTime(NewProductionRotateConfig(filename))
}
// NewProductionRotateBySize 创建按大小轮转的 io.Writer
func NewProductionRotateBySize(filename string) io.Writer {
return NewRotateBySize(NewProductionRotateConfig(filename))
}
func NewProductionRotateConfig(filename string) *RotateConfig {
return &RotateConfig{
Filename: filename,
MaxAge: 30, // 日志保留 30 天
RotationTime: time.Hour * 24, // 24 小时轮转一次
MaxSize: 100, // 100M
MaxBackups: 100,
Compress: true,
LocalTime: false,
}
}
func NewRotateByTime(cfg *RotateConfig) io.Writer {
opts := []rotatelogs.Option{
rotatelogs.WithMaxAge(time.Duration(cfg.MaxAge) * time.Hour * 24),
rotatelogs.WithRotationTime(cfg.RotationTime),
rotatelogs.WithLinkName(cfg.Filename),
}
if !cfg.LocalTime {
rotatelogs.WithClock(rotatelogs.UTC)
}
filename := strings.SplitN(cfg.Filename, ".", 2)
l, _ := rotatelogs.New(
filename[0]+".%Y-%m-%d-%H-%M-%S."+filename[1],
opts...,
)
return l
}
func NewRotateBySize(cfg *RotateConfig) io.Writer {
return &lumberjack.Logger{
Filename: cfg.Filename,
MaxSize: cfg.MaxSize,
MaxAge: cfg.MaxAge,
MaxBackups: cfg.MaxBackups,
LocalTime: cfg.LocalTime,
Compress: cfg.Compress,
}
}

39
logger/tee.go Normal file
View File

@ -0,0 +1,39 @@
//
// tee.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"io"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type LevelEnablerFunc func(Level) bool
type TeeOption struct {
Out io.Writer
LevelEnablerFunc
}
// NewTee 根据日志级别写入多个输出
// https://pkg.go.dev/go.uber.org/zap#example-package-AdvancedConfiguration
func NewTee(tees []TeeOption, opts ...Option) *Logger {
var cores []zapcore.Core
for _, tee := range tees {
cfg := zap.NewProductionEncoderConfig()
cfg.EncodeTime = zapcore.RFC3339TimeEncoder
core := zapcore.NewCore(
zapcore.NewJSONEncoder(cfg),
zapcore.AddSync(tee.Out),
zap.LevelEnablerFunc(tee.LevelEnablerFunc),
)
cores = append(cores, core)
}
return &Logger{l: zap.New(zapcore.NewTee(cores...), opts...)}
}

View File

@ -1,52 +0,0 @@
//
// work.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package logger
import (
"os"
"sync"
"github.com/natefinch/lumberjack"
"github.com/rs/zerolog"
)
var work_once sync.Once
var work_log *zerolog.Logger
var work_log_path = "./var/log/work.log"
func SetupWorkLogFile(path string) {
access_log_path = path
}
func Work() *zerolog.Logger {
work_once.Do(func() {
fileLogger := &lumberjack.Logger{
Filename: work_log_path,
MaxSize: 5, //
MaxBackups: 10,
MaxAge: 14,
Compress: true,
}
output := zerolog.MultiLevelWriter(os.Stderr, fileLogger)
l := zerolog.New(output).
Level(loggerLevel).
With().
Timestamp().
Stack().
CallerWithSkipFrameCount(2).
Logger()
work_log = &l
})
return work_log
}

View File

@ -8,59 +8,41 @@
package middleware
import (
"bytes"
"io"
"io/ioutil"
"fmt"
"time"
"github.com/gin-gonic/gin"
"git.hexq.cn/tiglog/golib/logger"
"github.com/gin-gonic/gin"
)
func GinLogger() gin.HandlerFunc {
log := logger.Access()
func GinLogger(logfile string) gin.HandlerFunc {
log := logger.New(logger.NewProductionRotateBySize(logfile), logger.InfoLevel)
defer log.Sync()
return func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
raw := c.Request.URL.RawQuery
latency := time.Since(start)
// 处理请求
// Process request
c.Next()
clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
comment := c.Errors.ByType(gin.ErrorTypePrivate).String()
if raw != "" {
path = path + "?" + raw
// Stop timer
stop := time.Now()
latency := stop.Sub(start)
if latency > time.Minute {
latency = latency.Truncate(time.Second)
}
l := log.Log()
if comment != "" {
l = log.Error()
}
var buf bytes.Buffer
tee := io.TeeReader(c.Request.Body, &buf)
requestBody, _ := ioutil.ReadAll(tee)
c.Request.Body = ioutil.NopCloser(&buf)
l.
Str("proto", c.Request.Proto).
Str("server_name", c.Request.Host).
Str("content_type", c.Request.Header.Get("Content-Type")).
Str("user_agent", c.Request.UserAgent()).
Str("method", method).
Str("path", path).
Int("status_code", statusCode).
Str("client_ip", clientIP).
Dur("latency", latency)
if gin.IsDebugging() {
l.Str("content", string(requestBody))
}
l.Msg(comment)
log.Info("GIN request",
logger.String("start", start.Format(time.RFC3339)),
logger.Int("status", c.Writer.Status()),
logger.String("latency", fmt.Sprintf("%s", latency)),
logger.String("method", c.Request.Method),
logger.String("path", path),
logger.String("query", raw),
logger.String("clientIP", c.ClientIP()),
logger.String("userAgent", c.Request.UserAgent()),
logger.String("error", c.Errors.ByType(gin.ErrorTypePrivate).String()),
)
}
}

View File

@ -8,19 +8,21 @@
package middleware
import (
"errors"
"net"
"net/http"
"net/http/httputil"
"os"
"strings"
"time"
"git.hexq.cn/tiglog/golib/helper"
"git.hexq.cn/tiglog/golib/logger"
"github.com/gin-gonic/gin"
)
func GinRecover() gin.HandlerFunc {
var log = logger.Recover()
func GinRecover(logfile string) gin.HandlerFunc {
log := logger.New(logger.NewProductionRotateBySize(logfile), logger.ErrorLevel)
defer log.Sync()
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
@ -28,27 +30,42 @@ func GinRecover() gin.HandlerFunc {
// condition that warrants a panic stack trace.
var brokenPipe bool
if ne, ok := err.(*net.OpError); ok {
if se, ok := ne.Err.(*os.SyscallError); ok {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") ||
strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
var se *os.SyscallError
if errors.As(ne, &se) {
seStr := strings.ToLower(se.Error())
if strings.Contains(seStr, "broken pipe") ||
strings.Contains(seStr, "connection reset by peer") {
brokenPipe = true
}
}
}
httpRequest, _ := httputil.DumpRequest(c.Request, false)
headers := strings.Split(string(httpRequest), "\r\n")
for idx, header := range headers {
current := strings.Split(header, ":")
if current[0] == "Authorization" {
headers[idx] = current[0] + ": *"
}
}
headersToStr := strings.Join(headers, "\r\n")
if brokenPipe {
log.Error().Err(err.(error)).Str("request", string(httpRequest)).
Msg(c.Request.URL.Path)
log.Error(c.Request.URL.String(),
logger.Any("err", err),
logger.String("headers", headersToStr),
logger.Stack("stack"),
)
// If the connection is dead, we can't write a status to it.
c.Error(err.(error)) // nolint: errcheck
c.Abort()
return
} else {
log.Error(c.Request.URL.String(),
logger.Any("err", err),
logger.String("headers", headersToStr),
logger.Stack("stack"),
logger.String("panicRecoveredTime", time.Now().Format(time.RFC3339)),
)
c.AbortWithStatus(http.StatusInternalServerError)
}
var er = err.(error)
log.Error().Str("request", string(httpRequest)).
Err(helper.WrapErr(er, "wrap")).Msg("Recovery from panic")
c.AbortWithError(http.StatusInternalServerError, er)
}
}()
c.Next()