Giter Site home page Giter Site logo

getsentry / raven-go Goto Github PK

View Code? Open in Web Editor NEW
561.0 69.0 149.0 272 KB

Sentry client in Go

Home Page: https://sentry.io

License: BSD 3-Clause "New" or "Revised" License

Go 99.53% Shell 0.47%
error-monitoring crash-reporting crash-reports go tag-archived

raven-go's Introduction

raven

Build Status Go Report Card GoDoc


The raven-go SDK is no longer maintained and was superseded by the sentry-go SDK. Learn more about the project on GitHub and check out the migration guide.


raven is the official Go SDK for the Sentry event/error logging system.

Installation

go get github.com/getsentry/raven-go

Note: Go 1.7 and newer are supported.

raven-go's People

Contributors

aheuermann avatar bobrik avatar bsphere avatar codekitchen avatar dcramer avatar dvrkps avatar erikgrinaker avatar jackwink avatar joeirimpan avatar jonstaryuk avatar joshuaspence avatar jsm avatar jwagner avatar kamilogorek avatar ksophocleous avatar lumost avatar martinxsliu avatar marvell avatar mattrobenolt avatar mistereggroll avatar mitsuhiko avatar nexweb avatar shalakhin avatar sinjo avatar sjung-stripe avatar smarterclayton avatar taylortrimble avatar titanous avatar trilopin avatar vojtechvitek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

raven-go's Issues

No way to send custom extra data

Python client provides a way to send custom extra data client.captureMessage('message', extra={'foo': 'bar'}), but Go client doesn't.

Sending multiple exceptions at once

Is it possible to send multiple exceptions at once? I've tried creating a packet and then appending lots of "raven.Exception" structs to the .Interfaces field but only one exception ends up showing in Sentry. Am I doing it incorrectly?

Cannot "override" the `packet.Level` when calling `CaptureMessage`

It seams like there is no way to currently override the packet.Level when we call CaptureMessage. The call to client.context.interfaces() is also private so we cannot use the raw client.Capture() method to achieve the same result.

Is there any way to do this as we need to set the level tag to the "log level" on our side?

FAIL: TestStacktrace

go test

--- FAIL: TestStacktrace (0.00 seconds)
        stacktrace_test.go:64: incorrect ContextLine: "\treturn NewStacktrace(0, 2, []string{thisPackage})\r"
        stacktrace_test.go:67: incorrect PreContext []string{"// a\r", "func trace() *Stacktrace {\r"}
        stacktrace_test.go:70: incorrect PostContext []string{"\t// b\r", "}\r"}
FAIL
exit status 1
FAIL    github.com/cupcake/raven-go     0.301s

go version go1.2 windows/amd64

raven-go obscures panic error message

If I call panic, usually that error message appears in the stack trace.

package main

func main() {
    panic("error occurred")
}

Generates:

panic: error occurred

goroutine 1 [running]:
panic(0x56000, 0xc42000a130)
    /Users/kevin/go/src/runtime/panic.go:500 +0x1a1
main.main()
    /Users/kevin/foo.go:4 +0x6d
exit status 2

However when I use the RecoveryHandler, I get an empty panic message in the stack trace - I have to check my email or log into Sentry to actually see what the panic was.

Example:

goroutine 44 [running]:
runtime/debug.Stack(0x0, 0x3bb8a5e2010def0, 0x1c5243)
    /Users/kevin/go/src/runtime/debug/stack.go:24 +0x79
runtime/debug.PrintStack()
    /Users/kevin/go/src/runtime/debug/stack.go:16 +0x22
github.com/saintpete/logrole/vendor/github.com/getsentry/raven-go.RecoveryHandler.func1.1(0xc420746c30, 0x791be0, 0xc42023ee70)
    /Users/kevin/code/go/src/github.com/saintpete/logrole/vendor/github.com/getsentry/raven-go/http.go:74 +0x6e
panic(0x46d360, 0xc4204691a0)
    /Users/kevin/go/src/runtime/panic.go:458 +0x243
text/template.errRecover(0xc42010f248)
    /Users/kevin/go/src/text/template/exec.go:146 +0x18e

That panic is generated by this code in template/exec.go:

// errRecover is the handler that turns panics into returns from the top
// level of Parse.
func errRecover(errp *error) {
    e := recover()
    if e != nil {
        switch err := e.(type) {
        case runtime.Error:
            panic(e)
        case writeError:
            *errp = err.Err // Strip the wrapper.
        case ExecError:
            *errp = err // Keep the wrapper.
        default:
            panic(e)
        }
    }
}

In my email I see this:

*errors.errorString: unknown property FriendlyName

But for some reason that string is not in the generated stack trace; I expect it to say something like:

goroutine 44 [running]: unknown property FriendlyName

Methods do not check errors

Ran into an issue today where an Interface type contained a channel, which Go can't marshal into JSON. Obviously this isn't valid, but it didn't occur to me I was marshaling that (my Interface was a larger, quite nested struct) until I ran into an index out of range error which was quite annoying to debug at first.

My suggestion: check the errors and let them bubble up the stack.

(Here's the offending code:

interfaceJSON, _ := json.Marshal(interfaces)
)

Scanning through the library, there's a fair amount of other places where errors are swallowed.

Automatically populate modules

... or attempt to. This could prove to be difficult! 😉

If we get anywhere, we might want to share code (or steal code from) stacktrace.go

Spec:

modules

A list of relevant modules and their versions.

{
    "modules": [
        {
            "my.module.name": "1.0"
        }
    ]
}

CapturePanic not sending packets

I've hit a weird issue where if I use raven.CapturePanic, no data is sent to the sentry server if log.Panic is called. I am not sure why this happens, but it seems like a bug.

Environment:

  • OS: Max OS X
  • Go Version: 1.4.2
  • raven-go version/commit: e39495f
  • SENTRY_DSN env var is configured

Example Code:

import (
    "log"
    "github.com/getsentry/raven-go"
)

func main() {
    raven.CapturePanic(func() {
        log.Panic("My Panic")
    }, nil)
}

When running this code, no exception occurs in my Sentry server. Digging into the raven codebase on my local machine, I added some print statements in client.go:Capture:

func (client *Client) Capture(packet *Packet, captureTags map[string]string) (eventID string, ch chan error) {
    if client == nil {
        log.Print("NIL CLIENT")
        return
    }

    // Keep track of all running Captures so that we can wait for them all to finish
    // *Must* call client.wg.Done() on any path that indicates that an event was
    // finished being acted upon, whether success or failure
    client.wg.Add(1)

    ch = make(chan error, 1)

    // Merge capture tags and client tags
    packet.AddTags(captureTags)
    packet.AddTags(client.Tags)
    packet.AddTags(client.context.tags)

    // Initialize any required packet fields
    client.mu.RLock()
    projectID := client.projectID
    release := client.release
    client.mu.RUnlock()

    err := packet.Init(projectID)
    if err != nil {
        ch <- err
        client.wg.Done()
        return
    }
    packet.Release = release

    outgoingPacket := &outgoingPacket{packet, ch}

    select {
    case client.queue <- outgoingPacket:
    default:
        log.Print("PACKET DROP")
        // Send would block, drop the packet
        if client.DropHandler != nil {
            client.DropHandler(packet)
        }
        ch <- ErrPacketDropped
        client.wg.Done()
    }

    log.Print("DUN CAPTURE")
    return packet.EventID, ch
}

I also added a print statement in `client.go:worker()':

func (client *Client) worker() {
    for outgoingPacket := range client.queue {

        log.Print("outgoing packet")
        client.mu.RLock()
        url, authHeader := client.url, client.authHeader
        client.mu.RUnlock()

        outgoingPacket.ch <- client.Transport.Send(url, authHeader, outgoingPacket.packet)
        client.wg.Done()
    }
}

Running the code with this setup, I get the following output:

2016/06/07 10:32:58 My Panic
2016/06/07 10:32:58 DUN CAPTURE

As you notice, there is no print statement for outgoing packet. This seems to indicate that the error message packet is not being added to the channel/client.queue and preventing the packet from being sent to the server before the program exits.

Fix tag merging implementation to be on-spec

From the spec:

Tags are key/value pairs that describe an event. They should be configurable in the > following contexts:

  • Environment (client-level)
  • Thread (block-level)
  • Event (as part of capture)

Each of these should inherit its parent. So for example, if you configure your client as so:

client = Client(..., {
    'tags': {'foo': 'bar'},
})

And then you capture an event:

client.captureMessage('test', {
    'tags': {'foo': 'baz'},
})

The client should send the following upstream for tags:

{
    "tags": [
        ["foo", "bar"],
        ["foo", "baz"]
    ],
}

What does this mean for us? We should rethink how we merge tags, and allow duplicate "keys" by making packet.Tags something like this:

type Tag struct {
    Key   string,
    Value string
}

type Packet struct {
    ...
    Tags       []Tag      `json:"tags,omitempty"`
    ...
}

Memory leaks of `NewStacktraceFrame`

The raven-go version is SHA1 e39495fea085e98d1281fac0ff4d6eb8dc56f86d

How I use raven-go:

func init() {
    raven.SetDSN("http://6be8669224e04b92840321344621c998:[email protected]:9999/6")
}


...

raven.CaptureMessageAndWait("msg", nil)

Memory Profiling result:

Entering interactive mode (type "help" for commands)
(pprof) top
2155.64MB of 2155.69MB total (  100%)
Dropped 35 nodes (cum <= 10.78MB)
      flat  flat%   sum%        cum   cum%
 2122.53MB 98.46% 98.46%  2122.55MB 98.46%  github.com/getsentry/raven-go.NewStacktraceFrame
   33.11MB  1.54%   100%  2155.66MB   100%  github.com/getsentry/raven-go.NewStacktrace
         0     0%   100%  2155.66MB   100%  github.com/getsentry/raven-go.(*Client).CaptureErrorAndWait
         0     0%   100%  2155.66MB   100%  github.com/getsentry/raven-go.CaptureErrorAndWait
         0     0%   100%  2155.66MB   100%  main.(*Haijia).CheckAvail
         0     0%   100%  2155.66MB   100%  main.main
         0     0%   100%  2155.66MB   100%  main.main.func2
         0     0%   100%  2155.66MB   100%  main.notifyError
         0     0%   100%  2155.69MB   100%  runtime.goexit
         0     0%   100%  2155.66MB   100%  runtime.main

list

(pprof) list NewStacktraceFrame
Total: 2.11GB
ROUTINE ======================== github.com/getsentry/raven-go.NewStacktraceFrame in /Users/holys/code/src/github.com/getsentry/raven-go/stacktrace.go
    2.07GB     2.07GB (flat, cum) 98.46% of Total
         .          .     91:// one line with no surrounding context, and 0 returns no context.
         .          .     92://
         .          .     93:// appPackagePrefixes is a list of prefixes used to check whether a package should
         .          .     94:// be considered "in app".
         .          .     95:func NewStacktraceFrame(pc uintptr, file string, line, context int, appPackagePrefixes []string) *StacktraceFrame {
  641.16MB   641.16MB     96:   frame := &StacktraceFrame{AbsolutePath: file, Filename: trimPath(file), Lineno: line, InApp: false}
         .          .     97:   frame.Module, frame.Function = functionName(pc)
         .          .     98:
         .          .     99:   // `runtime.goexit` is effectively a placeholder that comes from
         .          .    100:   // runtime/asm_amd64.s and is meaningless.
         .          .    101:   if frame.Module == "runtime" && frame.Function == "goexit" {
         .          .    102:       return nil
         .          .    103:   }
         .          .    104:
         .          .    105:   if frame.Module == "main" {
         .          .    106:       frame.InApp = true
         .          .    107:   } else {
         .          .    108:       for _, prefix := range appPackagePrefixes {
         .          .    109:           if strings.HasPrefix(frame.Module, prefix) && !strings.Contains(frame.Module, "vendor") && !strings.Contains(frame.Module, "third_party") {
         .          .    110:               frame.InApp = true
         .          .    111:           }
         .          .    112:       }
         .          .    113:   }
         .          .    114:
         .          .    115:   if context > 0 {
         .    15.28kB    116:       contextLines, lineIdx := fileContext(file, line, context)
         .          .    117:       if len(contextLines) > 0 {
         .          .    118:           for i, line := range contextLines {
         .          .    119:               switch {
         .          .    120:               case i < lineIdx:
  901.01MB   901.01MB    121:                   frame.PreContext = append(frame.PreContext, string(line))
         .          .    122:               case i == lineIdx:
  192.24MB   192.24MB    123:                   frame.ContextLine = string(line)
         .          .    124:               default:
  388.12MB   388.12MB    125:                   frame.PostContext = append(frame.PostContext, string(line))
         .          .    126:               }
         .          .    127:           }
         .          .    128:       }
         .          .    129:   } else if context == -1 {
         .          .    130:       contextLine, _ := fileContext(file, line, 0)

It Seems the for loop never ends:

func NewStacktrace(skip int, context int, appPackagePrefixes []string) *Stacktrace {
    var frames []*StacktraceFrame
    for i := 1 + skip; ; i++ {
        pc, file, line, ok := runtime.Caller(0)
        if !ok {
            break
        }
            // it never break
        frame := NewStacktraceFrame(pc, file, line, context, appPackagePrefixes)
        if frame != nil {
            frames = append(frames, frame)
        }
    }

SetTagsContext, SetUserContext and SetHttpContext not working?

Hi,

I'm creating one recovery middleware to use with gin but on my tests the user and http contexts aren't being sent to sentry.

client, _ := raven.New(config.GetString("sentry.connection"))

ru := &raven.User{
    IP: c.ClientIP(),
}

tags := map[string]string{
    "endpoint": c.Request.RequestURI,
}

client.SetTagsContext(tags)
client.SetUserContext(ru)
client.SetHttpContext(raven.NewHttp(c.Request))

rvalStr := fmt.Sprint(rval)
packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)))
eventID, _ := client.Capture(packet, map[string]string{
    "environment": "production",
})

raven.ClearContext()

I noticed that when I use only the client.SetTagsContext the tags are not sent to sentry also.
Am I missing something here?

Thanks.

errors.errorString groups errors with different messages together

We are using errors.New(string) to generate dynamic errors from an external API. This API returns several errors codes in the body of the response.

Right now sentry groups all these errors into one, even when the messages are different. Is this the expected behavior?. And if it is, what suggestions do you guys have to handle errors in this case?

Panic handling using defer

Normal panic handling in go is done using a defered function: https://blog.golang.org/defer-panic-and-recover

How come we have to wrap our function in the raven library? Wrapping prevents us from returning values without using named returns, as far as I know.
It also means it adds another layer of complexity, whereas doing

defer raven.CapturePanic()

Any particular reason why it was done like that?
Is it possible to have use the normal pattern of panic handling?

Move to getsentry org?

I've been playing with this and I like it. Want to move it over to the org and we can share in maintaining and keeping it up to date?

Go client causes regression email to contain stale message field in subject line

Summary

I've run into this strange issue where the notification email for a regression shows a stale message field in the email subject. I've tried doing the exact same thing using raven-python, and it does not exhibit this behavior (of having a lagged/stale message in the regression email).

I'm not entirely sure if this is an issue with the go raven client or the Sentry server, since email should be completely handled by the server, but the Python raven client doesn't exhibit this problem...

Code:

package main
​
import (
    "fmt"
    "math/rand"
    "time""github.com/getsentry/raven-go"
)
​
func main() {
    sentryDSN := "<some sentry DSN here>"
    err := raven.SetDSN(sentryDSN)
    if err != nil {
        fmt.Printf("Could not initialize sentry at dsn %v: %v\n",
            sentryDSN, err)
        return
    }
​
    rand.Seed(time.Now().Unix())
    i := rand.Intn(10000)
    fmt.Printf("i= %v\n", i)
    raven.CaptureError(fmt.Errorf("i = %v", i), nil)
}

Repro steps:

  1. Run above go code. Say that the code randomly picked i = 123.
  2. See that issue shows up in Sentry. See that email notification subject line says "i = 123".
  3. Resolve issue in Sentry. Wait until after the notification digest period, say 5 min.
  4. Run above go code again. Say that this time the code picked i = 987.
  5. See the regression email notification subject line say "i = 123", which was the old message value.
  6. Also see that the Sentry web dashboard also says "i = 123" for a while.
  7. Wait a little, and then the Sentry web dashboard updates to correctly say "i = 987".

Versions

raven-go: dffeb57
go: go1.6.2 darwin/amd64
sentry: self-hosted install on version 8.5.1.

Could you create a tag or a release please?

Hi there

Loving the software!!

Any chance you could create a tag or a release version so we can stipulate what version to install with govendor?

So we could do something like this?

govendor get github.com/getsentry/raven-go@v=1.0

https://github.com/kardianos/govendor

We're currently pulling down master so at the mercy of any changes to master.

Thanks in advance

Matt

net/http: raven.RecoveryHandler cannot be passed into mux.Handle

If I create a new HTTP handler like so:

fooHandler, err := handlers.NewFooHandler()
if err != nil {
    log.Fatalf("Error: %s", err)
}

mux := http.NewServeMux()
mux.Handle("/foo/", raven.RecoveryHandler(fooHandler))

I get the following two exceptions:

cannot use fooHandler (type *handlers.SnsBounceHandler) as type func(http.ResponseWriter, *http.Request) in argument to raven.RecoveryHandler

cannot use raven.RecoveryHandler(snsBh) (type func(http.ResponseWriter, *http.Request)) as type http.Handler in argument to mux.Handle:
    func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method)

It looks like two things are occurring here:

  1. Custom objects that implement the http.Handler interface are not accepted in the raven.RecoveryHandler function.
  2. One cannot use the raven.RecoverHandler function with mux.Handle because RecoveryHandler returns a function handler instead of a http.Handle object.

Add crash handler

In a use-case I had locally, I wanted to purely capture top level crashes (and still raise them). There's nothing built-in as far as I could see to do this, so I ended up copy/pasting CapturePanic:

dropbox/changes-client#23

The big issues here are:

  • Ideally CapturePanic would work similar to CaptureError (and not have a crazy different callable signature)
  • There's no way to say "wait" when you Capture*
  • We want to re-panic() after

runtime.Caller() - Propegate line number and stack trace up to main package

My scenario is as follows. I have a package main and a package mylibrary. I have code in mylibrary that has the raven-go package imported and configured. I then run raven.CaptureAndWait().

I run my application that I have compiled (which runs func main() from package main). The package main imports mylibrary and the func main() makes a call to a visible function inside of mylibrary. In the event that an error is encoutered the raven.CaptureAndWait() is ran and the event is sent to Sentry. When I look in Sentry I see the line number in package main but not the line that caused the actual error in mylibrary. Is this an implementation issue with runtime.Caller() or am I implementing this incorrectly?

Timestamp produces an error

Hi,

Thanks for contributing this lib! Having issues logging events on sentry. It looks like the default timestamp on packets is not what sentry is expecting hence creating an error on every events.

There was 1 error encountered while processing this event.
Discarded invalid value for parameter 'timestamp' Collapse
{
"name": "timestamp",
"value": "2015-09-30T18:22:28Z"
}

Can't seem to locate the api docs to figure out what shape the timestamp should be??

Leaking goroutines.

Merely including raven-go results in leaking goroutines. The culprit is this line:

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

main.go

package main

main_test.go

package main

import (
    "fmt"
    "os"
    "testing"

    _ "github.com/getsentry/raven-go"

    "github.com/uber/tchannel-go/testutils/goroutines"
)

func TestMain(m *testing.M) {
    exitCode := m.Run()
    if err := goroutines.IdentifyLeaks(nil); err != nil && exitCode == 0 {
        fmt.Fprintf(os.Stderr, "Found goroutine leaks on successful test run: %v", err)
        exitCode = 1
    }
    os.Exit(exitCode)
}
$ go test
PASS
Found goroutine leaks on successful test run: found unexpected goroutines:
[Goroutine 5 in state chan receive, with vendor/github.com/getsentry/raven-go.(*Client).worker on top of the stack:
goroutine 5 [chan receive]:
vendor/github.com/getsentry/raven-go.(*Client).worker(0xc8200be210)
    vendor/github.com/getsentry/raven-go/client.go:418 +0x60
created by vendor/github.com/getsentry/raven-go.newClient
    vendor/github.com/getsentry/raven-go/client.go:307 +0x193
]FAIL   test    0.913s

Stack trace, wrong skip

In Client.CaptureError(), NewStacktrace() is called with skip=1.
So, it properly skips the current function.

In in CaptureError() (the "global" function), DefaultClient.CaptureError is called, but the skip value is the same.
Iit doesn't skip the call to CaptureError().

Is it the right way to use raven-go?

Hi!

Is it the right way to use raven-go? If yes I get empty stacktrace in sentry. Event ID is also None.

screenshot 2014-03-09 03 29 03

// trace generates raven traceback
func trace() *raven.Stacktrace {
    return raven.NewStacktrace(0, 3, []string{"myproject"})
}

// HandleError handles error like logging, mail notification.
func HandleError(err error) {
    packet := &raven.Packet{Message: err.Error(), Interfaces: []raven.Interface{raven.NewException(err, trace())}}
    if client, err := raven.NewClient(production.Sentry.DSN, map[string]string{}); err != nil {
            panic(err)
    }
    client.Capture(packet, nil)
    log.SetPrefix("[ERROR]")
    log.Println(err.Error())
}

CaptureWarning

Same as CaptureError, or a way to add severity level to CaptureError...

Context methods

From the spec:

You should also provide relevant contextual interfaces. These should last for the lifecycle of a request, and the general interface is “bind some kind of context”, and then at the end of a request lifecycle, clear any present context.

This interface consists of *_context methods, as well as a “clear context” method. The following is an example API which is implemented in most clients:

# Bind sentry.interfaces.User
client.user_context({
    'email': '[email protected]',
})

# Merge in additional tag context
client.tags_context({
    'key': 'value',
})

# Merge in additional extra context
client.extra_context({
    'key': 'value',
})

# Clear context
client.context.clear()

Some additional examples of context helpers which might be relevant:

http_context(data) – bind sentry.interfaces.Http
wsgi_context(env) – bind http_context based on a wsgi environment

However, the context they're talking about relies heavily on thread locals. This is true of the raven-python and raven-ruby client implementations.

What this essentially means is that in Go (which has nothing like thread-global accessible thread-local storage) we have to pass something around. This can be the context itself, or, my preference, a copy of the client with context added.

Do you support github.com/pkg/errors stacktrace ?

In go, errors don't have a stacktrace.
Errors reported with Sentry/raven-go show the stacktrace of the Capture call, instead of where the errors come from.

The github.com/pkg/errors package adds stack trace to Go errors. (you must wrap all errors with errors.Wrap)
I don't think you currently support the stacktrace format of this package.
Do you plan to support it?

questions about mobile / offline

I am looking something to catch all errors that occur on my golang clients.
I use web, desktop and mobile and code then all with golang.

I have a few questions, as i could not see the answers to these:

Do you have a gomobile version for android / ios ?

Do you have an offline version, so that errors are stored and then forwarded ?

A simple example

Morning all

We're just starting on our Go journey, so please excuse the dumbass.

Do you have a very simple example of how to trigger a push to our sentry server using raven-go?

I'm on OSX 10.11.1, and running go1.5.1 darwin/amd64.

I've tried using some of the examples in this repo, and some I've found elsewhere, but I must be doing something fundamentally wrong as I just can't get it to push to sentry.

Any tips, or links, gratefully accepted.

Log warning if SENTRY_DSN is not set

If the DSN is not configured for the client, no warning or message gets logged indicating that there is a problem. Compared to the python version of the raven library, a message DOES get logged indicating that the SENTRY_DSN has not been set in the codebase or environment variable.

To help users debug configuration issues, a message should be logged when raven-go does not get configured with a DSN.

Breaking API, Versioning, and Beyond

Hey all!

I'm back to work on this again, and am really motivated to polish raven-go into a package that matches the client spec and has most of the same characteristics as the other raven packages. See #19, and hold me to it! 😃

However, changing API brings up a problem... go get! If we're making a few API changes that's going to be breaking people who use go get. I have some thoughts about how to manage this.

Releases and Versions

It would be nice to start tagging versioned releases with GitHub. Semver of course. I'd also like to say that we declare the package 1.0 when we match the client spec linked above.

Not Breaking

I have a small plan.

Keep breaking changes out of master for a guaranteed minimum period of time. This will make sure our go get people don't have to be integrating new changes all the time; I'd like them to like us. 😄 We can pick a breaking release schedule and set up a mailing list for reminders.

So for working on 1.0 and other breaking releases, develop in a vX branch. When it's ready to ship on schedule, we pull it into master. Anyone can get them from the tags if they're anxious for the changes ahead of schedule.


Feedback please! Esp. @titanous and @mattrobenolt. Thank you guys, excited to jump back into this.

Async submission by default

Currently, the Sentry docs encourage you to do async submission whenever possible:

Additionally, the following features are highly encouraged:

  • Automated error handling (e.g. default error handlers)
  • Logging integration (to whatever standard solution is available)
  • Non-blocking event submission
  • Basic data sanitization (e.g. filtering out values that look like passwords)

This is the desirable configuration in 99% of production cases, but it means that simple "hey look I can send" demos don't work if you don't make your goroutine sleep.

The raven-python client only has a send method, and automatically decides whether or not to send asynchronously based on the transport. I think we should do this as well. We could supply an option to disable it, but that would still trip up newbies just trying to send and oh-my-it-works.

I recommend making the change as a highly desirable default, and updating the docs and example. We could also consider making that example show up as a step-by-step demo in the README. I could do that.

Whatchya think?

Compilation failed due to difference in package names

I have a package that depends on this package and it fails on tests due to following

➜  logrus_sentry git:(master) ✗ go test
# _/Users/<username>/Projects/logrus_sentry
./sentry.go:71: undefined: raven.New
./sentry.go:82: undefined: raven.NewWithTags
./sentry_test.go:107: undefined: raven.New
FAIL    _/Users/<username>/Projects/logrus_sentry [build failed]

Support UDP transport

It would be great to support UDP DSNs (I don't believe that this is supported currently). The Raven node.js client supports this.

CapturePanic for goroutines

Hey!

Is there a way to add a global panic handler? Using CapturePanic limits the scope to the current go routine. A cursory search seems to indicate nothing in Go allows one to install such a handler.

UUID should not have hyphens

Other clients do use UUID4s, but we shouldn't use hypens. Spec:

event_id

Hexadecimal string representing a uuid4 value.

Maximum length is 32 characters.

{
    "event_id": "fc6d8c0c43fc4630ad850ee518f1b9d0"
}

I actually addressed this in #19, so if we merge that we'll be golden.

Nil packet Interface causes panic

When nil is included in the ...raven.Interface arguments, panic: runtime error: invalid memory address or nil pointer dereference occurs in the http transport worker.

Example:

package main

import (
    "time"
    "github.com/getsentry/raven-go"
)

func main() {
    dsn := "https://12312312:[email protected]/231231" // any valid looking dsn, doesn't matter
    c, err := raven.NewClient(dsn, nil)
    if err != nil {
        panic(err)
    }
    defer c.Close()
    msg := "msg"
    tags := map[string]string{"foo": "bar"}
    c.CaptureMessage(msg, tags, nil) // extra nil raven.Interface
    time.Sleep(time.Second * 3)
}
$ go run main.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x473a7a]

goroutine 21 [running]:
github.com/getsentry/raven-go.(*Packet).JSON(0xc8200c8500, 0x0, 0x0, 0x0)
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:238 +0x15a
github.com/getsentry/raven-go.serializedPacket(0xc8200c8500, 0x0, 0x0, 0x0, 0x0)
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:682 +0x58
github.com/getsentry/raven-go.(*HTTPTransport).Send(0xc820085470, 0xc8200854d0, 0x2b, 0xc8200a2780, 0x45, 0xc8200c8500, 0x0, 0x0)
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:664 +0x6a
github.com/getsentry/raven-go.(*Client).worker(0xc8200de160)
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:421 +0x166
created by github.com/getsentry/raven-go.newClient
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:304 +0x192

goroutine 1 [sleep]:
time.Sleep(0xb2d05e00)
    /home/steve/.gvm/gos/go1.5/src/runtime/time.go:59 +0xf9
main.main()
    /tmp/rvn/2/main.go:18 +0x210

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /home/steve/.gvm/gos/go1.5/src/runtime/asm_amd64.s:1696 +0x1

goroutine 20 [chan receive]:
github.com/getsentry/raven-go.(*Client).worker(0xc8200de0b0)
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:415 +0x60
created by github.com/getsentry/raven-go.newClient
    /home/steve/.gvm/pkgsets/go1.5/raven-go/src/github.com/getsentry/raven-go/client.go:304 +0x192
exit status 2

Clever Capture Culpriting

... and stacktracing.

When we use CapturePanics, do we get the ideal culprit? Stacktrace? What if we have multiple levels of defers?

I'm guessing that right now we don't: at the very least we should write tests, and anything that is sub-par should be fixed.

Random panics

Raven library randomly panics
stack := raven.NewStacktrace(0, contextLines, []string{})

runtime.panic(0xb94200, 0x1831fea)
/usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
github.com/cupcake/raven-go.fileContext(0x161e3d0, 0x24, 0xfffffffffffffffe, 0x7, 0x0, ...)
/data/jenkins/jobs/master-build/workspace/lib/src/github.com/cupcake/raven-go/stacktrace.go:163 +0x2ca
github.com/cupcake/raven-go.NewStacktraceFrame(0x6ae5f5, 0x161e3d0, 0x24, 0x1, 0x3, ...)
/data/jenkins/jobs/master-build/workspace/lib/src/github.com/cupcake/raven-go/stacktrace.go:98 +0x1f1
github.com/cupcake/raven-go.NewStacktrace(0x0, 0x3, 0x7fa918f718f8, 0x0, 0x0, ...)
/data/jenkins/jobs/master-build/workspace/lib/src/github.com/cupcake/raven-go/stacktrace.go:67 +0x196
util.newRavenStacktrace(0x481d00)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.