-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Update core usage stats collection #85706
Update core usage stats collection #85706
Conversation
b46f5e6
to
673536b
Compare
Added fields for namespace (default or custom).
First implementation made a best-effort attempt to determine whether or not a request was "first-party" (from the Kibana client) by checking "kbn-version", "origin", and "referer". If these three headers are all present, we thought it was very likely that the request was first-party. However, further testing after adding usage stats collection for additional SO APIs determined this to be inaccurate; some actual first-party requests do not include the "origin" header. I am not sure exactly why this is the case, but I have changed the check to use "user-agent" instead. This is another indicator that a request likely did not come from a programmatic consumer.
673536b
to
4d9d7f8
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.
Author's notes for reviewers.
'apiCalls.savedObjectsImport.total': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.kibanaRequest.yes': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.kibanaRequest.no': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.default.total': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.default.kibanaRequest.yes': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.default.kibanaRequest.no': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.custom.total': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.custom.kibanaRequest.yes': { type: 'long' }, | ||
'apiCalls.savedObjectsImport.namespace.custom.kibanaRequest.no': { type: 'long' }, |
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 each existing SO API, I removed these two usage stats fields in favor of these 6 additional ones. This gives us the ability to tell how many consumers, first- or third-party, are using SO APIs in non-default spaces.
version: 'WzgsMV0=', | ||
version: resp.body.saved_objects[1].version, |
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.
Some SO API integration tests already had a "relaxed" version check like I've changed this to.
The usage stats collection additions caused flaky behavior for those tests that have "strict" version checks (version could be slightly different depending upon whether the usage stats incrementCounter
finished before the operation in question, I am guessing). At any rate it seemed prudent to change these integration test assertions so that slight version deviations don't cause flaky behavior.
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.
Looking good. Just got a question regarding the schema / data format
const pathToCheck = this.basePath.remove(requestBasePath); // remove the server basePath from the request basePath | ||
const matchResult = pathToCheck.match(SPACE_CONTEXT_REGEX); // Look for `/s/space-url-context` in the base path |
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.
🙈 , but I don't see any other easy option if we need this to be in core...
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 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 haven't tested this (sorry...not at my laptop at the moment), but could we infer this by checking to see if the requestBasePath
=== this.basePath.serverBasePath
? If they match, then we'd be in the default space. If the request has a modified base path, then we'd be in the non-default space. This wouldn't account for users who explicitly target the default space via /s/default
, but I'd expect (with no evidence) that this is uncommon.
Feel free to ignore this, just pitching a potential 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.
I tested it and it does seem to work. I'd be hesitant to use this without accounting for /s/default
, though, and we have an explicit check for that it doesn't really simplify our code. At least with the current approach, it's the same in Core and the Spaces plugin, so if it ever needs to change for some reason, it'll be more evident that the same change needs to be made in both places.
I'll leave it as-is for now and if we decide to revisit in #85869 we can do so.
export const BULK_CREATE_STATS_PREFIX = 'apiCalls.savedObjectsBulkCreate'; | ||
export const BULK_GET_STATS_PREFIX = 'apiCalls.savedObjectsBulkGet'; | ||
export const BULK_UPDATE_STATS_PREFIX = 'apiCalls.savedObjectsBulkUpdate'; | ||
export const CREATE_STATS_PREFIX = 'apiCalls.savedObjectsCreate'; |
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.
NIT: I think I'm starting to see a factorizable pattern here 😅
// Saved Objects Client APIs | ||
'apiCalls.savedObjectsBulkCreate.total'?: number; | ||
'apiCalls.savedObjectsBulkCreate.namespace.default.total'?: number; | ||
'apiCalls.savedObjectsBulkCreate.namespace.default.kibanaRequest.yes'?: number; | ||
'apiCalls.savedObjectsBulkCreate.namespace.default.kibanaRequest.no'?: number; | ||
'apiCalls.savedObjectsBulkCreate.namespace.custom.total'?: number; | ||
'apiCalls.savedObjectsBulkCreate.namespace.custom.kibanaRequest.yes'?: number; |
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 guess this reflects the ES schema? Don't we want nested properties instead of flattening everything?
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 this reflects the schema. In the original PR I had nested properties, but I flattened the fields so we could use the incrementCounter
API to increment the counter fields instead of get
+update
. At any rate, the fields are flattened inside of ES so it doesn't make a difference for how we'll consume the usage data 🙂
💚 Build SucceededMetrics [docs]Distributable file count
History
To update your PR or re-run it, just comment with: |
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.
LGTM, code review only. Let me know if you'd like me to manually test, and I can do so tomorrow
const pathToCheck = this.basePath.remove(requestBasePath); // remove the server basePath from the request basePath | ||
const matchResult = pathToCheck.match(SPACE_CONTEXT_REGEX); // Look for `/s/space-url-context` in the base path |
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 haven't tested this (sorry...not at my laptop at the moment), but could we infer this by checking to see if the requestBasePath
=== this.basePath.serverBasePath
? If they match, then we'd be in the default space. If the request has a modified base path, then we'd be in the non-default space. This wouldn't account for users who explicitly target the default space via /s/default
, but I'd expect (with no evidence) that this is uncommon.
Feel free to ignore this, just pitching a potential alternative
Resolves #85621.
Testing
Log into Kibana, navigate to Stack Management -> Advanced Settings, scroll to the bottom, click on the cluster data link, and Ctrl+F for "apiCalls". This will show you the cluster usage data payload, specifically the fields that this PR adds/changes.