Code

Add a separate package for handling graphs and plots.
[sysdb/webui.git] / server / graph.go
1 //
2 // Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 // ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
18 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 package server
28 // Helper functions for handling and plotting graphs.
30 import (
31         "bytes"
32         "fmt"
33         "io"
34         "net/http"
35         "time"
37         "github.com/gonum/plot/vg"
38         "github.com/sysdb/webui/graph"
39 )
41 var urldate = "20060102150405"
43 func (s *Server) graph(w http.ResponseWriter, req request) {
44         if len(req.args) < 2 || 4 < len(req.args) {
45                 s.badrequest(w, fmt.Errorf("Missing host/metric information"))
46                 return
47         }
49         end := time.Now()
50         start := end.Add(-24 * time.Hour)
51         var err error
52         if len(req.args) > 2 {
53                 if start, err = time.Parse(urldate, req.args[2]); err != nil {
54                         s.badrequest(w, fmt.Errorf("Invalid start time: %v", err))
55                         return
56                 }
57         }
58         if len(req.args) > 3 {
59                 if end, err = time.Parse(urldate, req.args[3]); err != nil {
60                         s.badrequest(w, fmt.Errorf("Invalid start time: %v", err))
61                         return
62                 }
63         }
64         g := &graph.Graph{
65                 Start:   start,
66                 End:     end,
67                 Metrics: [][2]string{{req.args[0], req.args[1]}},
68         }
69         p, err := g.Plot(s.c)
70         if err != nil {
71                 s.internal(w, err)
72                 return
73         }
75         pw, err := p.WriterTo(vg.Length(500), vg.Length(200), "svg")
76         if err != nil {
77                 s.internal(w, fmt.Errorf("Failed to write plot: %v", err))
78                 return
79         }
81         var buf bytes.Buffer
82         if _, err := pw.WriteTo(&buf); err != nil {
83                 s.internal(w, fmt.Errorf("Failed to write plot: %v", err))
84                 return
85         }
86         w.Header().Set("Content-Type", "image/svg+xml")
87         w.WriteHeader(http.StatusOK)
88         io.Copy(w, &buf)
89 }
91 // vim: set tw=78 sw=4 sw=4 noexpandtab :