class ExternalApiClient
def fetch_user_data(user_id)
ActiveSupport::Notifications.instrument(
'api.external_service',
service: 'user_service',
operation: 'fetch_user',
user_id: user_id
) do
response = HTTP.get("https://api.example.com/users/#{user_id}")
if response.status.success?
JSON.parse(response.body)
else
raise ApiError, "Failed to fetch user: #{response.status}"
end
end
rescue StandardError => e
ActiveSupport::Notifications.instrument(
'api.external_service.error',
service: 'user_service',
operation: 'fetch_user',
error: e.class.name
)
raise e
end
end
# Subscribe to custom events
ActiveSupport::Notifications.subscribe('api.external_service') do |name, start, finish, id, payload|
duration = ((finish - start) * 1000).round(2)
Rails.logger.info(
event: 'external_api_call',
service: payload[:service],
operation: payload[:operation],
duration_ms: duration,
success: true
)
# Send to metrics service
if defined?(Datadog::Statsd)
statsd = Datadog::Statsd.new('localhost', 8125)
statsd.histogram('api.external.duration', duration, tags: [
"service:#{payload[:service]}",
"operation:#{payload[:operation]}"
])
end
end
ActiveSupport::Notifications.subscribe('api.external_service.error') do |name, start, finish, id, payload|
Rails.logger.error(
event: 'external_api_error',
service: payload[:service],
operation: payload[:operation],
error: payload[:error]
)
if defined?(Datadog::Statsd)
statsd = Datadog::Statsd.new('localhost', 8125)
statsd.increment('api.external.errors', tags: [
"service:#{payload[:service]}",
"operation:#{payload[:operation]}",
"error:#{payload[:error]}"
])
end
end