debug.go 2.9 KB

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