Skip to content
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 UI Metric for Discover 2.0 #8345

Merged
merged 1 commit into from
Oct 1, 2024

Conversation

LDrago27
Copy link
Collaborator

@LDrago27 LDrago27 commented Sep 25, 2024

Description

The PR aims at capturing following UI Metrics.

  1. No of times discover has been loaded
  2. No of times new discover has been loaded
  3. No of times each datasource type queries have been executed
  4. No of times each language queries have been executed

Issues Resolved

Screenshot

image

Testing the changes

  1. Set usageCollection.uiMetric.enabled to true
  2. Call the API /api/stats?extended=true&legacy=true&exclude_usage=false
  3. Verify the ui_metric doesn't contain an entry corresponding to Discover
  4. Navigate to Discover
  5. Interact with Discover change the datasources, language
  6. Wait for 90s
  7. Call the API /api/stats?extended=true&legacy=true&exclude_usage=false and verify ui_metric contains an entry corresponding to Discover with the metrics corresponding to above interaction

Changelog

  • skip

Check List

  • All tests pass
    • yarn test:jest
    • yarn test:jest_integration
  • New functionality includes testing.
  • New functionality has been documented.
  • Update CHANGELOG.md
  • Commits are signed per the DCO using --signoff

Copy link
Contributor

❌ Empty Changelog Section

The Changelog section in your PR description is empty. Please add a valid changelog entry or entries. If you did add a changelog entry, check to make sure that it was not accidentally included inside the comment block in the Changelog section.

@github-actions github-actions bot added the Skip-Changelog PRs that are too trivial to warrant a changelog or release notes entry label Sep 25, 2024
Copy link

codecov bot commented Sep 25, 2024

Codecov Report

Attention: Patch coverage is 54.05405% with 17 lines in your changes missing coverage. Please review.

Project coverage is 60.92%. Comparing base (33f4f64) to head (c6e407a).
Report is 26 commits behind head on main.

Files with missing lines Patch % Lines
...gins/discover/public/ui_metric/report_ui_metric.ts 28.57% 10 Missing ⚠️
...ic/application/view_components/utils/use_search.ts 0.00% 3 Missing ⚠️
.../data_explorer/public/components/app_container.tsx 33.33% 1 Missing and 1 partial ⚠️
src/plugins/data_explorer/public/plugin.ts 0.00% 1 Missing ⚠️
...data_explorer/public/ui_metric/report_ui_metric.ts 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8345      +/-   ##
==========================================
- Coverage   60.95%   60.92%   -0.04%     
==========================================
  Files        3743     3756      +13     
  Lines       88857    89185     +328     
  Branches    13859    13941      +82     
==========================================
+ Hits        54164    54337     +173     
- Misses      31383    31467      +84     
- Partials     3310     3381      +71     
Flag Coverage Δ
Linux_1 28.85% <37.50%> (+<0.01%) ⬆️
Linux_2 56.35% <ø> (?)
Linux_3 37.73% <54.05%> (-0.06%) ⬇️
Linux_4 29.96% <ø> (+0.02%) ⬆️
Windows_1 28.87% <37.50%> (+<0.01%) ⬆️
Windows_2 56.30% <ø> (+<0.01%) ⬆️
Windows_3 37.74% <54.05%> (-0.05%) ⬇️
Windows_4 29.96% <ø> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@LDrago27 LDrago27 requested a review from huyaboo as a code owner September 25, 2024 23:36
Copy link
Member

@kavilla kavilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple nits and potential suggestion

@@ -33,6 +33,11 @@ import {
} from '../../../opensearch_dashboards_services';
import { SEARCH_ON_PAGE_LOAD_SETTING } from '../../../../common';
import { syncQueryStateWithUrl } from '../../../../../data/public';
import {
DATASOURCE_METRIC_SUFFIX,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit pick so feel free to ignore. i find it easier to have a const object that groups the constants so that i can import more with less.

for example.

METRIC_SUFFIX = {
  LANGUAGE: 'language_queries_count',
  DATA_SOURCE: 'data_source_queries_count'
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appreciation comment for adding an index file

@LDrago27 LDrago27 force-pushed the discoverUiMetric branch 2 times, most recently from 97e3456 to 792dff7 Compare September 26, 2024 19:07
@LDrago27 LDrago27 force-pushed the discoverUiMetric branch 2 times, most recently from 81c30aa to 299c541 Compare September 26, 2024 21:23
@@ -236,6 +241,19 @@ export const useSearch = (services: DiscoverViewServices) => {
elapsedMs,
},
});

// Add tracking for datasource type and query if the query is not same as last query
const query = searchSource.getField('query');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't remember if discover creates a new search source and it doesn't have a parent but we could also check if searchSource.parent.getField('query') . but then again i haven't checked so it parent might not ever be set for discover

@LDrago27 LDrago27 force-pushed the discoverUiMetric branch 2 times, most recently from 244244d to 2e3e574 Compare September 30, 2024 21:32
@@ -35,10 +42,34 @@ export const AppContainer = React.memo(

const topLinkRef = useRef<HTMLDivElement>(null);
const datePickerRef = useRef<HTMLDivElement>(null);

const initialQueryEnhancement = useRef(null); // Initialize to null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

i think precedent has been to have a reference like

const isMounted = useRef(false);

and add a similar use hook to check if isMounted is true then we check if initialQueryEnhancement !== isEnhancementsEnabled. if false then we set initialQueryEnhancement.current to isEnhancementsEnabled. for consistency with other parts of the application

that said could we make the isEnhancementsEnabled a reference? and just do

isEnhancementsEnabled.current !== uiSettings?.get(QUERY_ENHANCEMENT_ENABLED_SETTING);

to reduce additional constants

// Track the dataset type and language used

const query = searchSource.getField('query');
if (query && query.dataset?.type && query.language) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to verify, dataset with enhancements disabled will be undefined and therefore won't submit a ui metric. is that the current requirements or does it want to submit a ui metric for every language for every query

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its the former. Tracking dataset type and language are important only in the new discover

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requirements are specific to the new Discover experience , therefore in those cases where we don't have the datasets and language with enhancements off are not something we need to be worried about.

* SPDX-License-Identifier: Apache-2.0
*/

export const DATASOURCE_METRIC_SUFFIX = 'data_source_queries_count';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i really think this should be dataset_queries_count or dataset_type_queries_count or data_queries_count to avoid confusion with the concept of a dataSource since a dataset can have a dataSource

ex:

the Index Pattern dataset type would make this count

INDEX_PATTERN_data_source_queries_count I think but as you can see here it has a data source:

so the ui metric being data source would cause confusion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should also add a backlog item to migrate this portion over to the data plugin. eventually if the new discover ui becomes the standard and only or if other plugins on board to query enhancements then we can still get this insight on different types of dataset types and languages vs how it is used in discover

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the Metric to dataset_queries_count

* SPDX-License-Identifier: Apache-2.0
*/

export const NEW_DISCOVER_LOAD_EVENT = 'new_discover_load_count';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super duper nit: don't change this PR specifically for this but the import line for src/plugins/data_explorer/public/components/app_container.tsx could be a smaller and not require future updates if we utilize an object. and easier to access for developers. and probably should keep the casing and the same.

suggestion like:

const APP_NAME = `discover`;
const LOAD_EVENT = `load_count`;
const OPT_IN_EVENT = `opt_in_count`;
const OPT_OUT_EVENT = `opt_out_count`;
export const METRIC = {
  DEFAULT: {
     LOAD_EVENT: `${APP_NAME}_${LOAD_EVENT}`,
     OPT_IN_EVENT: `${APP_NAME}_${OPT_IN_EVENT}`,
     OPT_OUT_EVENT: `${APP_NAME}_${OPT_OUT_EVENT}`
  },
  LEGACY: {
     LOAD_EVENT: `${APP_NAME}_legacy_${LOAD_EVENT}`,
     OPT_IN_EVENT: `${APP_NAME}_legacy_${OPT_IN_EVENT}`,
     OPT_OUT_EVENT: `${APP_NAME}_legacy_${OPT_OUT_EVENT}`
  }
}

then we can just import METRIC and access the constant with the dot notation.

some things to mention is that proposing using legacy instead of classifying vs using the new because with new or utilizing the 2.0 is that we version this ui metric to be 2.0 and then if we make the new discover the default then it becomes confusing for those who don't have context that the the default is the new ui metric and the previous version was the one without any classifying word on the ui metric. however, im not super tied to calling legacy. but i think we should go with legacy or new and avoid the 2.0 or 2.

also opted to ensure all the metrics are the same structure like

appname_classifier_event_metrictype

classifier being like new or legacy or nothing. this way if other plugins utilize the same standard then we have a nice way to aggregate on the results in a similar structure for visualizations and decision making. vs writing a query that filters out only the new and making the regex be something so it filters for new_discover or discover_new.

the final is using of interpolation this way if another developer wants to track another metric they can add by seeing the standard of using interpolation and do it as well. the reason why because i've seen people hardcode type constants over and over again and then there was a typo at which point we used that in key for local storage. but since the users used it already we are kind of stuck. so if we reduce the amount of opportunities for someone to make a typo then we could avoid an issue like queries failing to show up if the query was appName: discover but the developer added a new metric discoever_refresh_count where they mixed the e and the v in discover.

Copy link
Member

@ashwin-pc ashwin-pc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lemme know your thoughts on the useEffect based tracking. The rest look good!

@@ -49,7 +49,7 @@ describe('IndexPatternSelect', () => {

bulkGetMock.mockResolvedValue({ savedObjects: [{ attributes: { title: 'test1' } }] });
compInstance.debouncedFetch('');
await new Promise((resolve) => setTimeout(resolve, 300));
await new Promise((resolve) => setTimeout(resolve, 600));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case was a bit flakey in nature. hence to resolve it I had increased the timeout.

Copy link
Collaborator

@AMoo-Miki AMoo-Miki Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the right way to deal with timers. Please revert this and i will deal with it in a separate PR.

Comment on lines +27 to +30
DISCOVER_LOAD_EVENT,
NEW_DISCOVER_LOAD_EVENT,
NEW_DISCOVER_OPT_IN,
NEW_DISCOVER_OPT_OUT,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need all 4? New discover cant be triggered without a page refresh. So the useEffect based tracking should be unnecessary.

Copy link
Collaborator Author

@LDrago27 LDrago27 Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Then it might not make sense to add them in here. Removing the OPT_IN and OPT_OUT tracking from here.

// Track the dataset type and language used

const query = searchSource.getField('query');
if (query && query.dataset?.type && query.language) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its the former. Tracking dataset type and language are important only in the new discover

Copy link
Member

@sejli sejli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to @kavilla's nonblocking comment on the string constants, might need that documented somewhere as part of OSD best practices. Otherwise, LGTM.

@LDrago27 LDrago27 merged commit daa59de into opensearch-project:main Oct 1, 2024
65 of 67 checks passed
opensearch-trigger-bot bot pushed a commit that referenced this pull request Oct 1, 2024
Signed-off-by: Suchit Sahoo <[email protected]>
(cherry picked from commit daa59de)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
LDrago27 pushed a commit that referenced this pull request Oct 2, 2024
SuZhou-Joe pushed a commit to SuZhou-Joe/OpenSearch-Dashboards that referenced this pull request Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
all-star-contributor backport 2.x discover for discover reinvent discover-next Skip-Changelog PRs that are too trivial to warrant a changelog or release notes entry v2.18.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants