Skip to content

Commit

Permalink
feat: Add custom key sanitization support
Browse files Browse the repository at this point in the history
  • Loading branch information
estolfo committed Mar 1, 2023
1 parent 8490ef9 commit 83a16e1
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ module Elasticsearch
end

require_relative './elasticsearch/instrumentation'
require_relative './elasticsearch/wildcard_pattern'
require_relative './elasticsearch/version'
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base
MINIMUM_VERSION = Gem::Version.new('8.0.0')

install do |_config|
convert_config(_config)
require_dependencies
patch
end
Expand All @@ -33,10 +34,16 @@ def patch

option :peer_service, default: nil, validate: :string
option :db_statement, default: :obfuscate, validate: %I[omit obfuscate include]
option :sanitize_field_names, default: [], validate: :array
option :sanitize_field_names, default: nil, validate: :array

private

def convert_config(config)
if field_names = config[:sanitize_field_names]
config[:sanitize_field_names] = field_names.map { |p| WildcardPattern.new(p) }
end
end

def gem_version
Gem::Version.new(::Elastic::Transport::VERSION)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

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

module OpenTelemetry
module Instrumentation
module Elasticsearch
class WildcardPattern
def initialize(str)
@pattern = convert(str)
end

attr_reader :pattern

def match?(other)
!!@pattern.match(other)
end

alias :match :match?

private

def convert(str)
case_sensitive = false

if str.start_with?('(?-i)')
str = str.gsub(/^\(\?-\i\)/, '')
case_sensitive = true
end

parts =
str.chars.each_with_object([]) do |char, arr|
arr << (char == '*' ? '.*' : Regexp.escape(char))
end

Regexp.new(
'\A' + parts.join + '\Z',
case_sensitive ? nil : Regexp::IGNORECASE
)
end
end
end
end
end

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@
end
end

describe 'sanitize_field_names as an array' do
let(:config) { { sanitize_field_names: ['Auth*tion', 'abc*', '*xyz'] } }
it 'converts to regexes' do
instrumentation.install(config)
_(instrumentation.config[:sanitize_field_names].collect(&:pattern)).must_equal(
[
/\AAuth.*tion\Z/i,
/\Aabc.*\Z/i,
/\A.*xyz\Z/i
]
)
end
end

describe 'compatible' do
it 'when older gem version installed' do
stub_const('::Elastic::Transport::VERSION', '7.17.7')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,39 @@
end
end

describe 'custom sanitization fields' do
let(:config) { { sanitize_field_names: ['abc*'] } }
it 'sanitizes certain fields' do
client.index(
index: 'users',
id: '1',
body: { name: 'Emily', abcde: 'top_secret' }
)

_(exporter.finished_spans.size).must_equal(1)
_(span.name).must_equal 'PUT users/_doc/1'
_(span.attributes['db.statement']).must_equal(
"{\"name\":\"Emily\",\"abcde\":\"?\"}"
)
_(span.attributes['db.system']).must_equal "elasticsearch"
_(span.attributes['db.operation']).must_equal "PUT"
_(span.attributes['elasticsearch.method']).must_equal 'PUT'
_(span.attributes['net.transport']).must_equal 'ip_tcp'

_(span.attributes['net.peer.name']).must_equal 'localhost'
_(span.attributes['net.peer.port']).must_equal 9200
#_(span.attributes['elasticsearch.url']).must_equal 'http://localhost:9200/_search?q=test'

_(span.attributes['elasticsearch.params']).must_equal '{}'
#_(span.attributes['elasticsearch.id']).must_equal # doc id
#_(span.attributes['elasticsearch.target']).must_equal '_search'
assert_requested(
:put,
'http://localhost:9200/users/_doc/1'
)
end
end

describe '#perform_request with exception' do
before do
stub_request(:get, %r{http://localhost:9200/.*})
Expand Down

0 comments on commit 83a16e1

Please sign in to comment.