chore(tracing): add tracing for frontend and db session (#91509)

This PR adds instrumentation for loading frontend SPA along with select methods in the dashboard service, and cleans up span handling in sqlstore.

---------

Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
This commit is contained in:
Jeff Levin
2024-08-05 17:17:39 -08:00
committed by GitHub
parent abbfc15563
commit d4916207a0
9 changed files with 56 additions and 9 deletions

View File

@@ -82,7 +82,7 @@ func dashboardGuardianResponse(err error) response.Response {
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response {
ctx, span := hs.tracer.Start(c.Req.Context(), "httpserver.GetDashboard")
ctx, span := hs.tracer.Start(c.Req.Context(), "api.GetDashboard")
defer span.End()
uid := web.Params(c.Req)[":uid"]
@@ -262,6 +262,9 @@ func (hs *HTTPServer) getUserLogin(ctx context.Context, userID int64) string {
}
func (hs *HTTPServer) getDashboardHelper(ctx context.Context, orgID int64, id int64, uid string) (*dashboards.Dashboard, response.Response) {
ctx, span := hs.tracer.Start(ctx, "api.getDashboardHelper")
defer span.End()
var query dashboards.GetDashboardQuery
if len(uid) > 0 {

View File

@@ -31,6 +31,9 @@ import (
// Returns a file that is easy to check for changes
// Any changes to the file means we should refresh the frontend
func (hs *HTTPServer) GetFrontendAssets(c *contextmodel.ReqContext) {
c, span := hs.injectSpan(c, "api.GetFrontendAssets")
defer span.End()
hash := sha256.New()
keys := map[string]any{}
@@ -97,6 +100,9 @@ func (hs *HTTPServer) GetFrontendSettings(c *contextmodel.ReqContext) {
//
//nolint:gocyclo
func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.FrontendSettingsDTO, error) {
c, span := hs.injectSpan(c, "api.getFrontendSettings")
defer span.End()
availablePlugins, err := hs.availablePlugins(c.Req.Context(), c.SignedInUser.GetOrgID())
if err != nil {
return nil, err
@@ -388,6 +394,9 @@ func getShortCommitHash(commitHash string, maxLength int) string {
}
func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlugins AvailablePlugins) (map[string]plugins.DataSourceDTO, error) {
c, span := hs.injectSpan(c, "api.getFSDataSources")
defer span.End()
orgDataSources := make([]*datasources.DataSource, 0)
if c.SignedInUser.GetOrgID() != 0 {
query := datasources.GetDataSourcesQuery{OrgID: c.SignedInUser.GetOrgID(), DataSourceLimit: hs.Cfg.DataSourceLimit}
@@ -620,6 +629,9 @@ func (ap AvailablePlugins) Get(pluginType plugins.Type, pluginID string) (*avail
}
func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (AvailablePlugins, error) {
ctx, span := hs.tracer.Start(ctx, "api.availablePlugins")
defer span.End()
ap := make(AvailablePlugins)
pluginSettingMap, err := hs.pluginSettings(ctx, orgID)
@@ -665,6 +677,9 @@ func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (Availa
}
func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[string]*pluginsettings.InfoDTO, error) {
ctx, span := hs.tracer.Start(ctx, "api.pluginSettings")
defer span.End()
pluginSettings := make(map[string]*pluginsettings.InfoDTO)
// fill settings from database

View File

@@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/login/social/socialimpl"
"github.com/grafana/grafana/pkg/plugins"
@@ -81,6 +82,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
namespacer: request.GetNamespaceMapper(cfg),
SocialService: socialimpl.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeCacheStorage(), nil, &ssosettingstests.MockService{}),
managedPluginsService: managedplugins.NewNoop(),
tracer: tracing.InitializeTracerForTest(),
}
m := web.New()

View File

@@ -23,6 +23,9 @@ import (
)
func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexViewData, error) {
c, span := hs.injectSpan(c, "api.setIndexViewData")
defer span.End()
settings, err := hs.getFrontendSettings(c)
if err != nil {
return nil, err
@@ -215,6 +218,9 @@ func hashUserIdentifier(identifier string, secret string) string {
}
func (hs *HTTPServer) Index(c *contextmodel.ReqContext) {
c, span := hs.injectSpan(c, "api.Index")
defer span.End()
data, err := hs.setIndexViewData(c)
if err != nil {
c.Handle(hs.Cfg, http.StatusInternalServerError, "Failed to get settings", err)

View File

@@ -23,6 +23,9 @@ import (
// 422: unprocessableEntityError
// 500: internalServerError
func (hs *HTTPServer) Search(c *contextmodel.ReqContext) response.Response {
c, span := hs.injectSpan(c, "api.Search")
defer span.End()
query := c.Query("query")
tags := c.QueryStrings("tag")
starred := c.Query("starred")

View File

@@ -11,6 +11,7 @@ import (
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/user"
"go.opentelemetry.io/otel/trace"
)
func (hs *HTTPServer) GetRedirectURL(c *contextmodel.ReqContext) string {
@@ -63,3 +64,9 @@ func ValidateAndNormalizeEmail(email string) (string, error) {
return e.Address, nil
}
func (hs *HTTPServer) injectSpan(c *contextmodel.ReqContext, name string) (*contextmodel.ReqContext, trace.Span) {
ctx, span := hs.tracer.Start(c.Req.Context(), name)
c.Req = c.Req.WithContext(ctx)
return c, span
}