Skip to content

Commit d0ccf1b

Browse files
committed
feat(adapter): log time taken by controller to process webhook events
Log the duration from when a webhook request is received until the controller responds, and separately the async event processing time. The event ID is extracted from provider-specific headers (GitHub, GitLab, Gitea, Bitbucket Cloud/DC) for log correlation. https://redhat.atlassian.net/browse/SRVKP-14040 Signed-off-by: Zaki Shaikh <zashaikh@redhat.com>
1 parent 6856ee8 commit d0ccf1b

3 files changed

Lines changed: 130 additions & 1 deletion

File tree

pkg/adapter/adapter.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ func (l *listener) Start(ctx context.Context) error {
173173

174174
func (l listener) handleEvent(ctx context.Context) http.HandlerFunc {
175175
return func(response http.ResponseWriter, request *http.Request) {
176+
start := time.Now().UnixMilli()
177+
eventID := getProviderEventIDFromHeader(request.Header)
178+
eventLogger := l.logger.With("event-id", eventID)
179+
defer func() {
180+
eventLogger.Infof("controller responded to event %s in %dms", eventID, time.Now().UnixMilli()-start)
181+
}()
176182
if request.Method != http.MethodPost {
177183
l.writeResponse(response, http.StatusOK, "ok")
178184
return
@@ -270,7 +276,11 @@ func (l listener) handleEvent(ctx context.Context) http.HandlerFunc {
270276
localRequest := request.Clone(request.Context())
271277

272278
go func() {
273-
defer span.End()
279+
eventHandlerStart := time.Now().UnixMilli()
280+
defer func() {
281+
logger.Infof("event %s processed in %dms", eventID, time.Now().UnixMilli()-eventHandlerStart)
282+
span.End()
283+
}()
274284
err := s.handleEvent(tracedCtx, localRequest)
275285
if err != nil {
276286
span.RecordError(err)
@@ -281,6 +291,30 @@ func (l listener) handleEvent(ctx context.Context) http.HandlerFunc {
281291
}
282292
}
283293

294+
func getProviderEventIDFromHeader(header http.Header) string {
295+
if header.Get("X-GitHub-Delivery") != "" {
296+
return header.Get("X-GitHub-Delivery")
297+
}
298+
// For Gitea
299+
if header.Get("X-Gitea-Delivery") != "" {
300+
return header.Get("X-Gitea-Delivery")
301+
}
302+
// For GitLab
303+
if header.Get("X-Gitlab-Event-UUID") != "" {
304+
return header.Get("X-Gitlab-Event-UUID")
305+
}
306+
// For Bitbucket cloud
307+
if header.Get("X-Request-UUID") != "" {
308+
return header.Get("X-Request-UUID")
309+
}
310+
// For Bitbucket data center
311+
if header.Get("X-Request-Id") != "" {
312+
return header.Get("X-Request-Id")
313+
}
314+
// return nil UUID to indicate that git provider is unknown
315+
return "00000000-0000-0000-0000-000000000000"
316+
}
317+
284318
func (l listener) processRes(processEvent bool, provider provider.Interface, logger *zap.SugaredLogger, skipReason string, err error) (provider.Interface, *zap.SugaredLogger, error) {
285319
if processEvent {
286320
if provider == nil {

pkg/adapter/adapter_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func TestHandleEvent(t *testing.T) {
132132
name string
133133
event []byte
134134
eventType string
135+
eventUUID string
135136
requestType string
136137
statusCode int
137138
wantLogSnippet string
@@ -183,6 +184,15 @@ func TestHandleEvent(t *testing.T) {
183184
event: event,
184185
statusCode: 200,
185186
},
187+
{
188+
name: "event time logged",
189+
requestType: "POST",
190+
eventType: "push",
191+
event: event,
192+
statusCode: 202,
193+
eventUUID: "1234567890",
194+
wantLogSnippet: "controller responded to event 1234567890",
195+
},
186196
}
187197

188198
for _, tt := range tests {
@@ -197,6 +207,10 @@ func TestHandleEvent(t *testing.T) {
197207
assert.NilError(t, err)
198208
req.Header.Set("X-Github-Event", tn.eventType)
199209

210+
if tn.eventUUID != "" {
211+
req.Header.Set("X-GitHub-Delivery", tn.eventUUID)
212+
}
213+
200214
resp, err := http.DefaultClient.Do(req)
201215
assert.NilError(t, err)
202216
defer resp.Body.Close()
@@ -326,3 +340,64 @@ func TestStartGracefulShutdown(t *testing.T) {
326340
t.Fatal("listener did not shut down after context cancellation")
327341
}
328342
}
343+
344+
func TestGetProviderEventIDFromHeader(t *testing.T) {
345+
tests := []struct {
346+
name string
347+
header map[string][]string
348+
want string
349+
}{
350+
{
351+
name: "github event",
352+
header: map[string][]string{
353+
"X-GitHub-Delivery": {"abcd"},
354+
},
355+
want: "abcd",
356+
},
357+
{
358+
name: "gitea event",
359+
header: map[string][]string{
360+
"X-Gitea-Delivery": {"abcd"},
361+
},
362+
want: "abcd",
363+
},
364+
{
365+
name: "gitlab event",
366+
header: map[string][]string{
367+
"X-Gitlab-Event-UUID": {"abcd"},
368+
},
369+
want: "abcd",
370+
},
371+
{
372+
name: "bitbucket cloud event",
373+
header: map[string][]string{
374+
"X-Request-UUID": {"abcd"},
375+
},
376+
want: "abcd",
377+
},
378+
{
379+
name: "bitbucket data center event",
380+
header: map[string][]string{
381+
"X-Request-Id": {"abcd"},
382+
},
383+
want: "abcd",
384+
},
385+
{
386+
name: "unknown git provider event",
387+
header: map[string][]string{},
388+
want: "00000000-0000-0000-0000-000000000000",
389+
},
390+
}
391+
for _, tt := range tests {
392+
t.Run(tt.name, func(t *testing.T) {
393+
header := http.Header{}
394+
for key, values := range tt.header {
395+
for _, value := range values {
396+
header.Set(key, value)
397+
}
398+
}
399+
got := getProviderEventIDFromHeader(header)
400+
assert.Equal(t, got, tt.want)
401+
})
402+
}
403+
}

test/github_pullrequest_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,26 @@ func TestGithubGHEPullRequestCELJoin(t *testing.T) {
787787
assert.NilError(t, err)
788788
}
789789

790+
func TestGithubGHEPullRequestEventTimeLogged(t *testing.T) {
791+
ctx := context.Background()
792+
g := &tgithub.PRTest{
793+
Label: "Github PullRequest Event Time Logged",
794+
YamlFiles: []string{"testdata/pipelinerun.yaml"},
795+
GHE: true,
796+
}
797+
g.RunPullRequest(ctx, t)
798+
defer g.TearDown(ctx, t)
799+
800+
globalNs, _, err := params.GetInstallLocation(ctx, g.Cnx)
801+
assert.NilError(t, err)
802+
ctx = info.StoreNS(ctx, globalNs)
803+
804+
reg := regexp.MustCompile("controller responded to event .* in .*ms")
805+
maxLines := int64(1000)
806+
err = twait.RegexpMatchingInControllerLog(ctx, g.Cnx, *reg, 20, "ghe-controller", &maxLines, nil)
807+
assert.NilError(t, err)
808+
}
809+
790810
// Local Variables:
791811
// compile-command: "go test -tags=e2e -v -info TestGithubPullRequest$ ."
792812
// End:

0 commit comments

Comments
 (0)