-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add pod-uid support for add_kubernetes_metadata #7072
Add pod-uid support for add_kubernetes_metadata #7072
Conversation
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
func TestPodUidIndexer(t *testing.T) { | ||
var testConfig = common.NewConfig() | ||
|
||
podUidIndexer, err := NewPodUidIndexer(*testConfig, metagen) |
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.
var podUidIndexer should be podUIDIndexer
} | ||
} | ||
|
||
func (p *PodUidIndexer) GetIndexes(pod *kubernetes.Pod) []string { |
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.
exported method PodUidIndexer.GetIndexes should have comment or be unexported
return &PodUidIndexer{metaGen: metaGen}, nil | ||
} | ||
|
||
func (p *PodUidIndexer) GetMetadata(pod *kubernetes.Pod) []MetadataIndex { |
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.
exported method PodUidIndexer.GetMetadata should have comment or be unexported
metaGen kubernetes.MetaGenerator | ||
} | ||
|
||
func NewPodUidIndexer(_ common.Config, metaGen kubernetes.MetaGenerator) (Indexer, error) { |
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.
exported function NewPodUidIndexer should have comment or be unexported
func NewPodUidIndexer should be NewPodUIDIndexer
@@ -128,6 +129,28 @@ func (p *PodNameIndexer) GetIndexes(pod *kubernetes.Pod) []string { | |||
return []string{fmt.Sprintf("%s/%s", pod.Metadata.Namespace, pod.Metadata.Name)} | |||
} | |||
|
|||
type PodUidIndexer struct { |
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.
exported type PodUidIndexer should have comment or be unexported
type PodUidIndexer should be PodUIDIndexer
@@ -67,6 +70,21 @@ func (g *metaGenerator) PodMetadata(pod *Pod) common.MapStr { | |||
return meta | |||
} | |||
|
|||
func (g *metaGenerator) PodMetadataWithUid(pod *Pod) common.MapStr { |
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.
method PodMetadataWithUid should be PodMetadataWithUID
// In case of the Kubernetes log path "/var/log/containers/", | ||
// the container ID will be located right before the ".log" extension. | ||
if strings.HasPrefix(f.LogsPath, "/var/log/containers/") && strings.HasSuffix(source, ".log") && sourceLen >= containerIdLen+4 { | ||
containerIdEnd := sourceLen - 4 |
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.
var containerIdEnd should be containerIDEnd
if strings.HasPrefix(f.LogsPath, "/var/lib/kubelet/pods/") && strings.HasSuffix(source, ".log") { | ||
pathDirs := strings.Split(source, "/") | ||
if len(pathDirs) > podUidPos { | ||
podUid := strings.Split(source, "/")[podUidPos] |
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.
var podUid should be podUID
// Pod UID is a 36-character-long string | ||
const podUidLen = 36 | ||
// Pod UID is on the 5th index of the path directories | ||
const podUidPos = 5 |
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.
const podUidPos should be podUIDPos
} | ||
|
||
// Docker container ID is a 64-character-long hexadecimal string | ||
const containerIdLen = 64 | ||
// Pod UID is a 36-character-long string | ||
const podUidLen = 36 |
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.
const podUidLen should be podUIDLen
I guess that the CI is failing because of the style and formatting. I have tried executing
Probably those cache lines are a hint that it tries to run a different pip version. I am confident that executing Fetched |
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.
Thank you for taking this!!
Overall this is looking good, what do you think about making pod.uid
optional to the metadata generator (also add_kubernetes_metadata
). You will need to add pod.id
mapping to https://github.com/elastic/beats/blob/master/libbeat/processors/add_kubernetes_metadata/_meta/fields.yml
} | ||
|
||
func newLogsPathMatcher(cfg common.Config) (add_kubernetes_metadata.Matcher, error) { | ||
config := struct { | ||
LogsPath string `config:"logs_path"` | ||
ResourceType string `config:"resource_type"` |
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.
this config starts to get complicated, I guess we can live with this how it is now, but I will try to give it a thought on how to simplify this mechanism. Not a blocker for this PR :)
@@ -67,6 +70,21 @@ func (g *metaGenerator) PodMetadata(pod *Pod) common.MapStr { | |||
return meta | |||
} | |||
|
|||
func (g *metaGenerator) PodMetadataWithUID(pod *Pod) common.MapStr { |
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 this should be a setting instead, so pod.uid
is added if requested (both by the user or your indexer
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.
Hey!
Thanks for the feedback. So, just to make sure I am understand correctly, we are talking about adding the pod.uid
from the configuration, anytime that
- The
pod_uid
Indexer is used pod.uid
is specified as a field inside thefields
element?
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 was thinking more about doing something similar to the current include_annotations
setting, for instance. Parameters are passed here: https://github.com/elastic/beats/blob/master/libbeat/common/kubernetes/metadata.go#L24
And the processor allows configuration for them here: https://github.com/elastic/beats/blob/master/libbeat/processors/add_kubernetes_metadata/config.go#L24
The indexer would pass the right parameter (enable pod.uid) without the user asking for it.
What do you think?
About the |
Hi, just refactored the code as discussed and updated the unit-tests (also the autodiscover feature albeit a bit late, apologies). |
You will need to:
|
…the Pod.UID as the key and inside the metadata. Extended Filebeat's LogPathMatcher with an additional configuration parameter (resource_type) which, when set to 'pod', uses a different logic to extract the MetadataIndex from the source field. Updated unit-tests accordingly.
… PodUIDIndexer being specified or by the "include_pod_uid" options in the configuration file. The result is used as a parameter for the metaGenerator which, in turn, adds the pod.uid to the existing metadata structure. Added and updated unit-tests accordingly.
…clude_pod_uid". Formatted code.
aa87349
to
1a0e10e
Compare
@@ -65,7 +66,10 @@ func newKubernetesAnnotator(cfg *common.Config) (processors.Processor, error) { | |||
Indexing.RUnlock() | |||
} | |||
|
|||
metaGen := kubernetes.NewMetaGenerator(config.IncludeAnnotations, config.IncludeLabels, config.ExcludeLabels) | |||
//Checks whether the PodUIDIndexer has been added in order to turn on the pod uid gathering | |||
_, hasPodUIDIndexer := Indexing.indexers["pod_uid"] |
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 it's better if we don't do this automatically, the user must enable it. In any case, the indexer would still work without this, isn't it?
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.
Hmmm the intention here was to enable the gathering of pod.uid
if the indexer was specified in the config, even if the config bool include_pod_uid
was not.
I thought this is what you meant with your previous comment: The indexer would pass the right parameter (enable pod.uid) without the user asking for it.
Or perhaps I am missing something...
EDIT:
Now that I check again, the Indexer would work even without any of the 2 being in the config as the key is not gotten from the metadata. Should I then remove it altogether?
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.
Hi,
Yes, I apologize as that is what I said, then I realized the indexer doesn't need the pod uid in the metadata 😇
Still, I think having pod.uid
is a good feature for some people, so I would keep it as something optional you can enable. I would only remove this auto-enable thingy and we are ready to go.
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.
Awesome!
I'll remove the auto-enable and add the info in the changelog first thing tomorrow.
Thanks man! And no need to apologise 🙂
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.
Thank you for the changes! I added a (hopefully) last thing :)
Please add a new entry to CHANGELOG.asciidoc
jenkins, test this please |
@mariomechoulam Can I use this with emptyDir like this now?
|
Thank you @mariomechoulam for your contribution 🎉 It will go out in |
Awesome! Many thanks @exekias for your support! |
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
Hi @yu-yang2 |
I can confirm it works, both the indexer and adding |
@mariomechoulam You have missing a
|
Nice spot @yu-yang2 ! And many thanks for adding the correct configuration here; I'll update the original post. |
Added PodUidIndexer to add_kubernetes_metadata processor, containing the Pod.UID as the key and inside the metadata. Extended Filebeat's LogPathMatcher with an additional configuration parameter (resource_type) which, when set to 'pod', uses a different logic to extract the MetadataIndex from the source field.
Added PodUidIndexer to add_kubernetes_metadata processor, containing the Pod.UID as the key and inside the metadata. Extended Filebeat's LogPathMatcher with an additional configuration parameter (resource_type) which, when set to 'pod', uses a different logic to extract the MetadataIndex from the source field.
@exekias |
unable to get kubernetes metadata to enrich log using filebeat 6.4.1. #8481 |
Hello everyone!
I am opening this pull request to gather some feedback on the approach.
There are a few things that can be cleaned up and improved for sure, as this is my first try with Go, but the basic should be working.
I was hesitating whether to create a completely new
Matcher
and duplicate a lot of the existing logic or extend the current one. Extending did not feel entirely right, because theLogPathMatcher
was focused on container ID - nevertheless it is still a log_path matcher. Thus this middle-ground approach in which I am adding a new configuration parameter for theMatcher
; it should be seamlessly backwards compatible.I believe this is the configuration that should make it work...
My understanding is that, ideally, an integration test of some sort would be useful - at least to test that the above configuration will indeed produce the desired functionality. Will welcome any guidance :)
Cheers!