mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 01:23:32 -06:00
Alerting: Fix images cached on rule instead of dashboard panel signature (#58510)
This commit is contained in:
parent
b92a0223e3
commit
7e852720e3
@ -132,12 +132,22 @@ func (s *ScreenshotImageService) NewImage(ctx context.Context, r *models.AlertRu
|
||||
return nil, ErrNoPanel
|
||||
}
|
||||
|
||||
opts := screenshot.ScreenshotOptions{
|
||||
DashboardUID: *r.DashboardUID,
|
||||
PanelID: *r.PanelID,
|
||||
Timeout: screenshotTimeout,
|
||||
}
|
||||
|
||||
// To prevent concurrent screenshots of the same dashboard panel we use singleflight,
|
||||
// deduplicated on a base64 hash of the screenshot options.
|
||||
optsHash := base64.StdEncoding.EncodeToString(opts.Hash())
|
||||
|
||||
logger := s.logger.FromContext(ctx).New(
|
||||
"dashboard", *r.DashboardUID,
|
||||
"panel", *r.PanelID)
|
||||
"dashboard", opts.DashboardUID,
|
||||
"panel", opts.PanelID)
|
||||
|
||||
// If there is an image is in the cache return it instead of taking another screenshot
|
||||
if image, ok := s.cache.Get(ctx, r.GetKey().String()); ok {
|
||||
if image, ok := s.cache.Get(ctx, optsHash); ok {
|
||||
logger.Debug("Found cached image", "token", image.Token)
|
||||
return &image, nil
|
||||
}
|
||||
@ -150,15 +160,6 @@ func (s *ScreenshotImageService) NewImage(ctx context.Context, r *models.AlertRu
|
||||
ctx, cancelFunc := context.WithTimeout(ctx, screenshotTimeout)
|
||||
defer cancelFunc()
|
||||
|
||||
opts := screenshot.ScreenshotOptions{
|
||||
DashboardUID: *r.DashboardUID,
|
||||
PanelID: *r.PanelID,
|
||||
Timeout: screenshotTimeout,
|
||||
}
|
||||
|
||||
// To prevent concurrent screenshots of the same dashboard panel we use singleflight,
|
||||
// deduplicated on a base64 hash of the screenshot options.
|
||||
optsHash := base64.StdEncoding.EncodeToString(opts.Hash())
|
||||
logger.Debug("Requesting screenshot")
|
||||
|
||||
result, err, _ := s.singleflight.Do(optsHash, func() (interface{}, error) {
|
||||
@ -195,7 +196,7 @@ func (s *ScreenshotImageService) NewImage(ctx context.Context, r *models.AlertRu
|
||||
}
|
||||
|
||||
image := result.(models.Image)
|
||||
if err = s.cache.Set(ctx, r.GetKey().String(), image); err != nil {
|
||||
if err = s.cache.Set(ctx, optsHash, image); err != nil {
|
||||
s.logger.Warn("Failed to cache image",
|
||||
"token", image.Token,
|
||||
"error", err)
|
||||
|
@ -36,7 +36,7 @@ func TestScreenshotImageService(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// assert that the cache is checked for an existing image
|
||||
cache.EXPECT().Get(gomock.Any(), "{orgID: 1, UID: foo}").Return(models.Image{}, false)
|
||||
cache.EXPECT().Get(gomock.Any(), "M2DGZaRLXtg=").Return(models.Image{}, false)
|
||||
|
||||
// assert that a screenshot is taken
|
||||
screenshots.EXPECT().Take(gomock.Any(), screenshot.ScreenshotOptions{
|
||||
@ -60,7 +60,7 @@ func TestScreenshotImageService(t *testing.T) {
|
||||
}
|
||||
|
||||
// assert that the image is saved into the cache
|
||||
cache.EXPECT().Set(gomock.Any(), "{orgID: 1, UID: foo}", expected).Return(nil)
|
||||
cache.EXPECT().Set(gomock.Any(), "M2DGZaRLXtg=", expected).Return(nil)
|
||||
|
||||
image, err := s.NewImage(ctx, &models.AlertRule{
|
||||
OrgID: 1,
|
||||
@ -71,7 +71,7 @@ func TestScreenshotImageService(t *testing.T) {
|
||||
assert.Equal(t, expected, *image)
|
||||
|
||||
// assert that the cache is checked for an existing image
|
||||
cache.EXPECT().Get(gomock.Any(), "{orgID: 1, UID: bar}").Return(models.Image{}, false)
|
||||
cache.EXPECT().Get(gomock.Any(), "rTOWVcbRidk=").Return(models.Image{}, false)
|
||||
|
||||
// assert that a screenshot is taken
|
||||
screenshots.EXPECT().Take(gomock.Any(), screenshot.ScreenshotOptions{
|
||||
@ -94,7 +94,7 @@ func TestScreenshotImageService(t *testing.T) {
|
||||
}
|
||||
|
||||
// assert that the image is saved into the cache, but without a URL
|
||||
cache.EXPECT().Set(gomock.Any(), "{orgID: 1, UID: bar}", expected).Return(nil)
|
||||
cache.EXPECT().Set(gomock.Any(), "rTOWVcbRidk=", expected).Return(nil)
|
||||
|
||||
image, err = s.NewImage(ctx, &models.AlertRule{
|
||||
OrgID: 1,
|
||||
@ -107,7 +107,7 @@ func TestScreenshotImageService(t *testing.T) {
|
||||
expected = models.Image{Path: "baz.png", URL: "https://example.com/baz.png"}
|
||||
|
||||
// assert that the cache is checked for an existing image and it is returned
|
||||
cache.EXPECT().Get(gomock.Any(), "{orgID: 1, UID: baz}").Return(expected, true)
|
||||
cache.EXPECT().Get(gomock.Any(), "8hJuVe20rVE=").Return(expected, true)
|
||||
|
||||
image, err = s.NewImage(ctx, &models.AlertRule{
|
||||
OrgID: 1,
|
||||
|
Loading…
Reference in New Issue
Block a user