diff --git a/config.yaml.example b/config.yaml.example index f4574a6..4bb59aa 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -4,6 +4,7 @@ app: jwt_secret: 'viletyy' jwt_expire: '7200' run_mode: 'debug' + default_context_timeout: 60 page_size: 10 upload_save_path: 'tmp/uploads' upload_server_path: '/static' diff --git a/config/app.go b/config/app.go index b1734d5..a02fdc1 100644 --- a/config/app.go +++ b/config/app.go @@ -1,20 +1,21 @@ /* * @Date: 2021-03-22 09:46:19 * @LastEditors: viletyy - * @LastEditTime: 2021-06-13 22:00:01 + * @LastEditTime: 2021-06-13 23:00:46 * @FilePath: /potato/config/app.go */ package config type App struct { - Name string `mapstructure:"name" json:"name" yaml:"name"` - Version string `mapstructure:"version" json:"version" yaml:"version"` - PageSize int64 `mapstructure:"page_size" json:"page_size" yaml:"page_size"` - JwtSecret string `mapstructure:"jwt_secret" json:"jwt_secret" yaml:"jwt_secret"` - JwtExpire int64 `mapstructure:"jwt_expire" json:"jwt_expire" yaml:"jwt_expire"` - RunMode string `mapstructure:"run_mode" json:"run_mode" yaml:"run_mode"` - UploadSavePath string `mapstructure:"upload_save_path" json:"upload_save_path" yaml:"upload_save_path"` - UploadServerPath string `mapstructure:"upload_server_path" json:"upload_server_path" yaml:"upload_server_path"` - UploadImageMaxSize int64 `mapstructure:"upload_image_max_size" json:"upload_image_max_size" yaml:"upload_image_max_size"` - UploadImageAllowExts []string `mapstructure:"upload_image_allow_exts" json:"upload_image_allow_exts" yaml:"upload_image_allow_exts"` + Name string `mapstructure:"name" json:"name" yaml:"name"` + Version string `mapstructure:"version" json:"version" yaml:"version"` + PageSize int64 `mapstructure:"page_size" json:"page_size" yaml:"page_size"` + JwtSecret string `mapstructure:"jwt_secret" json:"jwt_secret" yaml:"jwt_secret"` + JwtExpire int64 `mapstructure:"jwt_expire" json:"jwt_expire" yaml:"jwt_expire"` + RunMode string `mapstructure:"run_mode" json:"run_mode" yaml:"run_mode"` + DefaultContextTimeout int64 `mapstructure:"default_context_timeout" json:"default_context_timeout" yaml:"default_context_timeout"` + UploadSavePath string `mapstructure:"upload_save_path" json:"upload_save_path" yaml:"upload_save_path"` + UploadServerPath string `mapstructure:"upload_server_path" json:"upload_server_path" yaml:"upload_server_path"` + UploadImageMaxSize int64 `mapstructure:"upload_image_max_size" json:"upload_image_max_size" yaml:"upload_image_max_size"` + UploadImageAllowExts []string `mapstructure:"upload_image_allow_exts" json:"upload_image_allow_exts" yaml:"upload_image_allow_exts"` } diff --git a/config/server.go b/config/server.go index 126b0fb..51589cc 100644 --- a/config/server.go +++ b/config/server.go @@ -1,13 +1,14 @@ /* * @Date: 2021-03-22 09:54:07 * @LastEditors: viletyy - * @LastEditTime: 2021-03-22 09:56:38 + * @LastEditTime: 2021-06-14 20:40:49 * @FilePath: /potato/config/server.go */ package config type Server struct { - HttpPort int64 `mapstructure:"http_port" json:"http_port" yaml:"http_port"` - ReadTimeout int64 `mapstructure:"read_timeout" json:"read_timeout" yaml:"read_timeout"` - WriteTimeout int64 `mapstructure:"write_timeout" json:"write_timeout" yaml:"write_timeout"` + HttpPort int64 `mapstructure:"http_port" json:"http_port" yaml:"http_port"` + ReadTimeout int64 `mapstructure:"read_timeout" json:"read_timeout" yaml:"read_timeout"` + WriteTimeout int64 `mapstructure:"write_timeout" json:"write_timeout" yaml:"write_timeout"` + TracerHostPort string `mapstructure:"tracer_host_port" json:"tracer_host_port" yaml:"tracer_host_port"` } diff --git a/docs/docs.go b/docs/docs.go index aa22f8a..bf133bb 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -24,7 +24,7 @@ var doc = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/v1/auth": { + "/auth": { "post": { "consumes": [ "multipart/form-data" diff --git a/docs/swagger.json b/docs/swagger.json index 7569eea..48706b4 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -8,7 +8,7 @@ }, "basePath": "/api", "paths": { - "/v1/auth": { + "/auth": { "post": { "consumes": [ "multipart/form-data" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 6532eb2..d3f6a3c 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -17,7 +17,7 @@ info: title: Potato Api version: "1.0" paths: - /v1/auth: + /auth: post: consumes: - multipart/form-data diff --git a/global/global.go b/global/global.go index 6aec6c4..19d5a18 100644 --- a/global/global.go +++ b/global/global.go @@ -1,7 +1,7 @@ /* * @Date: 2021-03-22 09:42:09 * @LastEditors: viletyy - * @LastEditTime: 2021-04-06 18:18:15 + * @LastEditTime: 2021-06-13 23:53:51 * @FilePath: /potato/global/global.go */ package global @@ -9,6 +9,7 @@ package global import ( "github.com/go-redis/redis" "github.com/jinzhu/gorm" + "github.com/opentracing/opentracing-go" "github.com/spf13/viper" "github.com/viletyy/potato/config" "go.uber.org/zap" @@ -20,4 +21,5 @@ var ( GO_CONFIG *config.Config GO_VP *viper.Viper GO_LOG *zap.Logger + GO_TRACER opentracing.Tracer ) diff --git a/go.mod b/go.mod index 151283e..8899ad4 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,10 @@ module github.com/viletyy/potato go 1.15 require ( + github.com/HdrHistogram/hdrhistogram-go v1.1.0 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/eddycjy/opentracing-gorm v0.0.0-20200209122056-516a807d2182 github.com/fsnotify/fsnotify v1.4.9 github.com/gin-gonic/gin v1.7.2 github.com/go-playground/locales v0.13.0 @@ -17,10 +19,14 @@ require ( github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.13.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 github.com/spf13/viper v1.7.1 github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/swag v1.7.0 + github.com/uber/jaeger-client-go v2.22.1+incompatible + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/viletyy/yolk v1.0.1 + go.uber.org/atomic v1.8.0 // indirect go.uber.org/zap v1.17.0 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df diff --git a/initialize/gorm.go b/initialize/gorm.go index 5d2b15b..a4ceb5d 100644 --- a/initialize/gorm.go +++ b/initialize/gorm.go @@ -1,7 +1,7 @@ /* * @Date: 2021-03-22 10:12:38 * @LastEditors: viletyy - * @LastEditTime: 2021-06-10 21:53:31 + * @LastEditTime: 2021-06-14 21:11:29 * @FilePath: /potato/initialize/gorm.go */ package initialize @@ -9,6 +9,7 @@ package initialize import ( "fmt" + otgorm "github.com/eddycjy/opentracing-gorm" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" _ "github.com/jinzhu/gorm/dialects/postgres" @@ -68,4 +69,7 @@ func GormSet(db *gorm.DB) { // 设置打开数据库连接的最大数量 db.DB().SetMaxOpenConns(100) + + // 设置链路追踪 + otgorm.AddGormCallbacks(db) } diff --git a/initialize/tracer.go b/initialize/tracer.go new file mode 100644 index 0000000..1048672 --- /dev/null +++ b/initialize/tracer.go @@ -0,0 +1,25 @@ +/* + * @Date: 2021-06-13 23:25:52 + * @LastEditors: viletyy + * @LastEditTime: 2021-06-14 20:42:40 + * @FilePath: /potato/initialize/tracer.go + */ +package initialize + +import ( + "github.com/opentracing/opentracing-go" + "github.com/viletyy/potato/global" + "github.com/viletyy/potato/pkg/tracer" +) + +func Tracer() opentracing.Tracer { + jaegerTracer, _, err := tracer.NewJaegerTracer( + global.GO_CONFIG.App.Name, + global.GO_CONFIG.Server.TracerHostPort, + ) + if err != nil { + global.GO_LOG.Sugar().Errorf("tracer.NewJaegerTracer err: %v", err) + } + + return jaegerTracer +} diff --git a/internal/controller/api/auth.go b/internal/controller/api/auth.go index 337c89b..9cda7aa 100644 --- a/internal/controller/api/auth.go +++ b/internal/controller/api/auth.go @@ -1,7 +1,7 @@ /* * @Date: 2021-06-10 18:58:25 * @LastEditors: viletyy - * @LastEditTime: 2021-06-13 22:41:01 + * @LastEditTime: 2021-06-14 21:02:33 * @FilePath: /potato/internal/controller/api/auth.go */ package api diff --git a/internal/middleware/access_log.go b/internal/middleware/access_log.go index 3acbba6..b103963 100644 --- a/internal/middleware/access_log.go +++ b/internal/middleware/access_log.go @@ -1,7 +1,7 @@ /* * @Date: 2021-06-12 21:55:50 * @LastEditors: viletyy - * @LastEditTime: 2021-06-12 22:22:31 + * @LastEditTime: 2021-06-14 21:00:47 * @FilePath: /potato/internal/middleware/access_log.go */ package middleware @@ -40,6 +40,8 @@ func AccessLog() gin.HandlerFunc { global.GO_LOG.With( zap.String("request", c.Request.PostForm.Encode()), zap.String("response", bodyWriter.body.String()), + zap.String("trace_id", c.GetString("X-Trace-ID")), + zap.String("span_id", c.GetString("X-Span-ID")), ).Sugar().Infof("access log: method: %s, status_code: %d, begin_time: %d, end_time: %d", c.Request.Method, bodyWriter.Status(), diff --git a/internal/middleware/tracer.go b/internal/middleware/tracer.go new file mode 100644 index 0000000..07d3756 --- /dev/null +++ b/internal/middleware/tracer.go @@ -0,0 +1,57 @@ +/* + * @Date: 2021-06-13 23:33:05 + * @LastEditors: viletyy + * @LastEditTime: 2021-06-14 20:45:47 + * @FilePath: /potato/internal/middleware/tracer.go + */ +package middleware + +import ( + "context" + + "github.com/gin-gonic/gin" + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/uber/jaeger-client-go" + "github.com/viletyy/potato/global" +) + +func Tracing() gin.HandlerFunc { + return func(c *gin.Context) { + var newCtx context.Context + var span opentracing.Span + spanCtx, err := opentracing.GlobalTracer().Extract( + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(c.Request.Header), + ) + if err != nil { + span, newCtx = opentracing.StartSpanFromContextWithTracer( + c.Request.Context(), + global.GO_TRACER, + c.Request.URL.Path, + ) + } else { + span, newCtx = opentracing.StartSpanFromContextWithTracer( + c.Request.Context(), + global.GO_TRACER, + c.Request.URL.Path, + opentracing.ChildOf(spanCtx), + opentracing.Tag{Key: string(ext.Component), Value: "HTTP"}, + ) + } + defer span.Finish() + var traceID string + var spanID string + var spanContext = span.Context() + switch spanContext.(type) { + case jaeger.SpanContext: + jaegerContext := spanContext.(jaeger.SpanContext) + traceID = jaegerContext.TraceID().String() + spanID = jaegerContext.SpanID().String() + } + c.Set("X-Trace-ID", traceID) + c.Set("X-Span-ID", spanID) + c.Request = c.Request.WithContext(newCtx) + c.Next() + } +} diff --git a/internal/routers/router.go b/internal/routers/router.go index 040c10d..a219cf5 100644 --- a/internal/routers/router.go +++ b/internal/routers/router.go @@ -1,7 +1,7 @@ /* * @Date: 2021-03-21 19:54:57 * @LastEditors: viletyy - * @LastEditTime: 2021-06-13 22:46:46 + * @LastEditTime: 2021-06-13 23:39:38 * @FilePath: /potato/internal/routers/router.go */ package routers @@ -44,11 +44,12 @@ func InitRouter() *gin.Engine { Engine.Use(middleware.AccessLog()) Engine.Use(middleware.Recovery()) } - Engine.Use(middleware.AppInfo()) // 设置app信息 - Engine.Use(middleware.RateLimiter(methodLimiters)) // 设置限流控制 - Engine.Use(middleware.ContextTimeout(60 * time.Second)) // 设置统一超时控制 - Engine.Use(middleware.Translations()) // 设置自定义验证 - Engine.Use(middleware.CORS()) // 设置跨域 + Engine.Use(middleware.AppInfo()) // 设置app信息 + Engine.Use(middleware.RateLimiter(methodLimiters)) // 设置限流控制 + Engine.Use(middleware.ContextTimeout(time.Duration(global.GO_CONFIG.App.DefaultContextTimeout))) // 设置统一超时控制 + Engine.Use(middleware.Translations()) // 设置自定义验证 + Engine.Use(middleware.CORS()) // 设置跨域 + Engine.Use(middleware.Tracing()) Engine.StaticFS("/static", http.Dir(global.GO_CONFIG.App.UploadSavePath)) diff --git a/internal/service/service.go b/internal/service/service.go index c6172e1..e842463 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,7 +1,7 @@ /* * @Date: 2021-06-10 18:51:48 * @LastEditors: viletyy - * @LastEditTime: 2021-06-10 18:53:10 + * @LastEditTime: 2021-06-14 21:13:01 * @FilePath: /potato/internal/service/service.go */ package service @@ -9,6 +9,7 @@ package service import ( "context" + otgorm "github.com/eddycjy/opentracing-gorm" "github.com/viletyy/potato/global" "github.com/viletyy/potato/internal/dao" ) @@ -20,7 +21,7 @@ type Service struct { func New(ctx context.Context) Service { svc := Service{Ctx: ctx} - svc.dao = dao.New(global.GO_DB) + svc.dao = dao.New(otgorm.WithContext(svc.Ctx, global.GO_DB)) return svc } diff --git a/main.go b/main.go index be404c1..edfa04a 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ /* * @Date: 2021-03-21 19:54:57 * @LastEditors: viletyy - * @LastEditTime: 2021-06-10 10:28:27 + * @LastEditTime: 2021-06-13 23:32:06 * @FilePath: /potato/main.go */ package main @@ -21,6 +21,7 @@ func main() { global.GO_LOG = initialize.Zap() global.GO_DB = initialize.Gorm() global.GO_REDIS = initialize.Redis() + global.GO_TRACER = initialize.Tracer() defer global.GO_DB.Close() defer global.GO_REDIS.Close() diff --git a/pkg/tracer/tracer.go b/pkg/tracer/tracer.go new file mode 100644 index 0000000..d176706 --- /dev/null +++ b/pkg/tracer/tracer.go @@ -0,0 +1,37 @@ +/* + * @Date: 2021-06-13 23:16:55 + * @LastEditors: viletyy + * @LastEditTime: 2021-06-13 23:24:34 + * @FilePath: /potato/pkg/tracer/tracer.go + */ +package tracer + +import ( + "io" + "time" + + opentracing "github.com/opentracing/opentracing-go" + "github.com/uber/jaeger-client-go/config" +) + +func NewJaegerTracer(serviceName, agentHostPort string) (opentracing.Tracer, io.Closer, error) { + // 设置应用的基本信息 + cfg := &config.Configuration{ + ServiceName: serviceName, + Sampler: &config.SamplerConfig{ + Type: "const", + Param: 1, + }, // 固定采样、对所有数据都进行采样 + Reporter: &config.ReporterConfig{ + LogSpans: true, + BufferFlushInterval: 1 * time.Second, + LocalAgentHostPort: agentHostPort, + }, // 是否启用LoggingReporter、刷新缓冲区都频率、上报的Agent地址 + } + tracer, closer, err := cfg.NewTracer() + if err != nil { + return nil, nil, err + } + opentracing.SetGlobalTracer(tracer) + return tracer, closer, nil +}