first commit
This commit is contained in:
commit
eb7ef01bf3
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.idea
|
||||||
|
youtu_ecpm
|
||||||
|
youtu_ecpm.exe
|
||||||
|
data/logs
|
13
config.yaml
Normal file
13
config.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
ecpm:
|
||||||
|
value: 200
|
||||||
|
view: 2
|
||||||
|
log:
|
||||||
|
level: debug
|
||||||
|
douyin:
|
||||||
|
# 牛马
|
||||||
|
# app_id: tt8b32fd8f14071db707
|
||||||
|
# secret: 44018e80b1bde34395a52de67ce1e0c37c572d80
|
||||||
|
# 糖果
|
||||||
|
app_id: tt5bc32d7ec4f6ccb907
|
||||||
|
secret: da04822d0989831c6fd6e68ee847fa341bf6a23d
|
||||||
|
port: 9801
|
57
config/config.go
Normal file
57
config/config.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ecpmView int
|
||||||
|
ecpmValue int
|
||||||
|
|
||||||
|
appId string
|
||||||
|
secret string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
viper.SetConfigName("config") // name of config file (without extension)
|
||||||
|
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
||||||
|
viper.AddConfigPath("./") // call multiple times to add many search paths
|
||||||
|
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||||
|
err := viper.ReadInConfig() // Find and read the config file
|
||||||
|
if err != nil { // Handle errors reading the config file
|
||||||
|
panic(fmt.Errorf("fatal error config file: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEcpmView() int {
|
||||||
|
if ecpmView == 0 {
|
||||||
|
ecpmView = viper.GetInt("ecpm.view")
|
||||||
|
}
|
||||||
|
return ecpmView
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEcpmValue() int {
|
||||||
|
if ecpmValue == 0 {
|
||||||
|
ecpmValue = viper.GetInt("ecpm.value")
|
||||||
|
}
|
||||||
|
return ecpmValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAppId() string {
|
||||||
|
if appId == "" {
|
||||||
|
appId = viper.GetString("douyin.app_id")
|
||||||
|
}
|
||||||
|
return appId
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSecret() string {
|
||||||
|
if secret == "" {
|
||||||
|
secret = viper.GetString("douyin.secret")
|
||||||
|
}
|
||||||
|
return secret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPort() int {
|
||||||
|
return viper.GetInt("port")
|
||||||
|
}
|
59
go.mod
Normal file
59
go.mod
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
module youtu_ecpm
|
||||||
|
|
||||||
|
go 1.23.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/douyin-openapi-credential-go v0.0.0-20240627133153-7f4587ca06ce
|
||||||
|
github.com/bytedance/douyin-openapi-sdk-go v0.0.0-20240925072830-12f094544623
|
||||||
|
github.com/gin-gonic/gin v1.10.0
|
||||||
|
github.com/spf13/viper v1.19.0
|
||||||
|
go.uber.org/zap v1.27.0
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alibabacloud-go/debug v1.0.0 // indirect
|
||||||
|
github.com/alibabacloud-go/tea v1.2.2 // indirect
|
||||||
|
github.com/bytedance/douyin-openapi-util-go v0.0.0-20240627134255-db766d8741c8 // indirect
|
||||||
|
github.com/bytedance/sonic v1.11.6 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||||
|
github.com/go-resty/resty/v2 v2.12.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
|
github.com/spf13/cast v1.6.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
golang.org/x/arch v0.8.0 // indirect
|
||||||
|
golang.org/x/crypto v0.23.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||||
|
golang.org/x/net v0.25.0 // indirect
|
||||||
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
|
golang.org/x/text v0.15.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
194
go.sum
Normal file
194
go.sum
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
github.com/alibabacloud-go/debug v1.0.0 h1:3eIEQWfay1fB24PQIEzXAswlVJtdQok8f3EVN5VrBnA=
|
||||||
|
github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
|
||||||
|
github.com/alibabacloud-go/tea v1.2.2 h1:aTsR6Rl3ANWPfqeQugPglfurloyBJY85eFy7Gc1+8oU=
|
||||||
|
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
|
||||||
|
github.com/bytedance/douyin-openapi-credential-go v0.0.0-20240627133153-7f4587ca06ce h1:Mn9pJpYYR5tNQZEUorCj2NZoBWbCDjRZTbgRB4hMQXI=
|
||||||
|
github.com/bytedance/douyin-openapi-credential-go v0.0.0-20240627133153-7f4587ca06ce/go.mod h1:OKJKotnRJazXhZzj4dwUvdw9OuupYNJmctz70MoJme8=
|
||||||
|
github.com/bytedance/douyin-openapi-sdk-go v0.0.0-20240925072830-12f094544623 h1:NxYsIQCpexUPrzMnotXbTiCJKmhH9IsvjOGGOv+iztk=
|
||||||
|
github.com/bytedance/douyin-openapi-sdk-go v0.0.0-20240925072830-12f094544623/go.mod h1:dsLFkIt2aKodjL5Y+JDS0wK0PWb9/I7RwNu8JAixtPs=
|
||||||
|
github.com/bytedance/douyin-openapi-util-go v0.0.0-20240627134255-db766d8741c8 h1:71WIUeJE02/oi/sgrIseKSGBQtiA2Dofl/pV7oe4TZk=
|
||||||
|
github.com/bytedance/douyin-openapi-util-go v0.0.0-20240627134255-db766d8741c8/go.mod h1:GPiogxOAuOSzXMhJ+akYQBLnb6+lGv24kf8JBMtBb2Y=
|
||||||
|
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||||
|
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||||
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||||
|
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||||
|
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA=
|
||||||
|
github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0=
|
||||||
|
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/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
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/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||||
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
|
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||||
|
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||||
|
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
|
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||||
|
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||||
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||||
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
|
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||||
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||||
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||||
|
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
143
log/zap.go
Normal file
143
log/zap.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ZapLog *Logger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ZapLog = NewLog("json", "", "debug", "./data/logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctxLoggerKey = "zapLogger"
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
*zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLog(console, env, lv, lp string) *Logger {
|
||||||
|
//目录不存在则创建
|
||||||
|
if _, err := os.Stat(lp); err != nil {
|
||||||
|
err := os.MkdirAll(lp, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// log address "out.log" User-defined
|
||||||
|
var level zapcore.Level
|
||||||
|
//debug<info<warn<error<fatal<panic
|
||||||
|
switch lv {
|
||||||
|
case "debug":
|
||||||
|
level = zap.DebugLevel
|
||||||
|
case "info":
|
||||||
|
level = zap.InfoLevel
|
||||||
|
case "warn":
|
||||||
|
level = zap.WarnLevel
|
||||||
|
case "error":
|
||||||
|
level = zap.ErrorLevel
|
||||||
|
default:
|
||||||
|
level = zap.InfoLevel
|
||||||
|
}
|
||||||
|
//创建了一个 lumberjack.Logger 实例,用于配置日志文件的存储。
|
||||||
|
hook := lumberjack.Logger{
|
||||||
|
Filename: lp, // Log file path 日志文件的路径
|
||||||
|
MaxSize: 1024, // Maximum size unit for each log file: M 每个日志最大大小
|
||||||
|
MaxBackups: 30, // The maximum number of backups that can be saved for log files 可以保存的日志文件数量
|
||||||
|
MaxAge: 7, // Maximum number of days the file can be saved 日志文件保存的最大天数
|
||||||
|
Compress: true, // Compression or not 是否对日志文件进行压缩
|
||||||
|
}
|
||||||
|
|
||||||
|
//encoder:这是一个 zapcore.Encoder 实例,用于定义日志的格式。
|
||||||
|
//定义一个打印格式 json还是console
|
||||||
|
//console := "console"
|
||||||
|
var encoder zapcore.Encoder
|
||||||
|
if console == "console" {
|
||||||
|
encoder = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
|
||||||
|
TimeKey: "ts",
|
||||||
|
LevelKey: "level",
|
||||||
|
NameKey: "Logger",
|
||||||
|
CallerKey: "caller",
|
||||||
|
MessageKey: "msg",
|
||||||
|
StacktraceKey: "stacktrace",
|
||||||
|
LineEnding: zapcore.DefaultLineEnding,
|
||||||
|
EncodeLevel: zapcore.LowercaseColorLevelEncoder,
|
||||||
|
EncodeTime: timeEncoder,
|
||||||
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||||
|
EncodeCaller: zapcore.FullCallerEncoder,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
encoder = zapcore.NewJSONEncoder(zapcore.EncoderConfig{
|
||||||
|
TimeKey: "ts",
|
||||||
|
LevelKey: "level",
|
||||||
|
NameKey: "logger",
|
||||||
|
CallerKey: "caller",
|
||||||
|
FunctionKey: zapcore.OmitKey,
|
||||||
|
MessageKey: "msg",
|
||||||
|
StacktraceKey: "stacktrace",
|
||||||
|
LineEnding: zapcore.DefaultLineEnding,
|
||||||
|
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
||||||
|
EncodeTime: zapcore.EpochTimeEncoder,
|
||||||
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||||
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
core := zapcore.NewCore(
|
||||||
|
encoder,
|
||||||
|
//通过(NewMultiWriteSyncer)它将日志输出到多个目标。
|
||||||
|
//zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 同时讲日志输出到控制台和文件
|
||||||
|
zapcore.NewMultiWriteSyncer(zapcore.AddSync(&hook)), // Print to file
|
||||||
|
level,
|
||||||
|
)
|
||||||
|
//定义一个环境生产环境还是开发环境
|
||||||
|
//env := "local"
|
||||||
|
if env != "prod" {
|
||||||
|
// 开发模式下 Zap 会记录更详细的日志信息,包括调用者信息和错误级别的堆栈跟踪
|
||||||
|
return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
|
||||||
|
}
|
||||||
|
//如果是生产环境,创建一个 Logger 实例,仅记录调用者信息和错误级别的堆栈跟踪
|
||||||
|
return &Logger{zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeEncoder 格式化一下当前实际
|
||||||
|
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
//enc.AppendString(t.Format("2006-01-02 15:04:05"))
|
||||||
|
enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValue 将 Zap 日志字段和当前的 context.Context 绑定,以便在 HTTP 请求处理过程中可以方便地记录日志。
|
||||||
|
func (l *Logger) WithValue(ctx context.Context, fields ...zapcore.Field) context.Context {
|
||||||
|
// 检查传入的 context 是否为 *gin.Context 类型
|
||||||
|
if c, ok := ctx.(*gin.Context); ok {
|
||||||
|
// 将 gin.Context 转换为标准的 context.Context
|
||||||
|
ctx = c.Request.Context()
|
||||||
|
// 使用 context.WithValue 将 Zap 日志字段绑定到 context
|
||||||
|
// 这样在请求处理过程中就可以通过 context 获取日志记录器实例
|
||||||
|
c.Request = c.Request.WithContext(context.WithValue(ctx, ctxLoggerKey, l.WithContext(ctx).With(fields...)))
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
// 如果 context 不是 *gin.Context 类型,直接绑定 Zap 日志字段
|
||||||
|
return context.WithValue(ctx, ctxLoggerKey, l.WithContext(ctx).With(fields...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithContext Returns a zap instance from the specified context
|
||||||
|
func (l *Logger) WithContext(ctx context.Context) *Logger {
|
||||||
|
//检查传入的 context 是否为 *gin.Context 类型
|
||||||
|
//将 gin.Context 转换为标准的 context.Context
|
||||||
|
if c, ok := ctx.(*gin.Context); ok {
|
||||||
|
ctx = c.Request.Context()
|
||||||
|
}
|
||||||
|
//从上下文中提取键为ctxLoggerKey的值,并尝试将其转换为*zap.Logger。
|
||||||
|
zl := ctx.Value(ctxLoggerKey)
|
||||||
|
ctxLogger, ok := zl.(*zap.Logger)
|
||||||
|
if ok {
|
||||||
|
return &Logger{ctxLogger}
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
37
main.go
Normal file
37
main.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
viperConfig "youtu_ecpm/config"
|
||||||
|
"youtu_ecpm/log"
|
||||||
|
"youtu_ecpm/router"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := gin.New()
|
||||||
|
r.Use(gin.Recovery(), zapMiddleware(log.ZapLog))
|
||||||
|
router.InitGin(r)
|
||||||
|
r.Run(":" + strconv.Itoa(viperConfig.GetPort())) // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
// zapMiddleware 记录每个请求的基本信息
|
||||||
|
func zapMiddleware(zapLogger *log.Logger) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
// 请求开始时间
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
// 处理请求
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
// 记录请求信息
|
||||||
|
zapLogger.Info("HTTP Request",
|
||||||
|
zap.String("method", c.Request.Method),
|
||||||
|
zap.String("path", c.Request.URL.Path),
|
||||||
|
zap.String("status", strconv.Itoa(c.Writer.Status())),
|
||||||
|
zap.String("duration", time.Since(start).String()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
255
router/router.go
Normal file
255
router/router.go
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
credential "github.com/bytedance/douyin-openapi-credential-go/client"
|
||||||
|
openApiSdkClient "github.com/bytedance/douyin-openapi-sdk-go/client"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
viperConfig "youtu_ecpm/config"
|
||||||
|
"youtu_ecpm/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitGin(r *gin.Engine) *gin.Engine {
|
||||||
|
r.GET("/get-ecpm", getEcpm)
|
||||||
|
r.GET("/code2openId", code2openId)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义抖音 API 响应的结构体
|
||||||
|
type APIResponse struct {
|
||||||
|
BaseResp struct {
|
||||||
|
StatusCode int `json:"StatusCode"`
|
||||||
|
StatusMessage string `json:"StatusMessage"`
|
||||||
|
} `json:"BaseResp"`
|
||||||
|
Data struct {
|
||||||
|
Records []Record `json:"records"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
} `json:"data"`
|
||||||
|
ErrMsg string `json:"err_msg"`
|
||||||
|
ErrNo int `json:"err_no"`
|
||||||
|
LogID string `json:"log_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Record struct {
|
||||||
|
Aid string `json:"aid"`
|
||||||
|
Cost int `json:"cost"`
|
||||||
|
Did string `json:"did"`
|
||||||
|
EventName string `json:"event_name"`
|
||||||
|
EventTime string `json:"event_time"`
|
||||||
|
OpenID string `json:"open_id"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EcpmReq struct {
|
||||||
|
OpenId string `json:"open_id" form:"open_id"`
|
||||||
|
MpId string `json:"mp_id" form:"mp_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func code2openId(c *gin.Context) {
|
||||||
|
code := c.Query("code")
|
||||||
|
anonymousOpenid := c.Query("anonymous_openid")
|
||||||
|
openId, err := AppsJsCode2session(code, anonymousOpenid)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"code": 500,
|
||||||
|
"msg": http.StatusOK,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.String(http.StatusOK, openId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEcpm(c *gin.Context) {
|
||||||
|
var req EcpmReq
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.OpenId == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取动态的 access_token
|
||||||
|
accessToken, err := GetAccessToken()
|
||||||
|
if err != nil {
|
||||||
|
errorMessage := fmt.Sprintf("获取 access_token 失败: %v", err)
|
||||||
|
fmt.Println(errorMessage)
|
||||||
|
c.String(http.StatusInternalServerError, errorMessage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := getEcpmFromApi(req, accessToken)
|
||||||
|
|
||||||
|
// 计算 ECPM
|
||||||
|
totalCost := 0
|
||||||
|
totalRecords := len(res)
|
||||||
|
|
||||||
|
for _, record := range res {
|
||||||
|
totalCost += record.Cost
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有记录,则返回错误
|
||||||
|
if totalRecords == 0 {
|
||||||
|
errorMessage := "未找到记录,无法计算 ECPM"
|
||||||
|
fmt.Println(errorMessage)
|
||||||
|
c.JSON(http.StatusOK, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 总 cost / 100000 * 1000 / 总记录数
|
||||||
|
ecpm := float64(totalCost) / 100000 * 1000 / float64(totalRecords)
|
||||||
|
// 打印日志
|
||||||
|
log.ZapLog.Info("ECPM:", zap.Float64("ecpm", ecpm))
|
||||||
|
// 根据 ECPM 值判断并返回 "true" 或 "false"
|
||||||
|
var result bool
|
||||||
|
if ecpm > float64(viperConfig.GetEcpmValue()) && viperConfig.GetEcpmView() > 2 {
|
||||||
|
result = true
|
||||||
|
} else {
|
||||||
|
result = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
c.JSON(http.StatusOK, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEcpmFromApi(req EcpmReq, accessToken string) (list []Record, err error) {
|
||||||
|
// 构造抖音 API 请求的 URL
|
||||||
|
apiURL := "https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm"
|
||||||
|
params := url.Values{}
|
||||||
|
params.Add("open_id", req.OpenId)
|
||||||
|
params.Add("mp_id", req.MpId)
|
||||||
|
|
||||||
|
fullURL := fmt.Sprintf("%s?open_id=%s&mp_id=%s&access_token=%s&date_hour=%s&page_size=500&page_no=", apiURL, req.OpenId, req.MpId, accessToken, time.Now().Format(time.DateOnly))
|
||||||
|
pageNo := 1
|
||||||
|
for {
|
||||||
|
fullURL += strconv.Itoa(pageNo)
|
||||||
|
var responseBody []byte
|
||||||
|
func() {
|
||||||
|
// 调用抖音 API
|
||||||
|
var resp *http.Response
|
||||||
|
resp, err = http.Get(fullURL)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.New("调用抖音 API 失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
// 读取抖音 API 响应数据
|
||||||
|
responseBody, err = io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.New("读取抖音 API 响应失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 解析抖音 API 响应数据
|
||||||
|
var apiResponse APIResponse
|
||||||
|
err = json.Unmarshal(responseBody, &apiResponse)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.New("解析 API 响应数据失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 API 是否返回错误
|
||||||
|
if apiResponse.ErrNo != 0 {
|
||||||
|
errorMessage := fmt.Sprintf("抖音 API 返回错误: %s (错误码: %d)", apiResponse.ErrMsg, apiResponse.ErrNo)
|
||||||
|
err = errors.New(errorMessage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
list = append(list, apiResponse.Data.Records...)
|
||||||
|
if len(apiResponse.Data.Records) <= 500 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageNo++
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppsJsCode2session(code, anonymousOpenid string) (openId string, err error) {
|
||||||
|
|
||||||
|
/* 构建请求参数,该代码示例中只给出部分参数,请用户根据需要自行构建参数值
|
||||||
|
token:
|
||||||
|
1.若用户自行维护token,将用户维护的token赋值给该参数即可
|
||||||
|
2.SDK包中有获取token的函数,请根据接口path在《OpenAPI SDK 总览》文档中查找获取token函数的名字
|
||||||
|
在使用过程中,请注意token互刷问题
|
||||||
|
header:
|
||||||
|
sdk中默认填充content-type请求头,若不需要填充除content-type之外的请求头,删除该参数即可
|
||||||
|
*/
|
||||||
|
sdkRequest := &openApiSdkClient.AppsJscode2sessionRequest{}
|
||||||
|
sdkRequest.SetAppid(viperConfig.GetAppId())
|
||||||
|
if code == "" && anonymousOpenid == "" {
|
||||||
|
err = errors.New("code can not be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if code == "" {
|
||||||
|
sdkRequest.SetAnonymousCode(anonymousOpenid)
|
||||||
|
} else {
|
||||||
|
sdkRequest.SetCode(code)
|
||||||
|
}
|
||||||
|
sdkRequest.SetSecret(viperConfig.GetSecret())
|
||||||
|
|
||||||
|
// sdk调用
|
||||||
|
sdkResponse, err := sdkClient.AppsJscode2session(sdkRequest)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if sdkResponse.Error != nil && *sdkResponse.Error != 0 {
|
||||||
|
if sdkResponse.Errmsg != nil {
|
||||||
|
err = errors.New(*sdkResponse.Errmsg)
|
||||||
|
} else {
|
||||||
|
err = errors.New("api 未知错误")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if sdkResponse.Openid == nil {
|
||||||
|
err = errors.New("open id is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *sdkResponse.Openid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var sdkClient *openApiSdkClient.Client
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// 初始化 SDK 客户端,设置 app_id 和 secret
|
||||||
|
opt := new(credential.Config).
|
||||||
|
SetClientKey(viperConfig.GetAppId()). // 替换为你的 app_id
|
||||||
|
SetClientSecret(viperConfig.GetSecret()) // 替换为你的 secret
|
||||||
|
var err error
|
||||||
|
// 创建 SDK 客户端
|
||||||
|
sdkClient, err = openApiSdkClient.NewClient(opt)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 access_token 的函数
|
||||||
|
func GetAccessToken() (accecksToken string, err error) {
|
||||||
|
|
||||||
|
// 构造获取 token 的请求参数
|
||||||
|
sdkRequest := &openApiSdkClient.AppsV2TokenRequest{}
|
||||||
|
sdkRequest.SetAppid(viperConfig.GetAppId()) // 设置应用 ID
|
||||||
|
sdkRequest.SetGrantType("client_credential") // 设置授权类型(client_credentials 模式)
|
||||||
|
sdkRequest.SetSecret(viperConfig.GetSecret()) // 设置密钥
|
||||||
|
|
||||||
|
// 调用 SDK 获取 access_token
|
||||||
|
sdkResponse, err := sdkClient.AppsV2Token(sdkRequest)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("SDK 调用失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回 access_token
|
||||||
|
return *sdkResponse.Data.AccessToken, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user