-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Align Beyla setting Service Name/Namespace/Instance according to OTEL collector #1415
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1415 +/- ##
==========================================
- Coverage 80.97% 80.94% -0.04%
==========================================
Files 146 146
Lines 14843 14902 +59
==========================================
+ Hits 12019 12062 +43
- Misses 2235 2246 +11
- Partials 589 594 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Nice!
pkg/beyla/config_test.go
Outdated
@@ -101,6 +104,9 @@ network: | |||
nc.AgentIP = "1.2.3.4" | |||
nc.CIDRs = cidr.Definitions{"10.244.0.0/16"} | |||
|
|||
metaSources := kube.DefaultMetadataSources | |||
metaSources.ServiceNameLabels = []string{"titi.com/lala"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're the best! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great work, I think it's critical that we confirm the behaviour of the OTEL env variables and perhaps move the code to reflect that bahaviour.
pkg/internal/kube/store.go
Outdated
if s.sourceLabels.ServiceName != "" { | ||
if on, ok := om.Labels[s.sourceLabels.ServiceName]; ok { | ||
name = on | ||
if nameFromMeta := s.valueFromMetadata(om, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this here will override any service names set by the OTEL environment variables. I think this will introduce a difference in how it will be handled by the SDK, because environment variables passed to the process directly will, "I think", override whatever else is set. I think it might be better if we added this override in here:
func (s *Store) serviceNameNamespaceOwnerID(ownerKey, name, namespace string) (string, string) {
serviceName := name
serviceNamespace := namespace
...
}
Right after we set them from whatever k8s found, we can override them based on the labels and annotations and then let the envvar code do its thing.
But we should confirm with the SDKs team if my understanding is correct that the env variables take precedence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I reordered the preferences and modified some unit and integration tests to make sure that the environment variables take precedence over annotations or labels.
I wonder if it would be easier to understand for the user if we add an "operator mode" flag - that hides all the configuration needed? |
pkg/internal/kube/store.go
Outdated
|
||
var DefaultMetadataSources = MetadataSources{ | ||
ServiceNameAnnotations: []string{ | ||
"resource.opentelemetry.io/service.name", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all annotations starting with "resource.opentelemetry.io/" should be supported
if you want a flag (not sure that it's needed) then just "useAnnotationsForResourceAttributes"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this PR currently changes what we already support: service name, namespace and instance ID. Service version and deployment environment will go into another PR, as they are attributes that aren't currently provided by Beyla.
I'd prefer not using the useAnnotationsForResourceAttributes
flag, as it seems a very OTEL-opinionated option and I'd prefer something more flexible to use in other environments and use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, then maybe make it more generic like #1415 (comment)
pkg/internal/kube/store.go
Outdated
type MetadataSources struct { | ||
ServiceNameAnnotations []string `yaml:"service_name_annotations" env:"BEYLA_KUBE_ANNOTATIONS_SERVICE_NAME" envSeparator:","` | ||
ServiceNamespaceAnnotations []string `yaml:"service_namespace_annotations" env:"BEYLA_KUBE_ANNOTATIONS_SERVICE_NAMESPACE" envSeparator:","` | ||
ServiceNameLabels []string `yaml:"service_name_labels" env:"BEYLA_KUBE_LABELS_SERVICE_NAME" envSeparator:","` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
version is missing: https://github.com/open-telemetry/opentelemetry-operator/blob/aa3e781a95def24e52c0dceaf7c33ec5b6193a7e/pkg/constants/env.go#L39
you could make this even more generic:
meta_naming_sources:
labels:
service.name: ["app.kubernetes.io/name"]
service.namespace: ["app.kubernetes.io/part-of"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I like your proposal. Will implement it
); nsFromMeta != "" { | ||
namespace = nsFromMeta | ||
} | ||
return name, namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the fallback values are missing (at least not in this PR) - which are maybe the most important part.
In the operator, those are:
- name: https://github.com/open-telemetry/opentelemetry-operator/blob/84200196ff4e0fc9d8999b31891263f093fe7052/pkg/instrumentation/sdk.go#L408-L434
- version: https://github.com/open-telemetry/opentelemetry-operator/blob/84200196ff4e0fc9d8999b31891263f093fe7052/pkg/instrumentation/sdk.go#L456-L467
- instance.id: https://github.com/open-telemetry/opentelemetry-operator/blob/84200196ff4e0fc9d8999b31891263f093fe7052/pkg/instrumentation/sdk.go#L486-L490
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Beyla, the fallback values are previously set into the name
and namespace
variables, then overridden here if valueFromMetadata
returns a non-empty value. They were already set as required, so that's why they are not in this PR.
That's the reason I was mentioning that moving this code into a shared library could be complex due to the way multiple components could populate/store the same information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand - the important part is to have the same logic - can you point me to the logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On one side, Beyla does not store the metadata from the Pod owners (DaemonSet, Deployment, Job, etc...) so we cannot query the fallbacks one by one.
Instead, Beyla infers the pod owner name from the actual pod name (assuming the kubernetes pod naming conventions). So at the point we execute the above, service.name already contains the value of of one of the fallbacks (which at the end are nothing that the Pod owner name).
Is then that, if the service name/namespace can't be inferred from env/annotations/labels (in that priority), the original value is kept (the fallback).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so it should result in the same outcome - correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. My initial concern was not about the outcome but the code reutilization.
Merging. Any further concern or change request can be handled in a new issue/PR. |
Addresses issue: grafana/k8s-monitoring-helm#942
Aimed at Beyla 2.0, adds the following breaking changes with regards to Beyla 1.9:
BEYLA_KUBE_META_SOURCE_LABEL_SERVICE_NAME
andBEYLA_KUBE_META_SOURCE_LABEL_SERVICE_NAMESPACE
environment variables.attributes > kubernetes > meta_source_labels
YAML config section.BEYLA_KUBE_ANNOTATIONS_SERVICE_NAME
,BEYLA_KUBE_ANNOTATIONS_SERVICE_NAMESPACE
,BEYLA_KUBE_LABELS_SERVICE_NAME
andBEYLA_KUBE_LABELS_SERVICE_NAMESPACE
environent variables. They are now a string list.attributes > kubernetes > meta_naming_sources
YAML config section.kube-pod:container-name
tokube-ns.kube-pod.container-name
.Now the way of composing service name/namespace and instance ID are in parity with the OTEL operator, but the configuration is slightly different.
As the Operator and Beyla do not share any configuration structure, I think this difference is not an inconvenience but has the advantage of supporting labels and annotations that might be valid for other contexts outside of OTEL. If at some point Beyla is integrated with the operator (note por any external reader: there are no plans for that), the operator just need to configure Beyla with the above labels when the CRD
useLabelsForResourceAttributes
field is true.