-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbugsnag_performance.go
118 lines (99 loc) · 3.32 KB
/
bugsnag_performance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package bugsnagperformance
import (
"context"
"fmt"
"log"
"net/http"
"os"
"sync"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
)
// Version defines the version of this Bugsnag performance module
const Version = "1.0.0"
// Config is the configuration for the default Bugsnag performance module
var Config Configuration
var readEnvConfigOnce sync.Once
func init() {
fmt.Println("Starting bugsnag performance.")
Config = Configuration{
ReleaseStage: "production",
Logger: log.New(os.Stdout, "[BugsnagPerformance] ", log.LstdFlags),
MainContext: context.TODO(),
Transport: http.DefaultTransport,
}
}
// Configure Bugsnag. The only required setting is the APIKey, which can be
// obtained by clicking on "Settings" in your Bugsnag dashboard.
// Returns OTeL sampler, probability attribute processor, trace exporter and error
func Configure(config Configuration) ([]trace.TracerProviderOption, error) {
readEnvConfigOnce.Do(Config.loadEnv)
Config.update(&config)
err := Config.validate()
if err != nil {
return nil, err
}
otelOptions := createBugsnagOtelOptions()
return otelOptions, nil
}
func createBugsnagOtelOptions() []trace.TracerProviderOption {
delivery := createDelivery()
probabilityManager := createProbabilityManager(Config.MainContext, delivery)
sampler := createSampler(probabilityManager)
otelOptions := []trace.TracerProviderOption{}
probAttrProcessor := createProbabilityAttributeProcessor(probabilityManager)
otelOptions = append(otelOptions, trace.WithSpanProcessor(probAttrProcessor))
// enter unmanaged mode if the OTel sampler environment variable has been set
// note: we assume any value means a non-default sampler will be used because
// we don't control what the valid values are
unmanagedMode := false
if customSampler := os.Getenv("OTEL_TRACES_SAMPLER"); customSampler != "" || Config.CustomSampler != nil {
unmanagedMode = true
otelOptions = append(otelOptions, trace.WithSampler(Config.CustomSampler))
} else {
otelOptions = append(otelOptions, trace.WithSampler(sampler))
}
if Config.isReleaseStageEnabled() {
spanExporter := createSpanExporter(probabilityManager, sampler, delivery, unmanagedMode)
otelOptions = append(otelOptions, trace.WithSpanProcessor(trace.NewBatchSpanProcessor(spanExporter)))
}
otelOptions = append(otelOptions, trace.WithResource(createBugsnagMergedResource()))
return otelOptions
}
func createBugsnagMergedResource() *resource.Resource {
customResource := Config.Resource
if customResource == nil {
customResource = resource.Default()
}
attr := []attribute.KeyValue{
{
Key: deploymentEnvAttribute,
Value: attribute.StringValue(Config.ReleaseStage),
},
{
Key: serviceVersionAttribute,
Value: attribute.StringValue(Config.AppVersion),
},
{
Key: bugsnagSDKNameAttribute,
Value: attribute.StringValue(sdkName),
},
{
Key: bugsnagSDKVersionAttribute,
Value: attribute.StringValue(Version),
},
}
if Config.ServiceName != "" {
attr = append(attr, attribute.String(serviceNameAttribute, Config.ServiceName))
}
bsgResource, err := resource.Merge(
customResource,
resource.NewSchemaless(attr...),
)
if err != nil {
Config.Logger.Printf("Error while merging resource: %+v\n", err)
return customResource
}
return bsgResource
}