summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8c86d8c)
raw | patch | inline | side by side (parent: 8c86d8c)
author | Sebastian Harl <sh@tokkee.org> | |
Tue, 12 May 2015 20:43:16 +0000 (22:43 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Tue, 12 May 2015 20:43:16 +0000 (22:43 +0200) |
Drop the custom query abstraction in favor of client.Query().
main.go | patch | blob | history | |
server/graph.go | patch | blob | history | |
server/query.go | patch | blob | history | |
server/server.go | patch | blob | history |
index 0b2bfae0e9b4aaf1b1aa9089a62736951d630726..5ded81417cedb53920b393cbaacd471d64ee9e9b 100644 (file)
--- a/main.go
+++ b/main.go
"os"
"os/user"
- "github.com/sysdb/go/client"
"github.com/sysdb/webui/server"
)
flag.Parse()
log.Printf("Connecting to SysDB at %s.", *addr)
- var conns []*client.Conn
- for i := 0; i < 10; i++ {
- conn, err := client.Connect(*addr, *username)
- if err != nil {
- fatalf("Failed to connect to SysDB at %q: %v", *addr, err)
- }
- conns = append(conns, conn)
- }
- major, minor, patch, extra, err := conns[0].ServerVersion()
- if err != nil {
- fatalf("Failed to query server version: %v", err)
- }
- log.Printf("Connected to SysDB %d.%d.%d%s.", major, minor, patch, extra)
-
- srv, err := server.New(server.Config{
- Conns: conns,
+ srv, err := server.New(*addr, *username, server.Config{
TemplatePath: *tmpl,
StaticPath: *static,
})
diff --git a/server/graph.go b/server/graph.go
index 11254d6081526e60db2482dea11a1282982a566d..ed5c7fd8338cedb694944674e0cdfe1c440cdca0 100644 (file)
--- a/server/graph.go
+++ b/server/graph.go
"github.com/gonum/plot/plotter"
"github.com/gonum/plot/plotutil"
"github.com/gonum/plot/vg"
+ "github.com/sysdb/go/client"
"github.com/sysdb/go/sysdb"
)
return
}
- res, err := s.query("TIMESERIES %s.%s START %s END %s", req.args[0], req.args[1], start, end)
+ q, err := client.QueryString("TIMESERIES %s.%s START %s END %s", req.args[0], req.args[1], start, end)
+ if err != nil {
+ s.internal(w, fmt.Errorf("Failed to retrieve graph data: %v", err))
+ return
+ }
+ res, err := s.c.Query(q)
if err != nil {
s.internal(w, fmt.Errorf("Failed to retrieve graph data: %v", err))
return
}
- ts, ok := res.(sysdb.Timeseries)
+ ts, ok := res.(*sysdb.Timeseries)
if !ok {
s.internal(w, errors.New("TIMESERIES did not return a time-series"))
return
diff --git a/server/query.go b/server/query.go
index cb74f22f479dcd4bbec5dcd787b82f0fdb992c5c..6d8fddf252d8159e7c3facbf5b7e24b43d5120f5 100644 (file)
--- a/server/query.go
+++ b/server/query.go
import (
"errors"
"fmt"
- "log"
"strings"
"time"
"unicode"
+ "github.com/sysdb/go/client"
"github.com/sysdb/go/proto"
- "github.com/sysdb/go/sysdb"
)
func listAll(req request, s *Server) (*page, error) {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err := s.query("LIST %s", identifier(req.cmd))
+ q, err := client.QueryString("LIST %s", client.Identifier(req.cmd))
+ if err != nil {
+ return nil, err
+ }
+ res, err := s.c.Query(q)
if err != nil {
return nil, err
}
}
}
- res, err := s.query("LOOKUP %s MATCHING"+args, identifier(typ))
+ q, err := client.QueryString("LOOKUP %s MATCHING"+args, client.Identifier(typ))
+ if err != nil {
+ return nil, err
+ }
+ res, err := s.c.Query(q)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- var res interface{}
+ var q string
var err error
switch req.cmd {
case "host":
if len(req.args) != 1 {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err = s.query("FETCH host %s", req.args[0])
+ q, err = client.QueryString("FETCH host %s", req.args[0])
case "service", "metric":
if len(req.args) != 2 {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err = s.query("FETCH %s %s.%s", identifier(req.cmd), req.args[0], req.args[1])
- if err == nil && req.cmd == "metric" {
- return metric(req, res, s)
- }
+ q, err = client.QueryString("FETCH %s %s.%s", client.Identifier(req.cmd), req.args[0], req.args[1])
default:
panic("Unknown request: fetch(" + req.cmd + ")")
}
if err != nil {
return nil, err
}
+
+ res, err := s.c.Query(q)
+ if err != nil {
+ return nil, err
+ }
+ if req.cmd == "metric" {
+ return metric(req, res, s)
+ }
return tmpl(s.results[req.cmd], res)
}
return !unicode.IsSpace(r)
}
-type identifier string
-
-func (s *Server) query(cmd string, args ...interface{}) (interface{}, error) {
- c := <-s.conns
- defer func() { s.conns <- c }()
-
- for i, arg := range args {
- switch v := arg.(type) {
- case identifier:
- // Nothing to do.
- case string:
- args[i] = proto.EscapeString(v)
- case time.Time:
- args[i] = v.Format(datetime)
- default:
- panic(fmt.Sprintf("query: invalid type %T", arg))
- }
- }
-
- cmd = fmt.Sprintf(cmd, args...)
- m := &proto.Message{
- Type: proto.ConnectionQuery,
- Raw: []byte(cmd),
- }
- if err := c.Send(m); err != nil {
- return nil, fmt.Errorf("Query %q: %v", cmd, err)
- }
-
- for {
- m, err := c.Receive()
- if err != nil {
- return nil, fmt.Errorf("Failed to receive server response: %v", err)
- }
- if m.Type == proto.ConnectionLog {
- log.Println(string(m.Raw[4:]))
- continue
- } else if m.Type == proto.ConnectionError {
- return nil, errors.New(string(m.Raw))
- }
-
- t, err := m.DataType()
- if err != nil {
- return nil, fmt.Errorf("Failed to unmarshal response: %v", err)
- }
-
- var res interface{}
- switch t {
- case proto.HostList:
- var hosts []sysdb.Host
- err = proto.Unmarshal(m, &hosts)
- res = hosts
- case proto.Host:
- var host sysdb.Host
- err = proto.Unmarshal(m, &host)
- res = host
- case proto.Timeseries:
- var ts sysdb.Timeseries
- err = proto.Unmarshal(m, &ts)
- res = ts
- default:
- return nil, fmt.Errorf("Unsupported data type %d", t)
- }
- if err != nil {
- return nil, fmt.Errorf("Failed to unmarshal response: %v", err)
- }
- return res, nil
- }
-}
-
// vim: set tw=78 sw=4 sw=4 noexpandtab :
diff --git a/server/server.go b/server/server.go
index 093c683bb598eabc77e5e8ba76f80955cb39b459..8d0d72dc191770f6810896306ea3f0f3beca64b5 100644 (file)
--- a/server/server.go
+++ b/server/server.go
import (
"bytes"
- "errors"
"fmt"
"html/template"
"io"
+ "log"
"net/http"
"net/url"
"path/filepath"
// A Config specifies configuration values for a SysDB web server.
type Config struct {
- // Conns is a slice of connections to a SysDB server instance. The number of
- // elements specifies the maximum number of parallel queries to the backend.
- // Note that a client connection is not thread-safe but multiple idle
- // connections don't impose any load on the server.
- Conns []*client.Conn
-
// TemplatePath specifies the relative or absolute location of template files.
TemplatePath string
// A Server implements an http.Handler that serves the SysDB user interface.
type Server struct {
- conns chan *client.Conn
+ c *client.Client
// Request multiplexer
mux map[string]handler
}
// New constructs a new SysDB web server using the specified configuration.
-func New(cfg Config) (*Server, error) {
- if len(cfg.Conns) == 0 {
- return nil, errors.New("need at least one client connection")
- }
+func New(addr, user string, cfg Config) (*Server, error) {
+ s := &Server{results: make(map[string]*template.Template)}
- s := &Server{
- conns: make(chan *client.Conn, len(cfg.Conns)),
- results: make(map[string]*template.Template),
+ var err error
+ if s.c, err = client.Connect(addr, user); err != nil {
+ return nil, err
}
- for _, c := range cfg.Conns {
- s.conns <- c
+ if major, minor, patch, extra, err := s.c.ServerVersion(); err == nil {
+ log.Printf("Connected to SysDB %d.%d.%d%s.", major, minor, patch, extra)
}
- var err error
- s.main, err = cfg.parse("main.tmpl")
- if err != nil {
+ if s.main, err = cfg.parse("main.tmpl"); err != nil {
return nil, err
}
-
types := []string{"host", "hosts", "service", "services", "metric", "metrics"}
for _, t := range types {
s.results[t], err = cfg.parse(t + ".tmpl")
}
func index(_ request, s *Server) (*page, error) {
- c := <-s.conns
- defer func() { s.conns <- c }()
-
- major, minor, patch, extra, err := c.ServerVersion()
+ major, minor, patch, extra, err := s.c.ServerVersion()
if err != nil {
return nil, err
}