Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NH-85973 NH-89212 instrument function handler dependencies #144

Merged
merged 11 commits into from
Aug 27, 2024
4 changes: 3 additions & 1 deletion CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ Environment Variable | Config File Key | Description | Default
`SW_APM_LOG_FILEPATH` | N/A | Configure the log file path for the C extension, e.g. `export SW_APM_LOG_FILEPATH=/path/file_path.log`. If set, messages from the C extension are written to the specified file instead of stderr. | None
`SW_APM_PROXY` | `:http_proxy` | Configure an HTTP proxy through which the library connects to the collector. | None
`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](#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_TRUSTEDPATH` | N/A | The library uses the host system's default trusted CA certificates to verify the TLS connection to the collector. To override the default, define the trusted certificate path configuration option with an absolute path to a specific trusted certificate file in PEM format. | None
`SW_APM_LAMBDA_PRELOAD_DEPS` | N/A | This option is particularly used in apm-ruby lambda layer for preloading user-defined ruby library, and install opentelemetry instrumentation. | `false`
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
N/A | `:log_args` | Enable/disable the collection of URL query parameters, set to boolean false to disable. | `true`
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
`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_args` | Enable/disable the collection of URL query parameters, set to boolean false to disable. | true
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`
Expand Down
4 changes: 2 additions & 2 deletions lambda/otel/layer/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ source 'https://rubygems.org'

source 'https://rubygems.pkg.github.com/solarwinds' do
gem 'opentelemetry-exporter-otlp', '0.26.1'
gem 'opentelemetry-metrics-api', '0.0.1'
gem 'opentelemetry-metrics-sdk', '0.0.1'
end

gem 'opentelemetry-metrics-api', '0.1.0'
gem 'opentelemetry-metrics-sdk', '0.1.0'
gem 'solarwinds_apm', '6.0.2'
36 changes: 36 additions & 0 deletions lambda/otel/layer/otel_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,42 @@
require 'opentelemetry-metrics-api'
require 'opentelemetry-metrics-sdk'
require 'opentelemetry-exporter-otlp'

xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
# We need to load the function code's dependencies, and _before_ any dependencies might
# be initialized outside of the function handler, bootstrap instrumentation. This allows
# instrumentation targets to be present, and accommodates instrumentations like AWS SDK
# that add plugins on client initialization (vs. prepending methods).
def preload_function_dependencies
default_task_location = '/var/task'

handler_file = ENV.values_at('ORIG_HANDLER', '_HANDLER').compact.first&.split('.')&.first

unless handler_file && File.exist?("#{default_task_location}/#{handler_file}.rb")
OpenTelemetry.logger.warn { 'Could not find the original handler file to preload libraries.' }
return
end

libraries = File.read("#{default_task_location}/#{handler_file}.rb")
.scan(/^\s*require\s+['"]([^'"]+)['"]/)
.flatten

libraries.each do |lib|
require lib
rescue StandardError => e
OpenTelemetry.logger.warn { "Could not load library #{lib}: #{e.message}" }
end
end

unless ENV['SW_APM_LAMBDA_PRELOAD_DEPS'].to_s.downcase == 'false'
OpenTelemetry.logger.warn { "SW_APM_LAMBDA_PRELOAD_DEPS set to #{ENV.fetch('SW_APM_LAMBDA_PRELOAD_DEPS', nil)}. No libraries will be preloaded." }
preload_function_dependencies

cheempz marked this conversation as resolved.
Show resolved Hide resolved
require 'opentelemetry-registry'
require 'opentelemetry-instrumentation-all'

OpenTelemetry::Instrumentation.registry.install_all
end

cheempz marked this conversation as resolved.
Show resolved Hide resolved
require 'solarwinds_apm'

def otel_wrapper(event:, context:)
Expand Down
2 changes: 1 addition & 1 deletion lib/solarwinds_apm/opentelemetry/otlp_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def initialize
# @param [Context] parent_context the
# started span.
def on_start(span, parent_context)
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] processor on_start span: #{span.inspect}" }
SolarWindsAPM.logger.debug { "[#{self.class}/#{__method__}] processor on_start span: #{span.to_span_data.inspect}" }

return if non_entry_span(parent_context: parent_context)

Expand Down
61 changes: 61 additions & 0 deletions sample_ruby_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# require 'aws-sdk-lambda'
Fixed Show fixed Hide fixed
# require 'json'

# def lambda_handler(event:, context:)
# puts "called lambda_handler"
# if defined?(::OpenTelemetry::SDK)
# $client = Aws::Lambda::Client.new(stub_responses: true)
# $client.get_account_settings()
# { statusCode: 200, body: "Hello #{::OpenTelemetry::SDK::VERSION}" }
# else
# { statusCode: 200, body: "Missing OpenTelemetry" }
# end
# end

# lambda_function.rb
puts "initialize lambda_function.rb"
Fixed Show fixed Hide fixed


Fixed Show fixed Hide fixed
variable = 'logger'

require variable
require 'json'
require 'net/http'
if true
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
require 'uri'
end


Fixed Show fixed Hide fixed
# require 'logger'
# require 'json'
# require 'net/http'
# require 'uri'

# require 'aws-sdk-lambda'
# require 'opentelemetry'
# require 'opentelemetry-instrumentation-aws_sdk'
# #require 'aws-xray-sdk/lambda'

# for manual tracing
$tracer = ::OpenTelemetry.tracer_provider.tracer(ENV['OTEL_SERVICE_NAME'])
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
# $client = Aws::Lambda::Client.new(stub_responses: true)
# puts "Aws::Lambda::Client: #{Aws::Lambda::Client.ancestors}"
# # unexpected usage, this creates an extra trace during cold start
# $client.get_account_settings()
def lambda_handler(event:, context:)
Fixed Show fixed Hide fixed

Fixed Show fixed Hide fixed
# for manual tracing
# $tracer = ::OpenTelemetry.tracer_provider.tracer(ENV['OTEL_SERVICE_NAME'])
$client = Aws::Lambda::Client.new(stub_responses: true)
# unexpected usage, this creates an extra trace during cold start
# $client.get_account_settings()

if event.key?('exception')
# throw a division by zero
_ = 1/0
Fixed Show fixed Hide fixed
end
# puts "$client: #{$client.inspect}"
$client.get_account_settings().account_usage.to_h
Fixed Show fixed Hide fixed
body['awsclient'] = $client.get_account_settings().account_usage.to_h
Fixed Show fixed Hide fixed
{ "statusCode":200, "body": body.to_s }
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
end
Fixed Show fixed Hide fixed