From 1a07aa128e6ebc95b837c212facedfd5ce750d4a Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Fri, 19 Sep 2025 12:15:05 -0400 Subject: [PATCH 01/11] NH-116007: update contributing and config doc --- CONFIGURATION.md | 393 +++++++++++++++++++++++++++++++++++++---------- CONTRIBUTING.md | 221 ++++++++++++++++++-------- 2 files changed, 470 insertions(+), 144 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 66ded776..8c0d6548 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -1,79 +1,166 @@ -# Configuration +# SolarWinds APM Ruby Configuration Guide -By default all applicable instrumentations are enabled. The only required configuration is the service key, so a minimal example to get started is: +This guide covers all configuration options for the SolarWinds APM Ruby gem, an OpenTelemetry-based distribution that provides automatic instrumentation and observability features for Ruby applications. + +## Table of Contents + +- [Quick Start](#quick-start) +- [Configuration Precedence](#configuration-precedence) +- [Environment Variables](#environment-variables) +- [Configuration Files](#configuration-files) +- [Programmatic Configuration](#programmatic-configuration) +- [Advanced Configuration](#advanced-configuration) +- [Configuration Reference](#configuration-reference) +- [Troubleshooting](#troubleshooting) + +## Quick Start + +To get started quickly, you only need to set your service key: ```bash -export SW_APM_SERVICE_KEY= +export SW_APM_SERVICE_KEY=: +``` + +By default, all applicable instrumentations are enabled and the gem works out-of-the-box with sensible defaults. + +### Minimal Example + +```ruby +# Set the service key (required) +ENV['SW_APM_SERVICE_KEY'] = 'your-api-token:my-ruby-app' + +# Require the gem (typically done automatically by Bundler) +require 'solarwinds_apm' + +# Your application code here ``` -Configuration can be set several ways, with the following precedence: +## Configuration Precedence + +Configuration can be set in multiple ways with the following precedence order (highest to lowest): + +1. **Environment Variables** - Highest priority +2. **Programmatic Configuration** - Set in Ruby code +3. **Configuration Files** - Rails initializer or config file +4. **Default Values** - Built-in defaults -`environment variable > programmatic > configuration file > default` +> **💡 Tip:** Environment variables always take precedence, making them ideal for deployment-specific settings. ## Environment Variables -Settings specific to `solarwinds_apm` are prefixed by `SW_APM_` and described in the [Reference](#reference) section. Standard OpenTelemetry environment variables that impact this library's functionality are noted below. +Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. + +### Core Settings + +All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard OpenTelemetry environment variables are also supported where applicable. + +#### Required Configuration + +| Variable | Description | Example | +|----------|-------------|---------| +| `SW_APM_SERVICE_KEY` | API token and service name (required) | `your-token:my-service` | -### Exporter +#### Common Configuration -The default `solarwinds` exporter which communicates with the SolarWinds Observability backend is always configured as OTLP Exporter. Additional exporters can be configured via the `OTEL_TRACES_EXPORTER` environment variable. For example, console exporter is part of standard installation and can be enabled via: +| Variable | Description | Default | Example | +|----------|-------------|---------|---------| +| `SW_APM_ENABLED` | Enable/disable the entire library | `true` | `false` | +| `SW_APM_DEBUG_LEVEL` | Logging verbosity (-1 to 6) | `3` | `5` | +| `SW_APM_COLLECTOR` | Collector endpoint override | `apm.collector.na-01.cloud.solarwinds.com:443` | `custom.collector.com:443` | +### OpenTelemetry Integration + +#### Exporters + +The SolarWinds backend uses the OTLP exporter by default. You can configure additional exporters for debugging or multi-backend scenarios: + +**Console Exporter (for debugging):** ```bash export OTEL_TRACES_EXPORTER=console ``` -Other exporters (e.g. Jaeger) must first be installed and required before loading `solarwinds_apm`. For example, if dependencies are loaded by `Bundler.require`, add the OTLP exporter to the Gemfile: +**Multiple Exporters:** +```bash +export OTEL_TRACES_EXPORTER=otlp,console +``` -```ruby -# application dependencies, eg -# gem "rails", "~> 7.0.5", ">= 7.0.5.1" +**Third-party Exporters:** -gem 'opentelemetry-exporter-jaeger' +For exporters like Jaeger, first add them to your Gemfile: -# end of Gemfile +```ruby +# Add before solarwinds_apm in your Gemfile +gem 'opentelemetry-exporter-jaeger' gem 'solarwinds_apm' ``` -And set the environment variable: - +Then configure: ```bash export OTEL_TRACES_EXPORTER=jaeger ``` -### Service Name +#### Service Naming -By default the service name portion of the service key is used, e.g. `my-service` if the service key is `SW_APM_SERVICE_KEY=api-token:my-service`. If the `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES` environment variable is used to specify a service name, it will take precedence over the default. +The service name is extracted from your service key by default, but can be overridden: +**Service key format:** ```bash -# service name for instrumented app will be 'bar', not 'foo' -export SW_APM_SERVICE_KEY=:foo -export OTEL_SERVICE_NAME=bar +export SW_APM_SERVICE_KEY=: ``` -### Instrumentation Libraries +**Override with OpenTelemetry variables:** +```bash +# Service name will be 'production-api', not 'my-service' +export SW_APM_SERVICE_KEY=:my-service +export OTEL_SERVICE_NAME=production-api +``` -You can use OpenTelemetry Ruby instrumentation environment variables to [disable](https://opentelemetry.io/docs/languages/ruby/libraries/#overriding-configuration-for-specific-instrumentation-libraries-with-environment-variables) or [configure](https://opentelemetry.io/docs/languages/ruby/libraries/#configuring-specific-instrumentation-libraries-with-environment-variables) certain instrumentation, see the [OpenTelemetry Docs](https://opentelemetry.io/docs/languages/ruby/libraries/#use-instrumentation-libraries) for details. +**Resource attributes:** +```bash +export OTEL_RESOURCE_ATTRIBUTES=service.name=production-api,service.version=1.2.3 +``` -For example, to disable sinatra instrumentation and disable mysql2 instrumentation's obfuscation of db.statement: +#### Instrumentation Control +Fine-tune individual instrumentation libraries using OpenTelemetry environment variables: + +**Disable specific instrumentation:** ```bash export OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED=false -export OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS='db_statement=include;' +export OTEL_RUBY_INSTRUMENTATION_REDIS_ENABLED=false ``` -or in your initialization step: +**Configure instrumentation options:** +```bash +# Include full SQL statements (disable obfuscation) +export OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS='db_statement=include;' + +# Configure HTTP instrumentation +export OTEL_RUBY_INSTRUMENTATION_NET_HTTP_CONFIG_OPTS='untraced_hosts=localhost,internal.service;' +``` +Set inside file through ENV hash ```ruby +# Set before requiring solarwinds_apm ENV['OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED'] = 'false' ENV['OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS'] = 'db_statement=include;' ``` +> **📚 Learn More:** See the [OpenTelemetry Ruby instrumentation documentation](https://opentelemetry.io/docs/languages/ruby/libraries/) for all available options. + ## Programmatic Configuration -Many OpenTelemetry instrumentation library configurations can be set within the `SolarWindsAPM::OTelConfig.initialize_with_config ... end` block, please consult the individual [instrumentation](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation) README pages for the options available. Note this takes lower precedence than the [environment varable](#instrumentation-libraries) settings. +For advanced use cases, you can configure OpenTelemetry instrumentation libraries programmatically using the `SolarWindsAPM::OTelConfig.initialize_with_config` block. -> [!IMPORTANT] -> this feature is only enabled if auto-config is disabled via `SW_APM_AUTO_CONFIGURE=false`. +### Prerequisites + +> **⚠️ Important:** Programmatic configuration requires disabling auto-configuration: + +```bash +export SW_APM_AUTO_CONFIGURE=false +``` + +### Basic Example Below is an example that disables Dalli instrumentation and sets the Rack instrumentation to capture certain headers as Span attributes: @@ -89,105 +176,251 @@ SolarWindsAPM::OTelConfig.initialize_with_config do |config| end ``` -## Configuration File +### Advanced Configuration + +```ruby +SolarWindsAPM::OTelConfig.initialize_with_config do |config| + # HTTP client configuration + config["OpenTelemetry::Instrumentation::Net::HTTP"] = { + untraced_hosts: ['localhost', 'internal.service.com'], + untraced_requests: ->(uri, req) { uri.path == '/health' } + } + + # Rails configuration + config["OpenTelemetry::Instrumentation::Rails"] = { + enable_recognize_route: true, + enable_dependency_tracking: true + } + + # Redis configuration + config["OpenTelemetry::Instrumentation::Redis"] = { + peer_service: 'redis-cluster', + db_statement_serializer: ->(stmt) { stmt.truncate(100) } + } +end +``` -On startup, the library looks for the configuration file in the following locations under the application's current working directory: +> **📖 Reference:** Consult individual [instrumentation README files](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation) for complete configuration options. -* `config/initializers/solarwinds_apm.rb` for Rails applications, which can be created by running the provided generator: +## Configuration Files - ```bash - bundle exec rails generate solarwinds_apm:install - ``` +Configuration files provide a centralized way to manage settings, especially useful for complex configurations or when using multiple environments. -* `solarwinds_apm_config.rb` for non-Rails applications +### Rails Applications -The default location can be overridden via environment variable `SW_APM_CONFIG_RUBY`: +For Rails applications, use the built-in generator to create a configuration file: ```bash -export SW_APM_CONFIG_RUBY=config/file/location.rb +bundle exec rails generate solarwinds_apm:install ``` -The configuration file should be Ruby code that sets key/values in the hash exposed by `SolarWindsAPM::Config`. The bundled [Rails generator template file](https://github.com/solarwinds/apm-ruby/blob/main/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb) serves as an example of the supported values, see also the [Reference](#reference) section. +This creates `config/initializers/solarwinds_apm.rb` with documented configuration options. -## Reference +### Non-Rails Applications -Environment Variable | Config File Key | Description | Default --------------------- | --------------- | ----------- | ------- -`SW_APM_AUTO_CONFIGURE` | N/A | By default the library is configured to work out-of-the-box with all automatic instrumentation libraries enabled. Set this to `false` to custom initialize the library with configuration options for instrumentation, see [Programmatic Configuration](#programmatic-configuration) for details. | `true` -`SW_APM_COLLECTOR` | N/A | Override the default collector endpoint to which the library connects and exports data. It should be defined using the format host:port. | `apm.collector.na-01.cloud.solarwinds.com:443` -`SW_APM_CONFIG_RUBY` | N/A | Override the default location for the configuration file. This can be an absolute or relative filename, or the directory under which the `solarwinds_apm_config.rb` file would be looked for. | None -`SW_APM_DEBUG_LEVEL` | `:debug_level` | Set the library's logging level, valid values are -1 through 6 (least to most verbose).
Setting -1 disables logging from the library. | 3 -`SW_APM_ENABLED` | N/A | Enable/disable the library, setting `false` is an alternative to uninstalling `solarwinds_apm` since it will prevent the library from loading. | `true` -`SW_APM_SERVICE_KEY` | `:service_key` | API token and service name in the form of `token:service_name`, **required**. | None -`SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#tag-query-with-trace-context) for details.| `false` -`SW_APM_TRIGGER_TRACING_MODE` | `:trigger_tracing_mode` | Enable/disable trigger tracing for the service. Setting to `disabled` may impact DEM visibility into the service. | `enabled` -`SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option only takes effect in the AWS Lambda runtime. Set to `false` to disable the attempt to preload function dependencies and install instrumentations. | `true` -`SW_APM_TRANSACTION_NAME` | N/A | Customize the transaction name for all traces, typically used to target specific instrumented lambda functions. _Precedence order_: custom SDK > `SW_APM_TRANSACTION_NAME` > automatic naming | None -N/A | `:log_traceId` | Configure the insertion of trace context into application logs, setting `:traced` would include the available context fields such as trace_id, span_id into log messages. | `:never` -N/A | `:tracing_mode` | Enable/disable the tracing mode for this service, setting `:disabled` would suppress all trace spans and metrics. | `:enabled` -N/A | `:transaction_settings` | Configure tracing mode per transaction, aka transaction filtering. See [Transaction Filtering](#transaction-filtering) for details.| None +Create a file named `solarwinds_apm_config.rb` in your application's root directory: + +```ruby +# solarwinds_apm_config.rb +SolarWindsAPM::Config[:service_key] = 'your-token:your-service' +SolarWindsAPM::Config[:debug_level] = 3 +SolarWindsAPM::Config[:tag_sql] = true +``` + +### Custom Location + +Override the default configuration file location: + +```bash +export SW_APM_CONFIG_RUBY=/path/to/your/config.rb +``` + +### Configuration File Template + +Here's a comprehensive configuration file example: + +```ruby +# SolarWinds APM Configuration + +# Required: Service key +SolarWindsAPM::Config[:service_key] = ENV['SW_APM_SERVICE_KEY'] + +# Logging and debugging +SolarWindsAPM::Config[:debug_level] = 3 +SolarWindsAPM::Config[:log_traceId] = :traced + +# Tracing configuration +SolarWindsAPM::Config[:tracing_mode] = :enabled +SolarWindsAPM::Config[:trigger_tracing_mode] = :enabled + +# Database query tagging +SolarWindsAPM::Config[:tag_sql] = false + +# Transaction filtering (see Advanced Configuration section) +SolarWindsAPM::Config[:transaction_settings] = [ + { + regexp: '\.(css|js|png|jpg|gif|ico)$', + opts: Regexp::IGNORECASE, + tracing: :disabled + } +] +``` + +## Advanced Configuration ### Transaction Filtering -Specific transactions can be disabled from tracing (suppressing both spans and metrics) using the `:transaction_settings` configuration. An example that filters out static assets and a message consumer: +Control which transactions are traced using pattern-based filtering. This is useful for excluding static assets, health checks, or other requests that don't need tracing. +**Configuration:** ```ruby SolarWindsAPM::Config[:transaction_settings] = [ { - regexp: '\.(css|js|png)$', + regexp: '\.(css|js|png|jpg|gif|ico|woff2?)$', opts: Regexp::IGNORECASE, tracing: :disabled }, { - regexp: 'CONSUMER:mytopic process', + regexp: '/health|/status|/ping', + tracing: :disabled + }, + { + regexp: 'CONSUMER:.*process', # Background job patterns tracing: :disabled } ] ``` -### Tag Query with Trace Context +**Pattern Matching:** +- Uses Ruby regular expressions +- Matches against the transaction name +- Supports regex options like `Regexp::IGNORECASE` +- Can disable both spans and metrics -You can set the environment variable `SW_APM_TAG_SQL` or configuration file option `:tag_sql` to true to enable appending the current trace context into a database query as a SQL comment. For example: +### SQL Query Tagging -```console -# query without tag sql -SELECT * FROM SAMPLE_TABLE WHERE user_id = 1; +Append trace context to database queries as SQL comments for correlation between traces and database logs. -# query with tag sql -SELECT * FROM SAMPLE_TABLE WHERE user_id = 1; /* traceparent=7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01 */ +**Enable SQL tagging:** +```bash +export SW_APM_TAG_SQL=true ``` -#### Limitation - -> [!NOTE] -> This feature currently does not support prepared statements. For `mysql2` the `query` operation is supported, for `pg` the "[exec-ish](https://github.com/solarwinds/apm-ruby/blob/main/lib/solarwinds_apm/patch/tag_sql/sw_pg_patch.rb#L15)" operations like `exec` and `query` are supported. +**Example output:** +```sql +-- Before (without tagging) +SELECT * FROM users WHERE id = 1; -### Background Jobs +-- After (with tagging) +SELECT * FROM users WHERE id = 1; +/* traceparent=7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01 */ +``` -#### Resque +**Supported Operations:** +- **MySQL2**: `query` operations +- **PostgreSQL**: `exec`, `query`, and similar operations -[Resque](https://github.com/resque/resque) is a Redis-backed library for creating background jobs, queuing them on multiple queues, and processing them later. +> **⚠️ Limitation:** Currently does not support prepared statements. -When starting the Resque worker, it is necessary to set: `RUN_AT_EXIT_HOOKS=1`. +### Log Trace Context Integration -For example: +Include trace context in your application logs for better correlation: -```console -RUN_AT_EXIT_HOOKS=1 QUEUE=${QUEUE_NAME} ${EXTRA_OPTIONS} bundle exec rake resque:work +```ruby +SolarWindsAPM::Config[:log_traceId] = :traced ``` -Explanation: +This adds trace and span IDs to log entries when using supported logging frameworks. + +### Background Job Configuration -* `RUN_AT_EXIT_HOOKS`: This option, provided by Resque, ensures that the forked processes shut down gracefully (i.e., no immediate `exit!`). This allows the background processes that handle signal (trace, metrics, etc.) transmission to complete their tasks. +#### Resque -### Proxy +When using Resque, ensure graceful shutdown for proper trace transmission: + +```bash +RUN_AT_EXIT_HOOKS=1 QUEUE=myqueue bundle exec rake resque:work +``` + +The `RUN_AT_EXIT_HOOKS=1` ensures background processes complete before worker shutdown. This allows the background processes that handle signal (trace, metrics, etc.) transmission to complete their tasks. + +### Proxy Configuration Starting with version 7.0.0, the environment variable `SW_APM_PROXY` and configuration file option `:http_proxy` are deprecated since telemetry is exported with standard OTLP exporters. These exporters use Ruby's `Net::HTTP`, which supports configuring an [HTTP proxy](https://docs.ruby-lang.org/en/master/Net/HTTP.html#class-Net::HTTPSession-label-Proxy+Server). The examples below set the `http_proxy` environment variable for the Ruby process to configure the proxy: +For environments requiring HTTP proxies, configure using standard Ruby `Net::HTTP` proxy environment variables: + +**Basic proxy:** ```bash # proxy server with no authentication http_proxy=http://: ruby my.app # proxy server that requires basic authentication http_proxy=http://:@: ruby my.app -``` \ No newline at end of file +``` + +> **📝 Note:** Starting with version 7.0.0, `SW_APM_PROXY` is deprecated in favor of standard HTTP proxy environment variables. + +### Lambda Configuration + +For AWS Lambda deployments: + +```bash +# Disable dependency preloading if needed +export SW_APM_LAMBDA_PRELOAD_DEPS=false + +# Set custom transaction names +export SW_APM_TRANSACTION_NAME=my-lambda-function +``` + +## Configuration Reference + +### Environment Variables + +Environment Variable | Config File Key | Description | Default +-------------------- | --------------- | ----------- | ------- +`SW_APM_AUTO_CONFIGURE` | N/A | By default the library is configured to work out-of-the-box with all automatic instrumentation libraries enabled. Set this to `false` to custom initialize the library with configuration options for instrumentation, see [Programmatic Configuration](#programmatic-configuration) for details. | `true` +`SW_APM_COLLECTOR` | N/A | Override the default collector endpoint to which the library connects and exports data. It should be defined using the format host:port. | `apm.collector.na-01.cloud.solarwinds.com:443` +`SW_APM_CONFIG_RUBY` | N/A | Override the default location for the configuration file. This can be an absolute or relative filename, or the directory under which the `solarwinds_apm_config.rb` file would be looked for. | None +`SW_APM_DEBUG_LEVEL` | `:debug_level` | Set the library's logging level, valid values are -1 through 6 (least to most verbose).
Setting -1 disables logging from the library. | 3 +`SW_APM_ENABLED` | N/A | Enable/disable the library, setting `false` is an alternative to uninstalling `solarwinds_apm` since it will prevent the library from loading. | `true` +`SW_APM_SERVICE_KEY` | `:service_key` | API token and service name in the form of `token:service_name`, **required**. | None +`SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#tag-query-with-trace-context) for details.| `false` +`SW_APM_TRIGGER_TRACING_MODE` | `:trigger_tracing_mode` | Enable/disable trigger tracing for the service. Setting to `disabled` may impact DEM visibility into the service. | `enabled` +`SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option only takes effect in the AWS Lambda runtime. Set to `false` to disable the attempt to preload function dependencies and install instrumentations. | `true` +`SW_APM_TRANSACTION_NAME` | N/A | Customize the transaction name for all traces, typically used to target specific instrumented lambda functions. _Precedence order_: custom SDK > `SW_APM_TRANSACTION_NAME` > automatic naming | None +N/A | `:log_traceId` | Configure the insertion of trace context into application logs, setting `:traced` would include the available context fields such as trace_id, span_id into log messages. | `:never` +N/A | `:tracing_mode` | Enable/disable the tracing mode for this service, setting `:disabled` would suppress all trace spans and metrics. | `:enabled` +N/A | `:transaction_settings` | Configure tracing mode per transaction, aka transaction filtering. See [Transaction Filtering](#transaction-filtering) for details.| None + +### Debug Levels + +| Level | Description | +|-------|-------------| +| `-1` | Logging disabled | +| `0` | Fatal errors only | +| `1` | Errors | +| `2` | Warnings | +| `3` | Info (default) | +| `4` | Debug | +| `5` | Verbose | +| `6` | Maximum verbosity | + +## Troubleshooting + +### Log Analysis + +Enable debug logging and look for: +- Service key validation +- Collector connection status +- Instrumentation loading +- Span creation and export + +```bash +# Enable detailed logging +export SW_APM_DEBUG_LEVEL=5 +# Or use otel debug level +export OTEL_LOG_LEVEL=debug +``` + +For additional help, see the [SolarWinds documentation](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) or contact support. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70fa25aa..abb5b5eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,70 +1,114 @@ -# Contributing +# Contributing to SolarWinds APM Ruby -## Requirements +Thank you for your interest in contributing to the SolarWinds APM Ruby gem! This document provides guidelines and instructions for contributing to this OpenTelemetry-based Ruby distribution. -The descriptions below assume you are in the locally cloned project root directory, i.e. `apm-ruby`. +## Table of Contents -Prerequisites +- [Code of Conduct](#code-of-conduct) +- [How to Contribute](#how-to-contribute) +- [Development Setup](#development-setup) +- [Development Workflow](#development-workflow) +- [Testing](#testing) +- [Code Quality](#code-quality) +- [Getting Help](#getting-help) -* Docker -* Docker Compose +## Code of Conduct + +By participating in this project, you agree to abide by our Code of Conduct. Please treat all community members with respect and create a welcoming environment for everyone. + +## How to Contribute + +We welcome various types of contributions: + +- **Bug reports**: Help us identify and fix issues +- **Feature requests**: Suggest new functionality or improvements +- **Documentation**: Improve our docs, guides, and examples +- **Code contributions**: Bug fixes, new features, performance improvements +- **Testing**: Add test coverage or improve existing tests + +## Development Setup + +### Prerequisites + +Before you begin, ensure you have the following installed on your system: + +- **Docker** - Required for containerized development and testing +- **Docker Compose** - Used for orchestrating multi-container setups +- **Git** - For version control +- **Ruby** - For running Rake tasks + +> **Note:** All development work is done in Docker containers, so you don't need Ruby installed on your host machine, but it's helpful for running Rake tasks. + +The instructions below assume you are in the locally cloned project root directory (`apm-ruby`). + +### Getting Started + +1. **Fork the repository** on GitHub +2. **Clone your fork** locally: + ```bash + git clone https://github.com/YOUR_USERNAME/apm-ruby.git + cd apm-ruby + ``` +3. **Add the upstream remote**: + ```bash + git remote add upstream https://github.com/solarwinds/apm-ruby.git + ``` ## Host Machine Setup -You'll need a host environment that can run the various Rake tasks to spin up development and testing containers. The following describes how to do this with [rbenv](https://github.com/rbenv/rbenv). +For development, you'll need a host environment capable of running Rake tasks to manage development and testing containers. We recommend using [rbenv](https://github.com/rbenv/rbenv) for Ruby version management. ### 1. Install rbenv -Mac +Choose the installation method that works best for your system: +**macOS (using Homebrew):** ```bash brew install rbenv ruby-build ``` -Linux - +**Linux (Ubuntu/Debian):** ```bash sudo apt install rbenv ``` -Built from source (github) - +**Build from source:** ```bash git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc # for bash echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc # for zsh ``` -### 2. Install and Set Ruby Runtime +### 2. Install and Configure Ruby -Install ruby from rbenv: +Install Ruby using rbenv: ```bash -# list latest stable versions: +# List latest stable versions rbenv install -l -# list all local versions: +# List all available versions rbenv install -L -# install a Ruby version: +# Install the desired Ruby version rbenv install 3.1.2 ``` -Enable rbenv by following the instructions printed by this command: +Enable rbenv by following the initialization instructions: ```bash rbenv init ``` -Set ruby version to use. Set this at the global level to prevent `.ruby-version` conflicts within the development container which bind mounts the working tree: +Set the global Ruby version (this prevents conflicts within development containers): ```bash -rbenv global 3.1.2 # set the default Ruby version for this machine +rbenv global 3.1.2 # Set the default Ruby version for this machine ``` -### 3. Install Minimal Project Dependencies +### 3. Install Project Dependencies -Install bundler, configure it to skip unneeded groups, then install the project dependencies to allow working with Rake tasks: +Install Bundler and configure it for development: ```bash gem install bundler @@ -72,101 +116,150 @@ bundle config set --local without development test bundle install ``` -Should now be able to list the Rake tasks: +Verify the setup by listing available Rake tasks: ```bash bundle exec rake -T ``` -## Run Development Container +You should see tasks like `docker_dev`, `docker_tests`, `build_gem`, etc. -The `solarwinds_apm` gem requires a Linux run time environment. To work on the codebase we set up an Ubuntu container with the tools needed to build, install and work with the project. +## Development Workflow -Starting the container: +### Setting Up the Development Environment + +The `solarwinds_apm` gem requires a Linux runtime environment. We use Ubuntu containers with all necessary tools for building, installing, and working with the project. + +#### Starting the Development Container + +Launch the development container: ```bash bundle exec rake docker_dev ``` -In the container, set up the environment and project dependencies: +Once inside the container, set up the environment: ```bash -# choose the ruby version to use, setting it at the global level +# Choose and set the Ruby version (check available versions) rbenv versions rbenv global -# install project gem dependencies +# Install project dependencies bundle install ``` -### Building the Gem +#### Working in the Development Container + +The development container provides a complete environment for: +- Building and testing the gem +- Running linting tools +- Debugging issues +- Making code changes + +All source code is mounted from your host machine, so changes are immediately reflected in the container. + +### Building and Testing the Gem + +#### Building the Gem -The gem can be built, installed, and run inside the development container: +Build the gem within the development container: ```bash -# build the gem +# Build the gem bundle exec rake build_gem -# install the built gem +# Install the built gem locally gem install builds/solarwinds_apm-.gem -# load the gem +# Test the installation by loading the gem SW_APM_SERVICE_KEY= irb -r solarwinds_apm ``` -### Linting +#### Making Changes + +1. **Create a feature branch**: + ```bash + git checkout -b feature/your-feature-name + ``` + +2. **Make your changes** in the appropriate files under `lib/` + +3. **Write or update tests** in the `test/` directory + +4. **Test your changes** (see Testing section below) + +5. **Run linting** to ensure code quality -Use this Rake task to run rubocop inside the development container: +## Testing +> **Note:** Some tests require the `APM_RUBY_TEST_KEY` environment variable. Contact the maintainers if you need access to a test key. + +### Running Tests + +**Full test suite:** ```bash -bundle exec rake rubocop +APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh ``` -It will produce the file `rubocop_result.txt`. Issues found should be addressed prior to commit. - -## Run Test Containers +**Single test file:** +```bash +# Most tests require only the unit.gemfile dependencies +bundle update +bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb +``` -On the host machine, you can use the `docker_tests` Rake task to run the test suite, or launch an interactive shell session into the test container to run specific tests or to debug. +**Single test case:** +```bash +bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ +``` -### Run Test Suite +### Running the Complete Test Suite From the Host Machine -Run the test suite (some test cases rely on env `APM_RUBY_TEST_KEY`): +Execute the full test suite from the host machine: ```bash -# run tests in a ruby:3.1.0-bullseye container +# Run tests in Ruby 3.1.0 bullseye container bundle exec rake 'docker_tests[,,,APM_RUBY_TEST_KEY=your_service_key]' -# run tests in a ruby:3.2-alpine linux/amd64 container +# Run tests in Ruby 3.2 Alpine container for ARM64 bundle exec rake 'docker_tests[3.2-alpine,,linux/amd64,APM_RUBY_TEST_KEY=your_service_key]' ``` -Test logs are written to the project's `log` directory, which is bind mounted and available on the host machine. +Test logs are written to the `log/` directory and are available on the host machine. -### Launch Interactive Shell +### Test Organization -Start an interactive session in the container: +Tests are organized in the `test/` directory: +- `test/api/` - API-related tests +- `test/opentelemetry/` - OpenTelemetry integration tests +- `test/patch/` - Instrumentation patch tests +- `test/sampling/` - Sampling logic tests +- `test/support/` - Test utilities and helpers -```bash -bundle exec rake 'docker_tests[,false]' -``` +## Code Quality -In the container, set up the environment: +### Linting + +We use RuboCop for code style enforcement. Run linting in the development container: ```bash -test/test_setup.sh +bundle exec rake rubocop ``` -To run the full suite (some test cases rely on env `APM_RUBY_TEST_KEY`): +This generates a `rubocop_result.txt` file. **All linting issues must be resolved before submitting a pull request.** -```bash -APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh -``` +## Getting Help -To run a single test file or single test case: +- **Issues**: Check existing issues or create a new one +- **Discussions**: Use GitHub Discussions for questions +- **Documentation**: Refer to our [documentation website](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) +- **Email**: Contact technicalsupport@solarwinds.com for technical support -```bash -# most tests require just the unit.gemfile dependencies -bundle update -bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ -``` +## Additional Resources + +- [OpenTelemetry Ruby Documentation](https://opentelemetry.io/docs/instrumentation/ruby/) +- [SolarWinds Observability Documentation](https://documentation.solarwinds.com/en/success_center/observability/default.htm) +- [Project GitHub Repository](https://github.com/solarwinds/apm-ruby) + +Thank you for contributing to SolarWinds APM Ruby! 🙏 From 8e8d3390367e1d9db5d87b3cecdb8165343adc45 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Fri, 19 Sep 2025 12:22:25 -0400 Subject: [PATCH 02/11] lint --- CHANGELOG.md | 6 +++--- CONFIGURATION.md | 20 ++++++++++++++++++-- CONTRIBUTING.md | 14 +++++++++++++- README.md | 1 + 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be6a42d1..ce439b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,9 +13,9 @@ This release includes the following features: * OTLP trace and metric exporter are the now default exporters for swo backend * NH-103815: Added resource detectors for Kubernetes and UAMS client * Added Lambda instrumentation for 6.1.2 -* Update tag_sql section by @cheempz in https://github.com/solarwinds/apm-ruby/pull/176 -* NH-103804: reverselab scan gem by @xuan-cao-swi in https://github.com/solarwinds/apm-ruby/pull/179 -* Bump DavidAnson/markdownlint-cli2-action from 19 to 20 by @dependabot in https://github.com/solarwinds/apm-ruby/pull/193 +* Update tag_sql section by @cheempz in +* NH-103804: reverselab scan gem by @xuan-cao-swi in +* Bump DavidAnson/markdownlint-cli2-action from 19 to 20 by @dependabot in ## solarwinds_apm 6.1.2 (02/28/2025) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 8c0d6548..5e2dba26 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -75,11 +75,13 @@ All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard OpenT The SolarWinds backend uses the OTLP exporter by default. You can configure additional exporters for debugging or multi-backend scenarios: **Console Exporter (for debugging):** + ```bash export OTEL_TRACES_EXPORTER=console ``` **Multiple Exporters:** + ```bash export OTEL_TRACES_EXPORTER=otlp,console ``` @@ -95,6 +97,7 @@ gem 'solarwinds_apm' ``` Then configure: + ```bash export OTEL_TRACES_EXPORTER=jaeger ``` @@ -104,11 +107,13 @@ export OTEL_TRACES_EXPORTER=jaeger The service name is extracted from your service key by default, but can be overridden: **Service key format:** + ```bash export SW_APM_SERVICE_KEY=: ``` **Override with OpenTelemetry variables:** + ```bash # Service name will be 'production-api', not 'my-service' export SW_APM_SERVICE_KEY=:my-service @@ -116,6 +121,7 @@ export OTEL_SERVICE_NAME=production-api ``` **Resource attributes:** + ```bash export OTEL_RESOURCE_ATTRIBUTES=service.name=production-api,service.version=1.2.3 ``` @@ -125,12 +131,14 @@ export OTEL_RESOURCE_ATTRIBUTES=service.name=production-api,service.version=1.2. Fine-tune individual instrumentation libraries using OpenTelemetry environment variables: **Disable specific instrumentation:** + ```bash export OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED=false export OTEL_RUBY_INSTRUMENTATION_REDIS_ENABLED=false ``` **Configure instrumentation options:** + ```bash # Include full SQL statements (disable obfuscation) export OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS='db_statement=include;' @@ -140,6 +148,7 @@ export OTEL_RUBY_INSTRUMENTATION_NET_HTTP_CONFIG_OPTS='untraced_hosts=localhost, ``` Set inside file through ENV hash + ```ruby # Set before requiring solarwinds_apm ENV['OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED'] = 'false' @@ -273,6 +282,7 @@ SolarWindsAPM::Config[:transaction_settings] = [ Control which transactions are traced using pattern-based filtering. This is useful for excluding static assets, health checks, or other requests that don't need tracing. **Configuration:** + ```ruby SolarWindsAPM::Config[:transaction_settings] = [ { @@ -292,6 +302,7 @@ SolarWindsAPM::Config[:transaction_settings] = [ ``` **Pattern Matching:** + - Uses Ruby regular expressions - Matches against the transaction name - Supports regex options like `Regexp::IGNORECASE` @@ -302,11 +313,13 @@ SolarWindsAPM::Config[:transaction_settings] = [ Append trace context to database queries as SQL comments for correlation between traces and database logs. **Enable SQL tagging:** + ```bash export SW_APM_TAG_SQL=true ``` **Example output:** + ```sql -- Before (without tagging) SELECT * FROM users WHERE id = 1; @@ -317,6 +330,7 @@ SELECT * FROM users WHERE id = 1; ``` **Supported Operations:** + - **MySQL2**: `query` operations - **PostgreSQL**: `exec`, `query`, and similar operations @@ -351,6 +365,7 @@ Starting with version 7.0.0, the environment variable `SW_APM_PROXY` and configu For environments requiring HTTP proxies, configure using standard Ruby `Net::HTTP` proxy environment variables: **Basic proxy:** + ```bash # proxy server with no authentication http_proxy=http://: ruby my.app @@ -385,7 +400,7 @@ Environment Variable | Config File Key | Description | Default `SW_APM_DEBUG_LEVEL` | `:debug_level` | Set the library's logging level, valid values are -1 through 6 (least to most verbose).
Setting -1 disables logging from the library. | 3 `SW_APM_ENABLED` | N/A | Enable/disable the library, setting `false` is an alternative to uninstalling `solarwinds_apm` since it will prevent the library from loading. | `true` `SW_APM_SERVICE_KEY` | `:service_key` | API token and service name in the form of `token:service_name`, **required**. | None -`SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#tag-query-with-trace-context) for details.| `false` +`SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#sql-query-tagging) for details.| `false` `SW_APM_TRIGGER_TRACING_MODE` | `:trigger_tracing_mode` | Enable/disable trigger tracing for the service. Setting to `disabled` may impact DEM visibility into the service. | `enabled` `SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option only takes effect in the AWS Lambda runtime. Set to `false` to disable the attempt to preload function dependencies and install instrumentations. | `true` `SW_APM_TRANSACTION_NAME` | N/A | Customize the transaction name for all traces, typically used to target specific instrumented lambda functions. _Precedence order_: custom SDK > `SW_APM_TRANSACTION_NAME` > automatic naming | None @@ -411,6 +426,7 @@ N/A | `:transaction_settings` | Configure tracing mode per transaction, aka tran ### Log Analysis Enable debug logging and look for: + - Service key validation - Collector connection status - Instrumentation loading @@ -423,4 +439,4 @@ export SW_APM_DEBUG_LEVEL=5 export OTEL_LOG_LEVEL=debug ``` -For additional help, see the [SolarWinds documentation](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) or contact support. \ No newline at end of file +For additional help, see the [SolarWinds documentation](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) or contact support. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abb5b5eb..260d6d41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,11 +45,14 @@ The instructions below assume you are in the locally cloned project root directo 1. **Fork the repository** on GitHub 2. **Clone your fork** locally: + ```bash git clone https://github.com/YOUR_USERNAME/apm-ruby.git cd apm-ruby ``` + 3. **Add the upstream remote**: + ```bash git remote add upstream https://github.com/solarwinds/apm-ruby.git ``` @@ -63,16 +66,19 @@ For development, you'll need a host environment capable of running Rake tasks to Choose the installation method that works best for your system: **macOS (using Homebrew):** + ```bash brew install rbenv ruby-build ``` **Linux (Ubuntu/Debian):** + ```bash sudo apt install rbenv ``` **Build from source:** + ```bash git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc # for bash @@ -152,6 +158,7 @@ bundle install #### Working in the Development Container The development container provides a complete environment for: + - Building and testing the gem - Running linting tools - Debugging issues @@ -179,6 +186,7 @@ SW_APM_SERVICE_KEY= irb -r solarwinds_apm #### Making Changes 1. **Create a feature branch**: + ```bash git checkout -b feature/your-feature-name ``` @@ -198,11 +206,13 @@ SW_APM_SERVICE_KEY= irb -r solarwinds_apm ### Running Tests **Full test suite:** + ```bash APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh ``` **Single test file:** + ```bash # Most tests require only the unit.gemfile dependencies bundle update @@ -210,6 +220,7 @@ bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb ``` **Single test case:** + ```bash bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ ``` @@ -231,6 +242,7 @@ Test logs are written to the `log/` directory and are available on the host mach ### Test Organization Tests are organized in the `test/` directory: + - `test/api/` - API-related tests - `test/opentelemetry/` - OpenTelemetry integration tests - `test/patch/` - Instrumentation patch tests @@ -254,7 +266,7 @@ This generates a `rubocop_result.txt` file. **All linting issues must be resolve - **Issues**: Check existing issues or create a new one - **Discussions**: Use GitHub Discussions for questions - **Documentation**: Refer to our [documentation website](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) -- **Email**: Contact technicalsupport@solarwinds.com for technical support +- **Email**: Contact for technical support ## Additional Resources diff --git a/README.md b/README.md index 19cb22cc..276e871e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ The `solarwinds_apm` gem starting from version 6.0.0 is an [OpenTelemetry Ruby](https://opentelemetry.io/docs/instrumentation/ruby/) distribution. It provides automatic instrumentation and custom SolarWinds Observability features for Ruby applications. ## Requirements +> > [!NOTE] > Versions before 7.0.0 only support Linux and will go into no-op mode on other platforms. From b80566c7e383f3cea6eae3249c24619e86b4b523 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Fri, 19 Sep 2025 12:28:15 -0400 Subject: [PATCH 03/11] lint --- CONFIGURATION.md | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 5e2dba26..223d8898 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -46,21 +46,17 @@ Configuration can be set in multiple ways with the following precedence order (h > **💡 Tip:** Environment variables always take precedence, making them ideal for deployment-specific settings. -## Environment Variables - Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. -### Core Settings - All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard OpenTelemetry environment variables are also supported where applicable. -#### Required Configuration +**Required Configuration** | Variable | Description | Example | |----------|-------------|---------| | `SW_APM_SERVICE_KEY` | API token and service name (required) | `your-token:my-service` | -#### Common Configuration +**Common Configuration** | Variable | Description | Default | Example | |----------|-------------|---------|---------| @@ -185,7 +181,7 @@ SolarWindsAPM::OTelConfig.initialize_with_config do |config| end ``` -### Advanced Configuration +Advanced Configuration ```ruby SolarWindsAPM::OTelConfig.initialize_with_config do |config| @@ -392,21 +388,21 @@ export SW_APM_TRANSACTION_NAME=my-lambda-function ### Environment Variables -Environment Variable | Config File Key | Description | Default --------------------- | --------------- | ----------- | ------- -`SW_APM_AUTO_CONFIGURE` | N/A | By default the library is configured to work out-of-the-box with all automatic instrumentation libraries enabled. Set this to `false` to custom initialize the library with configuration options for instrumentation, see [Programmatic Configuration](#programmatic-configuration) for details. | `true` -`SW_APM_COLLECTOR` | N/A | Override the default collector endpoint to which the library connects and exports data. It should be defined using the format host:port. | `apm.collector.na-01.cloud.solarwinds.com:443` -`SW_APM_CONFIG_RUBY` | N/A | Override the default location for the configuration file. This can be an absolute or relative filename, or the directory under which the `solarwinds_apm_config.rb` file would be looked for. | None -`SW_APM_DEBUG_LEVEL` | `:debug_level` | Set the library's logging level, valid values are -1 through 6 (least to most verbose).
Setting -1 disables logging from the library. | 3 -`SW_APM_ENABLED` | N/A | Enable/disable the library, setting `false` is an alternative to uninstalling `solarwinds_apm` since it will prevent the library from loading. | `true` -`SW_APM_SERVICE_KEY` | `:service_key` | API token and service name in the form of `token:service_name`, **required**. | None -`SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#sql-query-tagging) for details.| `false` -`SW_APM_TRIGGER_TRACING_MODE` | `:trigger_tracing_mode` | Enable/disable trigger tracing for the service. Setting to `disabled` may impact DEM visibility into the service. | `enabled` -`SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option only takes effect in the AWS Lambda runtime. Set to `false` to disable the attempt to preload function dependencies and install instrumentations. | `true` -`SW_APM_TRANSACTION_NAME` | N/A | Customize the transaction name for all traces, typically used to target specific instrumented lambda functions. _Precedence order_: custom SDK > `SW_APM_TRANSACTION_NAME` > automatic naming | None -N/A | `:log_traceId` | Configure the insertion of trace context into application logs, setting `:traced` would include the available context fields such as trace_id, span_id into log messages. | `:never` -N/A | `:tracing_mode` | Enable/disable the tracing mode for this service, setting `:disabled` would suppress all trace spans and metrics. | `:enabled` -N/A | `:transaction_settings` | Configure tracing mode per transaction, aka transaction filtering. See [Transaction Filtering](#transaction-filtering) for details.| None +| Environment Variable | Config File Key | Description | Default | +| -------------------- | --------------- | ----------- | ------- | +| `SW_APM_AUTO_CONFIGURE` | N/A | By default the library is configured to work out-of-the-box with all automatic instrumentation libraries enabled. Set this to `false` to custom initialize the library with configuration options for instrumentation, see [Programmatic Configuration](#programmatic-configuration) for details. | `true` | +| `SW_APM_COLLECTOR` | N/A | Override the default collector endpoint to which the library connects and exports data. It should be defined using the format host:port. | `apm.collector.na-01.cloud.solarwinds.com:443` | +| `SW_APM_CONFIG_RUBY` | N/A | Override the default location for the configuration file. This can be an absolute or relative filename, or the directory under which the `solarwinds_apm_config.rb` file would be looked for. | None | +| `SW_APM_DEBUG_LEVEL` | `:debug_level` | Set the library's logging level, valid values are -1 through 6 (least to most verbose).
Setting -1 disables logging from the library. | 3 | +| `SW_APM_ENABLED` | N/A | Enable/disable the library, setting `false` is an alternative to uninstalling `solarwinds_apm` since it will prevent the library from loading. | `true` | +| `SW_APM_SERVICE_KEY` | `:service_key` | API token and service name in the form of `token:service_name`, **required**. | None | +| `SW_APM_TAG_SQL` | `:tag_sql` | Enable/disable injecting trace context into supported SQL statements. Set to boolean true or (or string `true` in env var) to enable, see [Tag Query with Trace Context](#sql-query-tagging) for details.| `false` | +| `SW_APM_TRIGGER_TRACING_MODE` | `:trigger_tracing_mode` | Enable/disable trigger tracing for the service. Setting to `disabled` may impact DEM visibility into the service. | `enabled` | +| `SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option only takes effect in the AWS Lambda runtime. Set to `false` to disable the attempt to preload function dependencies and install instrumentations. | `true` | +| `SW_APM_TRANSACTION_NAME` | N/A | Customize the transaction name for all traces, typically used to target specific instrumented lambda functions. _Precedence order_: custom SDK > `SW_APM_TRANSACTION_NAME` > automatic naming | None | +| N/A | `:log_traceId` | Configure the insertion of trace context into application logs, setting `:traced` would include the available context fields such as trace_id, span_id into log messages. | `:never` | +| N/A | `:tracing_mode` | Enable/disable the tracing mode for this service, setting `:disabled` would suppress all trace spans and metrics. | `:enabled` | +| N/A | `:transaction_settings` | Configure tracing mode per transaction, aka transaction filtering. See [Transaction Filtering](#transaction-filtering) for details.| None | ### Debug Levels From e58ebc48af19a7fd94faafa1991e90a84d7ffd1e Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Mon, 22 Sep 2025 14:39:01 -0400 Subject: [PATCH 04/11] revision --- CONFIGURATION.md | 21 ++++++++------------- CONTRIBUTING.md | 10 ---------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 223d8898..6cf863d9 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -2,17 +2,6 @@ This guide covers all configuration options for the SolarWinds APM Ruby gem, an OpenTelemetry-based distribution that provides automatic instrumentation and observability features for Ruby applications. -## Table of Contents - -- [Quick Start](#quick-start) -- [Configuration Precedence](#configuration-precedence) -- [Environment Variables](#environment-variables) -- [Configuration Files](#configuration-files) -- [Programmatic Configuration](#programmatic-configuration) -- [Advanced Configuration](#advanced-configuration) -- [Configuration Reference](#configuration-reference) -- [Troubleshooting](#troubleshooting) - ## Quick Start To get started quickly, you only need to set your service key: @@ -48,7 +37,7 @@ Configuration can be set in multiple ways with the following precedence order (h Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. -All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard OpenTelemetry environment variables are also supported where applicable. +All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard [OpenTelemetry environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) are also supported where applicable. **Required Configuration** @@ -64,6 +53,8 @@ All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard OpenT | `SW_APM_DEBUG_LEVEL` | Logging verbosity (-1 to 6) | `3` | `5` | | `SW_APM_COLLECTOR` | Collector endpoint override | `apm.collector.na-01.cloud.solarwinds.com:443` | `custom.collector.com:443` | +More configuration option see [Configuration Reference](#configuration-reference) + ### OpenTelemetry Integration #### Exporters @@ -100,7 +91,11 @@ export OTEL_TRACES_EXPORTER=jaeger #### Service Naming -The service name is extracted from your service key by default, but can be overridden: +The service name is extracted from your service key by default, but can be overridden. + +By default the service name portion of the service key is used, e.g. `my-service` if the service key is `SW_APM_SERVICE_KEY=api-token:my-service`. If the `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES` environment variable is used to specify a service name, it will take precedence over the default. + +`OTEL_SERVICE_NAME` > `OTEL_RESOURCE_ATTRIBUTES` > `SW_APM_SERVICE_KEY` > `SolarWindsAPM::Config[:service_key]` **Service key format:** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 260d6d41..1e45c10e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,16 +2,6 @@ Thank you for your interest in contributing to the SolarWinds APM Ruby gem! This document provides guidelines and instructions for contributing to this OpenTelemetry-based Ruby distribution. -## Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [How to Contribute](#how-to-contribute) -- [Development Setup](#development-setup) -- [Development Workflow](#development-workflow) -- [Testing](#testing) -- [Code Quality](#code-quality) -- [Getting Help](#getting-help) - ## Code of Conduct By participating in this project, you agree to abide by our Code of Conduct. Please treat all community members with respect and create a welcoming environment for everyone. From 9101dbab3f2d37ff31f77dac2b17bad83db1c67d Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Mon, 22 Sep 2025 17:31:09 -0400 Subject: [PATCH 05/11] neutralize the need for docke container for running all the test case --- CONTRIBUTING.md | 86 +++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e45c10e..407bc198 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,14 +22,10 @@ We welcome various types of contributions: Before you begin, ensure you have the following installed on your system: -- **Docker** - Required for containerized development and testing -- **Docker Compose** - Used for orchestrating multi-container setups - **Git** - For version control - **Ruby** - For running Rake tasks - -> **Note:** All development work is done in Docker containers, so you don't need Ruby installed on your host machine, but it's helpful for running Rake tasks. - -The instructions below assume you are in the locally cloned project root directory (`apm-ruby`). +- **Docker** - (Optional) Required for containerized development and testing +- **Docker Compose** - (Optional) Used for some rake tests that start the container ### Getting Started @@ -49,7 +45,7 @@ The instructions below assume you are in the locally cloned project root directo ## Host Machine Setup -For development, you'll need a host environment capable of running Rake tasks to manage development and testing containers. We recommend using [rbenv](https://github.com/rbenv/rbenv) for Ruby version management. +We recommend using [rbenv](https://github.com/rbenv/rbenv) for Ruby version management. ### 1. Install rbenv @@ -71,35 +67,22 @@ sudo apt install rbenv ```bash git clone https://github.com/rbenv/rbenv.git ~/.rbenv +git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc # for bash echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc # for zsh +source ~/.bashrc # for bash +source ~/.zshrc # for zsh ``` ### 2. Install and Configure Ruby -Install Ruby using rbenv: - -```bash -# List latest stable versions -rbenv install -l - -# List all available versions -rbenv install -L - -# Install the desired Ruby version -rbenv install 3.1.2 -``` - -Enable rbenv by following the initialization instructions: +Install Ruby using rbenv, enable rbenv, and set the global Ruby version ```bash rbenv init -``` - -Set the global Ruby version (this prevents conflicts within development containers): - -```bash -rbenv global 3.1.2 # Set the default Ruby version for this machine +rbenv install -L # List all available versions +rbenv install 3.1.2 # Install the desired Ruby version +rbenv global 3.1.2 # Set the default Ruby version for this machine ``` ### 3. Install Project Dependencies @@ -108,23 +91,23 @@ Install Bundler and configure it for development: ```bash gem install bundler -bundle config set --local without development test bundle install ``` -Verify the setup by listing available Rake tasks: +## Development Workflow -```bash -bundle exec rake -T -``` +### Development Environment -You should see tasks like `docker_dev`, `docker_tests`, `build_gem`, etc. +You can use your host machine for building, installing, and testing. -## Development Workflow +```bash +# e.g. running all test case after update +APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh +``` -### Setting Up the Development Environment +### Development Environment inside Container -The `solarwinds_apm` gem requires a Linux runtime environment. We use Ubuntu containers with all necessary tools for building, installing, and working with the project. +You can use Ubuntu containers with all necessary tools for building, installing, and working with the project. #### Starting the Development Container @@ -137,16 +120,10 @@ bundle exec rake docker_dev Once inside the container, set up the environment: ```bash -# Choose and set the Ruby version (check available versions) -rbenv versions -rbenv global - -# Install project dependencies -bundle install +rbenv global # Choose and set the Ruby version (check available versions) +bundle install # Install project dependencies ``` -#### Working in the Development Container - The development container provides a complete environment for: - Building and testing the gem @@ -160,17 +137,20 @@ All source code is mounted from your host machine, so changes are immediately re #### Building the Gem -Build the gem within the development container: +Build the gem: ```bash -# Build the gem -bundle exec rake build_gem +bundle exec rake build_gem # Build the gem +gem install builds/solarwinds_apm-.gem # Install the built gem locally +SW_APM_SERVICE_KEY= irb -r solarwinds_apm # Test the installation by loading the gem +``` -# Install the built gem locally -gem install builds/solarwinds_apm-.gem +Build the gem without rake task: -# Test the installation by loading the gem -SW_APM_SERVICE_KEY= irb -r solarwinds_apm +```bash +gem build solarwinds_apm.gemspec # Build the gem +gem install solarwinds_apm-.gem # Install the built gem locally +SW_APM_SERVICE_KEY= irb -r solarwinds_apm # Test the installation by loading the gem ``` #### Making Changes @@ -215,7 +195,7 @@ bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ ``` -### Running the Complete Test Suite From the Host Machine +### Running the Complete Test Suite inside Container From the Host Machine Execute the full test suite from the host machine: @@ -243,7 +223,7 @@ Tests are organized in the `test/` directory: ### Linting -We use RuboCop for code style enforcement. Run linting in the development container: +We use RuboCop for code style enforcement. Run linting: ```bash bundle exec rake rubocop From 9c67f7e876b9d86d8c2094c049b78644868dc668 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Tue, 23 Sep 2025 10:48:10 -0400 Subject: [PATCH 06/11] revision --- CONFIGURATION.md | 17 +---------------- CONTRIBUTING.md | 4 ---- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 6cf863d9..a2824e5f 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -33,8 +33,6 @@ Configuration can be set in multiple ways with the following precedence order (h 3. **Configuration Files** - Rails initializer or config file 4. **Default Values** - Built-in defaults -> **💡 Tip:** Environment variables always take precedence, making them ideal for deployment-specific settings. - Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard [OpenTelemetry environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) are also supported where applicable. @@ -89,9 +87,7 @@ Then configure: export OTEL_TRACES_EXPORTER=jaeger ``` -#### Service Naming - -The service name is extracted from your service key by default, but can be overridden. +#### Service Name By default the service name portion of the service key is used, e.g. `my-service` if the service key is `SW_APM_SERVICE_KEY=api-token:my-service`. If the `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES` environment variable is used to specify a service name, it will take precedence over the default. @@ -292,13 +288,6 @@ SolarWindsAPM::Config[:transaction_settings] = [ ] ``` -**Pattern Matching:** - -- Uses Ruby regular expressions -- Matches against the transaction name -- Supports regex options like `Regexp::IGNORECASE` -- Can disable both spans and metrics - ### SQL Query Tagging Append trace context to database queries as SQL comments for correlation between traces and database logs. @@ -353,10 +342,6 @@ The `RUN_AT_EXIT_HOOKS=1` ensures background processes complete before worker sh Starting with version 7.0.0, the environment variable `SW_APM_PROXY` and configuration file option `:http_proxy` are deprecated since telemetry is exported with standard OTLP exporters. These exporters use Ruby's `Net::HTTP`, which supports configuring an [HTTP proxy](https://docs.ruby-lang.org/en/master/Net/HTTP.html#class-Net::HTTPSession-label-Proxy+Server). The examples below set the `http_proxy` environment variable for the Ruby process to configure the proxy: -For environments requiring HTTP proxies, configure using standard Ruby `Net::HTTP` proxy environment variables: - -**Basic proxy:** - ```bash # proxy server with no authentication http_proxy=http://: ruby my.app diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 407bc198..4075d860 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,10 +2,6 @@ Thank you for your interest in contributing to the SolarWinds APM Ruby gem! This document provides guidelines and instructions for contributing to this OpenTelemetry-based Ruby distribution. -## Code of Conduct - -By participating in this project, you agree to abide by our Code of Conduct. Please treat all community members with respect and create a welcoming environment for everyone. - ## How to Contribute We welcome various types of contributions: From 2395b6e05fccd0a0693bf98e47cc3b225913c4f8 Mon Sep 17 00:00:00 2001 From: Xuan <112967240+xuan-cao-swi@users.noreply.github.com> Date: Tue, 23 Sep 2025 10:49:20 -0400 Subject: [PATCH 07/11] Apply suggestions from code review Co-authored-by: Lin Lin --- CONFIGURATION.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 6cf863d9..fa25eced 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -51,7 +51,7 @@ All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard [Open |----------|-------------|---------|---------| | `SW_APM_ENABLED` | Enable/disable the entire library | `true` | `false` | | `SW_APM_DEBUG_LEVEL` | Logging verbosity (-1 to 6) | `3` | `5` | -| `SW_APM_COLLECTOR` | Collector endpoint override | `apm.collector.na-01.cloud.solarwinds.com:443` | `custom.collector.com:443` | +| `SW_APM_COLLECTOR` | Collector endpoint override | `apm.collector.na-01.cloud.solarwinds.com:443` | `apm.collector.eu-01.cloud.solarwinds.com:443` | More configuration option see [Configuration Reference](#configuration-reference) @@ -93,7 +93,7 @@ export OTEL_TRACES_EXPORTER=jaeger The service name is extracted from your service key by default, but can be overridden. -By default the service name portion of the service key is used, e.g. `my-service` if the service key is `SW_APM_SERVICE_KEY=api-token:my-service`. If the `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES` environment variable is used to specify a service name, it will take precedence over the default. +By default the service name portion of the service key is used, e.g. `my-service` if the service key is `SW_APM_SERVICE_KEY=api-token:my-service`. If the `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES` environment variable is used to specify a service name, it will take precedence over the default. The precedence is as follows: `OTEL_SERVICE_NAME` > `OTEL_RESOURCE_ATTRIBUTES` > `SW_APM_SERVICE_KEY` > `SolarWindsAPM::Config[:service_key]` @@ -270,7 +270,7 @@ SolarWindsAPM::Config[:transaction_settings] = [ ### Transaction Filtering -Control which transactions are traced using pattern-based filtering. This is useful for excluding static assets, health checks, or other requests that don't need tracing. +Specific transactions can be disabled from tracing (suppressing both spans and metrics) using the `:transaction_settings` configuration. An example that filters out static assets, health check requests, and a background job consumer: **Configuration:** @@ -323,7 +323,7 @@ SELECT * FROM users WHERE id = 1; **Supported Operations:** - **MySQL2**: `query` operations -- **PostgreSQL**: `exec`, `query`, and similar operations +- **PostgreSQL**: the "[exec-ish](https://github.com/solarwinds/apm-ruby/blob/main/lib/solarwinds_apm/patch/tag_sql/sw_pg_patch.rb#L15)" operations like `exec` and `query` are supported. > **⚠️ Limitation:** Currently does not support prepared statements. @@ -341,7 +341,7 @@ This adds trace and span IDs to log entries when using supported logging framewo #### Resque -When using Resque, ensure graceful shutdown for proper trace transmission: +When starting the Resque worker, it is necessary to set `RUN_AT_EXIT_HOOKS=1`. For example: ```bash RUN_AT_EXIT_HOOKS=1 QUEUE=myqueue bundle exec rake resque:work @@ -381,7 +381,7 @@ export SW_APM_TRANSACTION_NAME=my-lambda-function ## Configuration Reference -### Environment Variables +### All Options | Environment Variable | Config File Key | Description | Default | | -------------------- | --------------- | ----------- | ------- | From 1417e64e9e153770facbbd1846206cba9ff12ca4 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Tue, 23 Sep 2025 10:50:56 -0400 Subject: [PATCH 08/11] revision --- CONFIGURATION.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 1046d861..845ed679 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -340,7 +340,8 @@ The `RUN_AT_EXIT_HOOKS=1` ensures background processes complete before worker sh ### Proxy Configuration -Starting with version 7.0.0, the environment variable `SW_APM_PROXY` and configuration file option `:http_proxy` are deprecated since telemetry is exported with standard OTLP exporters. These exporters use Ruby's `Net::HTTP`, which supports configuring an [HTTP proxy](https://docs.ruby-lang.org/en/master/Net/HTTP.html#class-Net::HTTPSession-label-Proxy+Server). The examples below set the `http_proxy` environment variable for the Ruby process to configure the proxy: +Starting with version 7.0.0, the environment variable `SW_APM_PROXY` and configuration file option `:http_proxy` are deprecated since telemetry is exported with standard OTLP exporters. These exporters use Ruby +'s `Net::HTTP`, which supports configuring an [HTTP proxy](https://docs.ruby-lang.org/en/master/Net/HTTP.html#class-Net::HTTPSession-label-Proxy+Server). The examples below set the `http_proxy` environment variable for the Ruby process to configure the proxy: ```bash # proxy server with no authentication From 8157fbcf3a5deae88dca1f5fe2e8787cde247586 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Tue, 23 Sep 2025 11:15:34 -0400 Subject: [PATCH 09/11] update --- CONFIGURATION.md | 123 ++++++++++++----------------------------------- 1 file changed, 32 insertions(+), 91 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 845ed679..6d6c2d45 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -33,9 +33,9 @@ Configuration can be set in multiple ways with the following precedence order (h 3. **Configuration Files** - Rails initializer or config file 4. **Default Values** - Built-in defaults -Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. +## Environment Variables -All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard [OpenTelemetry environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) are also supported where applicable. +Environment variables are the most flexible way to configure the SolarWinds APM gem, especially in containerized or cloud environments. All SolarWinds APM-specific settings are prefixed with `SW_APM_`. Standard [OpenTelemetry environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) are also supported where applicable. **Required Configuration** @@ -59,32 +59,10 @@ More configuration option see [Configuration Reference](#configuration-reference The SolarWinds backend uses the OTLP exporter by default. You can configure additional exporters for debugging or multi-backend scenarios: -**Console Exporter (for debugging):** - -```bash -export OTEL_TRACES_EXPORTER=console -``` - -**Multiple Exporters:** - ```bash -export OTEL_TRACES_EXPORTER=otlp,console -``` - -**Third-party Exporters:** - -For exporters like Jaeger, first add them to your Gemfile: - -```ruby -# Add before solarwinds_apm in your Gemfile -gem 'opentelemetry-exporter-jaeger' -gem 'solarwinds_apm' -``` - -Then configure: - -```bash -export OTEL_TRACES_EXPORTER=jaeger +export OTEL_TRACES_EXPORTER=console # Console Exporter (for debugging) +export OTEL_TRACES_EXPORTER=otlp,console # Multiple Exporters +export OTEL_TRACES_EXPORTER=jaeger # Third-party Exporters (e.g. jaeger, add gem opentelemetry-exporter-jaeger before solarwinds_apm) ``` #### Service Name @@ -93,13 +71,13 @@ By default the service name portion of the service key is used, e.g. `my-service `OTEL_SERVICE_NAME` > `OTEL_RESOURCE_ATTRIBUTES` > `SW_APM_SERVICE_KEY` > `SolarWindsAPM::Config[:service_key]` -**Service key format:** +Service key format: ```bash export SW_APM_SERVICE_KEY=: ``` -**Override with OpenTelemetry variables:** +Override with OpenTelemetry variables: ```bash # Service name will be 'production-api', not 'my-service' @@ -107,7 +85,7 @@ export SW_APM_SERVICE_KEY=:my-service export OTEL_SERVICE_NAME=production-api ``` -**Resource attributes:** +Resource attributes: ```bash export OTEL_RESOURCE_ATTRIBUTES=service.name=production-api,service.version=1.2.3 @@ -117,14 +95,14 @@ export OTEL_RESOURCE_ATTRIBUTES=service.name=production-api,service.version=1.2. Fine-tune individual instrumentation libraries using OpenTelemetry environment variables: -**Disable specific instrumentation:** +Disable specific instrumentation: ```bash export OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED=false export OTEL_RUBY_INSTRUMENTATION_REDIS_ENABLED=false ``` -**Configure instrumentation options:** +Configure instrumentation options: ```bash # Include full SQL statements (disable obfuscation) @@ -134,15 +112,15 @@ export OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS='db_statement=include;' export OTEL_RUBY_INSTRUMENTATION_NET_HTTP_CONFIG_OPTS='untraced_hosts=localhost,internal.service;' ``` -Set inside file through ENV hash +Set inside file through ENV hash: ```ruby # Set before requiring solarwinds_apm -ENV['OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED'] = 'false' ENV['OTEL_RUBY_INSTRUMENTATION_MYSQL2_CONFIG_OPTS'] = 'db_statement=include;' +ENV['OTEL_RUBY_INSTRUMENTATION_NET_HTTP_CONFIG_OPTS'] = 'untraced_hosts=localhost,internal.service;' ``` -> **📚 Learn More:** See the [OpenTelemetry Ruby instrumentation documentation](https://opentelemetry.io/docs/languages/ruby/libraries/) for all available options. +> See the [OpenTelemetry Ruby instrumentation documentation](https://opentelemetry.io/docs/languages/ruby/libraries/) for all available options. ## Programmatic Configuration @@ -161,11 +139,8 @@ export SW_APM_AUTO_CONFIGURE=false Below is an example that disables Dalli instrumentation and sets the Rack instrumentation to capture certain headers as Span attributes: ```ruby -# note auto-configure must be disabled, e.g. -# export SW_APM_AUTO_CONFIGURE=false - +# note auto-configure must be disabled, e.g. export SW_APM_AUTO_CONFIGURE=false require 'solarwinds_apm' - SolarWindsAPM::OTelConfig.initialize_with_config do |config| config["OpenTelemetry::Instrumentation::Dalli"] = {:enabled => false} config["OpenTelemetry::Instrumentation::Rack"] = {:allowed_request_headers => ['header1', 'header2']} @@ -196,13 +171,15 @@ SolarWindsAPM::OTelConfig.initialize_with_config do |config| end ``` -> **📖 Reference:** Consult individual [instrumentation README files](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation) for complete configuration options. +> **Reference:** Consult individual [instrumentation README files](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation) for complete configuration options. ## Configuration Files -Configuration files provide a centralized way to manage settings, especially useful for complex configurations or when using multiple environments. +The configuration file should be Ruby code that sets key/values in the hash exposed by `SolarWindsAPM::Config`. The bundled [Rails generator template file](https://github.com/solarwinds/apm-ruby/blob/main/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb) serves as an example of the supported values, see also the [Configuration Reference](#configuration-reference) section. + +### How to install the file -### Rails Applications +#### Rails Applications For Rails applications, use the built-in generator to create a configuration file: @@ -212,7 +189,7 @@ bundle exec rails generate solarwinds_apm:install This creates `config/initializers/solarwinds_apm.rb` with documented configuration options. -### Non-Rails Applications +#### Non-Rails Applications Create a file named `solarwinds_apm_config.rb` in your application's root directory: @@ -223,7 +200,7 @@ SolarWindsAPM::Config[:debug_level] = 3 SolarWindsAPM::Config[:tag_sql] = true ``` -### Custom Location +#### Custom Location Override the default configuration file location: @@ -231,45 +208,12 @@ Override the default configuration file location: export SW_APM_CONFIG_RUBY=/path/to/your/config.rb ``` -### Configuration File Template +### Config Options -Here's a comprehensive configuration file example: - -```ruby -# SolarWinds APM Configuration - -# Required: Service key -SolarWindsAPM::Config[:service_key] = ENV['SW_APM_SERVICE_KEY'] - -# Logging and debugging -SolarWindsAPM::Config[:debug_level] = 3 -SolarWindsAPM::Config[:log_traceId] = :traced - -# Tracing configuration -SolarWindsAPM::Config[:tracing_mode] = :enabled -SolarWindsAPM::Config[:trigger_tracing_mode] = :enabled - -# Database query tagging -SolarWindsAPM::Config[:tag_sql] = false - -# Transaction filtering (see Advanced Configuration section) -SolarWindsAPM::Config[:transaction_settings] = [ - { - regexp: '\.(css|js|png|jpg|gif|ico)$', - opts: Regexp::IGNORECASE, - tracing: :disabled - } -] -``` - -## Advanced Configuration - -### Transaction Filtering +#### Transaction Filtering Specific transactions can be disabled from tracing (suppressing both spans and metrics) using the `:transaction_settings` configuration. An example that filters out static assets, health check requests, and a background job consumer: -**Configuration:** - ```ruby SolarWindsAPM::Config[:transaction_settings] = [ { @@ -288,35 +232,32 @@ SolarWindsAPM::Config[:transaction_settings] = [ ] ``` -### SQL Query Tagging +#### SQL Query Tagging Append trace context to database queries as SQL comments for correlation between traces and database logs. -**Enable SQL tagging:** - ```bash -export SW_APM_TAG_SQL=true +export SW_APM_TAG_SQL=true # Enable SQL tagging ``` -**Example output:** +Output: ```sql -- Before (without tagging) SELECT * FROM users WHERE id = 1; -- After (with tagging) -SELECT * FROM users WHERE id = 1; -/* traceparent=7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01 */ +SELECT * FROM users WHERE id = 1; /* traceparent=7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01 */ ``` -**Supported Operations:** +Supported Operations: - **MySQL2**: `query` operations - **PostgreSQL**: the "[exec-ish](https://github.com/solarwinds/apm-ruby/blob/main/lib/solarwinds_apm/patch/tag_sql/sw_pg_patch.rb#L15)" operations like `exec` and `query` are supported. > **⚠️ Limitation:** Currently does not support prepared statements. -### Log Trace Context Integration +#### Log Trace Context Integration Include trace context in your application logs for better correlation: @@ -326,9 +267,9 @@ SolarWindsAPM::Config[:log_traceId] = :traced This adds trace and span IDs to log entries when using supported logging frameworks. -### Background Job Configuration +### Other Configuration -#### Resque +#### Background Job Configuration: Resque When starting the Resque worker, it is necessary to set `RUN_AT_EXIT_HOOKS=1`. For example: @@ -351,7 +292,7 @@ http_proxy=http://: ruby my.app http_proxy=http://:@: ruby my.app ``` -> **📝 Note:** Starting with version 7.0.0, `SW_APM_PROXY` is deprecated in favor of standard HTTP proxy environment variables. +> **Note:** Starting with version 7.0.0, `SW_APM_PROXY` is deprecated in favor of standard HTTP proxy environment variables. ### Lambda Configuration From f5170abda72b51c2a960c046125d936e5e937a2d Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Tue, 23 Sep 2025 11:27:38 -0400 Subject: [PATCH 10/11] update --- CONTRIBUTING.md | 196 ++++++++++++++---------------------------------- 1 file changed, 58 insertions(+), 138 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4075d860..16c20c0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,16 +12,16 @@ We welcome various types of contributions: - **Code contributions**: Bug fixes, new features, performance improvements - **Testing**: Add test coverage or improve existing tests -## Development Setup +## Development Environment Setup ### Prerequisites -Before you begin, ensure you have the following installed on your system: +Before you begin, ensure you have the following installed: - **Git** - For version control -- **Ruby** - For running Rake tasks -- **Docker** - (Optional) Required for containerized development and testing -- **Docker Compose** - (Optional) Used for some rake tests that start the container +- **rbenv** - For Ruby version management (see [rbenv installation guide](https://github.com/rbenv/rbenv#installation)) +- **Ruby** - Install via rbenv +- **Docker** - (Optional) ### Getting Started @@ -39,161 +39,110 @@ Before you begin, ensure you have the following installed on your system: git remote add upstream https://github.com/solarwinds/apm-ruby.git ``` -## Host Machine Setup +### Setup Ruby Environment -We recommend using [rbenv](https://github.com/rbenv/rbenv) for Ruby version management. +1. **Install Ruby** using rbenv (install appropriate version as needed): -### 1. Install rbenv - -Choose the installation method that works best for your system: - -**macOS (using Homebrew):** + ```bash + rbenv install 3.1.2 + rbenv local 3.1.2 # or rbenv global 3.1.2 + ``` -```bash -brew install rbenv ruby-build -``` +2. **Install dependencies** with isolated vendoring: -**Linux (Ubuntu/Debian):** + ```bash + gem install bundler + bundle install --path vendor/bundle + ``` -```bash -sudo apt install rbenv -``` +3. **Verify setup** by listing available rake tasks: -**Build from source:** + ```bash + bundle exec rake -T + ``` -```bash -git clone https://github.com/rbenv/rbenv.git ~/.rbenv -git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build -echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc # for bash -echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc # for zsh -source ~/.bashrc # for bash -source ~/.zshrc # for zsh -``` + You should see various available tasks for building, testing, and linting. -### 2. Install and Configure Ruby +## Development Workflow -Install Ruby using rbenv, enable rbenv, and set the global Ruby version +### Making Changes -```bash -rbenv init -rbenv install -L # List all available versions -rbenv install 3.1.2 # Install the desired Ruby version -rbenv global 3.1.2 # Set the default Ruby version for this machine -``` +1. **Create a feature branch**: -### 3. Install Project Dependencies + ```bash + git checkout -b feature/your-feature-name + ``` -Install Bundler and configure it for development: +2. **Make your changes** in the appropriate files under `lib/` -```bash -gem install bundler -bundle install -``` +3. **Write or update tests** in the `test/` directory -## Development Workflow +### Testing Your Changes -### Development Environment +#### Load Changes Interactively -You can use your host machine for building, installing, and testing. +Test your changes without building a gem: ```bash -# e.g. running all test case after update -APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh +bundle exec irb -Ilib -r solarwinds_apm ``` -### Development Environment inside Container +This loads your source code changes directly for quick testing and debugging. -You can use Ubuntu containers with all necessary tools for building, installing, and working with the project. +#### Running Tests -#### Starting the Development Container +> **Note:** Some tests require the `APM_RUBY_TEST_KEY` environment variable. Contact the maintainers if you need access to a test key. -Launch the development container: +**Single test file:** ```bash -bundle exec rake docker_dev +bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb ``` -Once inside the container, set up the environment: +**Single test case:** ```bash -rbenv global # Choose and set the Ruby version (check available versions) -bundle install # Install project dependencies +bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ ``` -The development container provides a complete environment for: - -- Building and testing the gem -- Running linting tools -- Debugging issues -- Making code changes - -All source code is mounted from your host machine, so changes are immediately reflected in the container. - -### Building and Testing the Gem - -#### Building the Gem - -Build the gem: +**Local test suite (run all test file):** ```bash -bundle exec rake build_gem # Build the gem -gem install builds/solarwinds_apm-.gem # Install the built gem locally -SW_APM_SERVICE_KEY= irb -r solarwinds_apm # Test the installation by loading the gem +APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh ``` -Build the gem without rake task: +#### Code Quality + +Run RuboCop for code style enforcement: ```bash -gem build solarwinds_apm.gemspec # Build the gem -gem install solarwinds_apm-.gem # Install the built gem locally -SW_APM_SERVICE_KEY= irb -r solarwinds_apm # Test the installation by loading the gem +bundle exec rake rubocop ``` -#### Making Changes - -1. **Create a feature branch**: - - ```bash - git checkout -b feature/your-feature-name - ``` - -2. **Make your changes** in the appropriate files under `lib/` - -3. **Write or update tests** in the `test/` directory - -4. **Test your changes** (see Testing section below) - -5. **Run linting** to ensure code quality - -## Testing +All linting issues must be resolved before submitting a pull request. -> **Note:** Some tests require the `APM_RUBY_TEST_KEY` environment variable. Contact the maintainers if you need access to a test key. +## Advanced Setup (Optional) -### Running Tests +### Development Environment inside Container -**Full test suite:** +For complex debugging or if you prefer working in a containerized environment, you can use Ubuntu containers with all necessary tools: ```bash -APM_RUBY_TEST_KEY=your_service_key test/run_tests.sh +bundle exec rake docker_dev ``` -**Single test file:** +Once inside the container: ```bash -# Most tests require only the unit.gemfile dependencies -bundle update -bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb +rbenv global # Set Ruby version +bundle install # Install dependencies ``` -**Single test case:** - -```bash -bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb -n /trace_state_header/ -``` +The development container provides a complete isolated environment with all source code mounted from your host machine. -### Running the Complete Test Suite inside Container From the Host Machine +### Full Regression Testing -Execute the full test suite from the host machine: +Run the complete test suite in containers (from host machine): ```bash # Run tests in Ruby 3.1.0 bullseye container @@ -203,36 +152,7 @@ bundle exec rake 'docker_tests[,,,APM_RUBY_TEST_KEY=your_service_key]' bundle exec rake 'docker_tests[3.2-alpine,,linux/amd64,APM_RUBY_TEST_KEY=your_service_key]' ``` -Test logs are written to the `log/` directory and are available on the host machine. - -### Test Organization - -Tests are organized in the `test/` directory: - -- `test/api/` - API-related tests -- `test/opentelemetry/` - OpenTelemetry integration tests -- `test/patch/` - Instrumentation patch tests -- `test/sampling/` - Sampling logic tests -- `test/support/` - Test utilities and helpers - -## Code Quality - -### Linting - -We use RuboCop for code style enforcement. Run linting: - -```bash -bundle exec rake rubocop -``` - -This generates a `rubocop_result.txt` file. **All linting issues must be resolved before submitting a pull request.** - -## Getting Help - -- **Issues**: Check existing issues or create a new one -- **Discussions**: Use GitHub Discussions for questions -- **Documentation**: Refer to our [documentation website](https://documentation.solarwinds.com/en/success_center/observability/content/configure/services/ruby/install.htm) -- **Email**: Contact for technical support +Test logs are written to the `log/` directory. ## Additional Resources From 2856c47d333e8b1f362d42e0eefed3928f514318 Mon Sep 17 00:00:00 2001 From: xuan-cao-swi Date: Tue, 23 Sep 2025 16:38:02 -0400 Subject: [PATCH 11/11] revision --- CONFIGURATION.md | 14 +++++--------- CONTRIBUTING.md | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 6d6c2d45..dc1448f7 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -208,9 +208,9 @@ Override the default configuration file location: export SW_APM_CONFIG_RUBY=/path/to/your/config.rb ``` -### Config Options +## Configuration Topics -#### Transaction Filtering +### Transaction Filtering Specific transactions can be disabled from tracing (suppressing both spans and metrics) using the `:transaction_settings` configuration. An example that filters out static assets, health check requests, and a background job consumer: @@ -232,7 +232,7 @@ SolarWindsAPM::Config[:transaction_settings] = [ ] ``` -#### SQL Query Tagging +### SQL Query Tagging Append trace context to database queries as SQL comments for correlation between traces and database logs. @@ -257,7 +257,7 @@ Supported Operations: > **⚠️ Limitation:** Currently does not support prepared statements. -#### Log Trace Context Integration +### Log Trace Context Integration Include trace context in your application logs for better correlation: @@ -267,9 +267,7 @@ SolarWindsAPM::Config[:log_traceId] = :traced This adds trace and span IDs to log entries when using supported logging frameworks. -### Other Configuration - -#### Background Job Configuration: Resque +### Background Job Configuration: Resque When starting the Resque worker, it is necessary to set `RUN_AT_EXIT_HOOKS=1`. For example: @@ -308,8 +306,6 @@ export SW_APM_TRANSACTION_NAME=my-lambda-function ## Configuration Reference -### All Options - | Environment Variable | Config File Key | Description | Default | | -------------------- | --------------- | ----------- | ------- | | `SW_APM_AUTO_CONFIGURE` | N/A | By default the library is configured to work out-of-the-box with all automatic instrumentation libraries enabled. Set this to `false` to custom initialize the library with configuration options for instrumentation, see [Programmatic Configuration](#programmatic-configuration) for details. | `true` | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 16c20c0b..ccc6d97e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,6 +158,5 @@ Test logs are written to the `log/` directory. - [OpenTelemetry Ruby Documentation](https://opentelemetry.io/docs/instrumentation/ruby/) - [SolarWinds Observability Documentation](https://documentation.solarwinds.com/en/success_center/observability/default.htm) -- [Project GitHub Repository](https://github.com/solarwinds/apm-ruby) -Thank you for contributing to SolarWinds APM Ruby! 🙏 +Thank you for contributing to SolarWinds APM Ruby!