Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set SDK Name According Framework being used #694

Merged
merged 10 commits into from Aug 29, 2023
Merged
34 changes: 28 additions & 6 deletions client.go
Expand Up @@ -17,6 +17,9 @@ import (
"github.com/getsentry/sentry-go/internal/debug"
)

// The identifier of the SDK.
const sdkIdentifier = "sentry.go"

// maxErrorDepth is the maximum number of errors reported in a chain of errors.
// This protects the SDK from an arbitrarily long chain of wrapped errors.
//
Expand Down Expand Up @@ -223,10 +226,13 @@ type ClientOptions struct {
// Client is the underlying processor that is used by the main API and Hub
// instances. It must be created with NewClient.
type Client struct {
mu sync.RWMutex
options ClientOptions
dsn *Dsn
eventProcessors []EventProcessor
integrations []Integration
sdkIdentifier string
sdkVersion string
// Transport is read-only. Replacing the transport of an existing client is
// not supported, create a new client instead.
Transport Transport
Expand Down Expand Up @@ -323,8 +329,10 @@ func NewClient(options ClientOptions) (*Client, error) {
}

client := Client{
options: options,
dsn: dsn,
options: options,
dsn: dsn,
sdkIdentifier: sdkIdentifier,
sdkVersion: SDKVersion,
}

client.setupTransport()
Expand Down Expand Up @@ -396,7 +404,7 @@ func (client *Client) AddEventProcessor(processor EventProcessor) {
}

// Options return ClientOptions for the current Client.
func (client Client) Options() ClientOptions {
func (client *Client) Options() ClientOptions {
// Note: internally, consider using `client.options` instead of `client.Options()` to avoid copying the object each time.
return client.options
}
Expand Down Expand Up @@ -561,6 +569,20 @@ func (client *Client) EventFromCheckIn(checkIn *CheckIn, monitorConfig *MonitorC
return event
}

func (client *Client) SetSDKIdentifier(identifier string) {
client.mu.Lock()
defer client.mu.Unlock()

client.sdkIdentifier = identifier
}

func (client *Client) GetSDKIdentifier() string {
client.mu.RLock()
defer client.mu.RUnlock()

return client.sdkIdentifier
}

// reverse reverses the slice a in place.
func reverse(a []Exception) {
for i := len(a)/2 - 1; i >= 0; i-- {
Expand Down Expand Up @@ -646,7 +668,7 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod

event.Platform = "go"
event.Sdk = SdkInfo{
Name: SDKIdentifier,
Name: client.GetSDKIdentifier(),
Version: SDKVersion,
Integrations: client.listIntegrations(),
Packages: []SdkPackage{{
Expand Down Expand Up @@ -687,15 +709,15 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod
return event
}

func (client Client) listIntegrations() []string {
func (client *Client) listIntegrations() []string {
integrations := make([]string, len(client.integrations))
for i, integration := range client.integrations {
integrations[i] = integration.Name()
}
return integrations
}

func (client Client) integrationAlreadyInstalled(name string) bool {
func (client *Client) integrationAlreadyInstalled(name string) bool {
for _, integration := range client.integrations {
if integration.Name() == name {
return true
Expand Down
8 changes: 8 additions & 0 deletions client_test.go
Expand Up @@ -717,6 +717,14 @@ func TestCustomMaxSpansProperty(t *testing.T) {
assertEqual(t, properClient.Options().MaxSpans, 3000)
}

func TestSDKIdentifier(t *testing.T) {
client, _, _ := setupClientTest()
assertEqual(t, client.GetSDKIdentifier(), "sentry.go")

client.SetSDKIdentifier("sentry.go.test")
assertEqual(t, client.GetSDKIdentifier(), "sentry.go.test")
}

func TestClientSetsUpTransport(t *testing.T) {
client, _ := NewClient(ClientOptions{Dsn: testDsn})
require.IsType(t, &HTTPTransport{}, client.Transport)
Expand Down
1 change: 1 addition & 0 deletions dsn.go
Expand Up @@ -197,6 +197,7 @@ func (dsn Dsn) GetAPIURL() *url.URL {
}

// RequestHeaders returns all the necessary headers that have to be used in the transport.
// Deprecated: To be removed in 0.25.0. Requests to /envelope are authenticated using the DSN in the envelope header itself.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleptric marked this conversation as resolved.
Show resolved Hide resolved
func (dsn Dsn) RequestHeaders() map[string]string {
auth := fmt.Sprintf("Sentry sentry_version=%s, sentry_timestamp=%d, "+
"sentry_client=sentry.go/%s, sentry_key=%s", apiVersion, time.Now().Unix(), Version, dsn.publicKey)
Expand Down
6 changes: 6 additions & 0 deletions echo/sentryecho.go
Expand Up @@ -9,6 +9,9 @@
"github.com/labstack/echo/v4"
)

// The identifier of the Echo SDK.
const sdkIdentifier = "sentry.go.echo"

const valuesKey = "sentry"

type handler struct {
Expand Down Expand Up @@ -49,8 +52,11 @@
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

hub.Scope().SetRequest(ctx.Request())
ctx.Set(valuesKey, hub)

Check warning on line 59 in echo/sentryecho.go

View check run for this annotation

Codecov / codecov/patch

echo/sentryecho.go#L56-L59

Added lines #L56 - L59 were not covered by tests
defer h.recoverWithSentry(hub, ctx.Request())
return next(ctx)
}
Expand Down
6 changes: 6 additions & 0 deletions fasthttp/sentryfasthttp.go
Expand Up @@ -13,6 +13,9 @@ import (
"github.com/valyala/fasthttp"
)

// The identifier of the FastHTTP SDK.
const sdkIdentifier = "sentry.go.fasthttp"

type contextKey int

const ContextKey = contextKey(1)
Expand Down Expand Up @@ -58,6 +61,9 @@ func (h *Handler) Handle(handler fasthttp.RequestHandler) fasthttp.RequestHandle
// standard net/http.Request and because fasthttp.RequestCtx implements
// context.Context but requires string keys.
hub := sentry.CurrentHub().Clone()

hub.Client().SetSDKIdentifier(sdkIdentifier)

scope := hub.Scope()
scope.SetRequest(convert(ctx))
scope.SetRequestBody(ctx.Request.Body())
Expand Down
6 changes: 6 additions & 0 deletions gin/sentrygin.go
Expand Up @@ -13,6 +13,9 @@ import (
"github.com/gin-gonic/gin"
)

// The identifier of the Gin SDK.
const sdkIdentifier = "sentry.go.gin"

const valuesKey = "sentry"

type handler struct {
Expand Down Expand Up @@ -54,6 +57,9 @@ func (h *handler) handle(c *gin.Context) {
hub = sentry.CurrentHub().Clone()
ctx = sentry.SetHubOnContext(ctx, hub)
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

options := []sentry.SpanOption{
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(c.Request),
Expand Down
6 changes: 6 additions & 0 deletions http/sentryhttp.go
Expand Up @@ -11,6 +11,9 @@ import (
"github.com/getsentry/sentry-go"
)

// The identifier of the Gin SDK.
const sdkIdentifier = "sentry.go.http"

// A Handler is an HTTP middleware factory that provides integration with
// Sentry.
type Handler struct {
Expand Down Expand Up @@ -86,6 +89,9 @@ func (h *Handler) handle(handler http.Handler) http.HandlerFunc {
hub = sentry.CurrentHub().Clone()
ctx = sentry.SetHubOnContext(ctx, hub)
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

options := []sentry.SpanOption{
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(r),
Expand Down
6 changes: 6 additions & 0 deletions iris/sentryiris.go
Expand Up @@ -12,6 +12,9 @@ import (
"github.com/kataras/iris/v12"
)

// The identifier of the Iris SDK.
const sdkIdentifier = "sentry.go.iris"

const valuesKey = "sentry"

type handler struct {
Expand Down Expand Up @@ -51,6 +54,9 @@ func (h *handler) handle(ctx iris.Context) {
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

hub.Scope().SetRequest(ctx.Request())
ctx.Values().Set(valuesKey, hub)
defer h.recoverWithSentry(hub, ctx.Request())
Expand Down
6 changes: 6 additions & 0 deletions logrus/logrusentry.go
Expand Up @@ -10,6 +10,9 @@ import (
"github.com/sirupsen/logrus"
)

// The identifier of the Logrus SDK.
const sdkIdentifier = "sentry.go.logrus"

// These default log field keys are used to pass specific metadata in a way that
// Sentry understands. If they are found in the log fields, and the value is of
// the expected datatype, it will be converted from a generic field, into Sentry
Expand Down Expand Up @@ -52,6 +55,9 @@ func New(levels []logrus.Level, opts sentry.ClientOptions) (*Hook, error) {
if err != nil {
return nil, err
}

client.SetSDKIdentifier(sdkIdentifier)

return NewFromClient(levels, client), nil
}

Expand Down
6 changes: 6 additions & 0 deletions martini/sentrymartini.go
Expand Up @@ -9,6 +9,9 @@
"github.com/go-martini/martini"
)

// The identifier of the Martini SDK.
const sdkIdentifier = "sentry.go.martini"

type handler struct {
repanic bool
waitForDelivery bool
Expand Down Expand Up @@ -46,6 +49,9 @@
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

Check warning on line 54 in martini/sentrymartini.go

View check run for this annotation

Codecov / codecov/patch

martini/sentrymartini.go#L53-L54

Added lines #L53 - L54 were not covered by tests
hub.Scope().SetRequest(r)
ctx.Map(hub)
defer h.recoverWithSentry(hub, r)
Expand Down
6 changes: 6 additions & 0 deletions negroni/sentrynegroni.go
Expand Up @@ -9,6 +9,9 @@
"github.com/urfave/negroni"
)

// The identifier of the Negroni SDK.
const sdkIdentifier = "sentry.go.negroni"

type handler struct {
repanic bool
waitForDelivery bool
Expand Down Expand Up @@ -47,6 +50,9 @@
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

hub.Client().SetSDKIdentifier(sdkIdentifier)

Check warning on line 55 in negroni/sentrynegroni.go

View check run for this annotation

Codecov / codecov/patch

negroni/sentrynegroni.go#L54-L55

Added lines #L54 - L55 were not covered by tests
hub.Scope().SetRequest(r)
ctx = sentry.SetHubOnContext(
context.WithValue(ctx, sentry.RequestContextKey, r),
Expand Down
10 changes: 5 additions & 5 deletions sentry.go
Expand Up @@ -5,22 +5,22 @@ import (
"time"
)

// Deprecated: Use SDKVersion instead.
// The version of the SDK.
// Deprecated: To be removed in 0.25.0. Use SDKVersion instead.
const Version = SDKVersion

// Version is the version of the SDK.
// The version of the SDK.
const SDKVersion = "0.23.0"

// The identifier of the SDK.
// Deprecated: To be removed in 0.25.0. Use Client.GetSDKIdentifier() instead.
const SDKIdentifier = "sentry.go"

// apiVersion is the minimum version of the Sentry API compatible with the
// sentry-go SDK.
// Deprecated: To be removed in 0.25.0.
const apiVersion = "7"

// userAgent is the User-Agent of outgoing HTTP requests.
const userAgent = "sentry-go/" + SDKVersion

// Init initializes the SDK with options. The returned error is non-nil if
// options is invalid, for instance if a malformed DSN is provided.
func Init(options ClientOptions) error {
Expand Down
11 changes: 2 additions & 9 deletions transport.go
Expand Up @@ -209,7 +209,8 @@ func envelopeFromBody(event *Event, dsn *Dsn, sentAt time.Time, body json.RawMes
func getRequestFromEvent(event *Event, dsn *Dsn) (r *http.Request, err error) {
defer func() {
if r != nil {
r.Header.Set("User-Agent", userAgent)
r.Header.Set("User-Agent", fmt.Sprintf("%s/%s", event.Sdk.Name, event.Sdk.Version))
r.Header.Set("Content-Type", "application/x-sentry-envelope")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}()
body := getRequestBodyFromEvent(event)
Expand Down Expand Up @@ -348,10 +349,6 @@ func (t *HTTPTransport) SendEvent(event *Event) {
return
}

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

// <-t.buffer is equivalent to acquiring a lock to access the current batch.
// A few lines below, t.buffer <- b releases the lock.
//
Expand Down Expand Up @@ -573,10 +570,6 @@ func (t *HTTPSyncTransport) SendEvent(event *Event) {
return
}

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

var eventType string
if event.Type == transactionType {
eventType = "transaction"
Expand Down
1 change: 1 addition & 0 deletions transport_test.go
Expand Up @@ -357,6 +357,7 @@ func TestGetRequestFromEvent(t *testing.T) {
t.Errorf("Incorrect API URL. want: %s, got: %s", test.apiURL, req.URL.String())
}

userAgent := fmt.Sprintf("%s/%s", test.event.Sdk.Name, test.event.Sdk.Version)
if ua := req.UserAgent(); ua != userAgent {
t.Errorf("got User-Agent = %q, want %q", ua, userAgent)
}
Expand Down