@@ -17,10 +17,12 @@ limitations under the License.
17
17
package main
18
18
19
19
import (
20
+ "context"
20
21
"flag"
21
22
"log"
22
23
"net/http"
23
24
"os"
25
+ "time"
24
26
25
27
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
26
28
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
@@ -36,11 +38,23 @@ import (
36
38
"knative.dev/pkg/injection"
37
39
"knative.dev/pkg/injection/sharedmain"
38
40
"knative.dev/pkg/signals"
41
+
42
+ "go.opentelemetry.io/otel"
43
+ "go.opentelemetry.io/otel/exporters/jaeger"
44
+ "go.opentelemetry.io/otel/propagation"
45
+ "go.opentelemetry.io/otel/sdk/resource"
46
+ tracesdk "go.opentelemetry.io/otel/sdk/trace"
47
+ semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
48
+ "go.opentelemetry.io/otel/trace"
39
49
)
40
50
41
51
const (
42
52
// ControllerLogKey is the name of the logger for the controller cmd
43
53
ControllerLogKey = "tekton-pipelines-controller"
54
+ // TraceProvider name for pipeline reconciler
55
+ TracerProviderPipelineRun = "pipeline-reconciler"
56
+ // TraceProvider name for taskrun reconciler
57
+ TracerProviderTaskRun = "taskrun-reconciler"
44
58
)
45
59
46
60
func main () {
@@ -102,17 +116,80 @@ func main() {
102
116
log .Fatal (http .ListenAndServe (":" + port , mux ))
103
117
}()
104
118
119
+ // initialize opentelemetry
120
+ tpPipelineRun , err := tracerProvider (TracerProviderPipelineRun )
121
+ if err != nil {
122
+ log .Printf ("failed to initialize tracerProvider for pipelinerun, falling back to no-op provider, %s" , err .Error ())
123
+ tpPipelineRun = trace .NewNoopTracerProvider ()
124
+ }
125
+ tpTaskrun , err := tracerProvider (TracerProviderTaskRun )
126
+ if err != nil {
127
+ log .Printf ("failed to initialize tracerProvider for taskrun, falling back to no-op provider, %s" , err .Error ())
128
+ tpTaskrun = trace .NewNoopTracerProvider ()
129
+ }
130
+ otel .SetTextMapPropagator (propagation.TraceContext {})
131
+ ctx , cancel := context .WithCancel (ctx )
132
+ defer cancel ()
133
+
105
134
ctx = filteredinformerfactory .WithSelectors (ctx , v1beta1 .ManagedByLabelKey )
106
135
sharedmain .MainWithConfig (ctx , ControllerLogKey , cfg ,
107
- taskrun .NewController (opts , clock.RealClock {}),
108
- pipelinerun .NewController (opts , clock.RealClock {}),
136
+ taskrun .NewController (opts , clock.RealClock {}, tpTaskrun ),
137
+ pipelinerun .NewController (opts , clock.RealClock {}, tpPipelineRun ),
109
138
run .NewController (),
110
139
resolutionrequest .NewController (clock.RealClock {}),
111
140
// TODO(jerop, abayer) uncomment after we align on retries in customruns
112
141
// customrun.NewController(),
113
142
)
143
+
144
+ // Cleanly shutdown and flush telemetry when the application exits.
145
+ defer func (ctx context.Context ) {
146
+ // Do not make the application hang when it is shutdown.
147
+ ctx , cancel = context .WithTimeout (ctx , time .Second * 5 )
148
+ defer cancel ()
149
+
150
+ // shutdown is only needed when tracerProvider is inialized with jaeger
151
+ // not needed when tracerProvider is NewNoopTracerProvider
152
+ if tp , ok := tpPipelineRun .(* tracesdk.TracerProvider ); ok {
153
+ tp .Shutdown (ctx )
154
+ }
155
+ if tp , ok := tpTaskrun .(* tracesdk.TracerProvider ); ok {
156
+ tp .Shutdown (ctx )
157
+ }
158
+ }(ctx )
114
159
}
115
160
116
161
func handler (w http.ResponseWriter , r * http.Request ) {
117
162
w .WriteHeader (http .StatusOK )
118
163
}
164
+
165
+ // tracerProvider returns an OpenTelemetry TracerProvider configured to use
166
+ // the Jaeger exporter that will send spans to the provided url. The returned
167
+ // TracerProvider will also use a Resource configured with all the information
168
+ // about the application.
169
+ func tracerProvider (service string ) (trace.TracerProvider , error ) {
170
+ // Create the Jaeger exporter
171
+ // The following env variables are used by the sdk for creating the exporter
172
+ // - OTEL_EXPORTER_JAEGER_ENDPOINT is the HTTP endpoint for sending spans directly to a collector.
173
+ // - OTEL_EXPORTER_JAEGER_USER is the username to be sent as authentication to the collector endpoint.
174
+ // - OTEL_EXPORTER_JAEGER_PASSWORD is the password to be sent as authentication to the collector endpoint.
175
+
176
+ if _ , e := os .LookupEnv ("OTEL_EXPORTER_JAEGER_ENDPOINT" ); ! e {
177
+ // jaeger endpoint is not defined, disable tracing and return no-op tracerProvider
178
+ return trace .NewNoopTracerProvider (), nil
179
+ }
180
+
181
+ exp , err := jaeger .New (jaeger .WithCollectorEndpoint ())
182
+ if err != nil {
183
+ return nil , err
184
+ }
185
+ // Initialize tracerProvider with the jaeger exporter
186
+ tp := tracesdk .NewTracerProvider (
187
+ tracesdk .WithBatcher (exp ),
188
+ // Record information about the service in a Resource.
189
+ tracesdk .WithResource (resource .NewWithAttributes (
190
+ semconv .SchemaURL ,
191
+ semconv .ServiceNameKey .String (service ),
192
+ )),
193
+ )
194
+ return tp , nil
195
+ }
0 commit comments