Files
zeekay 54ffd7aa85 debrand: purge ClickHouse -> datastore + hanzo-ds; datastore:// DSN; no replace
- imports: ClickHouse/ch-go, clickhouse-go/v2, srikanthccv/ClickHouse-go-mock
  -> github.com/hanzo-ds/{native,go,mock} (require, clean semver, NO replace)
- identifiers/aliases/type-names/config-keys/type-IDs: clickhouse -> datastore
  (receiver dir clickhousesystemtablesreceiver -> datastoresystemtablesreceiver)
- DSN scheme clickhouse:// -> datastore:// (driver treats non-http/https as Native)
- removed the go.opencensus.io version-pin replace (require-pinned instead)
- kept: real external refs (github.com/ClickHouse, clickhouse.com docs) and the
  hanzo-ds/mock test API (NewClickHouseNative) pending the mock's own rename
Full ./... build passes. 0 replace directives, 0 signoz.
2026-07-12 19:08:48 -07:00

113 lines
3.1 KiB
Go

package v1
import (
"regexp"
"github.com/hanzoai/otel-collector/pkg/metering"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.uber.org/zap"
)
var (
excludeRegex = regexp.MustCompile("^(o11y|otelcol).*")
)
type metrics struct {
Logger *zap.Logger
Sizer metering.Sizer
}
func NewMetrics(logger *zap.Logger) metering.Metrics {
if logger == nil {
logger = zap.NewNop()
}
return &metrics{
Logger: logger,
Sizer: metering.NewJSONSizer(logger),
}
}
func (meter *metrics) Size(md pmetric.Metrics) int {
// Note: We will never use this function unless our billing mechanism changes
// The metrics limits should have been samples count based, however, we rolled out with size
// and many have a guestimated and set the size limits. So we will keep this as pmetric json size for now
bytes, err := (&pmetric.JSONMarshaler{}).MarshalMetrics(md)
if err != nil {
meter.Logger.Error("cannot marshal metrics", zap.Error(err))
return 0
}
return len(bytes)
}
func (meter *metrics) SizePerResource(rmd pmetric.ResourceMetrics) int {
// check what can be done here
return 0
}
func (meter *metrics) Count(md pmetric.Metrics) int {
count := 0
for i := 0; i < md.ResourceMetrics().Len(); i++ {
resourceMetric := md.ResourceMetrics().At(i)
count += meter.CountPerResource(resourceMetric)
}
return count
}
func (meter *metrics) CountPerResource(rmd pmetric.ResourceMetrics) int {
count := 0
for j := 0; j < rmd.ScopeMetrics().Len(); j++ {
scopeMetrics := rmd.ScopeMetrics().At(j)
for k := 0; k < scopeMetrics.Metrics().Len(); k++ {
metric := scopeMetrics.Metrics().At(k)
// if the metric satisifies the excluded regex then skip the metric
if excludeRegex.MatchString(metric.Name()) {
continue
}
switch metric.Type() {
case pmetric.MetricTypeGauge:
count += metric.Gauge().DataPoints().Len()
case pmetric.MetricTypeSum:
count += metric.Sum().DataPoints().Len()
case pmetric.MetricTypeHistogram:
subCount := 0
// each bucket is treated as separate sample
for i := 0; i < metric.Histogram().DataPoints().Len(); i++ {
subCount += metric.Histogram().DataPoints().At(i).BucketCounts().Len()
subCount += 1 // count metric
if metric.Histogram().DataPoints().At(i).HasSum() {
subCount += 1
}
if metric.Histogram().DataPoints().At(i).HasMin() {
subCount += 1
}
if metric.Histogram().DataPoints().At(i).HasMax() {
subCount += 1
}
}
count += subCount
case pmetric.MetricTypeSummary:
subCount := 0
for i := 0; i < metric.Summary().DataPoints().Len(); i++ {
subCount += metric.Summary().DataPoints().At(i).QuantileValues().Len()
subCount += 2 // count,sum metrics
}
count += subCount
case pmetric.MetricTypeExponentialHistogram:
// Intentionally not counted. Exp histograms aren't billable on Cloud yet,
// and counting each bucket as a sample would explode the count.
// Kept consistent with the o11ydatastoremetrics exporter's writeExpHist,
// which also does not count these toward usage.
// TODO(srikanthccv): revisit when exp histograms are supported on Cloud.
}
}
}
return count
}