Skip to content

Commit

Permalink
ref: Append Event struct with transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
AbhiPrasad committed Jun 1, 2020
1 parent b23d6a8 commit 1d9eeea
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 196 deletions.
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ func (client *Client) processEvent(event *Event, hint *EventHint, scope EventMod
return nil
}

if options.BeforeSend != nil {
if event.Type != "transaction" && options.BeforeSend != nil {
h := &EventHint{}
if hint != nil {
h = hint
Expand Down
117 changes: 38 additions & 79 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,40 @@ type Exception struct {

type EventID string

// Events are the fundamental data structure that are send to Sentry
// TraceContext describes the context of the trace.
type TraceContext struct {
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
Op string `json:"op,omitempty"`
Description string `json:"description,omitempty"`
}

// Span describes a AM Span following the Sentry format.
// Experimental: This is part of a beta feature of the SDK
type Span struct {
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
ParentSpanID string `json:"parent_span_id,omitempty"`
Description string `json:"description,omitempty"`
Op string `json:"op,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
StartTimestamp time.Time `json:"start_timestamp"`
EndTimestamp time.Time `json:"timestamp"`
Status string `json:"status"`
}

// MarshalJSON converts the Span struct to JSON.
func (s *Span) MarshalJSON() ([]byte, error) {
type alias Span

return json.Marshal(&struct {
*alias
}{
alias: (*alias)(s),
})
}

// Event is the fundamental data structure that is sent to Sentry
type Event struct {
Type string `json:"type,omitempty"`
Breadcrumbs []*Breadcrumb `json:"breadcrumbs,omitempty"`
Expand All @@ -168,8 +201,12 @@ type Event struct {
Modules map[string]string `json:"modules,omitempty"`
Request *Request `json:"request,omitempty"`
Exception []Exception `json:"exception,omitempty"`
// Experimental: This is part of a beta feature of the SDK
StartTimestamp time.Time `json:"start_timestamp"`
Spans []*Span `json:"spans,omitempty"`
}

// MarshalJSON converts the Event struct to JSON.
func (e *Event) MarshalJSON() ([]byte, error) {
type alias Event
// encoding/json doesn't support the "omitempty" option for struct types.
Expand Down Expand Up @@ -220,81 +257,3 @@ type EventHint struct {
Request *http.Request
Response *http.Response
}

// Span describes a AM Span following the Sentry format.
type Span struct {
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
ParentSpanID string `json:"parent_span_id,omitempty"`
Description string `json:"description,omitempty"`
Op string `json:"op,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
StartTimestamp time.Time `json:"start_timestamp"`
EndTimestamp time.Time `json:"timestamp"`
Status string `json:"status"`
}

// MarshalJSON converts the Span struct to JSON.
func (s *Span) MarshalJSON() ([]byte, error) {
type alias Span

if s.EndTimestamp.IsZero() || s.StartTimestamp.IsZero() {
return json.Marshal(&struct {
*alias
StartTimestamp json.RawMessage `json:"start_timestamp,omitempty"`
EndTimestamp json.RawMessage `json:"timestamp,omitempty"`
}{
alias: (*alias)(s),
})
}

return json.Marshal(&struct {
*alias
}{
alias: (*alias)(s),
})
}

// SentryEvent aliases the sentry Event type.
// Needed to Marshal the transactions into JSON properly.
type sentryEvent Event

// TraceContext describes the trace context of a transaction.
type TraceContext struct {
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
Op string `json:"op,omitempty"`
Description string `json:"description,omitempty"`
}

// Transaction describes a Sentry Transaction.
type Transaction struct {
*sentryEvent
StartTimestamp time.Time `json:"start_timestamp"`
Spans []*Span `json:"spans,omitempty"`
}

// MarshalJSON converts the Transaction struct to JSON.
func (t *Transaction) MarshalJSON() ([]byte, error) {
type alias Transaction

if t.Timestamp.IsZero() || t.StartTimestamp.IsZero() {
return json.Marshal(&struct {
*alias
StartTimestamp json.RawMessage `json:"start_timestamp,omitempty"`
EndTimestamp json.RawMessage `json:"timestamp,omitempty"`
Type string `json:"type"`
}{
Type: "transaction",
alias: (*alias)(t),
})
}

return json.Marshal(&struct {
*alias
Type string `json:"type"`
}{
Type: "transaction",
alias: (*alias)(t),
})
}
24 changes: 0 additions & 24 deletions interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,6 @@ func TestMarshalStruct(t *testing.T) {
testName: "span",
sentryStruct: testSpan,
},
{
testName: "transaction",
sentryStruct: func() *Transaction {
event := NewEvent()

event.Contexts["trace"] = TraceContext{
TraceID: "d6c4f03650bd47699ec65c84352b6208",
SpanID: "442bd97bbe564317",
Op: "http.server",
Description: "/api/users/{user_id}",
}

event.Tags["organization"] = "12345"
event.Timestamp = time.Unix(5, 0)

t := &Transaction{
sentryEvent: (*sentryEvent)(event),
StartTimestamp: time.Unix(0, 0),
Spans: []*Span{testSpan},
}

return t
}(),
},
}

for _, test := range testCases {
Expand Down
34 changes: 0 additions & 34 deletions testdata/transaction.golden

This file was deleted.

68 changes: 10 additions & 58 deletions transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strconv"
Expand All @@ -22,7 +20,6 @@ type Transport interface {
Flush(timeout time.Duration) bool
Configure(options ClientOptions)
SendEvent(event *Event)
SendTransaction(transaction *Transaction)
}

func getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL, error) {
Expand Down Expand Up @@ -95,15 +92,15 @@ func getRequestBodyFromEvent(event *Event) []byte {
return nil
}

func getRequestBodyFromTransaction(t *Transaction) (envelope *bytes.Buffer, err error) {
var b bytes.Buffer
enc := json.NewEncoder(&b)
// func getRequestBodyFromTransaction(t *Transaction) (envelope *bytes.Buffer, err error) {
// var b bytes.Buffer
// enc := json.NewEncoder(&b)

fmt.Fprintf(&b, `{"sent_at":"%s"}`, time.Now().UTC().Format(time.RFC3339Nano))
fmt.Fprint(&b, "\n", `{"type":"transaction"}`, "\n")
err = enc.Encode(t)
return &b, err
}
// fmt.Fprintf(&b, `{"sent_at":"%s"}`, time.Now().UTC().Format(time.RFC3339Nano))
// fmt.Fprint(&b, "\n", `{"type":"transaction"}`, "\n")
// err = enc.Encode(t)
// return &b, err
// }

// ================================
// HTTPTransport
Expand Down Expand Up @@ -188,53 +185,6 @@ func (t *HTTPTransport) Configure(options ClientOptions) {
})
}

// SendTransaction send a transaction to a remote server
func (t *HTTPTransport) SendTransaction(transaction *Transaction) error {
if t.dsn == nil {
return errors.New("Invalid DSN. Not sending Transaction")
}

t.mu.RLock()
disabled := time.Now().Before(t.disabledUntil)
t.mu.RUnlock()
if disabled {
return errors.New("Transport is disabled, cannot send transaction")
}

body, err := getRequestBodyFromTransaction(transaction)
if err != nil {
return err
}

request, _ := http.NewRequest(
http.MethodPost,
t.dsn.EnvelopeAPIURL().String(),
body,
)

for headerKey, headerValue := range t.dsn.RequestHeaders() {
request.Header.Set(headerKey, headerValue)
}

b := <-t.buffer

select {
case b.items <- request:
Logger.Printf(
"Sending %s transaction [%s] to %s project: %d\n",
transaction.Level,
transaction.EventID,
t.dsn.host,
t.dsn.projectID,
)
default:
Logger.Println("Event dropped due to transport buffer being full.")
}

t.buffer <- b
return nil
}

// SendEvent assembles a new packet out of `Event` and sends it to remote server.
func (t *HTTPTransport) SendEvent(event *Event) {
if t.dsn == nil {
Expand All @@ -254,6 +204,8 @@ func (t *HTTPTransport) SendEvent(event *Event) {

request, _ := http.NewRequest(
http.MethodPost,
// Need to skip before send
// TODO: Change based on event.type
t.dsn.StoreAPIURL().String(),
bytes.NewBuffer(body),
)
Expand Down

0 comments on commit 1d9eeea

Please sign in to comment.