mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:51:59 +00:00
Relates to #64041 This refactors the `adminanalytics` package to set the cache explicitly instead of implicitly relying on the global `redispool.Store`. The global store obfuscated the dependency and also made testing a bit awkward. Test plan: - new unit test - I ran a local instance and checked for panics in the logs from the worker job that updates the cache on startup. - Checked that the following GQL query returned results ```GQL query { site { analytics { search(dateRange: LAST_MONTH, grouping: WEEKLY) { searches { nodes { date count } summary { totalCount totalUniqueUsers totalRegisteredUsers } } } } } } ``` - I deleted the cache and ran the GQL query again and verified that cache had the following new entries ``` 1) "adminanalytics:Search:Searches:LAST_MONTH:WEEKLY:nodes" 2) "adminanalytics:Search:Searches:LAST_MONTH:WEEKLY:summary" ```
182 lines
4.5 KiB
Go
182 lines
4.5 KiB
Go
package adminanalytics
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/keegancsmith/sqlf"
|
|
|
|
"github.com/sourcegraph/sourcegraph/internal/database"
|
|
)
|
|
|
|
type CodeIntel struct {
|
|
Ctx context.Context
|
|
DateRange string
|
|
Grouping string
|
|
DB database.DB
|
|
Cache KeyValue
|
|
}
|
|
|
|
func (s *CodeIntel) ReferenceClicks() (*AnalyticsFetcher, error) {
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{"findReferences"})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:ReferenceClicks",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) DefinitionClicks() (*AnalyticsFetcher, error) {
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{"goToDefinition.preloaded", "goToDefinition"})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:DefinitionClicks",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) InAppEvents() (*AnalyticsFetcher, error) {
|
|
sourceCond := sqlf.Sprintf("source = 'WEB'")
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{"goToDefinition.preloaded", "goToDefinition", "findReferences"}, sourceCond)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:InAppEvents",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) CodeHostEvents() (*AnalyticsFetcher, error) {
|
|
sourceCond := sqlf.Sprintf("source = 'CODEHOSTINTEGRATION'")
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{"goToDefinition.preloaded", "goToDefinition", "findReferences"}, sourceCond)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:CodeHostEvents",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) SearchBasedEvents() (*AnalyticsFetcher, error) {
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{
|
|
"codeintel.searchDefinitions",
|
|
"codeintel.searchDefinitions.xrepo",
|
|
"codeintel.searchReferences",
|
|
"codeintel.searchReferences.xrepo",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:SearchBasedEvents",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) PreciseEvents() (*AnalyticsFetcher, error) {
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{
|
|
"codeintel.lsifDefinitions",
|
|
"codeintel.lsifDefinitions.xrepo",
|
|
"codeintel.lsifReferences",
|
|
"codeintel.lsifReferences.xrepo",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:PreciseEvents",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) CrossRepoEvents() (*AnalyticsFetcher, error) {
|
|
nodesQuery, summaryQuery, err := makeEventLogsQueries(s.DateRange, s.Grouping, []string{
|
|
"codeintel.searchDefinitions.xrepo",
|
|
"codeintel.searchReferences.xrepo",
|
|
"codeintel.lsifDefinitions.xrepo",
|
|
"codeintel.lsifReferences.xrepo",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AnalyticsFetcher{
|
|
db: s.DB,
|
|
dateRange: s.DateRange,
|
|
grouping: s.Grouping,
|
|
nodesQuery: nodesQuery,
|
|
summaryQuery: summaryQuery,
|
|
group: "CodeIntel:CrossRepoEvents",
|
|
cache: s.Cache,
|
|
}, nil
|
|
}
|
|
|
|
func (s *CodeIntel) CacheAll(ctx context.Context) error {
|
|
fetcherBuilders := []func() (*AnalyticsFetcher, error){
|
|
s.DefinitionClicks,
|
|
s.ReferenceClicks,
|
|
s.InAppEvents,
|
|
s.CodeHostEvents,
|
|
s.SearchBasedEvents,
|
|
s.PreciseEvents,
|
|
s.CrossRepoEvents,
|
|
}
|
|
|
|
for _, buildFetcher := range fetcherBuilders {
|
|
fetcher, err := buildFetcher()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := fetcher.Nodes(ctx); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := fetcher.Summary(ctx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|