tasker.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2019 github.com. All rights reserved.
  2. // Use of this source code is governed by github.com.
  3. package httptasker
  4. import (
  5. "fmt"
  6. "net/http"
  7. "time"
  8. "github.com/gin-gonic/gin"
  9. "git.getensh.com/common/gopkgs/tasker"
  10. "go.uber.org/zap"
  11. "google.golang.org/grpc/codes"
  12. "google.golang.org/grpc/status"
  13. "git.getensh.com/common/gopkgs/logger"
  14. )
  15. // Error 出错时数据结构
  16. type Error struct {
  17. Code codes.Code `json:"code"`
  18. Message string `json:"message"`
  19. }
  20. // Task 任务函数
  21. type Task func() error
  22. // Exec 执行任务
  23. func Exec(ctx *gin.Context, tasks ...Task) (err error) {
  24. // 进程中断中,不再处理任务
  25. if tasker.Interrupted() {
  26. return tasker.InterruptError
  27. }
  28. // 开始时间
  29. startTime := uint64(time.Now().UnixNano())
  30. // 抓异常代码
  31. defer func() {
  32. if r := recover(); r != nil {
  33. if e, ok := r.(error); ok {
  34. err = e
  35. } else {
  36. err = fmt.Errorf("%+v", r)
  37. logger.Error("err",
  38. zap.String("system_err", err.Error()),
  39. zap.Stack("stacktrace"))
  40. }
  41. s := status.New(10002, "内部服务错误")
  42. if v, ok := status.FromError(err); ok {
  43. s = v
  44. }
  45. ctx.JSON(http.StatusOK, Error{Code: s.Code(), Message: s.Message()})
  46. // 打印到access.log日志中
  47. endTime := uint64(time.Now().UnixNano())
  48. tasker.LogInfo(ctx.Request.Method,
  49. zap.String("path", ctx.Request.URL.Path),
  50. zap.String("status", "failure"),
  51. zap.String("elapsed", fmt.Sprintf("%fms", float64(endTime-startTime)/1000000)),
  52. zap.String("remote_addr", ctx.Request.RemoteAddr), // 这里必须要配置nginx正确,否则内网IP
  53. zap.String("error", err.Error())) // 具体的错误消息
  54. return // 这里必须返回
  55. }
  56. // TODO 需要记录哪些信息
  57. // 打印到access.log日志中
  58. endTime := uint64(time.Now().UnixNano())
  59. tasker.LogInfo(ctx.Request.Method,
  60. zap.String("path", ctx.Request.URL.Path),
  61. zap.String("status", "success"),
  62. zap.String("elapsed", fmt.Sprintf("%fms", float64(endTime-startTime)/1000000)),
  63. zap.String("remote_addr", ctx.Request.RemoteAddr)) // 这里必须要配置nginx正确,否则内网IP
  64. }()
  65. // 按顺序执行任务
  66. for _, task := range tasks {
  67. if task != nil {
  68. if err = task(); err != nil {
  69. panic(err)
  70. }
  71. }
  72. }
  73. return
  74. }