// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

// Package metric provides an implementation of the OpenTelemetry metrics SDK.
//
// See https://opentelemetry.io/docs/concepts/signals/metrics/ for information
// about the concept of OpenTelemetry metrics and
// https://opentelemetry.io/docs/concepts/components/ for more information
// about OpenTelemetry SDKs.
//
// The entry point for the metric package is the MeterProvider. It is the
// object that all API calls use to create Meters, instruments, and ultimately
// make metric measurements. Also, it is an object that should be used to
// control the life-cycle (start, flush, and shutdown) of the SDK.
//
// A MeterProvider needs to be configured to export the measured data, this is
// done by configuring it with a Reader implementation (using the WithReader
// MeterProviderOption). Readers take two forms: ones that push to an endpoint
// (NewPeriodicReader), and ones that an endpoint pulls from. See
// [go.opentelemetry.io/otel/exporters] for exporters that can be used as
// or with these Readers.
//
// Each Reader, when registered with the MeterProvider, can be augmented with a
// View. Views allow users that run OpenTelemetry instrumented code to modify
// the generated data of that instrumentation.
//
// Note that attributes filtered out by a View may still appear on Exemplars,
// because Exemplars are recorded with the dropped measurement attributes
// when View attribute filtering is applied.
//
// The data generated by a MeterProvider needs to include information about its
// origin. A MeterProvider needs to be configured with a Resource, using the
// WithResource MeterProviderOption, to include this information. This Resource
// should be used to describe the unique runtime environment instrumented code
// is being run on. That way when multiple instances of the code are collected
// at a single endpoint their origin is decipherable.
//
// To avoid leaking memory, the SDK returns the same instrument for calls to
// create new instruments with the same Name, Unit, and Description.
// Importantly, callbacks provided using metric.WithFloat64Callback or
// metric.WithInt64Callback will only apply for the first instrument created
// with a given Name, Unit, and Description. Instead, use
// Meter.RegisterCallback and Registration.Unregister to add and remove
// callbacks without leaking memory.
//
// # Cardinality Limits
//
// Cardinality refers to the number of unique attributes collected. High cardinality can lead to
// excessive memory usage, increased storage costs, and backend performance issues.
//
// By default, the OpenTelemetry Go Metric SDK enforces a cardinality limit of 2000.
//
// New attribute sets are dropped when the cardinality limit is reached. The measurement of
// these sets are aggregated into
// a special attribute set containing attribute.Bool("otel.metric.overflow", true).
// This ensures total metric values (e.g., Sum, Count) remain correct for the
// collection cycle, but information about the specific dropped sets
// is not preserved.
//
// Recommendations:
//
//   - Tune the limit based on the theoretical maximum combinations or expected
//     active combinations. The SDK default is 2000.
//   - A too high of a limit increases worst-case memory overhead in the SDK and may cause downstream
//     issues for databases that cannot handle high cardinality.
//   - A too low of a limit causes loss of attribute detail as more data falls into overflow.
//
// # Ordering and Collection Guarantees
//
// For performance reasons, the SDK does not guarantee that the order in which
// synchronous measurements are made to the SDK is reflected in the collected
// metric data. This means that even when a single goroutine makes sequential
// synchronous measurements, it is possible for a later measurement to be
// included in the collected metric data when an earlier measurement is not.
// This applies to measurements made to different instruments, or to different
// attribute sets on the same instrument. Sequential measurements made to the
// same instrument and with the same attributes are guaranteed to preserve
// ordering with respect to collection.
//
// Additionally, the SDK does not guarantee that exemplars are always included
// in the same batch of metric data as the measurement they are associated
// with.
//
// See [go.opentelemetry.io/otel/metric] for more information about
// the metric API.
//
// See [go.opentelemetry.io/otel/sdk/metric/internal/x] for information about
// the experimental features.
package metric // import "go.opentelemetry.io/otel/sdk/metric"
