-
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
Enhance add_kubernetes_metadata matcher #28868
Changes from 1 commit
a648d11
516cb13
dc3553b
ba54a8f
e8ab1fe
ab3c821
82a9f2d
2dfe013
de58076
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -78,59 +78,79 @@ func newLogsPathMatcher(cfg common.Config) (add_kubernetes_metadata.Matcher, err | |||
// Docker container ID is a 64-character-long hexadecimal string | ||||
const containerIdLen = 64 | ||||
|
||||
// Pod UID is on the 5th index of the path directories | ||||
const podUIDPos = 5 | ||||
|
||||
func (f *LogPathMatcher) MetadataIndex(event common.MapStr) string { | ||||
value, err := event.GetValue("log.file.path") | ||||
if err == nil { | ||||
source := value.(string) | ||||
f.logger.Debugf("Incoming log.file.path value: %s", source) | ||||
if err != nil { | ||||
f.logger.Errorf("Error extracting log.file.path from the event") | ||||
return "" | ||||
} | ||||
|
||||
if !strings.Contains(source, f.LogsPath) { | ||||
f.logger.Errorf("Error extracting container id - source value does not contain matcher's logs_path '%s'.", f.LogsPath) | ||||
return "" | ||||
} | ||||
source := value.(string) | ||||
f.logger.Debugf("Incoming log.file.path value: %s", source) | ||||
|
||||
if !strings.Contains(source, f.LogsPath) { | ||||
f.logger.Errorf("Error extracting container id - source value does not contain matcher's logs_path '%s'.", f.LogsPath) | ||||
return "" | ||||
} | ||||
|
||||
sourceLen := len(source) | ||||
logsPathLen := len(f.LogsPath) | ||||
sourceLen := len(source) | ||||
logsPathLen := len(f.LogsPath) | ||||
|
||||
if f.ResourceType == "pod" { | ||||
// Specify a pod resource type when manually mounting log volumes and they end up under "/var/lib/kubelet/pods/" | ||||
// This will extract only the pod UID, which offers less granularity of metadata when compared to the container ID | ||||
if strings.HasPrefix(f.LogsPath, podLogsPath()) && strings.HasSuffix(source, ".log") { | ||||
if f.ResourceType == "pod" { | ||||
// Pod resource type will extract only the pod UID, which offers less granularity of metadata when compared to the container ID | ||||
if strings.HasSuffix(source, ".log") { | ||||
// Specify a pod resource type when writting logs into manually mounted log volume, | ||||
// those logs apper under under "/var/lib/kubelet/pods/<pod_id>/volumes/..." | ||||
if strings.HasPrefix(f.LogsPath, podKubeletLogsPath()) { | ||||
pathDirs := strings.Split(source, pathSeparator) | ||||
podUIDPos := 5 | ||||
if len(pathDirs) > podUIDPos { | ||||
podUID := strings.Split(source, pathSeparator)[podUIDPos] | ||||
|
||||
f.logger.Debugf("Using pod uid: %s", podUID) | ||||
return podUID | ||||
} | ||||
|
||||
f.logger.Error("Error extracting pod uid - source value contains matcher's logs_path, however it is too short to contain a Pod UID.") | ||||
} | ||||
} else { | ||||
// 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, containerLogsPath()) && strings.HasSuffix(source, ".log") && sourceLen >= containerIdLen+4 { | ||||
containerIDEnd := sourceLen - 4 | ||||
cid := source[containerIDEnd-containerIdLen : containerIDEnd] | ||||
f.logger.Debugf("Using container id: %s", cid) | ||||
return cid | ||||
} | ||||
|
||||
// In any other case, we assume the container ID will follow right after the log path. | ||||
// However we need to check the length to prevent "slice bound out of range" runtime errors. | ||||
if sourceLen >= logsPathLen+containerIdLen { | ||||
cid := source[logsPathLen : logsPathLen+containerIdLen] | ||||
f.logger.Debugf("Using container id: %s", cid) | ||||
return cid | ||||
// In case of the Kubernetes log path "/var/log/pods/", | ||||
// the pod ID will be extracted from the directory name, | ||||
// file name example: "/var/log/pods/'<namespace>_<pod_name>_<pod_uid>'/container_name/0.log". | ||||
if strings.HasPrefix(f.LogsPath, podLogsPath()) { | ||||
pathDirs := strings.Split(source, pathSeparator) | ||||
podUIDPos := 4 | ||||
if len(pathDirs) > podUIDPos { | ||||
podUID := strings.Split(pathDirs[podUIDPos], "_") | ||||
if len(podUID) > 2 { | ||||
f.logger.Debugf("Using pod uid: %s", podUID) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe log the podUID[2] here instead of the array There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you for pointing it out! fixed: e8ab1fe |
||||
return podUID[2] | ||||
} | ||||
} | ||||
} | ||||
|
||||
f.logger.Error("Error extracting container id - source value contains matcher's logs_path, however it is too short to contain a Docker container ID.") | ||||
f.logger.Error(`Error extracting pod uid - source value does not contains matcher's logs_path, | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering if we should prevent this from happening by validating the configuration. wdyt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you please elaborate on this? do you mean do smth similar to other processors. like - https://github.com/elastic/beats/blob/master/libbeat/processors/add_kubernetes_metadata/config.go ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, in
matchers ' config is valid too so as to warn the users early on and avoid initialising the processor in case the config is not supported. I see that the matcher's config part is a map so not sure how much mangling this change would require but it should be doable. Let me know what you think.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will give it a try There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
supported log_path for 'pod' resource_type: '/var/lib/kubelet/pods/', '/var/log/pods/'.`) | ||||
return "" | ||||
} | ||||
} | ||||
// In case of the Kubernetes log path "/var/log/containers/", | ||||
// the container ID will be located right before the ".log" extension. | ||||
// file name example: /var/log/containers/<pod_name>_<namespace>_<container_name>-<continer_id>.log | ||||
if strings.HasPrefix(f.LogsPath, containerLogsPath()) && strings.HasSuffix(source, ".log") && sourceLen >= containerIdLen+4 { | ||||
containerIDEnd := sourceLen - 4 | ||||
cid := source[containerIDEnd-containerIdLen : containerIDEnd] | ||||
f.logger.Debugf("Using container id: %s", cid) | ||||
return cid | ||||
} | ||||
|
||||
// In any other case, we assume the container ID will follow right after the log path. | ||||
// However we need to check the length to prevent "slice bound out of range" runtime errors. | ||||
// for the default log path /var/lib/docker/containers/ container ID will follow right after the log path. | ||||
// file name example: /var/lib/docker/containers/<container_id>/<container_id>-json.log | ||||
if sourceLen >= logsPathLen+containerIdLen { | ||||
cid := source[logsPathLen : logsPathLen+containerIdLen] | ||||
f.logger.Debugf("Using container id: %s", cid) | ||||
return cid | ||||
} | ||||
|
||||
f.logger.Error("Error extracting container id - source value contains matcher's logs_path, however it is too short to contain a Docker container ID.") | ||||
return "" | ||||
} | ||||
|
||||
|
@@ -141,13 +161,20 @@ func defaultLogPath() string { | |||
return "/var/lib/docker/containers/" | ||||
} | ||||
|
||||
func podLogsPath() string { | ||||
func podKubeletLogsPath() string { | ||||
if runtime.GOOS == "windows" { | ||||
return "C:\\var\\lib\\kubelet\\pods\\" | ||||
} | ||||
return "/var/lib/kubelet/pods/" | ||||
} | ||||
|
||||
func podLogsPath() string { | ||||
if runtime.GOOS == "windows" { | ||||
return "C:\\var\\log\\pods\\" | ||||
} | ||||
return "/var/log/pods/" | ||||
} | ||||
|
||||
func containerLogsPath() string { | ||||
if runtime.GOOS == "windows" { | ||||
return "C:\\var\\log\\containers\\" | ||||
|
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.
We may still need to log
source
here so as to have a more clear view of how the event that is related to this error looks like.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.
do you mean
event
instead ofsource
? this error might only occur in caseevent
map does not containlog.file.path
(=source
) keyThere 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.
Yeap my wrong,
event
is what I was thinking about. Logging the wholeevent
would be helpful.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.
Also maybe just a debug message would be enough, since ERRORs would flood a basic case when the processor for some reason does not work.
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.
fixed: e8ab1fe