debug.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package api
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "os"
  6. "time"
  7. "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/errs"
  8. "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/sse"
  9. context "github.com/kataras/iris/v12/context"
  10. "go.mongodb.org/mongo-driver/bson/primitive"
  11. )
  12. type DebugStage struct {
  13. DebugEvent `json:",inline"`
  14. Events []*DebugEvent `json:"events"`
  15. }
  16. type DebugEvent struct {
  17. ID string `json:"id"`
  18. Type string `json:"type"`
  19. Status string `json:"status"`
  20. Created int64 `json:"created"`
  21. Error *errs.Error `json:"error"`
  22. Data interface{} `json:"data"`
  23. }
  24. type DebugTaks struct {
  25. ID string `json:"id"`
  26. Status string `json:"status"`
  27. Created int64 `json:"created"`
  28. Stages []*DebugStage `json:"stages"`
  29. CurrentStage *DebugStage `json:"-"`
  30. Debug *Debugger `json:"-"`
  31. Request *http.Request `json:"request"`
  32. }
  33. func NewDebugTaks() *DebugTaks {
  34. return &DebugTaks{
  35. Stages: []*DebugStage{},
  36. CurrentStage: &DebugStage{},
  37. }
  38. }
  39. func (debug *DebugTaks) Stage(id string) *DebugStage {
  40. stage := &DebugStage{}
  41. stage.ID = id
  42. stage.Events = []*DebugEvent{}
  43. debug.Stages = append(debug.Stages, stage)
  44. debug.CurrentStage = stage
  45. return stage
  46. }
  47. func (stage *DebugStage) PushEvent(event *DebugEvent) {
  48. stage.Events = append(stage.Events, event)
  49. }
  50. func (debug *DebugTaks) Event(eventType, eventId string) *DebugEvent {
  51. event := &DebugEvent{
  52. ID: eventId,
  53. Type: eventType,
  54. Created: time.Now().Unix(),
  55. }
  56. debug.CurrentStage.PushEvent(event)
  57. return event
  58. }
  59. func (task *DebugTaks) Finalize() {
  60. var (
  61. debug = task.Debug
  62. out []byte
  63. err error
  64. channel = debug.Hub.GetChannel(debug.ChannelID)
  65. )
  66. if out, err = json.Marshal(task); err != nil {
  67. channel.Emit(&sse.Event{
  68. Kind: "debugger.error",
  69. Payload: err.Error(),
  70. })
  71. } else {
  72. channel.Emit(&sse.Event{
  73. Kind: "request",
  74. Payload: string(out),
  75. })
  76. }
  77. }
  78. type Debugger struct {
  79. ChannelID string
  80. Tasks []*DebugTaks
  81. Hub *sse.SSEHub
  82. }
  83. func (debug *Debugger) Handler() func(context.Context) {
  84. return func(ctx context.Context) {
  85. task := debug.CreateTask()
  86. task.Request = ctx.Request()
  87. ctx.Values().Set("#debug", task)
  88. ctx.Next()
  89. }
  90. }
  91. func (debug *Debugger) CreateTask() *DebugTaks {
  92. task := &DebugTaks{
  93. ID: primitive.NewObjectID().Hex(),
  94. Status: "",
  95. Created: time.Now().Unix(),
  96. Debug: debug,
  97. }
  98. debug.Tasks = append(debug.Tasks, task)
  99. return task
  100. }
  101. func (debug *Debugger) EventStream() func(context.Context) (interface{}, *errs.Error) {
  102. return func(ctx context.Context) (resp interface{}, err *errs.Error) {
  103. if err = debug.Hub.UpgradeConnection(
  104. ctx,
  105. debug.ChannelID,
  106. ); err != nil {
  107. return
  108. }
  109. resp = true
  110. return
  111. }
  112. }
  113. func NewDebug() *Debugger {
  114. return &Debugger{
  115. ChannelID: "debug",
  116. Tasks: []*DebugTaks{},
  117. Hub: sse.NewSSEHub(&sse.SSEOptions{
  118. URI: os.Getenv("REDIS_URI"),
  119. Password: os.Getenv("REDIS_PASSWD"),
  120. ChannelCollection: "debugger",
  121. }),
  122. }
  123. }