@@ -3,10 +3,21 @@ package tracker
3
3
import (
4
4
"context"
5
5
"log"
6
+ "os"
6
7
7
8
"github.com/middleware-labs/golang-apm/logger"
9
+
10
+ "go.opentelemetry.io/otel/attribute"
11
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
12
+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
13
+ "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
14
+ "go.opentelemetry.io/otel/sdk/resource"
15
+ "go.opentelemetry.io/otel/sdk/trace"
16
+ "time"
17
+ "strings"
8
18
)
9
19
20
+
10
21
func TrackWithCtx (ctx context.Context , opts ... Options ) (* Config , error ) {
11
22
12
23
c := newConfig (opts ... )
@@ -45,3 +56,165 @@ func Track(opts ...Options) (*Config, error) {
45
56
ctx := context .Background ()
46
57
return TrackWithCtx (ctx , opts ... )
47
58
}
59
+
60
+
61
+ func NewTracerProviderCtx (ctx context.Context , c * Config , serviceName string ) * trace.TracerProvider {
62
+ collectorURL := c .Host
63
+ exporter , err := otlptrace .New (
64
+ ctx ,
65
+ otlptracegrpc .NewClient (
66
+ otlptracegrpc .WithEndpoint (collectorURL ),
67
+ // Gzip Compression
68
+ otlptracegrpc .WithCompressor ("gzip" ),
69
+ ),
70
+ )
71
+
72
+ if err != nil {
73
+ log .Fatalf ("failed to create exporter: %v" , err )
74
+ }
75
+
76
+ var file * os.File = os .Stdout
77
+ var consoleExporter * stdouttrace.Exporter
78
+ if c .debug {
79
+ if c .debugLogFile {
80
+ file , err = os .OpenFile ("./mw-traces.log" , os .O_WRONLY | os .O_CREATE | os .O_APPEND , 0600 )
81
+ if err != nil {
82
+ log .Println ("failed to create exporter file for traces: " , err )
83
+ }
84
+ }
85
+ consoleExporter , err = stdouttrace .New (stdouttrace .WithPrettyPrint (), stdouttrace .WithWriter (file ))
86
+ if err != nil {
87
+ log .Println ("failed to create debug console exporter for traces: " , err )
88
+ }
89
+ }
90
+
91
+ res , err := resource .New (context .Background (),
92
+ resource .WithAttributes (
93
+ attribute .String ("service.name" , serviceName ),
94
+ attribute .String ("library.language" , "go" ),
95
+ attribute .Bool ("mw_agent" , true ),
96
+ attribute .String ("project.name" , c .projectName ),
97
+ attribute .String ("mw.account_key" , c .AccessToken ),
98
+ attribute .String ("mw_serverless" , c .isServerless ),
99
+
100
+ ),
101
+ )
102
+
103
+ for key , value := range c .customResourceAttributes {
104
+ switch v := value .(type ) {
105
+ case string :
106
+ res , err = resource .Merge (res , resource .NewSchemaless (
107
+ attribute .String (key , v ),
108
+ ))
109
+ if err != nil {
110
+ log .Println ("failed to create resource: %v" , err )
111
+ }
112
+ case bool :
113
+ res , err = resource .Merge (res , resource .NewSchemaless (
114
+ attribute .Bool (key , v ),
115
+ ))
116
+ if err != nil {
117
+ log .Println ("failed to create resource: %v" , err )
118
+ }
119
+ case int :
120
+ res , err = resource .Merge (res , resource .NewSchemaless (
121
+ attribute .Int (key , v ),
122
+ ))
123
+ if err != nil {
124
+ log .Println ("failed to create resource: %v" , err )
125
+ }
126
+
127
+ case int64 :
128
+ res , err = resource .Merge (res , resource .NewSchemaless (
129
+ attribute .Int64 (key , v ),
130
+ ))
131
+ if err != nil {
132
+ log .Println ("failed to create resource: %v" , err )
133
+ }
134
+ case float64 :
135
+ res , err = resource .Merge (res , resource .NewSchemaless (
136
+ attribute .Float64 (key , v ),
137
+ ))
138
+ if err != nil {
139
+ log .Println ("failed to create resource: %v" , err )
140
+ }
141
+
142
+ case float32 :
143
+ res , err = resource .Merge (res , resource .NewSchemaless (
144
+ attribute .Float64 (key , float64 (v )),
145
+ ))
146
+ if err != nil {
147
+ log .Println ("failed to create resource: %v" , err )
148
+ }
149
+
150
+ case []string :
151
+ for _ , s := range v {
152
+ res , err = resource .Merge (res , resource .NewSchemaless (
153
+ attribute .String (key , s ),
154
+ ))
155
+ if err != nil {
156
+ log .Println ("failed to create resource: %v" , err )
157
+ }
158
+ }
159
+ case []int :
160
+ for _ , i := range v {
161
+ res , err = resource .Merge (res , resource .NewSchemaless (
162
+ attribute .Int (key , i ),
163
+ ))
164
+ if err != nil {
165
+ log .Println ("failed to create resource: %v" , err )
166
+ }
167
+ }
168
+ case []float64 :
169
+ for _ , f := range v {
170
+ res , err = resource .Merge (res , resource .NewSchemaless (
171
+ attribute .Float64 (key , f ),
172
+ ))
173
+ if err != nil {
174
+ log .Println ("failed to create resource: %v" , err )
175
+ }
176
+ }
177
+ default :
178
+ log .Printf ("Unsupported attribute type for key: %s\n " , key )
179
+ }
180
+ }
181
+
182
+ // Get the MW_CUSTOM_RESOURCE_ATTRIBUTES environment variable
183
+ envResourceAttributes := os .Getenv ("MW_CUSTOM_RESOURCE_ATTRIBUTES" )
184
+ // Split the attributes by comma
185
+ attrs := strings .Split (envResourceAttributes , "," )
186
+ for _ , attr := range attrs {
187
+ // Split each attribute by the '=' character
188
+ kv := strings .SplitN (attr , "=" , 2 )
189
+ if len (kv ) == 2 {
190
+ key := strings .TrimSpace (kv [0 ])
191
+ value := strings .TrimSpace (kv [1 ])
192
+ res , err = resource .Merge (res , resource .NewSchemaless (
193
+ attribute .String (key , value ),
194
+ ))
195
+ if err != nil {
196
+ log .Println ("failed to create resource: %v" , err )
197
+ }
198
+ }
199
+ }
200
+
201
+
202
+
203
+ var tp * trace.TracerProvider
204
+
205
+ if c .debug {
206
+ tp = trace .NewTracerProvider (
207
+ trace .WithResource (res ),
208
+ trace .WithSpanProcessor (trace .NewBatchSpanProcessor (exporter ,
209
+ trace .WithMaxExportBatchSize (10000 ), trace .WithBatchTimeout (10 * time .Second ))),
210
+ trace .WithSpanProcessor (trace .NewSimpleSpanProcessor (consoleExporter )),
211
+ )
212
+ } else {
213
+ tp = trace .NewTracerProvider (
214
+ trace .WithResource (res ),
215
+ trace .WithSpanProcessor (trace .NewBatchSpanProcessor (exporter ,
216
+ trace .WithMaxExportBatchSize (10000 ), trace .WithBatchTimeout (10 * time .Second ))),
217
+ )
218
+ }
219
+ return tp
220
+ }
0 commit comments