mirror of
https://github.com/hanzoai/metrics.git
synced 2026-10-30 20:03:39 +00:00
Updates: - unpin AWS dependencies and run `make vendor-update` - add config options to enable checksums only if required by storage in order to preserve backwards compatibility Related issues: - https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9748 - https://github.com/VictoriaMetrics/VictoriaMetrics/issues/8622 Tested with: AWS S3, self-hosted MinIO, Linode object storage as it was failing previously with multi-part uploads (reported here - https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8630#issuecomment-2772185033). An updated library allows (PR with the fix - https://github.com/aws/aws-sdk-go-v2/pull/3151) overriding multi-part upload configurations so that compatibility can be preserved. Signed-off-by: Zakhar Bessarab <[email protected]>
62 lines
1.9 KiB
Go
62 lines
1.9 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package internal // import "go.opentelemetry.io/collector/confmap/internal"
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
"github.com/go-viper/mapstructure/v2"
|
|
|
|
encoder "go.opentelemetry.io/collector/confmap/internal/mapstructure"
|
|
)
|
|
|
|
// EncoderConfig returns a default encoder.EncoderConfig that includes
|
|
// an EncodeHook that handles both TextMarshaler and Marshaler
|
|
// interfaces.
|
|
func EncoderConfig(rawVal any, _ MarshalOptions) *encoder.EncoderConfig {
|
|
return &encoder.EncoderConfig{
|
|
EncodeHook: mapstructure.ComposeDecodeHookFunc(
|
|
encoder.YamlMarshalerHookFunc(),
|
|
encoder.TextMarshalerHookFunc(),
|
|
marshalerHookFunc(rawVal),
|
|
),
|
|
}
|
|
}
|
|
|
|
// marshalerHookFunc returns a DecodeHookFuncValue that checks structs that aren't
|
|
// the original to see if they implement the Marshaler interface.
|
|
func marshalerHookFunc(orig any) mapstructure.DecodeHookFuncValue {
|
|
origType := reflect.TypeOf(orig)
|
|
return safeWrapDecodeHookFunc(func(from, _ reflect.Value) (any, error) {
|
|
if from.Kind() != reflect.Struct {
|
|
return from.Interface(), nil
|
|
}
|
|
|
|
// ignore original to avoid infinite loop.
|
|
if from.Type() == origType && reflect.DeepEqual(from.Interface(), orig) {
|
|
return from.Interface(), nil
|
|
}
|
|
marshaler, ok := from.Interface().(Marshaler)
|
|
if !ok {
|
|
return from.Interface(), nil
|
|
}
|
|
conf := NewFromStringMap(nil)
|
|
if err := marshaler.Marshal(conf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
stringMap := conf.ToStringMap()
|
|
if stringMap == nil {
|
|
// If conf is still nil after marshaling, we want to encode it as an untyped nil
|
|
// instead of a map-typed nil. This ensures the value is a proper null value
|
|
// in the final marshaled output instead of an empty map. We hit this case
|
|
// when marshaling wrapper structs that have no direct representation
|
|
// in the marshaled output that aren't tagged with "squash" on the fields
|
|
// they're used on.
|
|
return nil, nil
|
|
}
|
|
return stringMap, nil
|
|
})
|
|
}
|