Files
Zach LeslieandGitHub 237590bd68 Support exemplars with native-only histograms (#5520)
* Support exemplars with native-only histograms

* Update test to store traces separate from the wall

* Test exemplar contents

* Drop variables that were only used in debugging

* Address some PR feedback
2025-08-29 19:52:35 +00:00

71 lines
2.0 KiB
Go

package storage
import (
"log/slog"
"strings"
"github.com/grafana/dskit/user"
prometheus_config "github.com/prometheus/prometheus/config"
"github.com/grafana/tempo/pkg/util"
)
// generateTenantRemoteWriteConfigs creates a copy of the remote write configurations with the
// X-Scope-OrgID header present for the given tenant, unless Tempo is run in single tenant mode or instructed not to add X-Scope-OrgID header.
func generateTenantRemoteWriteConfigs(inputs []prometheus_config.RemoteWriteConfig, tenant string, headers map[string]string, addOrgIDHeader bool, logger *slog.Logger, sendNativeHistograms bool) []*prometheus_config.RemoteWriteConfig {
var outputs []*prometheus_config.RemoteWriteConfig
for _, input := range inputs {
output := &prometheus_config.RemoteWriteConfig{}
*output = input
// Copy headers so we can modify them
output.Headers = copyMap(output.Headers)
// Inject/overwrite custom headers from runtime overrides
for k, v := range headers {
output.Headers[k] = v
}
// Inject X-Scope-OrgID header in multi-tenant setups if not set already
if tenant != util.FakeTenantID && addOrgIDHeader {
existing := ""
for k, v := range output.Headers {
if strings.EqualFold(user.OrgIDHeaderName, strings.TrimSpace(k)) {
existing = v
break
}
}
if existing == "" {
output.Headers[user.OrgIDHeaderName] = tenant
} else {
// Remote write config already contains the header, so we don't overwrite it.
logger.Info("underlying remote write already contains X-Scope-OrgId header, not applying new value",
"remoteWriteName", input.Name,
"remoteWriteURL", input.URL.String(),
"existing", existing,
"new", tenant)
}
}
output.SendNativeHistograms = sendNativeHistograms
output.SendExemplars = true
outputs = append(outputs, output)
}
return outputs
}
// copyMap creates a new map containing all values from the given map.
func copyMap(m map[string]string) map[string]string {
newMap := make(map[string]string, len(m))
for k, v := range m {
newMap[k] = v
}
return newMap
}