Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion sentry-ruby/lib/sentry/hub.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,9 @@ def capture_log_event(message, **options)
# @param value [Numeric] the metric value
# @param unit [String, nil] (optional) the metric unit
# @param attributes [Hash, nil] (optional) additional attributes for the metric
# @param integration [String, Symbol, nil] (optional) registered integration emitting the metric
# @return [void]
def capture_metric(name:, type:, value:, unit: nil, attributes: nil)
def capture_metric(name:, type:, value:, unit: nil, attributes: nil, integration: nil)
return unless current_client

metric = MetricEvent.new(
Expand All @@ -250,6 +251,7 @@ def capture_metric(name:, type:, value:, unit: nil, attributes: nil)
type: type,
unit: unit,
attributes: attributes&.dup,
integration_meta: Sentry.integrations[integration.to_s]
)

current_client.buffer_metric_event(metric, current_scope)
Expand Down
12 changes: 12 additions & 0 deletions sentry-ruby/lib/sentry/integrable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,17 @@ def capture_check_in(slug, status, **options, &block)
options[:hint][:integration] = integration_name
Sentry.capture_check_in(slug, status, **options, &block)
end

def count(name, value: 1, attributes: nil)
Sentry.metrics.count(name, value: value, attributes: attributes, integration: integration_name)
end

def gauge(name, value, unit: nil, attributes: nil)
Sentry.metrics.gauge(name, value, unit: unit, attributes: attributes, integration: integration_name)
end

def distribution(name, value, unit: nil, attributes: nil)
Sentry.metrics.distribution(name, value, unit: unit, attributes: attributes, integration: integration_name)
end
end
end
6 changes: 4 additions & 2 deletions sentry-ruby/lib/sentry/metric_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@ module Sentry
class MetricEvent
include Sentry::Utils::TelemetryAttributes

attr_reader :name, :type, :value, :unit, :timestamp, :trace_id, :span_id, :attributes
attr_reader :name, :type, :value, :unit, :timestamp, :trace_id, :span_id, :attributes, :integration_meta
attr_writer :trace_id, :span_id, :attributes

def initialize(
name:,
type:,
value:,
unit: nil,
attributes: nil
attributes: nil,
integration_meta: nil
)
@name = name
@type = type
@value = value
@unit = unit
@attributes = attributes || {}
@integration_meta = integration_meta

@timestamp = Sentry.utc_now
@trace_id = nil
Expand Down
18 changes: 12 additions & 6 deletions sentry-ruby/lib/sentry/metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ class << self
# @param name [String] the metric name
# @param value [Numeric] the value to increment by (default: 1)
# @param attributes [Hash, nil] additional attributes for the metric (optional)
# @param integration [String, Symbol, nil] registered integration emitting the metric (optional)
# @return [void]
def count(name, value: 1, attributes: nil)
def count(name, value: 1, attributes: nil, integration: nil)
return unless Sentry.initialized?

Sentry.get_current_hub.capture_metric(
name: name,
type: :counter,
value: value,
attributes: attributes
attributes: attributes,
integration: integration
)
end

Expand All @@ -26,16 +28,18 @@ def count(name, value: 1, attributes: nil)
# @param value [Numeric] the gauge value
# @param unit [String, nil] the metric unit (optional)
# @param attributes [Hash, nil] additional attributes for the metric (optional)
# @param integration [String, Symbol, nil] registered integration emitting the metric (optional)
# @return [void]
def gauge(name, value, unit: nil, attributes: nil)
def gauge(name, value, unit: nil, attributes: nil, integration: nil)
return unless Sentry.initialized?

Sentry.get_current_hub.capture_metric(
name: name,
type: :gauge,
value: value,
unit: unit,
attributes: attributes
attributes: attributes,
integration: integration
)
end

Expand All @@ -44,16 +48,18 @@ def gauge(name, value, unit: nil, attributes: nil)
# @param value [Numeric] the distribution value
# @param unit [String, nil] the metric unit (optional)
# @param attributes [Hash, nil] additional attributes for the metric (optional)
# @param integration [String, Symbol, nil] registered integration emitting the metric (optional)
# @return [void]
def distribution(name, value, unit: nil, attributes: nil)
def distribution(name, value, unit: nil, attributes: nil, integration: nil)
return unless Sentry.initialized?

Sentry.get_current_hub.capture_metric(
name: name,
type: :distribution,
value: value,
unit: unit,
attributes: attributes
attributes: attributes,
integration: integration
)
end
end
Expand Down
6 changes: 4 additions & 2 deletions sentry-ruby/lib/sentry/scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ def apply_to_telemetry(telemetry)
configuration = Sentry.configuration
return telemetry unless configuration

telemetry.attributes["sentry.sdk.name"] ||= Sentry.sdk_meta["name"]
telemetry.attributes["sentry.sdk.version"] ||= Sentry.sdk_meta["version"]
sdk_meta = telemetry.respond_to?(:integration_meta) ? telemetry.integration_meta : nil
sdk_meta ||= Sentry.sdk_meta
telemetry.attributes["sentry.sdk.name"] ||= sdk_meta[:name] || sdk_meta["name"]
telemetry.attributes["sentry.sdk.version"] ||= sdk_meta[:version] || sdk_meta["version"]
telemetry.attributes["sentry.environment"] ||= configuration.environment if configuration.environment
telemetry.attributes["sentry.release"] ||= configuration.release if configuration.release
telemetry.attributes["server.address"] ||= configuration.server_name if configuration.server_name
Expand Down
7 changes: 1 addition & 6 deletions sentry-ruby/lib/sentry/telemetry_event_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,7 @@ def clear!
private

def send_items
envelope = Envelope.new(
event_id: Sentry::Utils.uuid,
sent_at: Sentry.utc_now.iso8601,
dsn: @dsn,
sdk: Sentry.sdk_meta
)
envelope = Envelope.new(sent_at: Sentry.utc_now.iso8601)

discarded_count = 0
discarded_bytes = 0
Expand Down
16 changes: 16 additions & 0 deletions sentry-ruby/spec/sentry/integrable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,21 @@ module AnotherIntegration; end
event = Sentry.capture_message(message)
expect(event.sdk).to eq(Sentry.sdk_meta)
end

it "generates integration-attributed metric helpers" do
expect(Sentry.metrics).to receive(:count).with(
"test.count", value: 2, attributes: { source: "test" }, integration: "fake_integration"
)
expect(Sentry.metrics).to receive(:gauge).with(
"test.gauge", 3, unit: "item", attributes: { source: "test" }, integration: "fake_integration"
)
expect(Sentry.metrics).to receive(:distribution).with(
"test.distribution", 4, unit: "second", attributes: { source: "test" }, integration: "fake_integration"
)

Sentry::FakeIntegration.count("test.count", value: 2, attributes: { source: "test" })
Sentry::FakeIntegration.gauge("test.gauge", 3, unit: "item", attributes: { source: "test" })
Sentry::FakeIntegration.distribution("test.distribution", 4, unit: "second", attributes: { source: "test" })
end
end
end
40 changes: 37 additions & 3 deletions sentry-ruby/spec/sentry/metrics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,42 @@
expect(metric_names).to contain_exactly("test.counter1", "test.counter2", "test.gauge")
end

context "with integration attribution" do
let(:integration_meta) { { name: "sentry.ruby.test", version: "1.2.3" }.freeze }

before do
Sentry.integrations["test"] = integration_meta
end

after do
Sentry.integrations.delete("test")
end

it "sets metric sdk attributes from the integration" do
Sentry.metrics.count("test.counter", integration: :test)

Sentry.get_current_client.flush

expect(sentry_metrics.first[:attributes]["sentry.sdk.name"]).to eq(
{ type: "string", value: "sentry.ruby.test" }
)
expect(sentry_metrics.first[:attributes]["sentry.sdk.version"]).to eq(
{ type: "string", value: "1.2.3" }
)
end

it "batches metrics with different sdk attributes into one envelope" do
Sentry.metrics.count("test.manual")
Sentry.metrics.count("test.integration", integration: "test")

Sentry.get_current_client.flush

expect(sentry_envelopes.count).to eq(1)
sdk_names = sentry_metrics.map { |metric| metric[:attributes]["sentry.sdk.name"][:value] }
expect(sdk_names).to contain_exactly("sentry.ruby", "sentry.ruby.test")
end
end

describe "envelope structure" do
it "includes correct envelope headers" do
Sentry.metrics.count("test.counter")
Expand All @@ -237,10 +273,8 @@
envelope = sentry_envelopes.first
headers = envelope.headers

expect(headers[:event_id]).to match(/\A[0-9a-f]{32}\z/) # UUID format
expect(headers.keys).to contain_exactly(:sent_at)
expect(headers[:sent_at]).to match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/) # ISO8601 timestamp
expect(headers[:dsn]).to eq(Sentry.configuration.dsn)
expect(headers[:sdk]).to eq(Sentry.sdk_meta)
end

it "includes correct envelope item headers" do
Expand Down
8 changes: 4 additions & 4 deletions sentry-yabeda/lib/sentry/yabeda/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def register_summary!(_metric); end
def perform_counter_increment!(counter, tags, increment)
return unless enabled?

Sentry.metrics.count(
Sentry::Yabeda.count(
metric_name(counter),
value: increment,
attributes: attributes_for(tags)
Expand All @@ -24,7 +24,7 @@ def perform_counter_increment!(counter, tags, increment)
def perform_gauge_set!(gauge, tags, value)
return unless enabled?

Sentry.metrics.gauge(
Sentry::Yabeda.gauge(
metric_name(gauge),
value,
unit: unit_for(gauge),
Expand All @@ -35,7 +35,7 @@ def perform_gauge_set!(gauge, tags, value)
def perform_histogram_measure!(histogram, tags, value)
return unless enabled?

Sentry.metrics.distribution(
Sentry::Yabeda.distribution(
metric_name(histogram),
value,
unit: unit_for(histogram),
Expand All @@ -46,7 +46,7 @@ def perform_histogram_measure!(histogram, tags, value)
def perform_summary_observe!(summary, tags, value)
return unless enabled?

Sentry.metrics.distribution(
Sentry::Yabeda.distribution(
metric_name(summary),
value,
unit: unit_for(summary),
Expand Down
Loading
Loading