Skip to content
Open
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
14 changes: 0 additions & 14 deletions lib/sentry/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -437,17 +437,6 @@ defmodule Sentry.Config do
*Available since 12.0.0*.
"""
],
enable_metrics: [
type: :boolean,
default: true,
doc: """
Whether to enable sending metric events to Sentry. When enabled, the SDK will
capture and send metrics (counters, gauges, distributions) according to the
[Sentry Metrics Protocol](https://develop.sentry.dev/sdk/telemetry/metrics/).
Use `Sentry.Metrics` functions to record metrics.
*Available since 13.0.0*.
"""
],
logs: [
type: :keyword_list,
default: [],
Expand Down Expand Up @@ -1106,9 +1095,6 @@ defmodule Sentry.Config do
@spec enable_logs?() :: boolean()
def enable_logs?, do: fetch!(:enable_logs)

@spec enable_metrics?() :: boolean()
def enable_metrics?, do: fetch!(:enable_metrics)

@spec logs() :: keyword()
def logs, do: fetch!(:logs)

Expand Down
59 changes: 26 additions & 33 deletions lib/sentry/metrics.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ defmodule Sentry.Metrics do

## Configuration

Metrics can be disabled globally via configuration:

config :sentry, enable_metrics: false

You can also filter metrics using the `:before_send_metric` callback:
Metrics can be filtered using the `:before_send_metric` callback:

config :sentry,
before_send_metric: fn metric ->
Expand All @@ -42,7 +38,7 @@ defmodule Sentry.Metrics do
"""
@moduledoc since: "13.0.0"

alias Sentry.{ClientReport, Config, Metric, TelemetryProcessor}
alias Sentry.{ClientReport, Metric, TelemetryProcessor}

@doc """
Records a counter metric.
Expand Down Expand Up @@ -113,33 +109,30 @@ defmodule Sentry.Metrics do
## Private Functions

defp record_metric(type, name, value, opts) do
if Config.enable_metrics?() do
unit = Keyword.get(opts, :unit)
attributes = Keyword.get(opts, :attributes, %{})

{trace_id, span_id} = current_trace_context() || {generate_trace_id(), nil}

# Build metric struct
metric = %Metric{
type: type,
name: name,
value: value,
timestamp: System.system_time(:nanosecond) / 1_000_000_000,
trace_id: trace_id,
span_id: span_id,
unit: unit,
attributes: attributes
}

metric = Metric.attach_default_attributes(metric)

case TelemetryProcessor.add(metric) do
{:ok, {:rate_limited, _data_category}} ->
ClientReport.Sender.record_discarded_events(:ratelimit_backoff, [metric])

:ok ->
:ok
end
unit = Keyword.get(opts, :unit)
attributes = Keyword.get(opts, :attributes, %{})

{trace_id, span_id} = current_trace_context() || {generate_trace_id(), nil}

metric = %Metric{
type: type,
name: name,
value: value,
timestamp: System.system_time(:nanosecond) / 1_000_000_000,
trace_id: trace_id,
span_id: span_id,
unit: unit,
attributes: attributes
}

metric = Metric.attach_default_attributes(metric)

case TelemetryProcessor.add(metric) do
{:ok, {:rate_limited, _data_category}} ->
ClientReport.Sender.record_discarded_events(:ratelimit_backoff, [metric])

:ok ->
:ok
end

:ok
Expand Down
12 changes: 0 additions & 12 deletions test/sentry/config_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -447,18 +447,6 @@ defmodule Sentry.ConfigTest do
end
end

describe ":enable_metrics" do
test "defaults to true" do
config = Config.validate!([])
assert config[:enable_metrics] == true
end

test "can be set to false" do
config = Config.validate!(enable_metrics: false)
assert config[:enable_metrics] == false
end
end

describe ":before_send_metric" do
test "accepts a function callback" do
callback = fn metric -> metric end
Expand Down
1 change: 0 additions & 1 deletion test/sentry/metrics_integration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ defmodule Sentry.MetricsIntegrationTest do
%{bypass: bypass, telemetry_processor: processor_name, ref: ref} =
Sentry.Test.setup_sentry(
collect_envelopes: true,
enable_metrics: true,
telemetry_processor: [buffer_configs: %{metric: %{batch_size: 1}}]
)

Expand Down
73 changes: 13 additions & 60 deletions test/sentry/metrics_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,21 @@ defmodule Sentry.MetricsTest do

describe "count/2" do
test "creates a counter metric with default options" do
put_test_config(enable_metrics: true)

assert :ok = Metrics.count("button.clicks", 1)
end

test "creates a counter metric with unit" do
put_test_config(enable_metrics: true)

assert :ok = Metrics.count("http.requests", 5, unit: "request")
end

test "creates a counter metric with attributes" do
put_test_config(enable_metrics: true)

assert :ok =
Metrics.count("button.clicks", 1,
unit: "click",
attributes: %{button_id: "submit"}
)
end

test "respects enable_metrics kill switch when false" do
test_pid = self()

callback = fn metric ->
send(test_pid, {:metric_sent, metric})
metric
end

put_test_config(enable_metrics: false, before_send_metric: callback)

# Should not raise error, just silently return :ok
assert :ok = Metrics.count("button.clicks", 1)

# Verify the metric was NOT sent and callback was NOT called
refute_receive {:metric_sent, _}, 100
end

test "applies before_send_metric callback" do
test_pid = self()

Expand All @@ -58,7 +35,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

Metrics.count("test.counter", 42, unit: "item")
TelemetryProcessor.flush()
Expand All @@ -79,7 +56,6 @@ defmodule Sentry.MetricsTest do
end

put_test_config(
enable_metrics: true,
before_send_metric: callback,
environment_name: "test",
release: "1.0.0"
Expand All @@ -98,15 +74,15 @@ defmodule Sentry.MetricsTest do

test "filters metric when before_send_metric returns nil" do
callback = fn _metric -> nil end
put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

# Should not crash, just skip sending
assert :ok = Metrics.count("test.counter", 1)
end

test "filters metric when before_send_metric returns false" do
callback = fn _metric -> false end
put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

# Should not crash, just skip sending
assert :ok = Metrics.count("test.counter", 1)
Expand All @@ -120,7 +96,7 @@ defmodule Sentry.MetricsTest do
%{metric | value: metric.value * 2}
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

Metrics.count("test.counter", 5)
TelemetryProcessor.flush()
Expand All @@ -135,7 +111,7 @@ defmodule Sentry.MetricsTest do
end
end

put_test_config(enable_metrics: true, before_send_metric: {TestCallback, :filter_metric})
put_test_config(before_send_metric: {TestCallback, :filter_metric})

# Should be filtered out
assert :ok = Metrics.count("test.counter", 5)
Expand All @@ -152,7 +128,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

Metrics.count("test.counter", 1)
TelemetryProcessor.flush()
Expand All @@ -166,50 +142,30 @@ defmodule Sentry.MetricsTest do

describe "gauge/2" do
test "creates a gauge metric with default options" do
put_test_config(enable_metrics: true)

assert :ok = Metrics.gauge("memory.usage", 1024)
end

test "creates a gauge metric with unit and attributes" do
put_test_config(enable_metrics: true)

assert :ok =
Metrics.gauge("active.connections", 42,
unit: "connection",
attributes: %{pool: "main"}
)
end

test "respects enable_metrics kill switch" do
put_test_config(enable_metrics: false)

assert :ok = Metrics.gauge("memory.usage", 1024)
end
end

describe "distribution/2" do
test "creates a distribution metric with default options" do
put_test_config(enable_metrics: true)

assert :ok = Metrics.distribution("response.time", 42.5)
end

test "creates a distribution metric with unit and attributes" do
put_test_config(enable_metrics: true)

assert :ok =
Metrics.distribution("response.time", 42.5,
unit: "millisecond",
attributes: %{endpoint: "/api"}
)
end

test "respects enable_metrics kill switch" do
put_test_config(enable_metrics: false)

assert :ok = Metrics.distribution("response.time", 42.5)
end
end

describe "trace context extraction" do
Expand All @@ -221,7 +177,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

Metrics.count("test.counter", 1)
TelemetryProcessor.flush()
Expand All @@ -241,7 +197,7 @@ defmodule Sentry.MetricsTest do
raise "callback error"
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

import ExUnit.CaptureLog

Expand All @@ -261,10 +217,7 @@ defmodule Sentry.MetricsTest do
def before_send_metric(_metric), do: raise("MFA callback error")
end

put_test_config(
enable_metrics: true,
before_send_metric: {RaisingCallback, :before_send_metric}
)
put_test_config(before_send_metric: {RaisingCallback, :before_send_metric})

import ExUnit.CaptureLog

Expand All @@ -287,7 +240,7 @@ defmodule Sentry.MetricsTest do
:invalid_return
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

assert :ok = Metrics.count("test.counter", 1)
TelemetryProcessor.flush()
Expand All @@ -304,7 +257,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

assert :ok = Metrics.count("test.zero", 0)
TelemetryProcessor.flush()
Expand All @@ -319,7 +272,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

assert :ok = Metrics.gauge("test.negative", -42)
TelemetryProcessor.flush()
Expand All @@ -334,7 +287,7 @@ defmodule Sentry.MetricsTest do
metric
end

put_test_config(enable_metrics: true, before_send_metric: callback)
put_test_config(before_send_metric: callback)

assert :ok = Metrics.distribution("test.float", 0.001)
TelemetryProcessor.flush()
Expand Down
4 changes: 0 additions & 4 deletions test/sentry/telemetry_processor_integration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,6 @@ defmodule Sentry.TelemetryProcessorIntegrationTest do
end

test "a trace_metric_byte limit stops further metrics and reports paired outcomes", ctx do
put_test_config(enable_metrics: true)

ref = install_rate_limit_response(ctx.bypass, "trace_metric_byte")

Sentry.Metrics.count("first.metric", 1)
Expand Down Expand Up @@ -647,8 +645,6 @@ defmodule Sentry.TelemetryProcessorIntegrationTest do

test "a trace_metric_byte rate limit drops metrics emitted via Sentry.Metrics with paired outcomes",
ctx do
put_test_config(enable_metrics: true)

metric_buffer = TelemetryProcessor.get_buffer(ctx.processor, :metric)

set_rate_limit("trace_metric_byte")
Expand Down
1 change: 0 additions & 1 deletion test_integrations/phoenix_app/config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ config :sentry,
test_mode: true,
send_result: :sync,
traces_sample_rate: 1.0,
enable_metrics: true,
enable_logs: true,
logs: [
level: :info,
Expand Down
Loading