diff --git a/receiver/githubreceiver/README.md b/receiver/githubreceiver/README.md index ecff5133e990..691364c1a485 100644 --- a/receiver/githubreceiver/README.md +++ b/receiver/githubreceiver/README.md @@ -95,8 +95,7 @@ see the [Scraping README][ghsread]. ## Traces - Getting Started -Workflow tracing support is actively being added to the GitHub receiver. -This is accomplished through the processing of GitHub Actions webhook +Workflow tracing support processes the GitHub Actions webhook events for workflows and jobs. The [`workflow_job`][wjob] and [`workflow_run`][wrun] event payloads are then constructed into `trace` telemetry. @@ -107,14 +106,13 @@ success, and failure rates. ### Configuration -**IMPORTANT: At this time the tracing portion of this receiver only serves a health check endpoint.** - The WebHook configuration exposes the following settings: * `endpoint`: (default = `localhost:8080`) - The address and port to bind the WebHook to. * `path`: (default = `/events`) - The path for Action events to be sent to. * `health_path`: (default = `/health`) - The path for health checks. * `secret`: (optional) - The secret used to [validates the payload][valid]. ++ `service_name`: (optional) - The `service.name` to set in created spans. * `required_header`: (optional) - The required header key and value for incoming requests. The WebHook configuration block also accepts all the [confighttp][cfghttp] diff --git a/receiver/githubreceiver/traces_receiver_test.go b/receiver/githubreceiver/traces_receiver_test.go index e35f8a22ff6d..bd025468d681 100644 --- a/receiver/githubreceiver/traces_receiver_test.go +++ b/receiver/githubreceiver/traces_receiver_test.go @@ -17,8 +17,10 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/receiver/receivertest" + semconv "go.opentelemetry.io/collector/semconv/v1.27.0" ) func TestHealthCheck(t *testing.T) { @@ -49,18 +51,21 @@ func TestWebhook(t *testing.T) { { "validEvent", github.WorkflowJobEvent{ + Action: github.Ptr(COMPLETED), WorkflowJob: &github.WorkflowJob{ WorkflowName: github.Ptr("test"), + StartedAt: &github.Timestamp{Time: time.Now().Add(time.Second)}, + CompletedAt: &github.Timestamp{Time: time.Now().Add(time.Second * 2)}, Steps: []*github.TaskStep{ { Name: github.Ptr("test1"), - StartedAt: &github.Timestamp{Time: time.Now()}, - CompletedAt: &github.Timestamp{Time: time.Now()}, + StartedAt: &github.Timestamp{Time: time.Now().Add(time.Second * 3)}, + CompletedAt: &github.Timestamp{Time: time.Now().Add(time.Second * 4)}, }, { Name: github.Ptr("test2"), - StartedAt: &github.Timestamp{Time: time.Now()}, - CompletedAt: &github.Timestamp{Time: time.Now()}, + StartedAt: &github.Timestamp{Time: time.Now().Add(time.Second * 5)}, + CompletedAt: &github.Timestamp{Time: time.Now().Add(time.Second * 6)}, }, }, }, @@ -97,15 +102,58 @@ func TestWebhook(t *testing.T) { require.NoError(t, err) require.Equal(t, http.StatusOK, response.StatusCode, string(body)) - traces := consumer.AllTraces() + traces := clearTraces(consumer.AllTraces()) - require.Equal(t, len(traces), 1) + require.Equal(t, tracesFromEvent(&tc.event), traces) }) } } -func tracesFromEvent(event *github.WorkflowJobEvent) ptrace.Traces { +func tracesFromEvent(event *github.WorkflowJobEvent) []ptrace.Traces { trace := ptrace.NewTraces() - return trace + rs := trace.ResourceSpans().AppendEmpty() + attributes := rs.Resource().Attributes() + attributes.PutStr(semconv.AttributeServiceName, defaultServiceName) + attributes.PutStr("github.workflow.name", *event.WorkflowJob.WorkflowName) + rs.SetSchemaUrl(semconv.SchemaURL) + + ss := rs.ScopeSpans().AppendEmpty() + + createSpan(event.WorkflowJob).CopyTo(ss.Spans().AppendEmpty()) + for _, step := range event.WorkflowJob.Steps { + span := createSpan(step) + + span.CopyTo(ss.Spans().AppendEmpty()) + } + + return []ptrace.Traces{trace} +} + +func clearTraces(traces []ptrace.Traces) []ptrace.Traces { + newTraces := make([]ptrace.Traces, len(traces)) + + for i, trace := range traces { + newTrace := ptrace.NewTraces() + trace.CopyTo(newTrace) + + for i := 0; i < trace.ResourceSpans().Len(); i++ { + rs := newTrace.ResourceSpans().At(i) + + for i := 0; i < rs.ScopeSpans().Len(); i++ { + ss := rs.ScopeSpans().At(i) + + for i := 0; i < ss.Spans().Len(); i++ { + span := ss.Spans().At(i) + span.SetTraceID(pcommon.NewTraceIDEmpty()) + span.SetSpanID(pcommon.NewSpanIDEmpty()) + span.SetParentSpanID(pcommon.NewSpanIDEmpty()) + } + } + } + + newTraces[i] = newTrace + } + + return newTraces }