-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Refactoring logging and metrics #835
Conversation
✔️ Deploy Preview for karpenter-docs-prod canceled. 🔨 Explore the source changes: fd52ec2 🔍 Inspect the deploy log: https://app.netlify.com/sites/karpenter-docs-prod/deploys/619d1bddcd68c100070f0042 |
@@ -75,7 +75,7 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reco | |||
func (c *Controller) Register(_ context.Context, m manager.Manager) error { | |||
return controllerruntime. | |||
NewControllerManagedBy(m). | |||
Named(controllerName). | |||
Named(strings.ToLower(controllerName)). |
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.
consider just making the variable lower, rather than lowering it in both places.
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
@@ -59,7 +59,7 @@ type Controller struct { | |||
|
|||
// Reconcile executes a reallocation control loop for the resource | |||
func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { | |||
ctx = logging.WithLogger(ctx, logging.FromContext(ctx).Named("Node")) | |||
ctx = logging.WithLogger(ctx, logging.FromContext(ctx).Named("node").With("node", req.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.
With this change, I think we can change lines like 105 from
fmt.Errorf("patching node %s, %w", node.Name, err)
to
fmt.Errorf("patching node, %w", err)
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.
@@ -74,7 +75,7 @@ type Packing struct { | |||
// It follows the First Fit Decreasing bin packing technique, reference- | |||
// https://en.wikipedia.org/wiki/Bin_packing_problem#First_Fit_Decreasing_(FFD) | |||
func (p *Packer) Pack(ctx context.Context, schedule *scheduling.Schedule, instances []cloudprovider.InstanceType) []*Packing { | |||
defer metrics.Measure(packDuration)() | |||
defer metrics.Measure(packDuration.WithLabelValues(ctx.Value("provisioner").(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.
consider making a helper function to avoid casting inline. Maybe something like:
inject.GetResource(ctx)
injection.WithResource(ctx)
There are some other helpers that you could move into this pattern like
injection.GetRestConfig(ctx)
and injection.GetOptions
Check out the pattern defined by knative in /cmd/webhook/main.go
injection.WithNamespaceScope
.
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 idea. I created one under utility. There are a few similar helper functions under utility already. I learned from that pattern.
f6202b0
to
d0aa1a6
Compare
limitations under the License. | ||
*/ | ||
|
||
package reconcilename |
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.
Can we merge all of these into a single injection package? I really like the knative approach I linked. I think it'll cause this to read really nicely.
injection.WithFoo(ctx, foo)
injection.GetFoo(ctx)
type contextKey string | ||
|
||
func Inject(ctx context.Context, contextkey string, resourcename string) context.Context { | ||
return context.WithValue(ctx, contextKey(contextkey), resourcename) |
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.
Ideally your callers wouldn't need to be aware of the string. The concept of a reconciled object name is general to every controller. There's a bit of a hiccup since some objects can have both names and namespaces, but for us provisioners and nodes are both un-namespaced concepts. I might name it something like
injection.WithResourceKey() // returns "name" or "namespace/name"
We could also go totally crazy and stuff in a pointer to the full object like
injection.WithObject(ctx, provisioner)
injection.GetObject(ctx).GetName()
I'm not sure how I feel about this. It gives every piece of the code access to the resource that's being reconciled, which is kind of nice. It may be a little bit of an abuse of the context mechanism. Happy to discuss.
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 agree injecting the entire object seems to be abusing the mechanism. Injecting the type.NamespacedName will give us a good starting point. As you suggested, now we have a unified injection package that handles options, restconfig and the resource namespaced name. It looks much cleaner this way.
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 injection package will also be the perfect place to implement a generic injection function that allows us to pass multiple labels down the call path (one for each node when there are multiple nodes in the defragmentation reconcile loop). It will be very useful later when we implement the Karpenter health metrics dashboard. In that case, there may be a need to let karpenter manage the injection key. We may pass the injection key through argument dynamically. Let's revisit this later when we come to the implementation details.
87962e9
to
bf5cf90
Compare
cmd/webhook/main.go
Outdated
@@ -20,6 +20,7 @@ import ( | |||
"github.com/awslabs/karpenter/pkg/apis" | |||
"github.com/awslabs/karpenter/pkg/cloudprovider" | |||
"github.com/awslabs/karpenter/pkg/cloudprovider/registry" | |||
karpenterinjection "github.com/awslabs/karpenter/pkg/utils/injection" |
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.
consider injection for karpenter and kinjection or knativeinjection for knative
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/utils/injection/injection.go
Outdated
|
||
type resourceKey struct{} | ||
|
||
func WithResource(ctx context.Context, namespacedname types.NamespacedName) context.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.
consider WithNamespacedName, GetNamespacedName
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
|
||
func GetResource(ctx context.Context) types.NamespacedName { | ||
retval := ctx.Value(resourceKey{}) | ||
if retval == nil { |
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.
Why is this if check necessary compared to e.g. line 45
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 question. In fact there should be a nil check at line 45 as well. Or it will fail if GetOptions is called without calling WithOptions first. May need to beef up nil checking for all the places that call GetOptions.
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.
Nice! Some optional comments
0aa582e
to
fa57c53
Compare
cmd/controller/main.go
Outdated
@@ -67,8 +67,8 @@ func main() { | |||
|
|||
// Set up logger and watch for changes to log level | |||
ctx := LoggingContextOrDie(config, clientSet) | |||
ctx = restconfig.Inject(ctx, config) | |||
ctx = options.Inject(ctx, opts) | |||
ctx = karpenterinjection.WithConfig(ctx, config) |
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 here re: injection, knativeinjection
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
fa57c53
to
fd52ec2
Compare
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.
Nicely done!
1. Issue, if available:
Logging and Metrics improvements #811
Closes #811
2. Description of changes:
3. Does this change impact docs?
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.