We welcome your contributions to this project!
Please read the OpenTelemetry Contributor Guide for general information on how to contribute including signing the Contributor License Agreement, the Code of Conduct, and Community Expectations.
As with other OpenTelemetry clients, opentelemetry-ruby follows the opentelemetry-specification and the library guidelines.
OpenTelemetry is an evolving specification, one where the desires and use cases are clear, but the method to satisfy those use cases are not.
As such, Contributions should provide functionality and behavior that conforms to the specification, but the interface and structure are flexible.
It is preferable to have contributions follow the idioms of the language rather than conform to specific API names or argument patterns in the spec.
For a deeper discussion, see: open-telemetry/opentelemetry-specification#165
Everyone is welcome to contribute code via GitHub Pull Requests (PRs).
Fork the project on GitHub by clicking the Fork button at the top of the
repository and clone your fork locally:
git clone git@github.com:YOUR_GITHUB_NAME/opentelemetry-ruby-contrib.gitor
git clone https://github.com/YOUR_GITHUB_NAME/opentelemetry-ruby-contrib.gitIt can be helpful to add the open-telemetry/opentelemetry-ruby-contrib repo as a
remote so you can track changes (we're adding as upstream here):
git remote add upstream git@github.com:open-telemetry/opentelemetry-ruby-contrib.gitor
git remote add upstream https://github.com/open-telemetry/opentelemetry-ruby-contrib.gitFor more detailed information on this workflow read the GitHub Workflow.
Setting up a running Ruby environment is outside the scope of this document.
This repository contains multiple Ruby gems:
- Various instrumentation gems located in subdirectories of
instrumentation - Various resource detector gems located in subdirectories of
resources - Various propagation gems located in the subdirectories of
propagator opentelemetry-sampler-xraylocated in thesampler/xraydirectory
Each of these gems has its configuration and tests.
For example, to test opentelemetry-instrumentation-action_pack you would:
- Change directory to
instrumentation/action_pack - Install the bundle with
bundle install - Run the tests with
bundle exec rake
Note: Some test suites make use of Appraisal, a library for testing against different versions of dependencies. To run tests in suites that use Appraisal:
- Change directory to the instrumentation you'd like to test, ex:
instrumentation/action_pack - Install the bundle with
bundle exec appraisal install - Run the tests with
bundle exec appraisal rake test
We use Docker Compose to configure and build services used in development and
testing. This makes it easier to test against libraries that have dependencies,
such as the MySQL instrumentation gem. See docker-compose.yml for specific
configuration details.
The services provided include:
app- main container environment scoped to the/appdirectory. Used primarily to build and tag theopentelemetry/opentelemetry-ruby-contrib:latestimage.x-instrumentation-<library_name>- container environment scoped to a specific instrumentation library. Seedocker-compose.ymlfor available services.
To test using Docker:
- Install Docker and Docker Compose for your operating system
- Get the latest code for the project
- Build the
opentelemetry/opentelemetry-ruby-contribimagedocker-compose build- This makes the image available locally
- Install dependencies for the service you want to interact with
docker-compose run <service-name> bundle install
- Run the tests
docker-compose run <service-name> bundle exec rake test
You may wish to test your changes against an OpenTelemetry collector. To facilitate this, we provide configuration in docker-compose.yml that should be sufficient.
By default, docker-compose launches all services, including the collector - docker-compose up from the repository root is sufficient.
However, if you only wish to launch the collector, run docker-compose up jaeger otelcol instead.
The collector listens on the default HTTP and GRPC ports (4318 and 4317, respectively). You can visualize the traces from your work via the Jaeger trace UI by visiting localhost:16686 in your browser.
Some important tips to keep in mind when making your modifications.
git checkout -b my-feature-branchDo not open a pull request from your own main branch, because we squash when merging, and that will cause you problems when you update your fork after merging.
All commits to the main repository should follow the
conventional commit standard. In a nutshell,
this means commit messages should begin with a semantic tag such as feat:,
fix:, docs:, test:, refactor:, etc... Our release tooling uses these tags
to determine the semantics of your commit, such as how it affects semantic
versioning of the libraries, and to generate changelogs from commit
descriptions. If you are not familiar with conventional commits, please review
the specification. It is pretty simple.
If you open a pull request without a conventional commit message, your reviewer may ask you to amend the commit message.
We use a combinations of tool to check style rules, linting, links and spelling of the files within this repo. To run these checks, please run:
bundle install
npm cito ensure that the tools are installed.
And prior to submitting a pr run the following to perform all the checks:
npm run check
bundle exec rake rubocopwhich will help to ensure your code complies and it passes all the test required of a pull request.
We also use Yard to generate class documentation automatically. Among other things, this means:
- Methods and arguments should include the appropriate type annotations
- You can use markdown formatting in your documentation comments
You can generate the docs locally to see the results, by running:
bundle install
bundle exec rake yardPlease make sure that you review the Instrumentation author's guide before submitting a new instrumentation.
You'll need to create a Pull Request once you've finished your work. The Kubernetes GitHub Workflow document has a significant section on PRs.
Open the PR against the open-telemetry/opentelemetry-ruby-contrib repository.
Please put [WIP] in the title, or create it as a Draft PR
if the PR is not ready for review.
An important implication of conventional commits
is that each commit message can describe at most one change. For example, if you
add a feature and fix a bug, the commit message cannot include both the feat:
and fix: semantic tags, so you should split your change into multiple commits.
The same goes for pull requests. When we merge pull requests, we generally do so by squashing, so your pull request will result in a single commit in the repository, and in turn will correspond to exactly one entry in the changelog. Therefore, please scope each pull request to include a single change.
All PRs are automatically checked for a signed CLA. Your first PR fails this check if you haven't signed the CNCF CLA.
The failed check displays a link to details which walks you through the
process. Don't worry it's painless!
PRs require a review from one or more of the code owners before merge. You'll probably get some feedback from these fine folks which helps to make the project that much better. Respond to the feedback and work with your reviewer(s) to resolve any issues.
Some of the things the code owners are looking for include:
- a signed CNCF CLA
- a passing CI build
- adherence to the principles and features outlined in the instrumentation author's guide
Reviewers are responsible for ensuring that each merged PR's commit message conforms to conventional commits. This may mean editing the commit message or the pull request title when you merge the pull request. Alternately, the reviewer may ask the pull request submitter to amend the commit message of their initial commit.
In addition, when a change is complex or a reviewer is unfamiliar with the code, the reviewer may seek additional reviews from people more familiar with the change before merging a PR.
This repository contains many components which are maintained by more than the typical set of ruby-contrib maintainers and approvers. Each component in this repository SHOULD have a component owner who is responsible for maintaining it. The README.md for each component SHOULD contain its owner, but the source of truth for component ownership is in .github/component_owners.yml.
Component owners are generally given authority to make decisions relating to implementation and feature requests for their components, provided they follow the best practices set out by the maintainers and the mission, vision and values of the OpenTelemetry Project. To facilitate independent triage of issues pertaining to the owned component, component owners are assigned the Triager role.
Component owners MUST do their best to maintain a high level of quality, security, performance, and specification compliance within their components. Maintainers may override the decisions of component owners, but should only do so when they feel one or more of these traits is compromised.
To become a component owner, contributors MUST be a member of the OpenTelemetry GitHub organization. To become a member, follow the steps in the community guidelines for membership requirements.
To become a component owner, contributors SHOULD demonstrate prior knowledge of the instrumented package or the concepts therein.
Ways do to so may be by providing proof of:
- current or prior involvement with the community that develops the upstream package
- Example: A person working on MongoDB requesting ownership over a MongoDB instrumentation
- current or prior involvement with a community that develops systems with similar concepts
- Example: A person previously working on MySQL requesting ownership of a instrumentation package that instruments another database client library instrumentation.
- current or prior extensive use of the instrumented package in other project they are involved in
- Example: A person working at a company that makes extensive use of the
koalalibrary requesting ownership of theopentelemetry-instrumentation-koalapackage.
- Example: A person working at a company that makes extensive use of the
- a vested interest in the telemetry being emitted from that instrumentation
- Example: A person employed at an observability vendor that relies on the continued maintenance of the instrumentation
Examples of proof may include but are not limited to:
- Links to issues/PRs they worked on
- Links to blog posts authored by them on behalf of the organization developing that system
- Membership in GitHub teams/organizations that are associated with the development of the upstream package
Aspiring Component Owners MUST agree to uphold the mission, vision and values of the OpenTelemetry project. Further, aspiring component owners are expected to have knowledge of the OpenTelemetry Semantic Conventions and MUST agree to adhere to the rules set out therein.
If all these conditions are met, aspiring component owners are encouraged to self-nominate by opening an issue. @open-telemetry/ruby-contrib-maintainers will then engage on the issue, may ask questions, and will then - based on the information provided on the issue - either approve or deny the ownership request. If the ownership request has been approved, the new component owner opens a PR to add themselves to the list of owners (.github/component_owners.yml) for that package. @open-telemetry/ruby-contrib-maintainers will add the component owner to @open-telemetry/ruby-contrib-triagers.
This repository includes a set of tools for releasing gems. Only maintainers can perform releases.
Releases are normally performed using GitHub Actions.
- Wait for the CI checks on the latest main branch commit to succeed. The release scripts will not run unless the build is green.
- In the GitHub UI, go to the
Actionstab, select theOpen release requestworkflow, and run the workflow manually using the dropdown in the upper right.- Releases must be run from the main branch.
- If you leave the
Gems to releasefield blank, the script will find all the gems that have had conventional-commit-tagged changes since their last release. Alternately, you can specify which gems to release by including their names, space-delimited, in this field. You can optionally append:<version>to any gem in the list to specify the version to release, or omit the version to let the script decide based on conventional commits. You can also use the special nameallto force release of all gems (and evenall:<version>to release all gems with the same version.)
- The workflow will analyze the conventional commit messages for the gems to release, and will open a release pull request. This pull request will include the appropriate changes to each gem's version constants, and an initial changelog entry for each gem. Note that it is possible to release more than one gem using a single release pull request.
- You may optionally make further modifications to the pull request branch. For example, the workflow will suggest a version number based on semver analysis of the conventional commit types, but you can choose to release a different version. You might also want to edit the changelog wording.
- To trigger the release(s), merge the release pull request. Note that the
label
release: pendingwill have been applied to the pull request when it was opened; make sure the label is still there when you merge it. - The automated release script will run automatically, and will release the
gem(s) once CI has completed. This includes:
- For each gem, it will create a release tag and a GitHub release.
- It will build and push the gems to rubygems.
- If the releases succeed, the script will update the release pull
request with the results and change its label to
release: complete. If something went wrong, the script will, if possible, report the error on the release pull request and change its label torelease: error. It will also attempt to open an issue to alert you to the failure.
- If you change your mind and do not want to follow through on a release pull
request, just close it without merging. (The release scripts will then
automatically change its label to
release: abortedfor you.)
If a release fails, the release scripts will attempt to alert you by opening an issue and/or updating the release pull request. However, you may also need to review the release logs for the GitHub Actions workflows.
There are four GitHub actions workflows related to releases.
Open release requestis the main release entrypoint, and is used to open a release pull request. If something goes wrong with this process, the logs will appear in the workflow run.Force releaseis generally used only to restart a failed release.[release hook] Update open releasesis run on pushes to the main branch, and pushes warnings to open release pull requests if you make modifications before triggering the release (i.e. because you might need to update the changelogs.)[release hook] Process releaseis the main release automation script and is run when a pull request is closed. If it determines that a release pull request was merged, it kicks off the release process for the affected gems. It also updates the label on a closed release pull request. Finally, it deletes release branches when they are no longer being used. If something goes wrong with any of these processes, the logs will appear here.
If you've already merged a release pull request and want to retry a failed
release, you can use the Force release workflow.
- If the release tag has already been created, delete it manually using the GitHub UI.
- In the GitHub UI, go to the
Actionstab, select theForce releaseworkflow, and run it manually.- You must provide the gem name and version explicitly in the fields.
- The
Extra flagsfield is useful for advanced cases. For example, if the GitHub release tag is already created and the gem already pushed to Rubygems, but the docs still need to be built, you can pass--only=docsto perform only that one step. You can also force a release even if the build is not green or the version/changelog checks are failing, by passing--skip-checks. For more details, install thetoysgem and runtoys release perform --helplocally.
It is possible to run the release scripts locally if GitHub Actions is having
problems. You will need to install the toys gem first, and you will need the
Rubygems API key for opentelemetry-ruby-contrib. These commands will succeed only if
you have write access to the repository.
To open a release pull request:
toys release requestPass the --gems= flag to provide a list of gems, or omit it to release all
changed gems.
To force-release, assuming the version and changelog are already modified:
toys release perform --rubygems-api-key=$API_KEY $GEM_NAME $GEM_VERSIONPass --help to either command for details on the options.
The release configuration is defined in the .toys/.data/releases.yml file.
Gems must be listed in this file to be supported by the release process.
To add a gem, add an appropriate entry under the gems: section. The name:
and directory: fields are generally required, as is version_constant:.
Some gems will also need to provide version_rb_path: if the file path does
not correspond exactly to the gem name.
For releases to succeed, new gems MUST include the following:
- The above configuration entry.
- The
*.gemspecfile, with the name matching the gem name. - A
version.rbfile in the standard location, or in a location listed in the configuration. - A
CHANGELOG.mdfile. - A
yardrake task.
Note
This repository is in the process of migrating to Renovate.
This repository uses Dependabot to keep dependencies up to date, however there shared development dependencies are often scattered across multiple gems. Dependabot does not currently support the ability to group dependencies for gems in multiple subdirectories, so we use a custom script to bulk update dependencies across all gems.
Note: This script uses a version of sed that isn't available on MacOS bash. You'll need to use an ubuntu-linux machine to execute it. One way to accomplish this is to run docker-compose run app and execute the script within the container.
E.g. if you want to update Rubocop to version 1.56.1, you would run:
$> bin/update-dependencies rubocop 1.56.1
Review your changes and commit
Press any key to continue
This will then run a bulk update on all of the gems in the repository, and then prompt you to review the changes and stage them for a commit:
diff --git a/propagator/ottrace/Gemfile b/propagator/ottrace/Gemfile
index 42c5ecba..74fcc743 100644
--- a/propagator/ottrace/Gemfile
+++ b/propagator/ottrace/opentelemetry-propagator-ottrace.gemspec
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
gem 'minitest', '~> 5.0'
gem 'rake', '~> 13.0'
- gem 'rubocop', '~> 1.50.0'
+ gem 'rubocop', '~> 1.56.1'
gem 'simplecov', '~> 0.22.0'
gem 'yard', '~> 0.9'
gem 'yard-doctest', '~> 0.1.6'
(1/1) Stage this hunk [y,n,q,a,d,e,?]? y
diff --git a/propagator/xray/Gemfile b/propagator/xray/Gemfile
index e29acbfc..85622d25 100644
--- a/propagator/xray/Gemfile
+++ b/propagator/xray/Gemfile
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
gem 'minitest', '~> 5.0'
gem 'rake', '~> 13.0'
- gem 'rubocop', '~> 1.50.0'
+ gem 'rubocop', '~> 1.56.1'
gem 'simplecov', '~> 0.22.0'
gem 'yard', '~> 0.9'
gem 'yard-doctest', '~> 0.1.6'
(1/1) Stage this hunk [y,n,q,a,d,e,?]? yTo update the minimum Ruby version requirement across all gems in the repository, use the bin/update-ruby-version script:
# Update to Ruby 3.3 minimum
bin/update-ruby-version 3.3
# Supports patch versions and pre-releases
bin/update-ruby-version 3.2.0
bin/update-ruby-version 3.4.0.alphaThe script will:
- Validate the version format
- Update
spec.required_ruby_versionin all gemspec files - Show a summary of changes
After running the script:
- Review changes with
git diff - Test against the new minimum Ruby version
- Update CI configurations in
.github/workflows - Update
.rubocop.ymlto set theTargetRubyVersion - Remove any conditional logic handling Ruby versions in Appraisal files that are no longer needed
- Remove any conditional logic in test cases that are no longer needed
- Commit with a message like
chore: update minimum Ruby version to 3.3