Skip to main content

Github Receiver

Status Available in: contrib Maintainers: @adrielp, @crobert-1, @TylerHelmuth Source: opentelemetry-collector-contrib

Supported Telemetry

Metrics Traces

Overview

Overview

The GitHub receiver receives data from GitHub via two methods:
  1. Scrapes version control system metrics from GitHub repositories and organizations using the GraphQL and REST APIs.
  2. Receives GitHub Actions events by serving a webhook endpoint, converting those events into traces.

Metrics - Getting Started

The current default set of metrics can be found in documentation.md. These metrics can be used as leading indicators (capabilities) to the DORA metrics; helping provide insight into modern-day engineering practices. The collection interval is common to all scrapers and is set to 30 seconds by default.
Note: Generally speaking, if the vendor allows for anonymous API calls, then you won’t have to configure any authentication, but you may only see public repositories and organizations. You may also run into significantly more rate limiting.
github:
    collection_interval: <duration> #default = 30s recommended 300s
    scrapers:
        scraper/config-1:
        scraper/config-2:
        ...
A more complete example using the GitHub scrapers with authentication is as follows:
extensions:
    bearertokenauth/github:
        token: ${env:GH_PAT}

receivers:
    github:
        initial_delay: 1s
        collection_interval: 60s
        scrapers:
            scraper:
                metrics: #Optional
                    vcs.contributor.count:
                        enabled: true
                github_org: <myfancyorg> 
                search_query: "org:<myfancyorg> topic:<o11yalltheway>" # Recommended optional query override, defaults to "{org,user}:<github_org>"
                concurrency_limit: 50  # Optional: (default: 50)
                merged_pr_lookback_days: 30 # Optional: (default: 30)
                endpoint: "https://selfmanagedenterpriseserver.com" # Optional
                auth:
                    authenticator: bearertokenauth/github
service:
    extensions: [bearertokenauth/github]
    pipelines:
        metrics:
            receivers: [..., github]
            processors: []
            exporters: [...]

Configuration

github_org (required): Specify the GitHub organization or username to scrape. endpoint (optional): Set this only when using a self-managed GitHub instance (e.g., https://selfmanagedenterpriseserver.com β€” SHOULD NOT include api subdomain or /graphql context path). search_query (optional): A filter to narrow down repositories. Defaults to org:<github_org> (or user:<username>). For example, use repo:<org>/<repo> to target a specific repository. Any valid GitHub search syntax is allowed. concurrency_limit (optional): Maximum number of concurrent repository processing goroutines. Defaults to 50 to stay under GitHub’s 100 concurrent request limit. Set to 0 for unlimited concurrency (not recommended for >100 repositories). merged_pr_lookback_days (optional): Number of days to query back in time when fetching merged pull requests. Defaults to 30. Set to 0 to fetch all merged PRs. metrics (optional): Enable or disable metrics scraping. See the metrics documentation for details.

Scraping

Important:
  • The GitHub scraper does not emit metrics for branches that have not had changes since creation from the default branch (trunk).
  • Due to GitHub API limitations, it is possible for the branch time metric to change when rebases occur, recreating the commits with new timestamps.
For additional context on GitHub scraper limitations and inner workings please see the Scraping README.

GitHub Personal Access Token (PAT) Setup

To create a GitHub Personal Access Token (PAT), please refer to the official documentation. Organization or Personal Access: When generating the PAT, select the appropriate Resource owner β€” either your personal account or the organization and choose the correct Repository access type. For fine-grained tokens, explicitly configure the necessary Repository permissions or Organization permissions. Note: The PAT must have read access to the target repositories. If the PAT doesn’t have permission to access repositories in the target organization, only the repository count metric will be available. Detailed repository metrics cannot be fetched.

Traces - Getting Started

Workflow tracing support is accomplished through the processing of GitHub Actions webhook events for workflows and jobs. The workflow_job and workflow_run event payloads are then constructed into trace telemetry. Each GitHub Action workflow or job, along with its steps, are converted into trace spans, allowing the observation of workflow execution times, success, and failure rates. Each Trace and Span ID is deterministic. This enables the underlying actions to emit telemetry from any command running in any step. This can be achieved by using tools like the run-with-telemetry action and otel-cli. The key is generating IDs in the same way that this GitHub receiver does. The trace_event_handling.go file contains the new*ID functions that generate deterministic IDs. IMPORTANT - Workflow Job names MUST be unique in each workflow for deterministic span IDs to not conflict with eachother. GitHub does not enforce this behavior, but when linting a workflow, warns that there are duplicate job names.

Receiver Configuration

IMPORTANT - Ensure your WebHook endpoint is secured with a secret and a Web Application Firewall (WAF) or other security measure. 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.
  • required_header: (optional) - The required header key and value for incoming requests.
  • service_name: (optional) - The service name for the traces. See the Configuring Service Name section for more information.
  • include_span_events: (default = false) - When set to true, attaches the raw webhook event JSON as a span event. The workflow run event is attached to the workflow run span, and the workflow job event is attached to the job span.
The WebHook configuration block also accepts all the confighttp settings. An example configuration is as follows:
receivers:
    github:
        webhook:
            endpoint: localhost:19418
            path: /events
            health_path: /health
            secret: ${env:SECRET_STRING_VAR}
            service_name: github-actions  # single logical CI service (See Configuring Service Name section below)
            required_headers:
                WAF-Header: "value"
        scrapers: # The validation expects at least a dummy scraper config
            scraper:
                github_org: open-telemetry
For tracing, all configuration is set under the webhook key. The full set of exposed configuration values can be found in config.go.

Configuring Service Name

The service_name option in the WebHook configuration can be used to set a pre-defined service.name resource attribute for all traces emitted by the receiver. This value should represent the logical service producing telemetry (as defined by OpenTelemetry resource semantics), not individual repositories or components. For CI/CD usage, a typical choice is a single service such as github-actions (optionally paired with service.namespace for ownership and uniqueness). If you choose to set service_name explicitly, consider running a separate GitHub receiver (and/or GitHub App) for each distinct service that you want to model. If you do not set service_name, the receiver supports deriving it from repository metadata. You can configure Custom Properties in each GitHub repository by adding a service_name key; all events from that repository will then carry the specified service.name. If no custom property is found, the receiver will derive service.name from the repository name.
Note: Deriving service.name from repositories is a convenience and may be sufficient for small setups. In larger organizations, mapping repositories directly to service.name often leads to many pseudo-services and can make cross-repository analysis harder. Prefer an explicit CI service name when modeling your pipelines as a platform service.
Precedence for setting service.name:
  1. service_name in the WebHook configuration.
  2. service_name key in the repository’s Custom Properties.
  3. service_name derived from the repository name.
  4. service.name defaults to unknown_service per the semantic conventions.

Span Events

When include_span_events is enabled, the receiver attaches the raw GitHub webhook event JSON as a span event to the corresponding span:
  • Workflow Run events: Attached as a span event named github.workflow_run.event to the root workflow run span
  • Workflow Job events: Attached as a span event named github.workflow_job.event to the job span
The raw event is stored in the event.payload attribute as a JSON string. This allows for detailed inspection of the complete webhook payload, including fields that may not be mapped to span attributes. Note: The raw event payload can be large (typically 5-50KB). Consider the impact on storage and performance before enabling this feature in production environments. An example configuration with span events enabled:
receivers:
    github:
        webhook:
            endpoint: localhost:19418
            path: /events
            health_path: /health
            secret: ${env:SECRET_STRING_VAR}
            required_headers:
                WAF-Header: "value"
            include_span_events: true
        scrapers: # The validation expects at least a dummy scraper config
            scraper:
                github_org: open-telemetry

Configuring A GitHub App

To configure a GitHub App, you will need to create a new GitHub App within your organization. Refer to the general GitHub App documentation for how to create a GitHub App. During the subscription phase, subscribe to workflow_run and workflow_job events.

Custom Properties as Resource Attributes

The GitHub receiver supports adding custom properties from GitHub repositories as resource attributes in your telemetry data. This allows users to enrich traces and events with additional metadata specific to each repository.

How It Works

When a GitHub webhook event is received, the receiver extracts all custom properties from the repository and adds them as resource attributes with the prefix github.repository.custom_properties. For example, if your repository has these custom properties:
classification: public
service-tier: critical
slack-support-channel: #observability-alerts
team-name: observability-engineering
They will be added as resource attributes:
github.repository.custom_properties.classification: "public"
github.repository.custom_properties.service_tier: "critical"
github.repository.custom_properties.slack_support_channel: "#observability-alerts"
github.repository.custom_properties.team_name: "observability-engineering"

Key Formatting

To ensure consistency with OpenTelemetry naming conventions, all custom property keys are converted to snake_case format using the following rules:
  1. Hyphens, spaces, and dots are replaced with underscores
  2. Special characters like $ and # are replaced with _dollar_ and _hash_
  3. CamelCase and PascalCase are converted to snake_case by inserting underscores before uppercase letters
  4. Multiple consecutive underscores are replaced with a single underscore
Examples of key transformations:
Original KeyTransformed Key
teamNameteam_name
API-Keyapi_key
Service.Levelservice_level
$Cost_dollar_cost
#Priority_hash_priority
Note: The service_name custom property is handled specially and is not added as a resource attribute with the prefix. Instead, it’s used to set the service.name resource attribute directly, as described in the Configuring Service Name section.

Migration Notes

Semantic Conventions v1.37.0 Upgrade

The GitHub receiver has been updated to use OpenTelemetry semantic conventions v1.37.0. This brings standardization improvements and better alignment with the broader OpenTelemetry ecosystem.

Breaking Changes

Resource Attributes:
  • organization.name β†’ vcs.owner.name - The resource attribute for organization/owner name has been standardized
  • vcs.vendor.name β†’ vcs.provider.name - The VCS provider attribute has been standardized
Trace Attributes:
  • vcs.ref.head.type β†’ vcs.ref.type - Some trace attributes now use standardized naming

What This Means for Users

For Dashboard and Alerting Users:
  • Update your queries and dashboards to use the new attribute names
  • Old attribute names are no longer emitted starting with this version
  • The schema URL in telemetry data now references OpenTelemetry schemas v1.37.0
For Configuration Users:
  • No configuration changes are required
  • All existing receiver configurations continue to work unchanged
Migration Timeline:
  • Before upgrading: Update downstream systems (dashboards, alerts, queries) to use new attribute names
  • After upgrading: Verify that telemetry data is flowing correctly with the new attributes
For the complete list of semantic convention changes, see the OpenTelemetry semantic conventions v1.37.0 documentation.

Metrics

Metric NameDescriptionUnitTypeAttributes
βœ… vcs.change.countThe number of changes (pull requests) in a repository, categorized by their state (either open or merged).{change}Gaugevcs.repository.url.full, vcs.change.state, vcs.repository.name
βœ… vcs.change.durationThe time duration a change (pull request/merge request/changelist) has been in an open state.sGaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name, vcs.change.state
βœ… vcs.change.time_to_approvalThe amount of time it took a change (pull request) to go from open to approved.sGaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name
βœ… vcs.change.time_to_mergeThe amount of time it took a change (pull request) to go from open to merged.sGaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name
❌ vcs.contributor.countThe number of unique contributors to a repository.{contributor}Gaugevcs.repository.url.full, vcs.repository.name
βœ… vcs.ref.countThe number of refs of type branch in a repository.{ref}Gaugevcs.repository.url.full, vcs.repository.name, vcs.ref.type
βœ… vcs.ref.lines_deltaThe number of lines added/removed in a ref (branch) relative to the default branch (trunk).{line}Gaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name, vcs.ref.head.type, vcs.ref.base.name, vcs.ref.base.type, vcs.line_change.type
βœ… vcs.ref.revisions_deltaThe number of revisions (commits) a ref (branch) is ahead/behind the branch from trunk (default).{revision}Gaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name, vcs.ref.head.type, vcs.ref.base.name, vcs.ref.base.type, vcs.revision_delta.direction
βœ… vcs.ref.timeTime a ref (branch) created from the default branch (trunk) has existed. The vcs.ref.type attribute will always be branch.sGaugevcs.repository.url.full, vcs.repository.name, vcs.ref.head.name, vcs.ref.head.type
βœ… vcs.repository.countThe number of repositories in an organization.{repository}Gauge

Attributes

Attribute NameDescriptionTypeValues
vcs.change.stateThe state of a change (pull request)stringopen, merged
vcs.line_change.typeThe type of line change being measured on a ref (branch).stringadded, removed
vcs.ref.base.nameThe name of the VCS base reference (branch/tag) for comparison.string
vcs.ref.base.typeThe type of the base reference (branch, tag).stringbranch, tag
vcs.ref.head.nameThe name of the VCS head reference (branch).string
vcs.ref.head.typeThe type of the head reference (branch, tag).stringbranch, tag
vcs.ref.typeThe type of the reference in the repository.stringbranch, tag
vcs.repository.nameThe name of the VCS repository.string
vcs.repository.url.fullThe canonical URL of the repository providing the complete HTTPS address.string
vcs.revision_delta.directionThe type of revision comparison.stringahead, behind

Resource Attributes

Attribute NameDescriptionTypeEnabled
vcs.owner.nameThe group owner within the version control systemstringβœ…
vcs.provider.nameThe name of the version control system providerstringβœ…

Configuration

Example Configuration

receivers:
  github:
    initial_delay: 1s
    collection_interval: 60s
    scrapers:
      scraper:
    webhook:
      endpoint: localhost:8080
      read_timeout: "500ms"
      write_timeout: "500ms"
      path: "some/path"
      health_path: "health/path"
      required_headers:
        key: value-present

  github/customname:
    initial_delay: 1s
    collection_interval: 30s
    scrapers:
      scraper:
    webhook:
      endpoint: localhost:8080
      read_timeout: "500ms"
      write_timeout: "500ms"
      path: "some/path"
      health_path: "health/path"
      required_headers:
        key: value-present

processors:
  nop:

exporters:
  nop:

service:
  pipelines:
    metrics:
      receivers: [github, github/customname]
      processors: [nop]
      exporters: [nop]
    traces:
      receivers: [github, github/customname]
      processors: [nop]
      exporters: [nop]

Last generated: 2026-04-13