Skip to content

Commit

Permalink
Merge pull request #170 from solarwinds/NH-94970
Browse files Browse the repository at this point in the history
NH-94970: dbo integration for psql
  • Loading branch information
xuan-cao-swi authored Jan 8, 2025
2 parents bfdf80a + 879e8ee commit 2f6c615
Show file tree
Hide file tree
Showing 24 changed files with 252 additions and 641 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci-markdown-link.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
steps:
- uses: actions/checkout@v4

# act -j markdown-link-check --container-architecture linux/arm64
- name: "Markdown Link Check"
uses: gaurav-nelson/github-action-markdown-link-check@v1
# equivalent cli: linkspector check
- name: Run linkspector
uses: umbrelladocs/action-linkspector@v1
with:
config-file: '.markdown-link-check.json'
use-quiet-mode: 'yes'
use-verbose-mode: 'yes'
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
fail_on_error: true
25 changes: 10 additions & 15 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,24 +165,19 @@ SELECT * FROM SAMPLE_TABLE WHERE user_id = 1;
SELECT * FROM SAMPLE_TABLE WHERE user_id = 1; /* traceparent=7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01 */
```

For Rails < 7 and non-Rails applications, we use a port of [Marginalia](https://github.com/basecamp/marginalia) that patches ActiveRecord to inject the comment.
#### Limitation

For Rails >= 7, Marginalia is [integrated into ActiveRecord](https://api.rubyonrails.org/classes/ActiveRecord/QueryLogs.html) so enabling this feature should be done through Rails [configuration](https://guides.rubyonrails.org/v7.0/configuring.html#config-active-record-query-log-tags-enabled). For example:
> [!NOTE]
> This feature currently does not support prepared statements. Active Record by default enables prepared statements for the PostgreSQL adapter (`postgresql`), to use this feature you can explicitly disable it as shown below. Please evaluate the impact of disabling prepared statements on your system before proceeding.
```ruby
class Application < Rails::Application
config.active_record.query_log_tags_enabled = true
config.active_record.query_log_tags = [
{
traceparent: -> {
SolarWindsAPM::SWOMarginalia::Comment.traceparent
}
}
]
end
```
e.g.

Note that with Rails >= 7.1 the comment format can be specified via the `config.active_record.query_log_tags_format` option. SolarWinds Observability functionality depends on the default `:sqlcommenter` format, it is not recommended to change this value.
```yaml
development:
adapter: postgresql
# ...
prepared_statements: false
```
### Background Jobs
Expand Down
4 changes: 0 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ BUNDLE_GEMFILE=gemfiles/unit.gemfile bundle update

BUNDLE_GEMFILE=gemfiles/unit.gemfile bundle exec ruby -I test test/opentelemetry/solarwinds_exporter_test.rb
BUNDLE_GEMFILE=gemfiles/unit.gemfile bundle exec ruby -I test test/opentelemetry/solarwinds_propagator_test.rb

# marginalia tests require the rails_6x.gemfile dependencies
BUNDLE_GEMFILE=gemfiles/rails_6x.gemfile bundle install
BUNDLE_GEMFILE=gemfiles/rails_6x.gemfile bundle exec ruby -I test test/support/swomarginalia/swomarginalia_test.rb
```

To run a specific test (that requires unit.gemfile):
Expand Down
6 changes: 1 addition & 5 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,13 @@ Rake::TestTask.new do |t|
gem_file = ENV['BUNDLE_GEMFILE']&.split('/')&.last

case gem_file
when 'rails_6x.gemfile'
t.test_files = FileList['test/support/swomarginalia/*_test.rb']

when 'unit.gemfile'
t.test_files = FileList['test/api/*_test.rb'] +
FileList['test/solarwinds_apm/*_test.rb'] +
FileList['test/opentelemetry/*_test.rb'] +
FileList['test/noop/*_test.rb'] +
FileList['test/ext/*_test.rb'] +
FileList['test/support/*_test.rb'] -
FileList['test/support/swomarginalia/*_test.rb']
FileList['test/support/*_test.rb']
end
end

Expand Down
9 changes: 0 additions & 9 deletions gemfiles/rails_6x.gemfile

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,5 @@
# Example:
# SELECT `posts`.* FROM `posts` /*traceparent=00-a448f096d441e167d12ebd32a927c1a5-a29655a47e430119-01*/
#
# This option can add a small overhead for prepared statements since the traceparent value is unique per execution.
# This feature uses marginalia, see its caveat and possible workaround
# https://github.com/basecamp/marginalia/blob/master/README.md#prepared-statements
#
SolarWindsAPM::Config[:tag_sql] = false
end
35 changes: 35 additions & 0 deletions lib/solarwinds_apm/patch/tag_sql/sw_dbo_utils.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module SolarWindsAPM
module Patch
module TagSql
module SWODboUtils
def self.annotate_span_and_sql(sql)
return sql if sql.to_s.empty?

current_span = ::OpenTelemetry::Trace.current_span

annotated_sql = ''
if current_span.context.trace_flags.sampled?
traceparent = SolarWindsAPM::Utils.traceparent_from_context(current_span.context)
annotated_traceparent = "/*traceparent='#{traceparent}'*/"
current_span.add_attributes({ 'sw.query_tag' => annotated_traceparent })
annotated_sql = "#{sql} #{annotated_traceparent}"
else
annotated_sql = sql
end

SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] annotated_sql: #{annotated_sql}" }
annotated_sql
rescue StandardError => e
SolarWindsAPM.logger.error { "[#{self.class}/#{__method__}] Failed to annotated sql. Error: #{e.message}" }
sql
end
end
end
end
end
13 changes: 1 addition & 12 deletions lib/solarwinds_apm/patch/tag_sql/sw_mysql2_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,7 @@ module Patch
module TagSql
module SWOMysql2Patch
def query(sql, options = {})
current_span = ::OpenTelemetry::Trace.current_span

annotated_sql = ''
if current_span.context.trace_flags.sampled?
traceparent = SolarWindsAPM::Utils.traceparent_from_context(current_span.context)
annotated_traceparent = "/*traceparent='#{traceparent}'*/"
current_span.add_attributes({ 'sw.query_tag' => annotated_traceparent })
annotated_sql = "#{sql} #{annotated_traceparent}"
else
annotated_sql = sql
end

annotated_sql = ::SolarWindsAPM::Patch::TagSql::SWODboUtils.annotate_span_and_sql(sql)
super(annotated_sql, options)
end
end
Expand Down
39 changes: 39 additions & 0 deletions lib/solarwinds_apm/patch/tag_sql/sw_pg_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module SolarWindsAPM
module Patch
module TagSql
module SWOPgPatch
# We target operations covered by the upstream pg instrumentation.
# These are all alike in that they will have a SQL
# statement as the first parameter, and they are all
# non-prepared statement execute.
EXEC_ISH_METHODS = %i[
exec
query
sync_exec
async_exec
exec_params
async_exec_params
sync_exec_params
].freeze

EXEC_ISH_METHODS.each do |method|
define_method method do |*args|
annotated_sql = ::SolarWindsAPM::Patch::TagSql::SWODboUtils.annotate_span_and_sql(args[0])
args[0] = annotated_sql
super(*args)
end
end
end
end
end
end

# need to prepend before pg instrumentation patch itself
# upstream instrumentation -> our patch -> original function
PG::Connection.prepend(SolarWindsAPM::Patch::TagSql::SWOPgPatch) if defined?(PG::Connection)
2 changes: 2 additions & 0 deletions lib/solarwinds_apm/patch/tag_sql_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

require_relative 'tag_sql/sw_dbo_utils'
require_relative 'tag_sql/sw_mysql2_patch'
require_relative 'tag_sql/sw_pg_patch'
20 changes: 0 additions & 20 deletions lib/solarwinds_apm/support/swomarginalia/LICENSE

This file was deleted.

46 changes: 0 additions & 46 deletions lib/solarwinds_apm/support/swomarginalia/README.md

This file was deleted.

Loading

0 comments on commit 2f6c615

Please sign in to comment.