-
Notifications
You must be signed in to change notification settings - Fork 701
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
feature: migrate contextual logging #1613
base: master
Are you sure you want to change the base?
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
92cee90
to
6377812
Compare
@a7i @ingvagabund /PTAL |
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.
Wow, what an amazing work you have done. Thanks for taking the time to get this in. I have left a few comments.
pkg/descheduler/leaderelection.go
Outdated
@@ -46,7 +47,7 @@ func NewLeaderElection( | |||
id = hostname + "_" + string(uuid.NewUUID()) | |||
} | |||
|
|||
klog.V(3).Infof("Assigned unique lease holder id: %s", id) | |||
logger.V(3).Info(fmt.Sprintf("Assigned unique lease holder id: %s", id)) |
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.
Wouldn't this be better ?
logger.V(3).Info("Assigned unique lease holder id", "id", id)
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.
done
pkg/descheduler/leaderelection.go
Outdated
}, | ||
OnNewLeader: func(identity string) { | ||
// Just got the lock | ||
if identity == id { | ||
return | ||
} | ||
klog.V(1).Infof("New leader elected: %v", identity) | ||
logger.V(1).Info(fmt.Sprintf("New leader elected: %v", identity)) |
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.
Ditto.
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.
done
@@ -93,11 +93,12 @@ func (mc *MetricsCollector) AllNodesUsage() (map[string]map[v1.ResourceName]*res | |||
} | |||
|
|||
func (mc *MetricsCollector) NodeUsage(node *v1.Node) (map[v1.ResourceName]*resource.Quantity, error) { | |||
logger := klog.FromContext(context.TODO()) |
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 am not entirely sure we should have this TODO()
added to the code. The enhancement proposal mentions that the logger should either come in as part of a Context or as an explicit argument. Any reason for not receiving it as part of an existing Context ?
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.
done
pkg/descheduler/node/node.go
Outdated
return false | ||
}*/ | ||
} | ||
// Ignore nodes that are marked unschedulable | ||
/*if node.Spec.Unschedulable { | ||
klog.V(4).InfoS("Ignoring node since it is unschedulable", "node", klog.KObj(node.Name)) | ||
logger..V(4).Info("Ignoring node since it is unschedulable", "node", klog.KObj(node.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.
This seems to be commented out but there is an extra .
we should get rid 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.
done
pkg/descheduler/pod/pods.go
Outdated
@@ -157,7 +158,7 @@ func ConvertToPods(objs []interface{}, filter FilterFunc) []*v1.Pod { | |||
if !ok { | |||
continue | |||
} | |||
if filter == nil || filter(pod) { | |||
if filter == nil || filter(context.TODO(), pod) { |
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.
Shouldn't GetPodsAssignedToNodeFunc
type also receive a Context as argument ? I mean, now that FilterFunc
also requires one to be passed in ?
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.
done
@@ -57,8 +59,9 @@ func Register( | |||
pluginArgDefaulter PluginArgDefaulter, | |||
registry Registry, | |||
) { | |||
logger := klog.FromContext(context.TODO()) |
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.
Shouldn't this logger
be received through an argument ? Or maybe a Context.
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.
done
@@ -72,13 +72,15 @@ func New(args runtime.Object, handle frameworktypes.Handle) (frameworktypes.Plug | |||
return nil, fmt.Errorf("want args to be of type defaultEvictorFilterArgs, got %T", args) | |||
} | |||
|
|||
logger := klog.FromContext(context.TODO()) |
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.
Ditto. I don't think we should be introducing new TODO()
here. We could pass in the logger or a context.
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.
done
@@ -23,13 +24,14 @@ import ( | |||
|
|||
func ValidateDefaultEvictorArgs(obj runtime.Object) error { | |||
args := obj.(*DefaultEvictorArgs) | |||
logger := klog.FromContext(context.TODO()) |
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.
Ditto.
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.
done
if err := validateCanEvict(pod, failedPodsArgs); err != nil { | ||
klog.V(4).InfoS(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod)) | ||
logger.V(4).Info(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod)) |
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.
Shouldn't we be getting the logger from the Context received as an argument here ? More, if we do that then we can get rid of the line 52 above.
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.
done
if err := validateCanEvict(pod, tooManyRestartsArgs); err != nil { | ||
klog.V(4).InfoS(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod)) | ||
logger.V(4).Info(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod)) |
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.
Same thing here as my previous comment. I think we want to get the logger from the context received as an argument here as well.
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.
done
6377812
to
42303fd
Compare
42303fd
to
73764a5
Compare
2bb3baf
to
627da1c
Compare
627da1c
to
d33c671
Compare
@googs1025 This one looks good to me, most of the changes are really straightforward. We need a review from someone else now (as the number of changes is quite big the more eyes we get here the better). |
/cc @ingvagabund @a7i @seanmalloy |
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.
Should not we be using logger.WithName
at some places at least? This way there's nothing added to the structured logging besides what's already provided through the key/value pairs. Also, not every place is suitable for klog.FromContext
. The high level places (some I commented on) can probably keep the original klog
.
@@ -324,7 +328,7 @@ func Run(ctx context.Context, rs *options.DeschedulerServer) error { | |||
|
|||
// Add k8s compatibility warnings to logs | |||
if err := validateVersionCompatibility(rs.Client.Discovery(), version.Get()); err != nil { | |||
klog.Warning(err.Error()) | |||
logger.Error(err, "validate version 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.
This needs to stay as a warning/info.
@@ -57,7 +58,7 @@ func PodMatchesTermsNamespaceAndSelector(pod *v1.Pod, namespaces sets.Set[string | |||
} | |||
|
|||
// PodMatchNodeSelector checks if a pod node selector matches the node label. | |||
func PodMatchNodeSelector(pod *v1.Pod, node *v1.Node) (bool, error) { | |||
func PodMatchNodeSelector(ctx context.Context, pod *v1.Pod, node *v1.Node) (bool, 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.
ctx
is unused here
@@ -274,7 +277,7 @@ func GetNodeWeightGivenPodPreferredAffinity(pod *v1.Pod, node *v1.Node) (int32, | |||
preferredNodeSelector := &v1.NodeSelector{NodeSelectorTerms: []v1.NodeSelectorTerm{prefSchedulTerm.Preference}} | |||
match, err := corev1.MatchNodeSelectorTerms(node, preferredNodeSelector) | |||
if err != nil { | |||
klog.ErrorS(err, "error parsing node selector", "selector", preferredNodeSelector) | |||
logger.Error(err, "error parsing node selector", "selector", preferredNodeSelector) |
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.
Note: Hups. We forgot to continue
. Normally, match
should always be false
when err != nil
. Yet, noone never really knows :)
if _, ok := registry[name]; ok { | ||
klog.V(10).InfoS("Plugin already registered", "plugin", name) | ||
logger.V(10).Info("Plugin already registered", "plugin", 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.
We can sacrifice the context for keeping klog
here to avoid passing the extra ctx
argument. This is quite how level.
if err != nil { | ||
klog.Error(err, "Failed to get threshold priority from args") | ||
logger.Error(err, "Failed to get threshold priority from args") |
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.
The err
should be handled here too. Returning an error instead of profile
.
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.
For the consistency , I will submit another PR to complete these two things. (error handle) (add continue) ...
mc.mu.RLock() | ||
defer mc.mu.RUnlock() | ||
|
||
if _, exists := mc.nodes[node.Name]; !exists { | ||
klog.V(4).InfoS("unable to find node in the collected metrics", "node", klog.KObj(node)) | ||
logger.V(4).Info("unable to find node in the collected metrics", "node", klog.KObj(node)) |
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 can be kept with klog
as there's no additional value in the context.
Also, passing context into some of the functions like filter makes the wiring quite heavy. There's too many context arguments for the moment. I wonder if there's a way to reduce it. |
return false | ||
} /*else if cond.Type == v1.NodeOutOfDisk && cond.Status != v1.ConditionFalse { | ||
klog.V(4).InfoS("Ignoring node with condition status", "node", klog.KObj(node.Name), "condition", cond.Type, "status", cond.Status) | ||
logger.V(4).Info("Ignoring node with condition status", "node", klog.KObj(node.Name), "condition", cond.Type, "status", cond.Status) |
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.
E.g. how this log line will look different from the current one? The log line already has node
in it. Is there more context that needs to be added here?
@googs1025 this looks like tremendous amount of work you have done here. Thank you for the patience and effort. |
Indeed, when I work on this pr, I also found |
Hint: Context for any filter or similar function within a plugin is the plugin name and the extension point (Deschedule/Balance). Context that can be set by the framework. The pod and node names are "just" data. Before moving with any changes it's worth considering the actual context that each log represents. E.g. there are logs that print an error related to a plugin defaulting, conversions. Should these log a context or should they rather return an error instead that gets logged outside of them? |
Fix: #1608