Skip to content

feat: Add metrics support#1151

Merged
giortzisg merged 47 commits intogetsentry:masterfrom
aldy505:feat/sentry-metrics
Jan 26, 2026
Merged

feat: Add metrics support#1151
giortzisg merged 47 commits intogetsentry:masterfrom
aldy505:feat/sentry-metrics

Conversation

@aldy505
Copy link
Contributor

@aldy505 aldy505 commented Nov 30, 2025

Description

Implement metrics based on https://develop.sentry.dev/sdk/telemetry/metrics/ and https://develop.sentry.dev/sdk/data-model/envelope-items/#trace-metric

Issues

Usage example

ctx := context.Background()
meter := sentry.NewMeter(ctx)
// Attaching permanent attributes on the meter
meter.SetAttributes(
	attribute.String("version", "1.0.0"),
)

meter.Distribution("file_upload_size", 3.14,
	sentry.WithUnit(sentry.UnitMegabyte), // Using standard unit constants
	sentry.WithAttributes(
		attribute.String("file.type", "image/png"),
		attribute.String("bucket.region", "us-west-2"),
		attribute.String("bucket.name", "user-uploads"),
	),
)

Changelog Entry

  • Add metric support
    • support for three metric methods (counter, gauge, distribution)
    • custom metric units
    • unexport batchlogger

@aldy505 aldy505 changed the title Feat/sentry metrics feat: Sentry Metrics Nov 30, 2025
@aldy505 aldy505 marked this pull request as draft December 30, 2025 13:38
@codecov
Copy link

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 81.14754% with 92 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.46%. Comparing base (1ce3436) to head (fd95f1b).
⚠️ Report is 16 commits behind head on master.

Files with missing lines Patch % Lines
interfaces.go 75.51% 20 Missing and 4 partials ⚠️
transport.go 16.66% 20 Missing ⚠️
scope.go 70.00% 6 Missing and 6 partials ⚠️
metrics.go 91.59% 6 Missing and 4 partials ⚠️
client.go 50.00% 7 Missing ⚠️
internal/protocol/metric_batch.go 70.00% 3 Missing and 3 partials ⚠️
internal/telemetry/scheduler.go 64.28% 3 Missing and 2 partials ⚠️
metric_batch_processor.go 71.42% 2 Missing and 2 partials ⚠️
internal/protocol/envelope.go 83.33% 1 Missing and 1 partial ⚠️
log_batch_processor.go 85.71% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1151      +/-   ##
==========================================
- Coverage   86.04%   85.46%   -0.58%     
==========================================
  Files          62       67       +5     
  Lines        6090     6509     +419     
==========================================
+ Hits         5240     5563     +323     
- Misses        635      708      +73     
- Partials      215      238      +23     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@giortzisg giortzisg force-pushed the feat/sentry-metrics branch 3 times, most recently from 345f1c0 to 8ee32f7 Compare January 14, 2026 12:00
interfaces.go Outdated
// Count records a count metric.
Count(name string, count int64, options MeterOptions)
// Gauge records a gauge metric.
Gauge(name string, value float64, options MeterOptions)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giortzisg Gauge can accept normal integers (non-floats), that's why I created the Numbers interface above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but the generic solution didn't make much sense. It didn't apply to Count and Dist and in most cases you would need float64 anyways for most calculations, so it is extra verbose for no reason. Type casting in some cases is fine, but I might introduce also a GaugeInt and some other convenience methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convenience methods would be nice!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On another note, I was thinking it's because of JSON serialization for float64 and int differences.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON serialization for float64 and int differences.

That still is a problem, but doesn't get solved by generics. Count should be an int and Gauge/Dist floats, so the problem is storing and converting without precision loss between count/gauge/dist metric events.

@github-actions
Copy link

github-actions bot commented Jan 20, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • Add metric support by aldy505 in #1151
    • support for three metric methods (counter, gauge, distribution)
    • custom metric units
    • unexport batchlogger
  • Add metric support by aldy505 in #1151
    • support for three metric methods (counter, gauge, distribution)
    • custom metric units
    • unexport batchlogger

Internal Changes 🔧

Release

  • Fix changelog-preview permissions by BYK in #1181
  • Switch from action-prepare-release to Craft by BYK in #1167

Other

  • (repo) Add Claude Code settings with basic permissions by philipphofmann in #1175
  • Update release and changelog-preview workflows by giortzisg in #1177
  • Bump echo to 4.10.1 by giortzisg in #1174

🤖 This preview updates automatically when you update the PR.

cursor[bot]

This comment was marked as outdated.

@giortzisg giortzisg requested a review from Litarnus January 22, 2026 09:23
The previous batch_processor implementation needed to stop and read the timer so that any stale data was cleared. From go1.23 and on, the time.Timer uses an unbuffered channel, meaning that we can remove both reading and stop(), which simplifies the batch_processor significantly.
Copy link

@Litarnus Litarnus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

sentryhttp "github.com/getsentry/sentry-go/http"
)

var meter sentry.Meter
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nooo don't do this. It looks a lot like otel.

"github.com/getsentry/sentry-go/internal/ratelimit"
)

const errorType = ""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for? Providing comment would be great.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the errorType if an empty string if you have a look at how the sdk currently works. Just added the type so that it makes more sense.

Comment on lines +789 to +800
name: "metric event",
event: &Event{
EventID: "12345678901234567890123456789012",
Type: "trace_metric",
Metrics: []Metric{
{
Name: "test.metric",
Value: Int64MetricValue(42),
Timestamp: time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC),
Type: MetricTypeCounter,
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also test for invalid and nil MetricValue, as well as invalid metric type (other than count, dist, gauge)

// If there are duplicate keys, the value from the last map takes precedence.
//
// CC BY-SA 4.0 Oliver (https://stackoverflow.com/a/74750675/3153224)
func MergeMaps[M ~map[K]V, K comparable, V any](src ...M) M {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can safely remove this if this is not used.

Comment on lines +14 to +24
// Duration Units.
const (
UnitNanosecond = "nanosecond"
UnitMicrosecond = "microsecond"
UnitMillisecond = "millisecond"
UnitSecond = "second"
UnitMinute = "minute"
UnitHour = "hour"
UnitDay = "day"
UnitWeek = "week"
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to have this as a type of it's own, better for static typing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to receive custom units as string, but also allow the users to use the supported ones like that, so can't really have a custom type for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the freedom of type/unit is intentional?

@codecov
Copy link

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 80.60606% with 96 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.45%. Comparing base (1ce3436) to head (e143a53).
⚠️ Report is 18 commits behind head on master.

Files with missing lines Patch % Lines
interfaces.go 75.51% 20 Missing and 4 partials ⚠️
client.go 54.16% 17 Missing and 5 partials ⚠️
transport.go 16.66% 20 Missing ⚠️
metrics.go 93.06% 4 Missing and 3 partials ⚠️
internal/protocol/metric_batch.go 70.00% 3 Missing and 3 partials ⚠️
scope.go 84.61% 3 Missing and 3 partials ⚠️
internal/telemetry/scheduler.go 64.28% 3 Missing and 2 partials ⚠️
internal/protocol/envelope.go 83.33% 1 Missing and 1 partial ⚠️
log_batch_processor.go 84.61% 1 Missing and 1 partial ⚠️
metric_batch_processor.go 84.61% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1151      +/-   ##
==========================================
- Coverage   86.04%   85.45%   -0.60%     
==========================================
  Files          62       67       +5     
  Lines        6090     6509     +419     
==========================================
+ Hits         5240     5562     +322     
- Misses        635      709      +74     
- Partials      215      238      +23     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@giortzisg giortzisg changed the title feat: Sentry Metrics feat: add metrics support Jan 26, 2026
@giortzisg giortzisg changed the title feat: add metrics support feat: Add metrics support Jan 26, 2026
@giortzisg giortzisg merged commit 5d2aa89 into getsentry:master Jan 26, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sentry Metrics for Go

5 participants