diff --git a/api/config/crd/bases/odigos.io_collectorsgroups.yaml b/api/config/crd/bases/odigos.io_collectorsgroups.yaml index 0fc09ae442..b8dca11fc5 100644 --- a/api/config/crd/bases/odigos.io_collectorsgroups.yaml +++ b/api/config/crd/bases/odigos.io_collectorsgroups.yaml @@ -48,6 +48,57 @@ spec: This can be used to resolve conflicting ports when a collector is using the host network. format: int32 type: integer + memorySettings: + description: |- + Memory settings for the collectors group. + these settings are used to protect the collectors instances from: + - running out of memory and being killed by the k8s OOM killer + - consuming all available memory on the node which can lead to node instability + - pushing back pressure to the instrumented applications + properties: + gomemlimitMiB: + description: |- + the GOMEMLIMIT environment variable value for the collector pod. + this is when go runtime will start garbage collection. + it is recommended to be set to 80% of the hard limit of the memory limiter. + type: integer + memoryLimitMiB: + description: |- + This option sets the limit on the memory usage of the collector. + since the memory limiter mechanism is heuristic, and operates on fixed intervals, + while it cannot fully prevent OOMs, it can help in reducing the chances of OOMs in edge cases. + the settings should prevent the collector from exceeding the memory request, + so one can set this to the same value as the memory request or higher to allow for some buffer for bursts. + type: integer + memoryLimiterLimitMiB: + description: |- + this parameter sets the "limit_mib" parameter in the memory limiter configuration for the collector. + it is the hard limit after which a force garbage collection will be performed. + this value will end up comparing against the go runtime reported heap Alloc value. + According to the memory limiter docs: + > Note that typically the total memory usage of process will be about 50MiB higher than this value + a test from nov 2024 showed that fresh odigos collector with no traffic takes 38MiB, + thus the 50MiB is a good value to start with. + type: integer + memoryLimiterSpikeLimitMiB: + description: |- + this parameter sets the "spike_limit_mib" parameter in the memory limiter configuration for the collector memory limiter. + note that this is not the processor soft limit itself, but the diff in Mib between the hard limit and the soft limit. + according to the memory limiter docs, it is recommended to set this to 20% of the hard limit. + changing this value allows trade-offs between memory usage and resiliency to bursts. + type: integer + memoryRequestMiB: + description: |- + MemoryRequestMiB is the memory resource request to be used on the pod template. + it will be embedded in the as a resource request of the form "memory: Mi" + type: integer + required: + - gomemlimitMiB + - memoryLimitMiB + - memoryLimiterLimitMiB + - memoryLimiterSpikeLimitMiB + - memoryRequestMiB + type: object role: enum: - CLUSTER_GATEWAY @@ -55,6 +106,7 @@ spec: type: string required: - collectorOwnMetricsPort + - memorySettings - role type: object status: diff --git a/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupmemorysettings.go b/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupmemorysettings.go new file mode 100644 index 0000000000..4bd5e45d61 --- /dev/null +++ b/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupmemorysettings.go @@ -0,0 +1,74 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// CollectorsGroupMemorySettingsApplyConfiguration represents a declarative configuration of the CollectorsGroupMemorySettings type for use +// with apply. +type CollectorsGroupMemorySettingsApplyConfiguration struct { + MemoryRequestMiB *int `json:"memoryRequestMiB,omitempty"` + MemoryLimitMiB *int `json:"memoryLimitMiB,omitempty"` + MemoryLimiterLimitMiB *int `json:"memoryLimiterLimitMiB,omitempty"` + MemoryLimiterSpikeLimitMiB *int `json:"memoryLimiterSpikeLimitMiB,omitempty"` + GomemlimitMiB *int `json:"gomemlimitMiB,omitempty"` +} + +// CollectorsGroupMemorySettingsApplyConfiguration constructs a declarative configuration of the CollectorsGroupMemorySettings type for use with +// apply. +func CollectorsGroupMemorySettings() *CollectorsGroupMemorySettingsApplyConfiguration { + return &CollectorsGroupMemorySettingsApplyConfiguration{} +} + +// WithMemoryRequestMiB sets the MemoryRequestMiB field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MemoryRequestMiB field is set to the value of the last call. +func (b *CollectorsGroupMemorySettingsApplyConfiguration) WithMemoryRequestMiB(value int) *CollectorsGroupMemorySettingsApplyConfiguration { + b.MemoryRequestMiB = &value + return b +} + +// WithMemoryLimitMiB sets the MemoryLimitMiB field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MemoryLimitMiB field is set to the value of the last call. +func (b *CollectorsGroupMemorySettingsApplyConfiguration) WithMemoryLimitMiB(value int) *CollectorsGroupMemorySettingsApplyConfiguration { + b.MemoryLimitMiB = &value + return b +} + +// WithMemoryLimiterLimitMiB sets the MemoryLimiterLimitMiB field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MemoryLimiterLimitMiB field is set to the value of the last call. +func (b *CollectorsGroupMemorySettingsApplyConfiguration) WithMemoryLimiterLimitMiB(value int) *CollectorsGroupMemorySettingsApplyConfiguration { + b.MemoryLimiterLimitMiB = &value + return b +} + +// WithMemoryLimiterSpikeLimitMiB sets the MemoryLimiterSpikeLimitMiB field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MemoryLimiterSpikeLimitMiB field is set to the value of the last call. +func (b *CollectorsGroupMemorySettingsApplyConfiguration) WithMemoryLimiterSpikeLimitMiB(value int) *CollectorsGroupMemorySettingsApplyConfiguration { + b.MemoryLimiterSpikeLimitMiB = &value + return b +} + +// WithGomemlimitMiB sets the GomemlimitMiB field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GomemlimitMiB field is set to the value of the last call. +func (b *CollectorsGroupMemorySettingsApplyConfiguration) WithGomemlimitMiB(value int) *CollectorsGroupMemorySettingsApplyConfiguration { + b.GomemlimitMiB = &value + return b +} diff --git a/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupspec.go b/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupspec.go index 776732e4af..f4ff9a4605 100644 --- a/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupspec.go +++ b/api/generated/odigos/applyconfiguration/odigos/v1alpha1/collectorsgroupspec.go @@ -24,8 +24,9 @@ import ( // CollectorsGroupSpecApplyConfiguration represents a declarative configuration of the CollectorsGroupSpec type for use // with apply. type CollectorsGroupSpecApplyConfiguration struct { - Role *v1alpha1.CollectorsGroupRole `json:"role,omitempty"` - CollectorOwnMetricsPort *int32 `json:"collectorOwnMetricsPort,omitempty"` + Role *v1alpha1.CollectorsGroupRole `json:"role,omitempty"` + CollectorOwnMetricsPort *int32 `json:"collectorOwnMetricsPort,omitempty"` + MemorySettings *CollectorsGroupMemorySettingsApplyConfiguration `json:"memorySettings,omitempty"` } // CollectorsGroupSpecApplyConfiguration constructs a declarative configuration of the CollectorsGroupSpec type for use with @@ -49,3 +50,11 @@ func (b *CollectorsGroupSpecApplyConfiguration) WithCollectorOwnMetricsPort(valu b.CollectorOwnMetricsPort = &value return b } + +// WithMemorySettings sets the MemorySettings field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MemorySettings field is set to the value of the last call. +func (b *CollectorsGroupSpecApplyConfiguration) WithMemorySettings(value *CollectorsGroupMemorySettingsApplyConfiguration) *CollectorsGroupSpecApplyConfiguration { + b.MemorySettings = value + return b +} diff --git a/api/generated/odigos/applyconfiguration/utils.go b/api/generated/odigos/applyconfiguration/utils.go index 123503121a..954bd9be8b 100644 --- a/api/generated/odigos/applyconfiguration/utils.go +++ b/api/generated/odigos/applyconfiguration/utils.go @@ -41,6 +41,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &odigosv1alpha1.CollectorGatewayConfigurationApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CollectorsGroup"): return &odigosv1alpha1.CollectorsGroupApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("CollectorsGroupMemorySettings"): + return &odigosv1alpha1.CollectorsGroupMemorySettingsApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CollectorsGroupSpec"): return &odigosv1alpha1.CollectorsGroupSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CollectorsGroupStatus"): diff --git a/api/odigos/v1alpha1/collectorsgroup_types.go b/api/odigos/v1alpha1/collectorsgroup_types.go index e04fc37cad..a8187f53b3 100644 --- a/api/odigos/v1alpha1/collectorsgroup_types.go +++ b/api/odigos/v1alpha1/collectorsgroup_types.go @@ -30,6 +30,44 @@ const ( CollectorsGroupRoleNodeCollector CollectorsGroupRole = CollectorsGroupRole(k8sconsts.CollectorsRoleNodeCollector) ) +// The raw values of the memory settings for the collectors group. +// any defaulting, validations and calculations should be done in the controllers +// that create this CR. +// Values will be used as is without any further processing. +type CollectorsGroupMemorySettings struct { + + // MemoryRequestMiB is the memory resource request to be used on the pod template. + // it will be embedded in the as a resource request of the form "memory: Mi" + MemoryRequestMiB int `json:"memoryRequestMiB"` + + // This option sets the limit on the memory usage of the collector. + // since the memory limiter mechanism is heuristic, and operates on fixed intervals, + // while it cannot fully prevent OOMs, it can help in reducing the chances of OOMs in edge cases. + // the settings should prevent the collector from exceeding the memory request, + // so one can set this to the same value as the memory request or higher to allow for some buffer for bursts. + MemoryLimitMiB int `json:"memoryLimitMiB"` + + // this parameter sets the "limit_mib" parameter in the memory limiter configuration for the collector. + // it is the hard limit after which a force garbage collection will be performed. + // this value will end up comparing against the go runtime reported heap Alloc value. + // According to the memory limiter docs: + // > Note that typically the total memory usage of process will be about 50MiB higher than this value + // a test from nov 2024 showed that fresh odigos collector with no traffic takes 38MiB, + // thus the 50MiB is a good value to start with. + MemoryLimiterLimitMiB int `json:"memoryLimiterLimitMiB"` + + // this parameter sets the "spike_limit_mib" parameter in the memory limiter configuration for the collector memory limiter. + // note that this is not the processor soft limit itself, but the diff in Mib between the hard limit and the soft limit. + // according to the memory limiter docs, it is recommended to set this to 20% of the hard limit. + // changing this value allows trade-offs between memory usage and resiliency to bursts. + MemoryLimiterSpikeLimitMiB int `json:"memoryLimiterSpikeLimitMiB"` + + // the GOMEMLIMIT environment variable value for the collector pod. + // this is when go runtime will start garbage collection. + // it is recommended to be set to 80% of the hard limit of the memory limiter. + GomemlimitMiB int `json:"gomemlimitMiB"` +} + // CollectorsGroupSpec defines the desired state of Collector type CollectorsGroupSpec struct { Role CollectorsGroupRole `json:"role"` @@ -37,6 +75,13 @@ type CollectorsGroupSpec struct { // The port to use for exposing the collector's own metrics as a prometheus endpoint. // This can be used to resolve conflicting ports when a collector is using the host network. CollectorOwnMetricsPort int32 `json:"collectorOwnMetricsPort"` + + // Memory settings for the collectors group. + // these settings are used to protect the collectors instances from: + // - running out of memory and being killed by the k8s OOM killer + // - consuming all available memory on the node which can lead to node instability + // - pushing back pressure to the instrumented applications + MemorySettings CollectorsGroupMemorySettings `json:"memorySettings"` } // CollectorsGroupStatus defines the observed state of Collector diff --git a/api/odigos/v1alpha1/zz_generated.deepcopy.go b/api/odigos/v1alpha1/zz_generated.deepcopy.go index 41f1abe041..07567069bf 100644 --- a/api/odigos/v1alpha1/zz_generated.deepcopy.go +++ b/api/odigos/v1alpha1/zz_generated.deepcopy.go @@ -153,9 +153,25 @@ func (in *CollectorsGroupList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorsGroupMemorySettings) DeepCopyInto(out *CollectorsGroupMemorySettings) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorsGroupMemorySettings. +func (in *CollectorsGroupMemorySettings) DeepCopy() *CollectorsGroupMemorySettings { + if in == nil { + return nil + } + out := new(CollectorsGroupMemorySettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CollectorsGroupSpec) DeepCopyInto(out *CollectorsGroupSpec) { *out = *in + out.MemorySettings = in.MemorySettings } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorsGroupSpec. diff --git a/autoscaler/controllers/gateway/configmap.go b/autoscaler/controllers/gateway/configmap.go index ab9a23af22..1547517e1f 100644 --- a/autoscaler/controllers/gateway/configmap.go +++ b/autoscaler/controllers/gateway/configmap.go @@ -111,13 +111,13 @@ func addSelfTelemetryPipeline(c *config.Config, ownTelemetryPort int32) error { return nil } -func syncConfigMap(dests *odigosv1.DestinationList, allProcessors *odigosv1.ProcessorList, gateway *odigosv1.CollectorsGroup, ctx context.Context, c client.Client, scheme *runtime.Scheme, memConfig *memoryConfigurations) (string, []odigoscommon.ObservabilitySignal, error) { +func syncConfigMap(dests *odigosv1.DestinationList, allProcessors *odigosv1.ProcessorList, gateway *odigosv1.CollectorsGroup, ctx context.Context, c client.Client, scheme *runtime.Scheme) (string, []odigoscommon.ObservabilitySignal, error) { logger := log.FromContext(ctx) memoryLimiterConfiguration := config.GenericMap{ "check_interval": "1s", - "limit_mib": memConfig.memoryLimiterLimitMiB, - "spike_limit_mib": memConfig.memoryLimiterSpikeLimitMiB, + "limit_mib": gateway.Spec.MemorySettings.MemoryLimiterLimitMiB, + "spike_limit_mib": gateway.Spec.MemorySettings.MemoryLimiterSpikeLimitMiB, } processors := common.FilterAndSortProcessorsByOrderHint(allProcessors, odigosv1.CollectorsGroupRoleClusterGateway) diff --git a/autoscaler/controllers/gateway/deployment.go b/autoscaler/controllers/gateway/deployment.go index 1a23eae84b..e15f98a45c 100644 --- a/autoscaler/controllers/gateway/deployment.go +++ b/autoscaler/controllers/gateway/deployment.go @@ -34,7 +34,7 @@ const ( ) func syncDeployment(dests *odigosv1.DestinationList, gateway *odigosv1.CollectorsGroup, configData string, - ctx context.Context, c client.Client, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string, memConfig *memoryConfigurations) (*appsv1.Deployment, error) { + ctx context.Context, c client.Client, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string) (*appsv1.Deployment, error) { logger := log.FromContext(ctx) secretsVersionHash, err := destinationsSecretsVersionsHash(ctx, c, dests) @@ -44,7 +44,7 @@ func syncDeployment(dests *odigosv1.DestinationList, gateway *odigosv1.Collector // Calculate the hash of the config data and the secrets version hash, this is used to make sure the gateway will restart when the config changes configDataHash := common.Sha256Hash(fmt.Sprintf("%s-%s", configData, secretsVersionHash)) - desiredDeployment, err := getDesiredDeployment(dests, configDataHash, gateway, scheme, imagePullSecrets, odigosVersion, memConfig) + desiredDeployment, err := getDesiredDeployment(dests, configDataHash, gateway, scheme, imagePullSecrets, odigosVersion) if err != nil { return nil, errors.Join(err, errors.New("failed to get desired deployment")) } @@ -88,9 +88,10 @@ func patchDeployment(existing *appsv1.Deployment, desired *appsv1.Deployment, ct } func getDesiredDeployment(dests *odigosv1.DestinationList, configDataHash string, - gateway *odigosv1.CollectorsGroup, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string, memConfig *memoryConfigurations) (*appsv1.Deployment, error) { + gateway *odigosv1.CollectorsGroup, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string) (*appsv1.Deployment, error) { - requestMemoryQuantity := resource.MustParse(fmt.Sprintf("%dMi", memConfig.memoryRequestMiB)) + requestMemoryQuantity := resource.MustParse(fmt.Sprintf("%dMi", gateway.Spec.MemorySettings.MemoryRequestMiB)) + limitMemoryQuantity := resource.MustParse(fmt.Sprintf("%dMi", gateway.Spec.MemorySettings.MemoryLimitMiB)) desiredDeployment := &appsv1.Deployment{ ObjectMeta: v1.ObjectMeta{ @@ -158,7 +159,7 @@ func getDesiredDeployment(dests *odigosv1.DestinationList, configDataHash string }, { Name: "GOMEMLIMIT", - Value: fmt.Sprintf("%dMiB", memConfig.gomemlimitMiB), + Value: fmt.Sprintf("%dMiB", gateway.Spec.MemorySettings.GomemlimitMiB), }, }, SecurityContext: &corev1.SecurityContext{ @@ -190,6 +191,9 @@ func getDesiredDeployment(dests *odigosv1.DestinationList, configDataHash string Requests: corev1.ResourceList{ corev1.ResourceMemory: requestMemoryQuantity, }, + Limits: corev1.ResourceList{ + corev1.ResourceMemory: limitMemoryQuantity, + }, }, }, }, diff --git a/autoscaler/controllers/gateway/hpa.go b/autoscaler/controllers/gateway/hpa.go index 7a47326152..a718cde6a1 100644 --- a/autoscaler/controllers/gateway/hpa.go +++ b/autoscaler/controllers/gateway/hpa.go @@ -30,12 +30,12 @@ var ( stabilizationWindowSeconds = intPtr(300) // cooldown period for scaling down ) -func syncHPA(gateway *odigosv1.CollectorsGroup, ctx context.Context, c client.Client, scheme *runtime.Scheme, memConfig *memoryConfigurations, kubeVersion *version.Version) error { +func syncHPA(gateway *odigosv1.CollectorsGroup, ctx context.Context, c client.Client, scheme *runtime.Scheme, kubeVersion *version.Version) error { logger := log.FromContext(ctx) var hpa client.Object - memLimit := memConfig.gomemlimitMiB * memoryLimitPercentageForHPA / 100.0 + memLimit := gateway.Spec.MemorySettings.GomemlimitMiB * memoryLimitPercentageForHPA / 100.0 metricQuantity := resource.MustParse(fmt.Sprintf("%dMi", memLimit)) switch { diff --git a/autoscaler/controllers/gateway/root.go b/autoscaler/controllers/gateway/root.go index 422a237526..552296b40a 100644 --- a/autoscaler/controllers/gateway/root.go +++ b/autoscaler/controllers/gateway/root.go @@ -6,10 +6,8 @@ import ( odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" commonconf "github.com/odigos-io/odigos/autoscaler/controllers/common" controllerconfig "github.com/odigos-io/odigos/autoscaler/controllers/controller_config" - odigoscommon "github.com/odigos-io/odigos/common" k8sconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" "github.com/odigos-io/odigos/k8sutils/pkg/env" - "github.com/odigos-io/odigos/k8sutils/pkg/utils" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -49,14 +47,7 @@ func Sync(ctx context.Context, k8sClient client.Client, scheme *runtime.Scheme, // Add the generic batch processor to the list of processors processors.Items = append(processors.Items, commonconf.GetGenericBatchProcessor()) - odigosConfig, err := utils.GetCurrentOdigosConfig(ctx, k8sClient) - if err != nil { - logger.Error(err, "failed to get odigos config") - return err - } - - err = syncGateway(&dests, &processors, &gatewayCollectorGroup, ctx, k8sClient, scheme, imagePullSecrets, odigosVersion, &odigosConfig, - config) + err = syncGateway(&dests, &processors, &gatewayCollectorGroup, ctx, k8sClient, scheme, imagePullSecrets, odigosVersion, config) statusPatchString := commonconf.GetCollectorsGroupDeployedConditionsPatch(err) statusErr := k8sClient.Status().Patch(ctx, &gatewayCollectorGroup, client.RawPatch(types.MergePatchType, []byte(statusPatchString))) if statusErr != nil { @@ -68,14 +59,12 @@ func Sync(ctx context.Context, k8sClient client.Client, scheme *runtime.Scheme, func syncGateway(dests *odigosv1.DestinationList, processors *odigosv1.ProcessorList, gateway *odigosv1.CollectorsGroup, ctx context.Context, - c client.Client, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string, odigosConfig *odigoscommon.OdigosConfiguration, + c client.Client, scheme *runtime.Scheme, imagePullSecrets []string, odigosVersion string, config *controllerconfig.ControllerConfig) error { logger := log.FromContext(ctx) logger.V(0).Info("Syncing gateway") - memConfig := getMemoryConfigurations(odigosConfig) - - configData, signals, err := syncConfigMap(dests, processors, gateway, ctx, c, scheme, memConfig) + configData, signals, err := syncConfigMap(dests, processors, gateway, ctx, c, scheme) if err != nil { logger.Error(err, "Failed to sync config map") return err @@ -93,7 +82,7 @@ func syncGateway(dests *odigosv1.DestinationList, processors *odigosv1.Processor return err } - _, err = syncDeployment(dests, gateway, configData, ctx, c, scheme, imagePullSecrets, odigosVersion, memConfig) + _, err = syncDeployment(dests, gateway, configData, ctx, c, scheme, imagePullSecrets, odigosVersion) if err != nil { logger.Error(err, "Failed to sync deployment") return err @@ -105,7 +94,7 @@ func syncGateway(dests *odigosv1.DestinationList, processors *odigosv1.Processor return err } - err = syncHPA(gateway, ctx, c, scheme, memConfig, config.K8sVersion) + err = syncHPA(gateway, ctx, c, scheme, config.K8sVersion) if err != nil { logger.Error(err, "Failed to sync HPA") } diff --git a/autoscaler/controllers/odigosconfig_controller.go b/autoscaler/controllers/odigosconfig_controller.go deleted file mode 100644 index b57330b70e..0000000000 --- a/autoscaler/controllers/odigosconfig_controller.go +++ /dev/null @@ -1,43 +0,0 @@ -package controllers - -import ( - "context" - - controllerconfig "github.com/odigos-io/odigos/autoscaler/controllers/controller_config" - odigospredicate "github.com/odigos-io/odigos/k8sutils/pkg/predicate" - - "github.com/odigos-io/odigos/autoscaler/controllers/gateway" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -type OdigosConfigReconciler struct { - client.Client - Scheme *runtime.Scheme - ImagePullSecrets []string - OdigosVersion string - Config *controllerconfig.ControllerConfig -} - -func (r *OdigosConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := log.FromContext(ctx) - logger.V(0).Info("Reconciling Odigos Configuration") - - err := gateway.Sync(ctx, r.Client, r.Scheme, r.ImagePullSecrets, r.OdigosVersion, r.Config) - if err != nil { - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -func (r *OdigosConfigReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&v1.ConfigMap{}). - WithEventFilter(predicate.And(odigospredicate.OdigosConfigMapPredicate, odigospredicate.ConfigMapDataChangedPredicate{})). - Complete(r) -} diff --git a/autoscaler/main.go b/autoscaler/main.go index 9fc6aa1179..5053d76144 100644 --- a/autoscaler/main.go +++ b/autoscaler/main.go @@ -234,16 +234,6 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "InstrumentedApplication") os.Exit(1) } - if err = (&controllers.OdigosConfigReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - ImagePullSecrets: imagePullSecrets, - OdigosVersion: odigosVersion, - Config: config, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OdigosConfig") - os.Exit(1) - } if err = (&controllers.SecretReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), diff --git a/common/config/root.go b/common/config/root.go index 1d6934bde8..52ef405316 100644 --- a/common/config/root.go +++ b/common/config/root.go @@ -149,7 +149,7 @@ func getBasicConfig(memoryLimiterConfig GenericMap) (*Config, []string) { "protocols": GenericMap{ "grpc": GenericMap{ // setting it to a large value to avoid dropping batches. - "max_recv_msg_size_mib": 128 * 1024 * 1024, + "max_recv_msg_size_mib": 128, "endpoint": "0.0.0.0:4317", }, // Node collectors send in gRPC, so this is probably not needed diff --git a/common/config/testdata/debugexporter.yaml b/common/config/testdata/debugexporter.yaml index 7d0bf7fa29..7683ce921c 100644 --- a/common/config/testdata/debugexporter.yaml +++ b/common/config/testdata/debugexporter.yaml @@ -3,7 +3,7 @@ receivers: protocols: grpc: endpoint: 0.0.0.0:4317 - max_recv_msg_size_mib: 134217728 + max_recv_msg_size_mib: 128 http: endpoint: 0.0.0.0:4318 exporters: diff --git a/common/config/testdata/minimal.yaml b/common/config/testdata/minimal.yaml index d7fc3af8ab..c96436796f 100644 --- a/common/config/testdata/minimal.yaml +++ b/common/config/testdata/minimal.yaml @@ -3,7 +3,7 @@ receivers: protocols: grpc: endpoint: 0.0.0.0:4317 - max_recv_msg_size_mib: 134217728 + max_recv_msg_size_mib: 128 http: endpoint: 0.0.0.0:4318 exporters: {} diff --git a/instrumentor/controllers/instrumentationconfig/instrumentedapplication_controller.go b/instrumentor/controllers/instrumentationconfig/instrumentedapplication_controller.go index c7f8faf05d..9718e5b5a3 100644 --- a/instrumentor/controllers/instrumentationconfig/instrumentedapplication_controller.go +++ b/instrumentor/controllers/instrumentationconfig/instrumentedapplication_controller.go @@ -20,6 +20,7 @@ import ( "context" odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + "github.com/odigos-io/odigos/k8sutils/pkg/utils" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -55,6 +56,9 @@ func (r *InstrumentedApplicationReconciler) Reconcile(ctx context.Context, req c instrumentationRules := &odigosv1.InstrumentationRuleList{} err = r.Client.List(ctx, instrumentationRules) + if client.IgnoreNotFound(err) != nil { + return ctrl.Result{}, err + } err = updateInstrumentationConfigForWorkload(&ic, &ia, instrumentationRules) if err != nil { @@ -62,12 +66,8 @@ func (r *InstrumentedApplicationReconciler) Reconcile(ctx context.Context, req c } err = r.Client.Update(ctx, &ic) - if client.IgnoreNotFound(err) != nil { - logger.Error(err, "error updating instrumentation config", "workload", ia.Name) - return ctrl.Result{}, err + if err == nil { + logger.V(0).Info("Updated instrumentation config", "workload", ia.Name) } - - logger.V(0).Info("Updated instrumentation config", "workload", ia.Name) - - return ctrl.Result{}, nil + return utils.K8SUpdateErrorHandler(err) } diff --git a/instrumentor/controllers/instrumentationdevice/instrumentedapplication_controller.go b/instrumentor/controllers/instrumentationdevice/instrumentedapplication_controller.go index 66f9dc4eaa..f1bcd2d6d6 100644 --- a/instrumentor/controllers/instrumentationdevice/instrumentedapplication_controller.go +++ b/instrumentor/controllers/instrumentationdevice/instrumentedapplication_controller.go @@ -52,10 +52,10 @@ func (r *InstrumentedApplicationReconciler) Reconcile(ctx context.Context, req c return ctrl.Result{}, err } err = removeInstrumentationDeviceFromWorkload(ctx, r.Client, req.Namespace, workloadKind, workloadName, ApplyInstrumentationDeviceReasonNoRuntimeDetails) - return utils.RetryOnConflict(err) + return utils.K8SUpdateErrorHandler(err) } isNodeCollectorReady := isDataCollectionReady(ctx, r.Client) err = reconcileSingleWorkload(ctx, r.Client, &runtimeDetails, isNodeCollectorReady) - return utils.RetryOnConflict(err) + return utils.K8SUpdateErrorHandler(err) } diff --git a/instrumentor/controllers/instrumentationdevice/workload_controllers.go b/instrumentor/controllers/instrumentationdevice/workload_controllers.go index f4c7769f14..faab085040 100644 --- a/instrumentor/controllers/instrumentationdevice/workload_controllers.go +++ b/instrumentor/controllers/instrumentationdevice/workload_controllers.go @@ -19,7 +19,7 @@ type DeploymentReconciler struct { func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { instrumentedAppName := workload.CalculateWorkloadRuntimeObjectName(req.Name, workload.WorkloadKindDeployment) err := reconcileSingleInstrumentedApplicationByName(ctx, r.Client, instrumentedAppName, req.Namespace) - return utils.RetryOnConflict(err) + return utils.K8SUpdateErrorHandler(err) } type DaemonSetReconciler struct { @@ -29,7 +29,7 @@ type DaemonSetReconciler struct { func (r *DaemonSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { instrumentedAppName := workload.CalculateWorkloadRuntimeObjectName(req.Name, workload.WorkloadKindDaemonSet) err := reconcileSingleInstrumentedApplicationByName(ctx, r.Client, instrumentedAppName, req.Namespace) - return utils.RetryOnConflict(err) + return utils.K8SUpdateErrorHandler(err) } type StatefulSetReconciler struct { @@ -39,7 +39,7 @@ type StatefulSetReconciler struct { func (r *StatefulSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { instrumentedAppName := workload.CalculateWorkloadRuntimeObjectName(req.Name, workload.WorkloadKindStatefulSet) err := reconcileSingleInstrumentedApplicationByName(ctx, r.Client, instrumentedAppName, req.Namespace) - return utils.RetryOnConflict(err) + return utils.K8SUpdateErrorHandler(err) } func reconcileSingleInstrumentedApplicationByName(ctx context.Context, k8sClient client.Client, instrumentedAppName string, namespace string) error { diff --git a/k8sutils/pkg/utils/retryonconflict.go b/k8sutils/pkg/utils/retryonconflict.go index 57a540b0c2..71833658fa 100644 --- a/k8sutils/pkg/utils/retryonconflict.go +++ b/k8sutils/pkg/utils/retryonconflict.go @@ -5,12 +5,21 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func RetryOnConflict(err error) (reconcile.Result, error) { +// K8SUpdateErrorHandler is a helper function to handle k8s update errors. +// It returns a reconcile.Result and an error +// If the error is a conflict error, it returns a requeue result without an error +// If the error is a not found error, it returns an empty result without an error +// For other errors, it returns the error as is - which will cause a requeue +func K8SUpdateErrorHandler(err error) (reconcile.Result, error) { if errors.IsConflict(err) { // For conflict errors, requeue without returning an error. // this is so that we don't have errors and stack traces in the logs for valid scenario return reconcile.Result{Requeue: true}, nil } + if errors.IsNotFound(err) { + // For not found errors, ignore + return reconcile.Result{}, nil + } // For other errors, return as is (will log the stack trace) return reconcile.Result{}, err } diff --git a/odiglet/Dockerfile b/odiglet/Dockerfile index 742e341065..cec9f8eadf 100644 --- a/odiglet/Dockerfile +++ b/odiglet/Dockerfile @@ -74,7 +74,7 @@ RUN ARCH_SUFFIX=$(cat /tmp/arch_suffix) && \ unzip opentelemetry-dotnet-instrumentation-linux-glibc-${ARCH_SUFFIX}.zip && \ rm opentelemetry-dotnet-instrumentation-linux-glibc-${ARCH_SUFFIX}.zip -FROM --platform=$BUILDPLATFORM keyval/odiglet-base:v1.5 AS builder +FROM --platform=$BUILDPLATFORM keyval/odiglet-base:v1.7 AS builder WORKDIR /go/src/github.com/odigos-io/odigos # Copy local modules required by the build COPY api/ api/ diff --git a/odiglet/base.Dockerfile b/odiglet/base.Dockerfile index 6327bb0c0b..d3c3b1b57d 100644 --- a/odiglet/base.Dockerfile +++ b/odiglet/base.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22.5-bookworm AS builder +FROM golang:1.23.3-bookworm AS builder # fury is our registry for linux packages RUN echo "deb [trusted=yes] https://apt.fury.io/cli/ * *" > /etc/apt/sources.list.d/fury-cli.list diff --git a/odiglet/go.mod b/odiglet/go.mod index 70b10aa8d0..108516fc81 100644 --- a/odiglet/go.mod +++ b/odiglet/go.mod @@ -16,9 +16,9 @@ require ( github.com/odigos-io/opentelemetry-zap-bridge v0.0.5 github.com/odigos-io/runtime-detector v0.0.2 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/auto v0.15.0-alpha - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 + go.opentelemetry.io/auto v0.17.0-alpha + go.opentelemetry.io/otel v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 go.uber.org/zap v1.27.0 google.golang.org/grpc v1.67.1 k8s.io/api v0.31.0 @@ -57,7 +57,7 @@ require ( github.com/imdario/mergo v0.3.6 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect @@ -66,46 +66,46 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.20.3 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/collector/pdata v1.16.0 // indirect - go.opentelemetry.io/contrib/bridges/prometheus v0.55.0 // indirect - go.opentelemetry.io/contrib/exporters/autoexport v0.55.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.6.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.6.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.52.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect - go.opentelemetry.io/otel/log v0.6.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.6.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect + go.opentelemetry.io/collector/pdata v1.18.0 // indirect + go.opentelemetry.io/contrib/bridges/prometheus v0.56.0 // indirect + go.opentelemetry.io/contrib/exporters/autoexport v0.56.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.53.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.7.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 // indirect + go.opentelemetry.io/otel/log v0.7.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.7.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.10.0 // indirect + golang.org/x/arch v0.11.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/odiglet/go.sum b/odiglet/go.sum index 5eb1074fb0..ca1c8e2e79 100644 --- a/odiglet/go.sum +++ b/odiglet/go.sum @@ -203,8 +203,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -284,8 +284,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= -github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -294,16 +294,16 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -333,50 +333,50 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/auto v0.15.0-alpha h1:pcjf4zeg3JzX2QGkRAoxsJRU+P/JwqbJS6AjseBRaR0= -go.opentelemetry.io/auto v0.15.0-alpha/go.mod h1:O70Ej16UUexLvKg+3j3m1UwkFiv1MTU2JwgvlzpdXYM= -go.opentelemetry.io/collector/pdata v1.16.0 h1:g02K8jlRnmQ7TQDuXpdgVL6vIxIVqr5Gbb1qIR27rto= -go.opentelemetry.io/collector/pdata v1.16.0/go.mod h1:YZZJIt2ehxosYf/Y1pbvexjNWsIGNNrzzlCTO9jC1F4= -go.opentelemetry.io/contrib/bridges/prometheus v0.55.0 h1:1oZYcP3wuazG3O1563m8cs5vc/pBMTymRwgG9yvxMm8= -go.opentelemetry.io/contrib/bridges/prometheus v0.55.0/go.mod h1:sU48aWFqiqBXo2RBtq7KarczkW8uK6RdIU54y4VzpZs= -go.opentelemetry.io/contrib/exporters/autoexport v0.55.0 h1:8kNP8SX9id5TY2feLB+79aFxE0kqzh3KvjF1nAfGxVM= -go.opentelemetry.io/contrib/exporters/autoexport v0.55.0/go.mod h1:WhcvzeuTOr58aYsJ7S4ubY1xMs0WXAPaqTQnxr8bRHk= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.6.0 h1:WYsDPt0fM4KZaMhLvY+x6TVXd85P/KNl3Ez3t+0+kGs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.6.0/go.mod h1:vfY4arMmvljeXPNJOE0idEwuoPMjAPCWmBMmj6R5Ksw= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.6.0 h1:QSKmLBzbFULSyHzOdO9JsN9lpE4zkrz1byYGmJecdVE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.6.0/go.mod h1:sTQ/NH8Yrirf0sJ5rWqVu+oT82i4zL9FaF6rWcqnptM= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:WypxHH02KX2poqqbaadmkMYalGyy/vil4HE4PM4nRJc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ= -go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0 h1:bZHOb8k/CwwSt0DgvgaoOhBXWNdWqFWaIsGTtg1H3KE= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0/go.mod h1:XlV163j81kDdIt5b5BXCjdqVfqJFy/LJrHA697SorvQ= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0 h1:IyFlqNsi8VT/nwYlLJfdM0y1gavxGpEvnf6FtVfZ6X4= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0/go.mod h1:bxiX8eUeKoAEQmbq/ecUT8UqZwCjZW52yJrXJUSozsk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 h1:kn1BudCgwtE7PxLqcZkErpD8GKqLZ6BSzeW9QihQJeM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0/go.mod h1:ljkUDtAMdleoi9tIG1R6dJUpVwDcYjw3J2Q6Q/SuiC0= -go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= -go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/log v0.6.0 h1:4J8BwXY4EeDE9Mowg+CyhWVBhTSLXVXodiXxS/+PGqI= -go.opentelemetry.io/otel/sdk/log v0.6.0/go.mod h1:L1DN8RMAduKkrwRAFDEX3E3TLOq46+XMGSbUfHU/+vE= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/auto v0.17.0-alpha h1:ppkt9JDK1nU9G2fERU9NbmQcm4tNzif8LC+8IteqBiI= +go.opentelemetry.io/auto v0.17.0-alpha/go.mod h1:x5tU1bUgUYMlfqfd7lWj9ZH7DbWG0opxfrejWmEAObY= +go.opentelemetry.io/collector/pdata v1.18.0 h1:/yg2rO2dxqDM2p6GutsMCxXN6sKlXwyIz/ZYyUPONBg= +go.opentelemetry.io/collector/pdata v1.18.0/go.mod h1:Ox1YVLe87cZDB/TL30i4SUz1cA5s6AM6SpFMfY61ICs= +go.opentelemetry.io/contrib/bridges/prometheus v0.56.0 h1:ax2MzrA26l3LTS2NRnagkbeKDrW4SM8VcAubasnpYqs= +go.opentelemetry.io/contrib/bridges/prometheus v0.56.0/go.mod h1:+aiuB6jaKqSb5xaY7sOpGZEMIgjL0sxXfIW1PQmp5d0= +go.opentelemetry.io/contrib/exporters/autoexport v0.56.0 h1:2k73WaZ+jHYcK3lLAC3CJ8viT/LqkIcDDUWpbbYbZK0= +go.opentelemetry.io/contrib/exporters/autoexport v0.56.0/go.mod h1:RAHAFqVEQ+iKEAPgm6z+Gnsi0Fd5MDuqnD5T3Ms6Kg4= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.7.0 h1:iNba3cIZTDPB2+IAbVY/3TUN+pCCLrNYo2GaGtsKBak= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.7.0/go.mod h1:l5BDPiZ9FbeejzWTAX6BowMzQOM/GeaUQ6lr3sOcSkc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.7.0 h1:mMOmtYie9Fx6TSVzw4W+NTpvoaS1JWWga37oI1a/4qQ= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.7.0/go.mod h1:yy7nDsMMBUkD+jeekJ36ur5f3jJIrmCwUrY67VFhNpA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 h1:FZ6ei8GFW7kyPYdxJaV2rgI6M+4tvZzhYsQ2wgyVC08= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0/go.mod h1:MdEu/mC6j3D+tTEfvI15b5Ci2Fn7NneJ71YMoiS3tpI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 h1:ZsXq73BERAiNuuFXYqP4MR5hBrjXfMGSO+Cx7qoOZiM= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0/go.mod h1:hg1zaDMpyZJuUzjFxFsRYBoccE86tM9Uf4IqNMUxvrY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/exporters/prometheus v0.53.0 h1:QXobPHrwiGLM4ufrY3EOmDPJpo2P90UuFau4CDPJA/I= +go.opentelemetry.io/otel/exporters/prometheus v0.53.0/go.mod h1:WOAXGr3D00CfzmFxtTV1eR0GpoHuPEu+HJT8UWW2SIU= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.7.0 h1:TwmL3O3fRR80m8EshBrd8YydEZMcUCsZXzOUlnFohwM= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.7.0/go.mod h1:tH98dDv5KPmPThswbXA0fr0Lwfs+OhK8HgaCo7PjRrk= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.31.0 h1:HZgBIps9wH0RDrwjrmNa3DVbNRW60HEhdzqZFyAp3fI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.31.0/go.mod h1:RDRhvt6TDG0eIXmonAx5bd9IcwpqCkziwkOClzWKwAQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6BmckTU+9Rxn04m2bD3gD6Mk0OIOCPk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0/go.mod h1:fcwWuDuaObkkChiDlhEpSq9+X1C0omv+s5mBtToAQ64= +go.opentelemetry.io/otel/log v0.7.0 h1:d1abJc0b1QQZADKvfe9JqqrfmPYQCz2tUSO+0XZmuV4= +go.opentelemetry.io/otel/log v0.7.0/go.mod h1:2jf2z7uVfnzDNknKTO9G+ahcOAyWcp1fJmk/wJjULRo= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/log v0.7.0 h1:dXkeI2S0MLc5g0/AwxTZv6EUEjctiH8aG14Am56NTmQ= +go.opentelemetry.io/otel/sdk/log v0.7.0/go.mod h1:oIRXpW+WD6M8BuGj5rtS0aRu/86cbDV/dAfNaZBIjYM= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -388,8 +388,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8= -golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= +golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -397,8 +397,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -442,14 +442,14 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -486,16 +486,16 @@ golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -555,10 +555,10 @@ google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBr google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -579,8 +579,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/odiglet/pkg/ebpf/sdks/go.go b/odiglet/pkg/ebpf/sdks/go.go index 57988e414a..d0338a2d03 100644 --- a/odiglet/pkg/ebpf/sdks/go.go +++ b/odiglet/pkg/ebpf/sdks/go.go @@ -117,5 +117,8 @@ func convertToGoInstrumentationConfig(instConfig *odigosv1.InstrumentationConfig // TODO: sampling config } + + // TODO: take sampling config from the CR + ic.Sampler = auto.DefaultSampler() return ic } diff --git a/scheduler/controllers/clustercollectorsgroup/common.go b/scheduler/controllers/clustercollectorsgroup/common.go new file mode 100644 index 0000000000..a88c0424b6 --- /dev/null +++ b/scheduler/controllers/clustercollectorsgroup/common.go @@ -0,0 +1,59 @@ +package clustercollectorsgroup + +import ( + "context" + + odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + "github.com/odigos-io/odigos/k8sutils/pkg/consts" + "github.com/odigos-io/odigos/k8sutils/pkg/env" + "github.com/odigos-io/odigos/k8sutils/pkg/utils" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func newClusterCollectorGroup(namespace string, memorySettings *odigosv1.CollectorsGroupMemorySettings) *odigosv1.CollectorsGroup { + return &odigosv1.CollectorsGroup{ + TypeMeta: metav1.TypeMeta{ + Kind: "CollectorsGroup", + APIVersion: "odigos.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: consts.OdigosClusterCollectorCollectorGroupName, + Namespace: namespace, + }, + Spec: odigosv1.CollectorsGroupSpec{ + Role: odigosv1.CollectorsGroupRoleClusterGateway, + CollectorOwnMetricsPort: consts.OdigosClusterCollectorOwnTelemetryPortDefault, + MemorySettings: *memorySettings, + }, + } +} + +func sync(ctx context.Context, c client.Client) error { + + namespace := env.GetCurrentNamespace() + + var dests odigosv1.DestinationList + err := c.List(ctx, &dests, client.InNamespace(namespace)) + if err != nil { + return err + } + + odigosConfig, err := utils.GetCurrentOdigosConfig(ctx, c) + if err != nil { + return err + } + + memorySettings := getMemorySettings(&odigosConfig) + + if len(dests.Items) > 0 { + err := utils.ApplyCollectorGroup(ctx, c, newClusterCollectorGroup(namespace, memorySettings)) + if err != nil { + return err + } + } + // once the gateway is created, it is not deleted, even if there are no destinations. + // we might want to re-consider this behavior. + + return nil +} diff --git a/scheduler/controllers/clustercollectorsgroup/destinations_controller.go b/scheduler/controllers/clustercollectorsgroup/destinations_controller.go new file mode 100644 index 0000000000..7ee964a75e --- /dev/null +++ b/scheduler/controllers/clustercollectorsgroup/destinations_controller.go @@ -0,0 +1,19 @@ +package clustercollectorsgroup + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type clusterCollectorsGroupController struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *clusterCollectorsGroupController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { + err := sync(ctx, r.Client) + return ctrl.Result{}, err +} diff --git a/scheduler/controllers/clustercollectorsgroup/manager.go b/scheduler/controllers/clustercollectorsgroup/manager.go new file mode 100644 index 0000000000..a0d398ff0a --- /dev/null +++ b/scheduler/controllers/clustercollectorsgroup/manager.go @@ -0,0 +1,37 @@ +package clustercollectorsgroup + +import ( + odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + odigospredicates "github.com/odigos-io/odigos/k8sutils/pkg/predicate" + corev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" +) + +func SetupWithManager(mgr ctrl.Manager) error { + + err := ctrl.NewControllerManagedBy(mgr). + For(&odigosv1.Destination{}). + Named("clustercollectorgroup-destinations"). + WithEventFilter(&odigospredicates.ExistencePredicate{}). + Complete(&clusterCollectorsGroupController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }) + if err != nil { + return err + } + + err = ctrl.NewControllerManagedBy(mgr). + For(&corev1.ConfigMap{}). + Named("clustercollectorgroup-odigosconfig"). + WithEventFilter(&odigospredicates.OdigosConfigMapPredicate). + Complete(&odigosConfigController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }) + if err != nil { + return err + } + + return nil +} diff --git a/autoscaler/controllers/gateway/memory.go b/scheduler/controllers/clustercollectorsgroup/memory.go similarity index 61% rename from autoscaler/controllers/gateway/memory.go rename to scheduler/controllers/clustercollectorsgroup/memory.go index 14f14232f0..7a8244a1a2 100644 --- a/autoscaler/controllers/gateway/memory.go +++ b/scheduler/controllers/clustercollectorsgroup/memory.go @@ -1,6 +1,7 @@ -package gateway +package clustercollectorsgroup import ( + odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" "github.com/odigos-io/odigos/common" ) @@ -18,21 +19,24 @@ const ( // the percentage out of the memory limiter hard limit, at which go runtime will start garbage collection. // it is used to calculate the GOMEMLIMIT environment variable value. defaultGoMemLimitPercentage = 80.0 -) -type memoryConfigurations struct { - memoryRequestMiB int - memoryLimiterLimitMiB int - memoryLimiterSpikeLimitMiB int - gomemlimitMiB int -} + // the memory settings should prevent the collector from exceeding the memory request. + // however, the mechanism is heuristic and does not guarantee to prevent OOMs. + // allowing the memory limit to be slightly above the memory request can help in reducing the chances of OOMs in edge cases. + // instead of having the process killed, it can use extra memory available on the node without allocating it preemptively. + memoryLimitAboveRequestFactor = 1.25 +) -func getMemoryConfigurations(odigosConfig *common.OdigosConfiguration) *memoryConfigurations { +// process the memory settings from odigos config and return the memory settings for the collectors group. +// apply any defaulting and calculations here. +func getMemorySettings(odigosConfig *common.OdigosConfiguration) *odigosv1.CollectorsGroupMemorySettings { memoryRequestMiB := defaultRequestMemoryMiB if odigosConfig.CollectorGateway != nil && odigosConfig.CollectorGateway.RequestMemoryMiB > 0 { memoryRequestMiB = odigosConfig.CollectorGateway.RequestMemoryMiB } + memoryLimitMiB := int(float64(memoryRequestMiB) * memoryLimitAboveRequestFactor) + // the memory limiter hard limit is set as 50 MiB less than the memory request memoryLimiterLimitMiB := memoryRequestMiB - defaultMemoryLimiterLimitDiffMib if odigosConfig.CollectorGateway != nil && odigosConfig.CollectorGateway.MemoryLimiterLimitMiB > 0 { @@ -49,10 +53,11 @@ func getMemoryConfigurations(odigosConfig *common.OdigosConfiguration) *memoryCo gomemlimitMiB = odigosConfig.CollectorGateway.GoMemLimitMib } - return &memoryConfigurations{ - memoryRequestMiB: memoryRequestMiB, - memoryLimiterLimitMiB: memoryLimiterLimitMiB, - memoryLimiterSpikeLimitMiB: memoryLimiterSpikeLimitMiB, - gomemlimitMiB: gomemlimitMiB, + return &odigosv1.CollectorsGroupMemorySettings{ + MemoryRequestMiB: memoryRequestMiB, + MemoryLimitMiB: memoryLimitMiB, + MemoryLimiterLimitMiB: memoryLimiterLimitMiB, + MemoryLimiterSpikeLimitMiB: memoryLimiterSpikeLimitMiB, + GomemlimitMiB: gomemlimitMiB, } } diff --git a/scheduler/controllers/clustercollectorsgroup/odigosconfig_controller.go b/scheduler/controllers/clustercollectorsgroup/odigosconfig_controller.go new file mode 100644 index 0000000000..2fe8de2d35 --- /dev/null +++ b/scheduler/controllers/clustercollectorsgroup/odigosconfig_controller.go @@ -0,0 +1,19 @@ +package clustercollectorsgroup + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type odigosConfigController struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *odigosConfigController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { + err := sync(ctx, r.Client) + return ctrl.Result{}, err +} diff --git a/scheduler/controllers/collectorgroups/cluster.go b/scheduler/controllers/collectorgroups/cluster.go deleted file mode 100644 index f9e9dfe633..0000000000 --- a/scheduler/controllers/collectorgroups/cluster.go +++ /dev/null @@ -1,24 +0,0 @@ -package collectorgroups - -import ( - odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" - "github.com/odigos-io/odigos/k8sutils/pkg/consts" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func NewClusterCollectorGroup(namespace string) *odigosv1.CollectorsGroup { - return &odigosv1.CollectorsGroup{ - TypeMeta: metav1.TypeMeta{ - Kind: "CollectorsGroup", - APIVersion: "odigos.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: consts.OdigosClusterCollectorCollectorGroupName, - Namespace: namespace, - }, - Spec: odigosv1.CollectorsGroupSpec{ - Role: odigosv1.CollectorsGroupRoleClusterGateway, - CollectorOwnMetricsPort: consts.OdigosClusterCollectorOwnTelemetryPortDefault, - }, - } -} diff --git a/scheduler/controllers/collectorgroups/datacollection.go b/scheduler/controllers/collectorgroups/datacollection.go deleted file mode 100644 index 3d3631d84d..0000000000 --- a/scheduler/controllers/collectorgroups/datacollection.go +++ /dev/null @@ -1,36 +0,0 @@ -package collectorgroups - -import ( - odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" - "github.com/odigos-io/odigos/common" - "github.com/odigos-io/odigos/k8sutils/pkg/consts" - "github.com/odigos-io/odigos/k8sutils/pkg/env" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func NewNodeCollectorGroup(odigosConfig common.OdigosConfiguration) *odigosv1.CollectorsGroup { - - ownMetricsPort := consts.OdigosNodeCollectorOwnTelemetryPortDefault - if odigosConfig.CollectorNode != nil && odigosConfig.CollectorNode.CollectorOwnMetricsPort != 0 { - ownMetricsPort = odigosConfig.CollectorNode.CollectorOwnMetricsPort - } - - return &odigosv1.CollectorsGroup{ - TypeMeta: metav1.TypeMeta{ - Kind: "CollectorsGroup", - APIVersion: "odigos.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: consts.OdigosNodeCollectorDaemonSetName, - Namespace: env.GetCurrentNamespace(), - }, - Spec: odigosv1.CollectorsGroupSpec{ - Role: odigosv1.CollectorsGroupRoleNodeCollector, - CollectorOwnMetricsPort: ownMetricsPort, - }, - } -} - -func ShouldHaveNodeCollectorGroup(gatewayReady bool, numberofInstrumentedApps int) bool { - return gatewayReady && numberofInstrumentedApps > 0 -} diff --git a/scheduler/controllers/destination_controller.go b/scheduler/controllers/destination_controller.go deleted file mode 100644 index 12fe20829d..0000000000 --- a/scheduler/controllers/destination_controller.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controllers - -import ( - "context" - - "github.com/odigos-io/odigos/k8sutils/pkg/utils" - - odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" - odigospredicates "github.com/odigos-io/odigos/k8sutils/pkg/predicate" - "github.com/odigos-io/odigos/scheduler/controllers/collectorgroups" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -type DestinationReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -func (r *DestinationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := log.FromContext(ctx) - - var dests odigosv1.DestinationList - err := r.List(ctx, &dests, client.InNamespace(req.Namespace)) - if err != nil { - logger.Error(err, "failed to list destinations") - return ctrl.Result{}, err - } - - if len(dests.Items) > 0 { - logger.V(0).Info("destinations found, syncing cluster collector group") - err := utils.ApplyCollectorGroup(ctx, r.Client, collectorgroups.NewClusterCollectorGroup(req.Namespace)) - if err != nil { - logger.Error(err, "failed to sync cluster collector group") - return ctrl.Result{}, err - } - } - // once the gateway is created, it is not deleted, even if there are no destinations. - // we might want to re-consider this behavior. - - return ctrl.Result{}, nil -} - -func (r *DestinationReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&odigosv1.Destination{}). - WithEventFilter(&odigospredicates.ExistencePredicate{}). // only care when destinations are created or deleted - Complete(r) -} diff --git a/scheduler/controllers/nodecollector_controller.go b/scheduler/controllers/nodecollector_controller.go deleted file mode 100644 index 1fbc5a0c1c..0000000000 --- a/scheduler/controllers/nodecollector_controller.go +++ /dev/null @@ -1,106 +0,0 @@ -package controllers - -import ( - "context" - - odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" - k8sutilsconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" - "github.com/odigos-io/odigos/k8sutils/pkg/env" - odigospredicates "github.com/odigos-io/odigos/k8sutils/pkg/predicate" - "github.com/odigos-io/odigos/k8sutils/pkg/utils" - nodeCollectorGroupUtil "github.com/odigos-io/odigos/scheduler/controllers/collectorgroups" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -type NodeCollectorsGroupReconciler struct { - client.Client - Scheme *runtime.Scheme - ImagePullSecrets []string - OdigosVersion string -} - -func (r *NodeCollectorsGroupReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { - logger := log.FromContext(ctx) - - namespace := env.GetCurrentNamespace() - - var instrumentedConfigs odigosv1.InstrumentationConfigList - err := r.List(ctx, &instrumentedConfigs) - if err != nil { - logger.Error(err, "failed to list InstrumentationConfigs") - return ctrl.Result{}, err - } - numberOfInstrumentedApps := len(instrumentedConfigs.Items) - - if numberOfInstrumentedApps == 0 { - if err = utils.DeleteCollectorGroup(ctx, r.Client, namespace, k8sutilsconsts.OdigosNodeCollectorCollectorGroupName); err != nil { - return ctrl.Result{}, err - } - } - - clusterCollectorGroup, err := utils.GetCollectorGroup(ctx, r.Client, namespace, k8sutilsconsts.OdigosClusterCollectorCollectorGroupName) - if err != nil { - if errors.IsNotFound(err) { - logger.V(3).Info("collector group doesn't exist", "collectorGroupName", clusterCollectorGroup) - return ctrl.Result{}, nil - } - logger.Error(err, "failed to get collector group", "collectorGroupName", k8sutilsconsts.OdigosClusterCollectorCollectorGroupName) - return ctrl.Result{}, err - } - - odigosConfig, err := utils.GetCurrentOdigosConfig(ctx, r.Client) - if err != nil { - logger.Error(err, "failed to get odigos config") - return ctrl.Result{}, err - } - - if nodeCollectorGroupUtil.ShouldHaveNodeCollectorGroup(clusterCollectorGroup.Status.Ready, numberOfInstrumentedApps) { - err = utils.ApplyCollectorGroup(ctx, r.Client, nodeCollectorGroupUtil.NewNodeCollectorGroup(odigosConfig)) - if err != nil { - logger.Error(err, "failed to create data collection collector group") - return ctrl.Result{}, err - } - } - - return ctrl.Result{}, nil -} - -func (r *NodeCollectorsGroupReconciler) SetupWithManager(mgr ctrl.Manager) error { - - // here we enumerate the inputs events that the controller when data collection collector group should be updated - - err := ctrl.NewControllerManagedBy(mgr). - For(&odigosv1.InstrumentationConfig{}). - Named("nodecollectorgroup-instrumentationconfig"). - WithEventFilter(&odigospredicates.ExistencePredicate{}). - Complete(r) - if err != nil { - return err - } - - err = ctrl.NewControllerManagedBy(mgr). - For(&corev1.ConfigMap{}). - Named("nodecollectorgroup-odigosconfig"). - WithEventFilter(&odigospredicates.OdigosConfigMapPredicate). - Complete(r) - if err != nil { - return err - } - - err = ctrl.NewControllerManagedBy(mgr). - For(&odigosv1.CollectorsGroup{}). - Named("nodecollectorgroup-collectorsgroup"). - WithEventFilter(predicate.And(&odigospredicates.OdigosCollectorsGroupClusterPredicate, &odigospredicates.CgBecomesReadyPredicate{})). - Complete(r) - if err != nil { - return err - } - - return nil -} diff --git a/scheduler/controllers/nodecollectorsgroup/clustercollectorsgroup_controller.go b/scheduler/controllers/nodecollectorsgroup/clustercollectorsgroup_controller.go new file mode 100644 index 0000000000..f607154d0a --- /dev/null +++ b/scheduler/controllers/nodecollectorsgroup/clustercollectorsgroup_controller.go @@ -0,0 +1,19 @@ +package nodecollectorsgroup + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type clusterCollectorsGroupController struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *clusterCollectorsGroupController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { + err := sync(ctx, r.Client) + return ctrl.Result{}, err +} diff --git a/scheduler/controllers/nodecollectorsgroup/common.go b/scheduler/controllers/nodecollectorsgroup/common.go new file mode 100644 index 0000000000..2e739a5e7e --- /dev/null +++ b/scheduler/controllers/nodecollectorsgroup/common.go @@ -0,0 +1,72 @@ +package nodecollectorsgroup + +import ( + "context" + "errors" + + odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + "github.com/odigos-io/odigos/common" + "github.com/odigos-io/odigos/k8sutils/pkg/consts" + k8sutilsconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" + "github.com/odigos-io/odigos/k8sutils/pkg/env" + "github.com/odigos-io/odigos/k8sutils/pkg/utils" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func newNodeCollectorGroup(odigosConfig common.OdigosConfiguration) *odigosv1.CollectorsGroup { + + ownMetricsPort := consts.OdigosNodeCollectorOwnTelemetryPortDefault + if odigosConfig.CollectorNode != nil && odigosConfig.CollectorNode.CollectorOwnMetricsPort != 0 { + ownMetricsPort = odigosConfig.CollectorNode.CollectorOwnMetricsPort + } + + return &odigosv1.CollectorsGroup{ + TypeMeta: metav1.TypeMeta{ + Kind: "CollectorsGroup", + APIVersion: "odigos.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: consts.OdigosNodeCollectorDaemonSetName, + Namespace: env.GetCurrentNamespace(), + }, + Spec: odigosv1.CollectorsGroupSpec{ + Role: odigosv1.CollectorsGroupRoleNodeCollector, + CollectorOwnMetricsPort: ownMetricsPort, + }, + } +} + +func sync(ctx context.Context, c client.Client) error { + + namespace := env.GetCurrentNamespace() + + var instrumentedConfigs odigosv1.InstrumentationConfigList + err := c.List(ctx, &instrumentedConfigs) + if err != nil { + return errors.Join(errors.New("failed to list InstrumentationConfigs"), err) + } + numberOfInstrumentedApps := len(instrumentedConfigs.Items) + + if numberOfInstrumentedApps == 0 { + // TODO: should we delete the collector group if cluster collector is not ready? + return utils.DeleteCollectorGroup(ctx, c, namespace, k8sutilsconsts.OdigosNodeCollectorCollectorGroupName) + } + + clusterCollectorGroup, err := utils.GetCollectorGroup(ctx, c, namespace, k8sutilsconsts.OdigosClusterCollectorCollectorGroupName) + if err != nil { + return client.IgnoreNotFound(err) + } + + odigosConfig, err := utils.GetCurrentOdigosConfig(ctx, c) + if err != nil { + return err + } + + clusterCollectorReady := clusterCollectorGroup.Status.Ready + if clusterCollectorReady { + return utils.ApplyCollectorGroup(ctx, c, newNodeCollectorGroup(odigosConfig)) + } + + return nil +} diff --git a/scheduler/controllers/nodecollectorsgroup/instrumentationconfig_controller.go b/scheduler/controllers/nodecollectorsgroup/instrumentationconfig_controller.go new file mode 100644 index 0000000000..a96d7c8560 --- /dev/null +++ b/scheduler/controllers/nodecollectorsgroup/instrumentationconfig_controller.go @@ -0,0 +1,19 @@ +package nodecollectorsgroup + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type instrumentationConfigController struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *instrumentationConfigController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { + err := sync(ctx, r.Client) + return ctrl.Result{}, err +} diff --git a/scheduler/controllers/nodecollectorsgroup/manager.go b/scheduler/controllers/nodecollectorsgroup/manager.go new file mode 100644 index 0000000000..de9653d312 --- /dev/null +++ b/scheduler/controllers/nodecollectorsgroup/manager.go @@ -0,0 +1,50 @@ +package nodecollectorsgroup + +import ( + odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + odigospredicates "github.com/odigos-io/odigos/k8sutils/pkg/predicate" + corev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +func SetupWithManager(mgr ctrl.Manager) error { + + err := ctrl.NewControllerManagedBy(mgr). + For(&odigosv1.InstrumentationConfig{}). + Named("nodecollectorgroup-instrumentationconfig"). + WithEventFilter(&odigospredicates.ExistencePredicate{}). + Complete(&instrumentationConfigController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }) + if err != nil { + return err + } + + err = ctrl.NewControllerManagedBy(mgr). + For(&corev1.ConfigMap{}). + Named("nodecollectorgroup-odigosconfig"). + WithEventFilter(&odigospredicates.OdigosConfigMapPredicate). + Complete(&odigosConfigController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }) + if err != nil { + return err + } + + err = ctrl.NewControllerManagedBy(mgr). + For(&odigosv1.CollectorsGroup{}). + Named("nodecollectorgroup-clustercollectorsgroup"). + WithEventFilter(predicate.And(&odigospredicates.OdigosCollectorsGroupClusterPredicate, &odigospredicates.CgBecomesReadyPredicate{})). + Complete(&clusterCollectorsGroupController{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }) + if err != nil { + return err + } + + return nil +} diff --git a/scheduler/controllers/nodecollectorsgroup/odigosconfig_controller.go b/scheduler/controllers/nodecollectorsgroup/odigosconfig_controller.go new file mode 100644 index 0000000000..bae2fa571f --- /dev/null +++ b/scheduler/controllers/nodecollectorsgroup/odigosconfig_controller.go @@ -0,0 +1,19 @@ +package nodecollectorsgroup + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type odigosConfigController struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *odigosConfigController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { + err := sync(ctx, r.Client) + return ctrl.Result{}, err +} diff --git a/scheduler/main.go b/scheduler/main.go index 21c1ad2a15..3224ab6428 100644 --- a/scheduler/main.go +++ b/scheduler/main.go @@ -42,7 +42,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" ctrlzap "sigs.k8s.io/controller-runtime/pkg/log/zap" - "github.com/odigos-io/odigos/scheduler/controllers" + "github.com/odigos-io/odigos/scheduler/controllers/clustercollectorsgroup" + "github.com/odigos-io/odigos/scheduler/controllers/nodecollectorsgroup" //+kubebuilder:scaffold:imports ) @@ -104,21 +105,16 @@ func main() { os.Exit(1) } - if err = (&controllers.DestinationReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Destination") + err = clustercollectorsgroup.SetupWithManager(mgr) + if err != nil { + setupLog.Error(err, "unable to create controllers for cluster collectors group") os.Exit(1) } - if err = (&controllers.NodeCollectorsGroupReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "InstrumentationConfig") + err = nodecollectorsgroup.SetupWithManager(mgr) + if err != nil { + setupLog.Error(err, "unable to create controllers for node collectors group") os.Exit(1) } - //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { setupLog.Error(err, "unable to set up health check")