feat: 日志简化,改用 zap 库
This commit is contained in:
parent
9742dccdfa
commit
29151e240d
13
go.mod
13
go.mod
@ -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
31
go.sum
@ -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=
|
||||
|
@ -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
|
||||
}
|
@ -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
62
logger/field.go
Normal 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
|
||||
)
|
@ -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
|
||||
}
|
122
logger/log.go
122
logger/log.go
@ -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() }
|
||||
|
@ -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
27
logger/options.go
Normal 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
|
||||
)
|
@ -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
84
logger/rotate.go
Normal 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
39
logger/tee.go
Normal 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...)}
|
||||
}
|
@ -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
|
||||
}
|
@ -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()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user