raven-go icon indicating copy to clipboard operation
raven-go copied to clipboard

Logging breadcrumbs

Open ernestoalejo opened this issue 8 years ago • 7 comments

A method to add breadcrumbs before capturing the error.

ernestoalejo avatar Jan 08 '17 21:01 ernestoalejo

I also think this is a needed feature. I tried to implement the interface and Sentry happily accepts it but wont show the breadcurmbs/doesn't include the posted data in the JSON (HOSTNAME/sentry/:project/issues/:id/events/:eid/json).

If I could get a valid json post for breadcrumbs I could probably implement this

For reference here is the interface that I'm passing to raven(in json form)

{  
   "breadcrumbs":[  
      {  
         "timestamp":1484704331,
         "type":"default",
         "message":"This is a test",
         "category":"root",
         "string":"debug",
         "data":{  
            "foo":"Hello this is foo",
            "blub":"blub blub fishy"
         }
      },
      {  
         "timestamp":1484704331,
         "type":"default",
         "message":"This another test",
         "category":"root",
         "string":"debug",
         "data":{  
            "foo":"still foo",
            "blub":"still fishy"
         }
      }
   ]
}

And in hopes that some progress happens from this here is the the snippet that I'm using to create and send some things need to be added like the error value and the tag map. I'm assuming this is just a small change away from actually working unless it is just a fundamental issue with how Sentry's Go package creates packets to send out.

type Breadcrumb struct {
	Breadcrumbs []Crumbs `json:"breadcrumbs"`
}

type Crumbs struct {
	Timestamp int64       `json:"timestamp"`
	Type      string      `json:"type"`
	Message   string      `json:"message"`
	Category  string      `json:"category"`
	Level     string      `json:"string"`
	Data      interface{} `json:"data"`
}

func (b *Breadcrumb) Class() string {
        // Was sentry.interfaces.Breadcrumbs but changed to match interfaces.go
	return "breadcrumbs"
}

bread := &Breadcrumb{
  Breadcrumbs: []Crumbs{
    Crumbs{
      Timestamp: int64(time.Now().Unix()),
      Type:      "default",
      Message:   "This is a test",
      Category:  "root",
      Level:     "debug",
      Data: struct {
        Foo  string `json:"foo"`
        Blub string `json:"blub"`
      }{
        Foo:  "Hello this is foo",
        Blub: "blub blub fishy",
      },
    },
    Crumbs{
      Timestamp: int64(time.Now().Unix()),
      Type:      "default",
      Message:   "This another test",
      Category:  "root",
      Level:     "debug",
      Data: struct {
        Foo  string `json:"foo"`
        Blub string `json:"blub"`
      }{
        Foo:  "still foo",
        Blub: "still fishy",
      },
    },
  },
}

raven.CaptureErrorAndWait(err, tags, []raven.Interface{
	bread,
}...)

0x4445565A avatar Jan 18 '17 01:01 0x4445565A

Managed to get this working at least with http messages

type Breadcrumb struct {
	Breadcrumbs []Crumbs `json:"values"`
}

type Crumbs struct {
	Timestamp int64       `json:"timestamp"`
	Type      string      `json:"type"`
	Message   string      `json:"message"`
	Category  string      `json:"category"`
	Level     string      `json:"string"`
	Data      interface{} `json:"data"`
}

func (b *Breadcrumb) Class() string {
	return "breadcrumbs"
}


	bread := &Breadcrumb{
		Breadcrumbs: []Crumbs{
			Crumbs{
				Timestamp: int64(time.Now().Unix()),
				Type:      "http",
				Data: struct {
					URL        string `json:"url"`
					Method     string `json:"method"`
					StatusCode int    `json:"status_code"`
					Reason     string `json:"reason"`
				}{
					URL:        "http://example.com/api/1.0/users",
					Method:     "GET",
					StatusCode: 200,
					Reason:     "OK",
				},
			},
		},
	}
	b, _ := json.Marshal(bread)
	fmt.Println(string(b))

	raven.CaptureErrorAndWait(errors.New("Testing error"), map[string]string{"test": "yes"}, []raven.Interface{
		bread,
	}...)

This leads me to think the documentation for sentry's breadcrumb interface is incorrect. https://docs.sentry.io/clientdev/interfaces/breadcrumbs/

The example json is an object with a property breadcrumbs that is array, when in reality it needs to be a property named values.

0x4445565A avatar Jan 18 '17 02:01 0x4445565A

Apart from incomplete/plain wrong documentation (I had to copy structures from the Python client and the JSON result like you did) breadcrumbs gets generated during app execution, stored in a ring list and only sent to Sentry if an error occurs. It would be very helpful to have some kind of instance where you can add and add breadcrumbs to an internal ring structure and we'll send that structure when capturing the error. Something akin to the way the HTTP info is stored in the context but using multiple instances that can be passed as additional interfaces to CaptureError or added easily to the exception struct (we're generating our custom stack traces).

I have structs similar to the ones of the last comment but I also added the logging levels as constants:

type Level string

const (
	LevelCritical = Level("critical")
	LevelWarning  = Level("warning")
	LevelError    = Level("error")
	LevelInfo     = Level("info")
	LevelDebug    = Level("debug")
)

ernestoalejo avatar Jan 18 '17 09:01 ernestoalejo

It seems sentry does have these constants available in just a slightly different form, and they are exported

https://github.com/getsentry/raven-go/blob/master/client.go#L44

You should be able to access them like raven.DEBUG only difference is they use the phrase fatal instead of critical.

0x4445565A avatar Jan 18 '17 17:01 0x4445565A

I should have looked better. Thank you!

ernestoalejo avatar Jan 18 '17 17:01 ernestoalejo

Are breadcrumbs for this library on the development Roadmap? If not, has any decision been made on whether the support for this feature would be implemented in the near future?

kshitij10496 avatar Jun 18 '19 09:06 kshitij10496

@kshitij10496 https://github.com/getsentry/sentry-go :) (we'll move out of beta this week with all the necessary docs)

kamilogorek avatar Jun 18 '19 09:06 kamilogorek