|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"git.buddy.wtf/buddy/open-hardware-monitor-client/lib/client"
|
|
|
|
"git.buddy.wtf/buddy/open-hardware-monitor-client/lib/metrics"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
|
|
|
// App context
|
|
|
|
type App struct {
|
|
|
|
cli *cli.App
|
|
|
|
Client *client.Client
|
|
|
|
Out io.Writer
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
// FlagHost flag for host
|
|
|
|
FlagHost = cli.StringFlag{
|
|
|
|
Name: "host",
|
|
|
|
EnvVar: "OHWM_HOST",
|
|
|
|
Value: "127.0.0.1:8085",
|
|
|
|
Usage: "open hardware monitor host [OSHW_HOST]",
|
|
|
|
}
|
|
|
|
|
|
|
|
// FlagScheme flag for host
|
|
|
|
FlagScheme = cli.StringFlag{
|
|
|
|
Name: "scheme",
|
|
|
|
EnvVar: "OHWM_SCHEME",
|
|
|
|
Value: "http",
|
|
|
|
Usage: "open hardware monitor scheme (http/https)",
|
|
|
|
}
|
|
|
|
|
|
|
|
// FlagPath flag for path url
|
|
|
|
FlagPath = cli.StringFlag{
|
|
|
|
Name: "path",
|
|
|
|
EnvVar: "OHWM_PATH",
|
|
|
|
Value: "/data.json",
|
|
|
|
Usage: "open hardware monitor path (ie /data.json)",
|
|
|
|
}
|
|
|
|
|
|
|
|
// FlagInterface flag for host
|
|
|
|
FlagInterface = cli.StringFlag{
|
|
|
|
Name: "http",
|
|
|
|
EnvVar: "OHWM_HTTP",
|
|
|
|
Value: ":9200",
|
|
|
|
Usage: "interface to serve http requests",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// New returns instance of an app
|
|
|
|
func New() *App {
|
|
|
|
cliapp := cli.NewApp()
|
|
|
|
app := &App{
|
|
|
|
Out: os.Stdout,
|
|
|
|
cli: cliapp,
|
|
|
|
}
|
|
|
|
|
|
|
|
app.cli.Name = "ohwm-client"
|
|
|
|
app.cli.Description = "Open Hardware Manager Client"
|
|
|
|
app.cli.UsageText = "ohwm-client [flags] <command> [flags]"
|
|
|
|
app.cli.HideVersion = true
|
|
|
|
|
|
|
|
app.cli.Flags = []cli.Flag{
|
|
|
|
FlagHost,
|
|
|
|
FlagScheme,
|
|
|
|
FlagPath,
|
|
|
|
}
|
|
|
|
|
|
|
|
app.cli.Commands = []cli.Command{
|
|
|
|
cli.Command{
|
|
|
|
Name: "print",
|
|
|
|
Usage: "pretty prints api result",
|
|
|
|
Action: app.ActionPrint,
|
|
|
|
},
|
|
|
|
cli.Command{
|
|
|
|
Name: "export",
|
|
|
|
Usage: "runs http exporter for prometheus",
|
|
|
|
Action: app.ActionMetrics,
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
FlagInterface,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
app.cli.Before = app.Before
|
|
|
|
return app
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run runs cli action
|
|
|
|
func (a *App) Run(args []string) error {
|
|
|
|
return a.cli.Run(args)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Before sets up app
|
|
|
|
func (a *App) Before(ctx *cli.Context) error {
|
|
|
|
a.Client = &client.Client{
|
|
|
|
URL: url.URL{
|
|
|
|
Scheme: ctx.String("scheme"),
|
|
|
|
Host: ctx.String("host"),
|
|
|
|
Path: ctx.String("path"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ActionPrint prints api result
|
|
|
|
func (a *App) ActionPrint(_ *cli.Context) error {
|
|
|
|
node, err := a.Client.Fetch()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fmt.Fprint(a.Out, node.Stringify())
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ActionMetrics serves http
|
|
|
|
func (a *App) ActionMetrics(ctx *cli.Context) error {
|
|
|
|
addr := ctx.String("http")
|
|
|
|
http.HandleFunc("/metrics", a.HandleMetrics)
|
|
|
|
log.Println("listen on: " + addr)
|
|
|
|
return http.ListenAndServe(addr, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// HandleMetrics handler
|
|
|
|
func (a *App) HandleMetrics(resp http.ResponseWriter, req *http.Request) {
|
|
|
|
log.Println("GET /metrics")
|
|
|
|
root, err := a.Client.Fetch()
|
|
|
|
if err != nil {
|
|
|
|
http.Error(resp, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
vals, err := root.Values()
|
|
|
|
if err != nil {
|
|
|
|
http.Error(resp, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
collection := metrics.FromVals(vals)
|
|
|
|
registry := prometheus.NewRegistry()
|
|
|
|
if err := registry.Register(collection); err != nil {
|
|
|
|
http.Error(resp, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{
|
|
|
|
Registry: registry,
|
|
|
|
})
|
|
|
|
|
|
|
|
handler.ServeHTTP(resp, req)
|
|
|
|
registry.Unregister(collection)
|
|
|
|
}
|