renderer.go 1.8 KB

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