Repository: prometheus/prometheus
File: config/config.go (Go)

Code before:
	// RemoteWriteProtoMsgV1 represents the `prometheus.WriteRequest` protobuf
	// message introduced in the https://prometheus.io/docs/specs/remote_write_spec/,
	// which will eventually be deprecated.
	//
	// NOTE: This string is used for both HTTP header values and config value, so don't change
	// this reference.
	RemoteWriteProtoMsgV1 RemoteWriteProtoMsg = "prometheus.WriteRequest"
	// RemoteWriteProtoMsgV2 represents the `io.prometheus.write.v2.Request` protobuf
	// message introduced in https://prometheus.io/docs/specs/remote_write_spec_2_0/
	//
	// NOTE: This string is used for both HTTP header values and config value, so don't change
	// this reference.
	RemoteWriteProtoMsgV2 RemoteWriteProtoMsg = "io.prometheus.write.v2.Request"
)

// RemoteWriteConfig is the configuration for writing to remote storage.
type RemoteWriteConfig struct {
	URL                  *config.URL       `yaml:"url"`
	RemoteTimeout        model.Duration    `yaml:"remote_timeout,omitempty"`
	Headers              map[string]string `yaml:"headers,omitempty"`
	WriteRelabelConfigs  []*relabel.Config `yaml:"write_relabel_configs,omitempty"`
	Name                 string            `yaml:"name,omitempty"`
	SendExemplars        bool              `yaml:"send_exemplars,omitempty"`
	SendNativeHistograms bool              `yaml:"send_native_histograms,omitempty"`
	// EnableTypeAndUnitLabels is a feature flag to enable the type-and-unit-labels feature.
	EnableTypeAndUnitLabels bool `yaml:"enable_type_and_unit_labels,omitempty"`
	RoundRobinDNS           bool `yaml:"round_robin_dns,omitempty"`
	// ProtobufMessage specifies the protobuf message to use against the remote
	// receiver as specified in https://prometheus.io/docs/specs/remote_write_spec_2_0/
	ProtobufMessage RemoteWriteProtoMsg `yaml:"protobuf_message,omitempty"`

	// We cannot do proper Go type embedding below as the parser will then parse
	// values arbitrarily into the overflow maps of further-down types.
	HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
	QueueConfig      QueueConfig             `yaml:"queue_config,omitempty"`
	MetadataConfig   MetadataConfig          `yaml:"metadata_config,omitempty"`
	SigV4Config      *sigv4.SigV4Config      `yaml:"sigv4,omitempty"`
	AzureADConfig    *azuread.AzureADConfig  `yaml:"azuread,omitempty"`
	GoogleIAMConfig  *googleiam.Config       `yaml:"google_iam,omitempty"`
}

// SetDirectory joins any relative file paths with dir.
func (c *RemoteWriteConfig) SetDirectory(dir string) {
	c.HTTPClientConfig.SetDirectory(dir)
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
	*c = DefaultRemoteWriteConfig
	type plain RemoteWriteConfig
	if err := unmarshal((*plain)(c)); err != nil {

Review comment (performance):
Not sure if we need this extra complexity here to user. My rationales:
1.  For config fields we have to very careful. Adding problematic one (inflexible, changing default) will require us to support it for long (until v4 at least) and confuse users. This is different with feature flags which can be removed anytime.
2. It's not clear what "enabling type and unit" on remote write config does. Does it pass through those labels? Does it disable them? Does it populate metadata? Mix of those?
3. To me, it's trivial that .. if possible, remote write should populate metadata. Type and unit is a solid possibility, so I think this should be a default behaviour WHEN  `type-and-unit` feature flag is enabled
4. We already have type-and-unit feature flags -- ideally we don't add too many flags and knobs if we don't need to  -- it's a huge burden for everyone. 

```suggestion
```



Code after:
	// message introduced in https://prometheus.io/docs/specs/remote_write_spec_2_0/
	//
	// NOTE: This string is used for both HTTP header values and config value, so don't change
	// this reference.
	RemoteWriteProtoMsgV2 RemoteWriteProtoMsg = "io.prometheus.write.v2.Request"
)

// RemoteWriteConfig is the configuration for writing to remote storage.
type RemoteWriteConfig struct {
	URL                  *config.URL       `yaml:"url"`
	RemoteTimeout        model.Duration    `yaml:"remote_timeout,omitempty"`
	Headers              map[string]string `yaml:"headers,omitempty"`
	WriteRelabelConfigs  []*relabel.Config `yaml:"write_relabel_configs,omitempty"`
	Name                 string            `yaml:"name,omitempty"`
	SendExemplars        bool              `yaml:"send_exemplars,omitempty"`
	SendNativeHistograms bool              `yaml:"send_native_histograms,omitempty"`
	RoundRobinDNS        bool              `yaml:"round_robin_dns,omitempty"`
	// ProtobufMessage specifies the protobuf message to use against the remote
	// receiver as specified in https://prometheus.io/docs/specs/remote_write_spec_2_0/
	ProtobufMessage RemoteWriteProtoMsg `yaml:"protobuf_message,omitempty"`

	// We cannot do proper Go type embedding below as the parser will then parse
	// values arbitrarily into the overflow maps of further-down types.
	HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
	QueueConfig      QueueConfig             `yaml:"queue_config,omitempty"`
	MetadataConfig   MetadataConfig          `yaml:"metadata_config,omitempty"`
	SigV4Config      *sigv4.SigV4Config      `yaml:"sigv4,omitempty"`
	AzureADConfig    *azuread.AzureADConfig  `yaml:"azuread,omitempty"`
	GoogleIAMConfig  *googleiam.Config       `yaml:"google_iam,omitempty"`
}

// SetDirectory joins any relative file paths with dir.
func (c *RemoteWriteConfig) SetDirectory(dir string) {
	c.HTTPClientConfig.SetDirectory(dir)
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(any) error) error {
	*c = DefaultRemoteWriteConfig
	type plain RemoteWriteConfig
	if err := unmarshal((*plain)(c)); err != nil {
		return err
	}
	if c.URL == nil {
		return errors.New("url for remote_write is empty")
	}
	for _, rlcfg := range c.WriteRelabelConfigs {
		if rlcfg == nil {
			return errors.New("empty or null relabeling rule in remote write config")
		}
	}