-
Notifications
You must be signed in to change notification settings - Fork 38.6k
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 APF's priorityLevel to httplog.go #104359
Conversation
Sample log entry (from presubmit https://storage.googleapis.com/sig-scalability-logs/pull-kubernetes-e2e-gce-100-performance/1426160239798915072/e2e-104359-95a39-master/kube-apiserver.log):
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
|
||
r = r.WithContext(request.WithPriorityAndFairnessClassification(ctx, &classification.PriorityAndFairnessClassification{})) |
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.
Is there a reason not to build this into the main APF handler?
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.
Correct me if I'm wrong, but I think that if we want to extract this from context in httplog handler, then this field must be added to context before we enter httplog's handler (as r.WithContext returns only a copy of request so the original request is not changed). If we set this only in the main APF handler, then the the httplog handler (which wraps APF handler) will never see the context change.
Similar approach is used for audit-id -- it is set before other audit handlers only to make it visible in WithLogging.
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.
An alternative approach would be to use httplog's "addedInfo" feature and in APF's handler extract logging from context and add priorityLevel to addedInfo. In the current form "addedInfo" is simply a string you can append to, but technically we can make it a key=value map and finally have similar readability as we have in this approach.
WDYT?
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.
it seems we are using this filter only to initialize a PriorityAndFairnessClassification
into the request context, can we do the initialization inside the main p&f filter?
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.
oh yes, WithLogging
won't have access to the copied request 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.
An alternative approach would be to use httplog's "addedInfo" feature and in APF's handler extract logging from context and add priorityLevel to addedInfo
I think we already use addedInfo
- https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/endpoints/filterlatency/filterlatency.go#L66-L68
It seems to be a good alternative.
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 addedInfo
in the current form is quite hard to read it prints as addedInfo="\nslowFilter=200ms\npriorityLevel=system\nflowSchema=abcd"
(where slowFilter=200ms
is from filterlatency.go linked above), but we may want to solve readability issue anyway (by e.g. making it key=value).
I prefer sticking to the current approach as it's already done this way and I'm not sure I see any real value from migrating to that approach right now, but if we find a good reason to change approach I can do that 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.
if we are using httplog.AddInfof
, do we still need the filter WithPriorityAndFairnessClassification
?
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.
it seems to be a runtime optimization if we can do without a new association in the request context. on the other hand, I am OK having WithPriorityAndFairnessClassification
.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
|
||
r = r.WithContext(request.WithPriorityAndFairnessClassification(ctx, &classification.PriorityAndFairnessClassification{})) |
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.
it seems we are using this filter only to initialize a PriorityAndFairnessClassification
into the request context, can we do the initialization inside the main p&f filter?
@@ -218,6 +218,10 @@ func (rl *respLogger) Log() { | |||
} | |||
} | |||
|
|||
if plName := request.GetPriorityLevelNameTruncated(rl.req.Context()); plName != "" { | |||
keysAndValues = append(keysAndValues, "priorityLevel", plName) |
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.
Multiple FlowSchemas can be associated with a single priorityLevel - so it may not be possible to get to the FlowSchema name from a given priority-level.
One option is to add both flowSchema
and priorityLevel
into httplog, thoughts?
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, the FlowSchema implies the priority level and not the other way around (for a given configuration), so if you want to log only one then it should be the FlowSchema.
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 on priorityLevel as this is actually what matters when we debug high latency calls.
Adding only flowSchema will make such debugging harder, but I'm happy to add flowSchema 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.
so if you want to log only one then it should be the FlowSchema.
I guess in most cases we would want to know the priorityLevel - if we add only flowSchema
then the operator will need to run kubectl
command and find the related priorityLevel
, which may be cumbersome. I am +1 for adding both.
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.
FlowSchema matters, for at least two reasons:
- Helping explain why the particular priority level applied, and
- the choice of flow distinguisher matters.
I am not enthused about making the httplog message longer. Another consideration might be how much information can be gotten by an investigator who does not have access to the cluster config (either at all, or because it is no longer the current config). Perhaps the logic that digests the config should be sure to write it at the same V level as the httplog message (which is 3, if I recall correctly)?
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 is worth making the message longer. I agree it's ideal to see something like APF(FS=<name> PL=<name> D=<value>)
to keep it compact. Log search is much easier if we include the PL.
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.
@lavalamp , what do you mean D=<value>
to refer to? As long as I am wondering, I suppose I wonder about the chosen width and extra latency.
I am not sure introducing a layer of syntax is a good idea. I hope we can agree on short enough identifiers that we can stay with a flat set of fields.
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.
+1 for keeping this as part of httplog. It simply makes debugging easier.
httplog doesn't support anything more than keys and values, but as suggested by @MikeSpreitzer we can use shorter identifiers like 'pl' for priorityLevel and 'fs' for flowSchema.
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.
By D
I meant the discriminator. If you don't wrap the whole thing with something APF specific it makes it a bit longer, e.g. APF_FS, APF_PL, APF_D etc. No one will figure out what "D" means without the APF context clue, but the others maybe would be ok.
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 added FlowDistinguisher and added APF_ prefix. PTAL
|
||
// priorityAndFairnessClassificationClassificationKey is the context key for | ||
// APF classification. | ||
priorityAndFairnessClassificationClassificationKey |
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.
What happened to the indentation here?
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'm not sure what you mean. Could you elaborate?
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 mean that the various entries in this ( ... )
are at different levels of indentation. How about making them all the same?
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'm pretty sure it's just visual "bug" on github. I've downloaded patch and all lines had the same indent.
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.
It renders properly on my side and I manually checked that all lines in (...)
have one tab indentation.
/assign @lavalamp |
be72b53
to
6dc5e26
Compare
/approve |
queueNoteFn fq.QueueNoteFn, | ||
execFn func(), | ||
) { | ||
if t.mockDecision == decisionSkipFilter { | ||
panic("Handle should not be invoked") | ||
} | ||
noteFn(bootstrap.SuggestedFlowSchemaGlobalDefault, bootstrap.SuggestedPriorityLevelConfigurationGlobalDefault) | ||
noteFn(bootstrap.SuggestedFlowSchemaGlobalDefault, bootstrap.SuggestedPriorityLevelConfigurationGlobalDefault, string(bootstrap.SuggestedFlowSchemaGlobalDefault.Spec.DistinguisherMethod.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.
I know this is only a test, so it does not really matter what the string is here, but note that in the regular code the distinguisher is not a DistinguisherMethod.Type
but rather a string computed by the identified method.
keysAndValues = append(keysAndValues, | ||
"apf_pl", truncateLogField(pfc.PriorityLevelName), | ||
"apf_fs", truncateLogField(pfc.FlowSchemaName), | ||
"apf_d", pfc.FlowDistinguisher, |
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 do not think these are intrinsically limited to 64 characters. A username could be longer, right?
/lgtm cancel Mike has some good points |
@@ -460,7 +460,7 @@ func checkNewFS(cts *ctlrTestState, rng *rand.Rand, trialName string, ftr *fsTes | |||
startWG.Add(1) | |||
go func(matches, isResource bool, rdu RequestDigest) { | |||
expectedMatch := matches && ftr.wellFormed && (fsPrecedes(fs, catchAlls[isResource]) || fs.Name == catchAlls[isResource].Name) | |||
ctlr.Handle(ctx, rdu, func(matchFS *flowcontrol.FlowSchema, matchPL *flowcontrol.PriorityLevelConfiguration) { | |||
ctlr.Handle(ctx, rdu, func(matchFS *flowcontrol.FlowSchema, matchPL *flowcontrol.PriorityLevelConfiguration, _ 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.
The flowDistinguisher could be checked. Does not have to be added in this PR.
structured key/value pair for httplog - work in progress #104465 @mborsz this is how we would use it, let me know if the httplog PR is useful
|
/retest |
@mborsz , @tkashem : I like the direction of PR #104465 very much. In fact, it enables an even better solution than suggested above to something that is bothering me about the present PR. This PR builds knowledge of the APF classification logging into httplog (which I think should be treated as a lower level thing). PR #104465 enables us to remove that detail from httplog, undo the added filter introduced by this PR, and make the regular APF filter add the classification information. I am willing to approve the present PR as an interim step, if we agree on the further direction. |
@tkashem Thanks a lot for #104465. I think it helps a lot! @tkashem @MikeSpreitzer I think in one of comments above I mentioned that I'm fine with both the current approach and using httplog's addedInfo (if we only manage to make it more readable). I was preferring to stick to the current approach as it's close to be submittable, but given that #104465 looks nearly ready to go, it seems to be reasonable to me to block this PR on #104465 and rewrite this using httplog.AddKeyValue. Anyway, after thinking on this again I agree that httplog.AddKeyValue-based solution seems to be better overall as:
So yes, let's wait for #104465 (assuming it will be merged in O(days)) and rebase this PR. |
Yes, the format looks good. The idea of implementing this way seems to be cleaner to me. Thanks a lot for your help here! |
@mborsz @MikeSpreitzer #104465 is ready for review. |
/assign |
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.
It looks much easier in the current version.
|
||
httplog.AddKeyValue(ctx, "apf_pl", truncateLogField(pl.Name)) | ||
httplog.AddKeyValue(ctx, "apf_fs", truncateLogField(fs.Name)) | ||
httplog.AddKeyValue(ctx, "apf_d", truncateLogField(flowDistinguisher)) |
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 we need to log flowDistinguisher too?
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.
There was a discussion above and I think the conclusion was that it may be useful. @lavalamp @MikeSpreitzer
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.
fs and pl names seem to be a good starting point for now, maybe we can add flowDistinguisher
in the future if we need to?
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 frankly am not sure how much value there is in including the flow distinguisher. It is definitely relevant. My concern is whether it is difficult enough to discover from other evidence that it is worth putting in this log line that is printed for every request. I will not object either way.
If we do include it, I suggest a slightly longer name: apf_fd
(for "flow distinguisher", a logical companion to "flow schema").
Sample log entry from presubmit (this run):
@tkashem I think it's slightly less readable when "resp=200" is the last part of httplog. It would be easier to read when it would be close to place it used to be and httplog.AddKeyValue logs would be simply in the end. WDYT? |
@mborsz sure, sounds good, I can restore the order of the key value pairs as part of the optimization PR I am working on. |
const maxFieldLogLength = 64 | ||
|
||
if len(s) > maxFieldLogLength { | ||
s = s[0:maxFieldLogLength] |
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 0
here is not incorrect, but is unnecessary and is traditionally omitted.
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 left a few minor remarks in independent comments. They can be addressed in follow-up.
/LGTM
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: lavalamp, mborsz, MikeSpreitzer The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind feature
What this PR does / why we need it:
It adds priorityLevel=X verb to httplog to increase visibility of what prioritylevel has been used for a given request.
Alternative implementations considered:
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
WIP, I will add more tests once we agree that this is a right approach to take.
Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:
/cc @wojtek-t @lavalamp