renderer.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package renderer
  2. import (
  3. "io"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "runtime"
  8. "time"
  9. "github.com/grafana/grafana/pkg/log"
  10. "github.com/grafana/grafana/pkg/setting"
  11. "github.com/grafana/grafana/pkg/util"
  12. )
  13. type RenderOpts struct {
  14. Url string
  15. Width string
  16. Height string
  17. SessionId string
  18. }
  19. func RenderToPng(params *RenderOpts) (string, error) {
  20. log.Info("PhantomRenderer::renderToPng url %v", params.Url)
  21. var executable = "phantomjs"
  22. if runtime.GOOS == "windows" {
  23. executable = executable + ".exe"
  24. }
  25. binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, executable))
  26. scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js"))
  27. pngPath, _ := filepath.Abs(filepath.Join(setting.ImagesDir, util.GetRandomString(20)))
  28. pngPath = pngPath + ".png"
  29. cmd := exec.Command(binPath, "--ignore-ssl-errors=true", scriptPath, "url="+params.Url, "width="+params.Width,
  30. "height="+params.Height, "png="+pngPath, "cookiename="+setting.SessionOptions.CookieName,
  31. "domain="+setting.Domain, "sessionid="+params.SessionId)
  32. stdout, err := cmd.StdoutPipe()
  33. if err != nil {
  34. return "", err
  35. }
  36. stderr, err := cmd.StderrPipe()
  37. if err != nil {
  38. return "", err
  39. }
  40. err = cmd.Start()
  41. if err != nil {
  42. return "", err
  43. }
  44. go io.Copy(os.Stdout, stdout)
  45. go io.Copy(os.Stdout, stderr)
  46. done := make(chan error)
  47. go func() {
  48. cmd.Wait()
  49. close(done)
  50. }()
  51. select {
  52. case <-time.After(15 * time.Second):
  53. if err := cmd.Process.Kill(); err != nil {
  54. log.Error(4, "failed to kill: %v", err)
  55. }
  56. case <-done:
  57. }
  58. return pngPath, nil
  59. }