Aggregation: Add aggregation data pings again (#43765)

* Add aggregation data events on the frontend

* Add aggregation data ping on the backend

* Update code insight pings doc
This commit is contained in:
Vova Kulikov 2022-11-02 12:13:01 -03:00 committed by GitHub
parent c7b81c164a
commit 65f3428fbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 154 additions and 4 deletions

View File

@ -53,6 +53,7 @@ export const SearchAggregationResult: FC<SearchAggregationResultProps> = props =
caseSensitive,
proactive: true,
extendedTimeout,
telemetryService,
})
const handleCollapseClick = (): void => {

View File

@ -3,14 +3,18 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react'
import { gql, useQuery } from '@apollo/client'
import { useHistory, useLocation } from 'react-router'
import { TelemetryService } from '@sourcegraph/shared/src/telemetry/telemetryService'
import {
GetSearchAggregationResult,
GetSearchAggregationVariables,
SearchAggregationMode,
NotAvailableReasonType,
SearchPatternType,
} from '../../../../graphql-operations'
import { AGGREGATION_MODE_URL_KEY, AGGREGATION_UI_MODE_URL_KEY } from './constants'
import { GroupResultsPing } from './pings'
import { AggregationUIMode } from './types'
interface URLStateOptions<State, SerializedState> {
@ -212,6 +216,7 @@ interface SearchAggregationDataInput {
caseSensitive: boolean
extendedTimeout: boolean
proactive?: boolean
telemetryService: TelemetryService
}
interface AggregationState {
@ -227,9 +232,17 @@ type SearchAggregationResults =
| { data: GetSearchAggregationResult; loading: false; error: undefined }
export const useSearchAggregationData = (input: SearchAggregationDataInput): SearchAggregationResults => {
const { query, patternType, aggregationMode, proactive, caseSensitive, extendedTimeout } = input
const {
query,
patternType,
aggregationMode,
caseSensitive,
extendedTimeout,
proactive = false,
telemetryService,
} = input
const [, setAggregationMode] = useAggregationSearchMode()
const [, setURLAggregationMode] = useAggregationSearchMode()
const [state, setState] = useState<AggregationState>(INITIAL_STATE)
// Search parses out the case argument, but backend needs it in the query
@ -272,12 +285,13 @@ export const useSearchAggregationData = (input: SearchAggregationDataInput): Sea
// Catch initial page mount when aggregation mode isn't set on the FE and BE
// calculated aggregation mode automatically on the backend based on given query
if (calculatedAggregationMode !== aggregationMode) {
setAggregationMode(calculatedAggregationMode)
setURLAggregationMode(calculatedAggregationMode)
}
// skip: true resets data field in the useQuery hook, in order to use previously
// saved data we use useState to store data outside useQuery hook
setState({ data, calculatedMode: calculatedAggregationMode })
sendAggregationPing({ data, extendedTimeout, proactive, telemetryService })
},
}
)
@ -320,3 +334,61 @@ export const isNonExhaustiveAggregationResults = (response?: GetSearchAggregatio
return response.searchQueryAggregate?.aggregations?.__typename === 'NonExhaustiveSearchAggregationResult'
}
interface UseAggregationPingsArgs {
data: GetSearchAggregationResult | undefined
proactive: boolean
extendedTimeout: boolean
telemetryService: TelemetryService
}
function sendAggregationPing(props: UseAggregationPingsArgs): void {
const { data, proactive, extendedTimeout, telemetryService } = props
const aggregation = data?.searchQueryAggregate.aggregations
if (!aggregation) {
return
}
const { __typename: aggregationType } = aggregation
if (aggregationType === 'SearchAggregationNotAvailable') {
const { reasonType, mode } = aggregation
const extensionAvailable = reasonType === NotAvailableReasonType.TIMEOUT_EXTENSION_AVAILABLE
const noExtensionAvailable = reasonType === NotAvailableReasonType.TIMEOUT_NO_EXTENSION_AVAILABLE
if (proactive && extensionAvailable) {
telemetryService.log(
GroupResultsPing.ProactiveLimitHit,
{ aggregationMode: mode },
{ aggregationMode: mode }
)
}
if (noExtensionAvailable) {
telemetryService.log(
GroupResultsPing.ExplicitLimitHit,
{ aggregationMode: mode },
{ aggregationMode: mode }
)
}
} else {
const { mode } = aggregation
if (extendedTimeout) {
telemetryService.log(
GroupResultsPing.ExplicitLimitSuccess,
{ aggregationMode: mode },
{ aggregationMode: mode }
)
} else {
telemetryService.log(
GroupResultsPing.ProactiveLimitSuccess,
{ aggregationMode: mode },
{ aggregationMode: mode }
)
}
}
}

View File

@ -13,4 +13,10 @@ export enum GroupResultsPing {
ExpandFullViewPanel = 'GroupResultsExpandedViewOpen',
CollapseFullViewPanel = 'GroupResultsExpandedViewCollapse',
InfoIconHover = 'GroupResultsInfoIconHover',
// Proactive
ProactiveLimitHit = 'ProactiveLimitHit',
ProactiveLimitSuccess = 'ProactiveLimitSuccess',
ExplicitLimitHit = 'ExplicitLimitHit',
ExplicitLimitSuccess = 'ExplicitLimitSuccess',
}

View File

@ -58,6 +58,7 @@ export const SearchAggregations: FC<SearchAggregationsProps> = memo(props => {
proactive,
caseSensitive,
extendedTimeout,
telemetryService,
})
// When query is updated reset extendedTimeout as per business rules
@ -156,3 +157,5 @@ export const SearchAggregations: FC<SearchAggregationsProps> = memo(props => {
</article>
)
})
SearchAggregations.displayName = 'SearchAggregations'

View File

@ -423,3 +423,15 @@ https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/sourcegrap
- [WeeklyGroupResultsChartBarClick](https://sourcegraph.com/search?q=context:%40sourcegraph/all+GroupResultsChartBarClick&patternType=regexp)
- [WeeklyGroupResultsChartBarHover](https://sourcegraph.com/search?q=context:%40sourcegraph/all+GroupResultsChartBarHover&patternType=regexp)
- **Version added:** 4.0 ([#40977](https://github.com/sourcegraph/sourcegraph/pull/40977))
### Search mode (proactive/extended) success rate
**Type:** FE event
**Intended purpose:** To track the number of aggregation searches that succeed or hit limit in either a proactive or extended search.
**Functional implementation:** These pings fire a telemetry event when an aggregation search completes or times out.
- Aggregation: weekly
- Event Code: [WeeklyGroupResultsSearches](https://sourcegraph.com/search?q=context:%40sourcegraph/all+WeeklyGroupResultsSearches&patternType=lucky)
- **Version added:** 4.1 ([#42554](https://github.com/sourcegraph/sourcegraph/pull/42554))

View File

@ -1458,6 +1458,7 @@ type CodeInsightsUsageStatistics struct {
WeeklyGroupResultsChartBarClick []GroupResultPing
WeeklyGroupResultsAggregationModeClicked []GroupResultPing
WeeklyGroupResultsAggregationModeDisabledHover []GroupResultPing
WeeklyGroupResultsSearches []GroupResultSearchPing
WeeklySeriesBackfillTime []InsightsBackfillTimePing
}
@ -1473,6 +1474,12 @@ type GroupResultExpandedViewPing struct {
Count *int32
}
type GroupResultSearchPing struct {
Name PingName
AggregationMode *string
Count *int32
}
type CodeInsightsCriticalTelemetry struct {
TotalInsights int32
}

View File

@ -227,6 +227,21 @@ func GetCodeInsightsUsageStatistics(ctx context.Context, db database.DB) (*types
}
stats.WeeklyGroupResultsExpandedViewCollapse = weeklyGroupResultsExpandedViewCollapse
weeklyGroupResultsSearches, err := GetGroupResultsSearchesPings(
ctx,
db,
[]types.PingName{
"ProactiveLimitHit",
"ProactiveLimitSuccess",
"ExplicitLimitHit",
"ExplicitLimitSuccess",
},
)
if err != nil {
return nil, errors.Wrap(err, "WeeklyGroupResultsSearches")
}
stats.WeeklyGroupResultsSearches = weeklyGroupResultsSearches
backfillTime, err := GetBackfillTimePing(ctx, db)
if err != nil {
return nil, errors.Wrap(err, "GetBackfillTimePing")
@ -442,6 +457,40 @@ func GetGroupResultsExpandedViewPing(ctx context.Context, db database.DB, pingNa
return groupResultsExpandedViewPings, nil
}
func GetGroupResultsSearchesPings(ctx context.Context, db database.DB, pingNames []types.PingName) ([]types.GroupResultSearchPing, error) {
pings := []types.GroupResultSearchPing{}
for _, name := range pingNames {
rows, err := db.QueryContext(ctx, getGroupResultsSql, string(name), timeNow())
if err != nil {
return nil, err
}
err = func() error {
defer rows.Close()
var noop *string
for rows.Next() {
ping := types.GroupResultSearchPing{
Name: name,
}
if err := rows.Scan(
&ping.Count,
&ping.AggregationMode,
&noop,
&noop,
); err != nil {
return err
}
pings = append(pings, ping)
}
return nil
}()
if err != nil {
return nil, err
}
}
return pings, nil
}
func GetBackfillTimePing(ctx context.Context, db database.DB) ([]types.InsightsBackfillTimePing, error) {
store := db.EventLogs()
name := InsightsBackfillTimePingName

View File

@ -10,7 +10,6 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/internal/database"
@ -126,6 +125,7 @@ func TestCodeInsightsUsageStatistics(t *testing.T) {
want.WeeklyGroupResultsChartBarClick = []types.GroupResultPing{}
want.WeeklyGroupResultsAggregationModeClicked = []types.GroupResultPing{}
want.WeeklyGroupResultsAggregationModeDisabledHover = []types.GroupResultPing{}
want.WeeklyGroupResultsSearches = []types.GroupResultSearchPing{}
want.WeeklySeriesBackfillTime = []types.InsightsBackfillTimePing{}
if diff := cmp.Diff(want, have); diff != "" {