From c5774761bfc7ea2690e0463e0f2908124a5c67a3 Mon Sep 17 00:00:00 2001 From: joelei Date: Thu, 11 Dec 2025 01:08:39 +0800 Subject: [PATCH] add config --- config/base.go | 32 +++++++++++----------- config/config.go | 64 ++++++++++++++++++++++++++++++++++++++++++++ config/database.go | 51 +++++++++++++++++++++++++++++++++++ config/etcd.go | 52 ++++++++++++++++++++++++++++++++++++ config/logging.go | 28 +++++++++++--------- config/redis.go | 26 +++++++++--------- config/tracing.go | 2 +- config/web.go | 48 +++++++++++++++++++++++++++++++++ go.mod | 19 ++++++++++--- go.sum | 34 ++++++++++++++++++++---- logger/logger.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++ task/handler.go | 4 +-- 12 files changed, 374 insertions(+), 52 deletions(-) create mode 100644 config/config.go create mode 100644 config/database.go create mode 100644 config/etcd.go create mode 100644 config/web.go diff --git a/config/base.go b/config/base.go index 230f50d..db1bfbf 100644 --- a/config/base.go +++ b/config/base.go @@ -2,34 +2,36 @@ package config import ( "time" + _ "time/tzdata" // tzdata + + "github.com/samber/lo" ) const ( - // DevEnv + // DevEnv ... DevEnv = "dev" - // ProdEnv + // ProdEnv ... ProdEnv = "prod" + // LocalEnv 本地开发, 和前端区别 + LocalEnv = "local" ) -// BaseConf +// BaseConf ... type BaseConf struct { - AppCode string `yaml:"app_code"` - AppSecret string `yaml:"app_secret"` TimeZone string `yaml:"time_zone"` LanguageCode string `yaml:"language_code"` RunEnv string `yaml:"run_env"` Location *time.Location `yaml:"-"` } -// Init -func (c *BaseConf) Init() error { - var err error - c.TimeZone = "Asia/Shanghai" - c.LanguageCode = "en-us" - c.RunEnv = DevEnv - c.Location, err = time.LoadLocation(c.TimeZone) - if err != nil { - return err +// NewBaseConf with default value +func NewBaseConf() *BaseConf { + c := &BaseConf{ + TimeZone: "Asia/Shanghai", + LanguageCode: "en-us", + RunEnv: DevEnv, } - return nil + c.Location = lo.Must(time.LoadLocation(c.TimeZone)) + + return c } diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..0adf8fd --- /dev/null +++ b/config/config.go @@ -0,0 +1,64 @@ +// Package config xxx +package config + +import ( + "io" + "os" + + "github.com/spf13/viper" + "gopkg.in/yaml.v3" +) + +// Configuration 配置 +type Configuration struct { + Viper *viper.Viper `yaml:"-"` + Base *BaseConf `yaml:"base"` + Logger *LogConf `yaml:"logger"` +} + +// New 新增配置 +func New() *Configuration { + c := &Configuration{} + + c.Base = NewBaseConf() + c.Logger = NewLogConf() + return c +} + +// IsLocalEnv 是否本地开发模式 +func (c *Configuration) IsLocalEnv() bool { + return c.Base.RunEnv == LocalEnv +} + +// IsProdEnv 是否生产环境 +func (c *Configuration) IsProdEnv() bool { + return c.Base.RunEnv == ProdEnv +} + +// ReadFrom read from file, should copy if embedded +func (c *Configuration) ReadFrom(content []byte) error { + if err := yaml.Unmarshal(content, c); err != nil { + return err + } + + return nil +} + +// ReadFromViper : read from viper, should copy if embedded +func (c *Configuration) ReadFromViper(v *viper.Viper) error { + // viper会把所有key处理为小写且不支持inline, 直接使用 yaml 库 + content, err := os.ReadFile(v.ConfigFileUsed()) + if err != nil { + return err + } + c.Viper = v + + return c.ReadFrom(content) +} + +// OutConf : print conf, should copy if embedded +func (c *Configuration) OutConf(w io.Writer) error { + encoder := yaml.NewEncoder(w) + encoder.SetIndent(2) + return encoder.Encode(c) +} diff --git a/config/database.go b/config/database.go new file mode 100644 index 0000000..3dc9d51 --- /dev/null +++ b/config/database.go @@ -0,0 +1,51 @@ +package config + +import "fmt" + +const ( + // MySQLDriver type + MySQLDriver = "mysql" + // SqliteDriver type + SqliteDriver = "sqlite" +) + +// create database `db` default character set utf8mb4 collate utf8mb4_unicode_ci; + +// DatabaseConf xxx +type DatabaseConf struct { + Driver string `yaml:"driver"` // "mysql or sqlite" + Host string `yaml:"host"` + Port int `yaml:"port"` + Username string `yaml:"username"` + Password string `yaml:"password"` + DB string `yaml:"db"` + MaxOpenConns int `yaml:"max_open_conns"` + MaxIdleConns int `yaml:"max_idle_conns"` + ConnMaxLifeSeconds int `yaml:"conn_max_life_seconds"` + Debug bool `yaml:"debug"` +} + +// NewDatabaseConf with default value +func NewDatabaseConf(db string) *DatabaseConf { + return &DatabaseConf{ + Driver: MySQLDriver, + Host: "127.0.0.1", + Port: 3306, + Username: "root", + Password: "", + DB: db, + Debug: false, + } +} + +// DSN ... +func (c *DatabaseConf) DSN() string { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", + c.Username, + c.Password, + c.Host, + c.Port, + c.DB, + ) + return dsn +} diff --git a/config/etcd.go b/config/etcd.go new file mode 100644 index 0000000..0317d1d --- /dev/null +++ b/config/etcd.go @@ -0,0 +1,52 @@ +package config + +import ( + "crypto/tls" + "crypto/x509" + "os" +) + +// EtcdConf etcd配置 +type EtcdConf struct { + Endpoints string `yaml:"endpoints"` + Ca string `yaml:"ca"` + Cert string `yaml:"cert"` + Key string `yaml:"key"` +} + +// NewEtcdConf with default value +func NewEtcdConf() *EtcdConf { + return &EtcdConf{ + Endpoints: "http://127.0.0.1:2379", + Cert: "", + Ca: "", + Key: "", + } +} + +// TLSConfig ... +func (c *EtcdConf) TLSConfig() (*tls.Config, error) { + if c.Cert == "" || c.Ca == "" || c.Key == "" { + return nil, nil + } + + cert, err := tls.LoadX509KeyPair(c.Cert, c.Key) + if err != nil { + return nil, err + } + + caData, err := os.ReadFile(c.Ca) + if err != nil { + return nil, err + } + pool := x509.NewCertPool() + pool.AppendCertsFromPEM(caData) + + // nolint TLS MinVersion too low. + tlsCfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: pool, + } + + return tlsCfg, nil +} diff --git a/config/logging.go b/config/logging.go index d390149..0859893 100644 --- a/config/logging.go +++ b/config/logging.go @@ -3,20 +3,22 @@ package config // LogConf : config for logging type LogConf struct { Level string `yaml:"level"` - File string `yaml:"file"` - Stderr bool `yaml:"stderr"` - CmdFile string `yaml:"-"` - CmdLevel string `yaml:"-"` + FileName string `yaml:"filename"` + Format string `yaml:"format"` + Stdout bool `yaml:"stdout"` + MaxSize int `yaml:"max_size"` + MaxNum int `yaml:"max_num"` } -// Init : init default logging config -func (c *LogConf) Init() error { +// NewLogConf with default value +func NewLogConf() *LogConf { // only for development - c.Level = "info" - c.File = "" - c.Stderr = true - c.CmdFile = "" - c.CmdLevel = "info" - - return nil + return &LogConf{ + Level: "info", + FileName: "", + Format: "text", + Stdout: true, + MaxSize: 0, + MaxNum: 0, + } } diff --git a/config/redis.go b/config/redis.go index d4fac52..554d663 100644 --- a/config/redis.go +++ b/config/redis.go @@ -1,5 +1,6 @@ package config +// RedisConf redis配置 type RedisConf struct { Host string `yaml:"host"` Port int `yaml:"port"` @@ -12,17 +13,18 @@ type RedisConf struct { WriteTimeout int `yaml:"write_timeout"` } -func (c *RedisConf) Init() error { +// NewRedisConf with default value +func NewRedisConf() *RedisConf { // only for development - c.Host = "127.0.0.1" - c.Port = 6379 - c.Password = "" - c.DB = 0 - - c.MaxPoolSize = 100 - c.MaxConnTimeout = 6 - c.IdleTimeout = 600 - c.ReadTimeout = 10 - c.WriteTimeout = 10 - return nil + return &RedisConf{ + Host: "127.0.0.1", + Port: 6379, + Password: "", + DB: 0, + MaxPoolSize: 100, + MaxConnTimeout: 6, + IdleTimeout: 600, + ReadTimeout: 10, + WriteTimeout: 10, + } } diff --git a/config/tracing.go b/config/tracing.go index 5ad5eae..f9dd797 100644 --- a/config/tracing.go +++ b/config/tracing.go @@ -1,6 +1,6 @@ package config -// Tracing +// Tracing ... type Tracing struct { Endpoint string `json:"endpoint"` Token string `json:"token"` diff --git a/config/web.go b/config/web.go new file mode 100644 index 0000000..855e4c2 --- /dev/null +++ b/config/web.go @@ -0,0 +1,48 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package config + +import ( + "net/url" + "path" +) + +// WebConf web 相关配置 +type WebConf struct { + Host string `yaml:"host"` + RoutePrefix string `yaml:"route_prefix"` + PreferredDomains string `yaml:"preferred_domains"` + BaseURL *url.URL `yaml:"-"` +} + +// Init 初始化 +func (c *WebConf) Init() error { + u, err := url.Parse(c.Host) + if err != nil { + return err + } + u.Path = path.Join(u.Path, c.RoutePrefix) + + c.BaseURL = u + return nil +} + +// NewWebConf 默认配置 +func NewWebConf() *WebConf { + c := &WebConf{ + Host: "", + RoutePrefix: "/", + PreferredDomains: "", + } + return c +} diff --git a/go.mod b/go.mod index 4ed15df..f812641 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,11 @@ require ( github.com/redis/go-redis/v9 v9.12.1 github.com/samber/lo v1.47.0 github.com/spf13/cobra v1.10.2 - github.com/stretchr/testify v1.10.0 + github.com/spf13/viper v1.21.0 + github.com/stretchr/testify v1.11.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -22,27 +25,35 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/subosito/gotenv v1.6.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/text v0.28.0 // indirect google.golang.org/protobuf v1.36.5 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3db6c57..19733eb 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,10 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +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.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= 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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -28,6 +32,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -46,6 +52,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= @@ -61,14 +69,27 @@ github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= @@ -79,6 +100,7 @@ go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= @@ -86,12 +108,14 @@ golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/logger/logger.go b/logger/logger.go index 3549c71..1d8a217 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -2,10 +2,15 @@ package logger import ( + "io" "log/slog" "os" "path/filepath" "strconv" + + "gopkg.in/natefinch/lumberjack.v2" + + "git.ifooth.com/common/pkg/config" ) // Init 初始化 slog @@ -20,6 +25,67 @@ func Init() { slog.SetDefault(logger) } +// GetLevelByName human readable logger level +func GetLevelByName(name string) slog.Level { + switch name { + case "error": + return slog.LevelError + case "warn": + return slog.LevelWarn + case "info": + return slog.LevelInfo + case "debug": + return slog.LevelDebug + default: + return slog.LevelInfo + } +} + +// NewLogger make a new logger +func NewLogger(opts *config.LogConf) *slog.Logger { + handler := NewHandler(opts) + logger := slog.New(handler) + return logger +} + +// NewHandler make a new handler +func NewHandler(opts *config.LogConf) slog.Handler { + ioWriter := io.Discard + + if opts.Stdout { + ioWriter = os.Stdout + } + + if opts.FileName != "" { + fileWriter := &lumberjack.Logger{ + Filename: opts.FileName, + MaxSize: opts.MaxSize, + MaxBackups: opts.MaxNum, + LocalTime: true, + Compress: false, + } + + if ioWriter == io.Discard { + ioWriter = fileWriter + } else { + ioWriter = io.MultiWriter(ioWriter, fileWriter) + } + } + + level := GetLevelByName(opts.Level) + + slogOpt := &slog.HandlerOptions{ + AddSource: true, + Level: level, + ReplaceAttr: ReplaceSourceAttr, + } + + if opts.Format == "json" { + return slog.NewJSONHandler(ioWriter, slogOpt) + } + return slog.NewTextHandler(ioWriter, slogOpt) +} + // ReplaceSourceAttr source 格式化为 dir/file:line 格式 func ReplaceSourceAttr(groups []string, a slog.Attr) slog.Attr { if a.Key != slog.SourceKey { diff --git a/task/handler.go b/task/handler.go index f9b19c4..b18dd6a 100644 --- a/task/handler.go +++ b/task/handler.go @@ -8,13 +8,13 @@ import ( "net/url" "time" - "git.ifooth.com/common/pkg/rest" - "git.ifooth.com/common/pkg/validator" "github.com/samber/lo" + "git.ifooth.com/common/pkg/rest" istore "git.ifooth.com/common/pkg/task/stores/iface" "git.ifooth.com/common/pkg/task/types" itypes "git.ifooth.com/common/pkg/task/types" + "git.ifooth.com/common/pkg/validator" ) type service struct {