interfaces.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package sentry
  2. import (
  3. "context"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "net/http"
  8. "strings"
  9. )
  10. // Protocol Docs (kinda)
  11. // https://github.com/getsentry/rust-sentry-types/blob/master/src/protocol/v7.rs
  12. // Level marks the severity of the event
  13. type Level string
  14. const (
  15. LevelDebug Level = "debug"
  16. LevelInfo Level = "info"
  17. LevelWarning Level = "warning"
  18. LevelError Level = "error"
  19. LevelFatal Level = "fatal"
  20. )
  21. // https://docs.sentry.io/development/sdk-dev/interfaces/sdk/
  22. type SdkInfo struct {
  23. Name string `json:"name,omitempty"`
  24. Version string `json:"version,omitempty"`
  25. Integrations []string `json:"integrations,omitempty"`
  26. Packages []SdkPackage `json:"packages,omitempty"`
  27. }
  28. type SdkPackage struct {
  29. Name string `json:"name,omitempty"`
  30. Version string `json:"version,omitempty"`
  31. }
  32. // TODO: This type could be more useful, as map of interface{} is too generic
  33. // and requires a lot of type assertions in beforeBreadcrumb calls
  34. // plus it could just be `map[string]interface{}` then
  35. type BreadcrumbHint map[string]interface{}
  36. // https://docs.sentry.io/development/sdk-dev/interfaces/breadcrumbs/
  37. type Breadcrumb struct {
  38. Category string `json:"category,omitempty"`
  39. Data map[string]interface{} `json:"data,omitempty"`
  40. Level Level `json:"level,omitempty"`
  41. Message string `json:"message,omitempty"`
  42. Timestamp int64 `json:"timestamp,omitempty"`
  43. Type string `json:"type,omitempty"`
  44. }
  45. // https://docs.sentry.io/development/sdk-dev/interfaces/user/
  46. type User struct {
  47. Email string `json:"email,omitempty"`
  48. ID string `json:"id,omitempty"`
  49. IPAddress string `json:"ip_address,omitempty"`
  50. Username string `json:"username,omitempty"`
  51. }
  52. // https://docs.sentry.io/development/sdk-dev/interfaces/http/
  53. type Request struct {
  54. URL string `json:"url,omitempty"`
  55. Method string `json:"method,omitempty"`
  56. Data string `json:"data,omitempty"`
  57. QueryString string `json:"query_string,omitempty"`
  58. Cookies string `json:"cookies,omitempty"`
  59. Headers map[string]string `json:"headers,omitempty"`
  60. Env map[string]string `json:"env,omitempty"`
  61. }
  62. func (r Request) FromHTTPRequest(request *http.Request) Request {
  63. // Method
  64. r.Method = request.Method
  65. // URL
  66. protocol := schemeHTTP
  67. if request.TLS != nil || request.Header.Get("X-Forwarded-Proto") == "https" {
  68. protocol = schemeHTTPS
  69. }
  70. r.URL = fmt.Sprintf("%s://%s%s", protocol, request.Host, request.URL.Path)
  71. // Headers
  72. headers := make(map[string]string, len(request.Header))
  73. for k, v := range request.Header {
  74. headers[k] = strings.Join(v, ",")
  75. }
  76. headers["Host"] = request.Host
  77. r.Headers = headers
  78. // Cookies
  79. r.Cookies = request.Header.Get("Cookie")
  80. // Env
  81. if addr, port, err := net.SplitHostPort(request.RemoteAddr); err == nil {
  82. r.Env = map[string]string{"REMOTE_ADDR": addr, "REMOTE_PORT": port}
  83. }
  84. // QueryString
  85. r.QueryString = request.URL.RawQuery
  86. // Body
  87. if request.GetBody != nil {
  88. if bodyCopy, err := request.GetBody(); err == nil && bodyCopy != nil {
  89. body, err := ioutil.ReadAll(bodyCopy)
  90. if err == nil {
  91. r.Data = string(body)
  92. }
  93. }
  94. }
  95. return r
  96. }
  97. // https://docs.sentry.io/development/sdk-dev/interfaces/exception/
  98. type Exception struct {
  99. Type string `json:"type,omitempty"`
  100. Value string `json:"value,omitempty"`
  101. Module string `json:"module,omitempty"`
  102. Stacktrace *Stacktrace `json:"stacktrace,omitempty"`
  103. RawStacktrace *Stacktrace `json:"raw_stacktrace,omitempty"`
  104. }
  105. type EventID string
  106. // https://docs.sentry.io/development/sdk-dev/attributes/
  107. type Event struct {
  108. Breadcrumbs []*Breadcrumb `json:"breadcrumbs,omitempty"`
  109. Contexts map[string]interface{} `json:"contexts,omitempty"`
  110. Dist string `json:"dist,omitempty"`
  111. Environment string `json:"environment,omitempty"`
  112. EventID EventID `json:"event_id,omitempty"`
  113. Extra map[string]interface{} `json:"extra,omitempty"`
  114. Fingerprint []string `json:"fingerprint,omitempty"`
  115. Level Level `json:"level,omitempty"`
  116. Message string `json:"message,omitempty"`
  117. Platform string `json:"platform,omitempty"`
  118. Release string `json:"release,omitempty"`
  119. Sdk SdkInfo `json:"sdk,omitempty"`
  120. ServerName string `json:"server_name,omitempty"`
  121. Threads []Thread `json:"threads,omitempty"`
  122. Tags map[string]string `json:"tags,omitempty"`
  123. Timestamp int64 `json:"timestamp,omitempty"`
  124. Transaction string `json:"transaction,omitempty"`
  125. User User `json:"user,omitempty"`
  126. Logger string `json:"logger,omitempty"`
  127. Modules map[string]string `json:"modules,omitempty"`
  128. Request Request `json:"request,omitempty"`
  129. Exception []Exception `json:"exception,omitempty"`
  130. }
  131. func NewEvent() *Event {
  132. event := Event{
  133. Contexts: make(map[string]interface{}),
  134. Extra: make(map[string]interface{}),
  135. Tags: make(map[string]string),
  136. Modules: make(map[string]string),
  137. }
  138. return &event
  139. }
  140. type Thread struct {
  141. ID string `json:"id,omitempty"`
  142. Name string `json:"name,omitempty"`
  143. Stacktrace *Stacktrace `json:"stacktrace,omitempty"`
  144. RawStacktrace *Stacktrace `json:"raw_stacktrace,omitempty"`
  145. Crashed bool `json:"crashed,omitempty"`
  146. Current bool `json:"current,omitempty"`
  147. }
  148. type EventHint struct {
  149. Data interface{}
  150. EventID string
  151. OriginalException error
  152. RecoveredException interface{}
  153. Context context.Context
  154. Request *http.Request
  155. Response *http.Response
  156. }