mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:11:48 +00:00
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:
parent
c7b81c164a
commit
65f3428fbe
@ -53,6 +53,7 @@ export const SearchAggregationResult: FC<SearchAggregationResultProps> = props =
|
||||
caseSensitive,
|
||||
proactive: true,
|
||||
extendedTimeout,
|
||||
telemetryService,
|
||||
})
|
||||
|
||||
const handleCollapseClick = (): void => {
|
||||
|
||||
@ -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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,4 +13,10 @@ export enum GroupResultsPing {
|
||||
ExpandFullViewPanel = 'GroupResultsExpandedViewOpen',
|
||||
CollapseFullViewPanel = 'GroupResultsExpandedViewCollapse',
|
||||
InfoIconHover = 'GroupResultsInfoIconHover',
|
||||
|
||||
// Proactive
|
||||
ProactiveLimitHit = 'ProactiveLimitHit',
|
||||
ProactiveLimitSuccess = 'ProactiveLimitSuccess',
|
||||
ExplicitLimitHit = 'ExplicitLimitHit',
|
||||
ExplicitLimitSuccess = 'ExplicitLimitSuccess',
|
||||
}
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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))
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 != "" {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user