Rendering: Adds PDF support behind feature toggle (#81811)

* start pdf refactor

* Update AppChrome.tsx

* Update AppChrome.tsx

* add encoding param to rendering grpc service

* fix plugin mode

* clean up

* fix backend tests

* fix lint errors

* Support pdf encoding in render http api

---------

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Agnès Toulet
2024-02-08 13:09:34 +01:00
committed by GitHub
co-authored by Torkel Ödegaard
parent 90a26e18db
commit 28e66b4ad8
24 changed files with 189 additions and 117 deletions
+24 -15
View File
@@ -58,16 +58,18 @@ type Plugin interface {
}
func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager, remoteCache *remotecache.RemoteCache, rm PluginManager) (*RenderingService, error) {
// ensure ImagesDir exists
err := os.MkdirAll(cfg.ImagesDir, 0700)
if err != nil {
return nil, fmt.Errorf("failed to create images directory %q: %w", cfg.ImagesDir, err)
folders := []string{
cfg.ImagesDir,
cfg.CSVsDir,
cfg.PDFsDir,
}
// ensure CSVsDir exists
err = os.MkdirAll(cfg.CSVsDir, 0700)
if err != nil {
return nil, fmt.Errorf("failed to create CSVs directory %q: %w", cfg.CSVsDir, err)
// ensure folders exists
for _, f := range folders {
err := os.MkdirAll(f, 0700)
if err != nil {
return nil, fmt.Errorf("failed to create directory %q: %w", f, err)
}
}
logger := log.New("rendering")
@@ -248,14 +250,14 @@ func (rs *RenderingService) renderUnavailableImage() *RenderResult {
}
}
func (rs *RenderingService) Render(ctx context.Context, opts Opts, session Session) (*RenderResult, error) {
func (rs *RenderingService) Render(ctx context.Context, renderType RenderType, opts Opts, session Session) (*RenderResult, error) {
startTime := time.Now()
renderKeyProvider := rs.perRequestRenderKeyProvider
if session != nil {
renderKeyProvider = session
}
result, err := rs.render(ctx, opts, renderKeyProvider)
result, err := rs.render(ctx, renderType, opts, renderKeyProvider)
elapsedTime := time.Since(startTime).Milliseconds()
saveMetrics(elapsedTime, err, RenderPNG)
@@ -263,7 +265,7 @@ func (rs *RenderingService) Render(ctx context.Context, opts Opts, session Sessi
return result, err
}
func (rs *RenderingService) render(ctx context.Context, opts Opts, renderKeyProvider renderKeyProvider) (*RenderResult, error) {
func (rs *RenderingService) render(ctx context.Context, renderType RenderType, opts Opts, renderKeyProvider renderKeyProvider) (*RenderResult, error) {
if int(atomic.LoadInt32(&rs.inProgressCount)) > opts.ConcurrentLimit {
rs.log.Warn("Could not render image, hit the currency limit", "concurrencyLimit", opts.ConcurrentLimit, "path", opts.Path)
if opts.ErrorConcurrentLimitReached {
@@ -306,7 +308,7 @@ func (rs *RenderingService) render(ctx context.Context, opts Opts, renderKeyProv
}()
metrics.MRenderingQueue.Set(float64(atomic.AddInt32(&rs.inProgressCount, 1)))
return rs.renderAction(ctx, renderKey, opts)
return rs.renderAction(ctx, renderType, renderKey, opts)
}
func (rs *RenderingService) RenderCSV(ctx context.Context, opts CSVOpts, session Session) (*RenderCSVResult, error) {
@@ -373,11 +375,18 @@ func (rs *RenderingService) getNewFilePath(rt RenderType) (string, error) {
return "", err
}
ext := "png"
folder := rs.Cfg.ImagesDir
if rt == RenderCSV {
var ext string
var folder string
switch rt {
case RenderCSV:
ext = "csv"
folder = rs.Cfg.CSVsDir
case RenderPDF:
ext = "pdf"
folder = rs.Cfg.PDFsDir
default:
ext = "png"
folder = rs.Cfg.ImagesDir
}
return filepath.Abs(filepath.Join(folder, fmt.Sprintf("%s.%s", rand, ext)))