Skip to content

Commit

Permalink
Merge branch 'FEAT/web-dashboard' of github.com:bisohns/saido into FE…
Browse files Browse the repository at this point in the history
…AT/web-dashboard
  • Loading branch information
Nurudeen38 committed Nov 12, 2022
2 parents 4009356 + 1c2aacf commit 4eef6a2
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 109 deletions.
55 changes: 0 additions & 55 deletions .air.toml

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ ssh-key/ci/
config-ci.yaml
config-test.yaml
tmp/
cmd/build/
*-packr.go
.air.toml
27 changes: 26 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
version=fake
ifeq ($(OS),Windows_NT)
bin=main.exe
else
bin=main
endif
# Example:
# make
# make prep-ci-ssh
Expand All @@ -18,7 +24,7 @@ prep-ci-local-windows:
cp ".\scripts\config.local.yaml" ".\config-test.yaml"
cat config-test.yaml

ifneq($(findstring fake, $(version)), fake)
ifneq ($(findstring fake, $(version)), fake)
upgrade:
@echo ">>> Recreating version_num.go"
@echo 'package cmd\n\nconst Version = "$(version)"' > cmd/version_num.go
Expand All @@ -30,3 +36,22 @@ else
upgrade:
@echo "Version not set - use syntax \`make upgrade version=0.x.x\`"
endif

dependencies:
ifeq ($(bin),main.exe)
@make prep-ci-local-windows
else
@make prep-ci-local
endif
go get .
cd web && yarn install && cd ..

.PHONY: build-frontend
build-frontend:
cd web && yarn build && cd ..

.PHONY: serve-backend
serve-backend:
air --build.cmd "go build -o ./tmp/$(bin) ." --build.bin "tmp/$(bin)" --build.exclude_dir "assets,docs,tmp,web,scripts,ssh-key,.github,.git" --build.include_ext "go,yaml,html,js" --build.exclude_file "config.example.yaml" --build.args_bin "dashboard,--config,config-test.yaml" --build.stop_on_error true --misc.clean_on_exit true --log.time true

app: build-frontend serve-backend
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,28 @@ For personal usage, install latest from [Github Releases](https://github.com/bis

```bash
# binary is downloaded and named as saido
saido api
saido dashboard --config config.yaml --port 3000
```


### Development

With Golang installed, run
#### Requirements
- [Golang](https://go.dev/doc/install)
- [Docker](https://docs.docker.com/get-docker/)
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/)
- [Air](https://github.com/cosmtrek/air)

```bash
git clone https://github.com/bisohns/saido
cd saido
## Update Golang dependencies
go get .
## Update dependencies
make dependencies

## Update yarn dependencies
cd web
yarn install
# Build and serve frontend
make app

# Run websocket server and serve frontend
go run main.go dashboard --config config-test.yaml
# Modify generated `config-test.yaml` file and air would reload server
```

## Deployment
Expand Down
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (client *Client) Write() {
if err != nil {
log.Error("Error inside client write ", err)
// check socket connection has been closed and end writer
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure, websocket.CloseInternalServerErr) || err == websocket.ErrCloseSent {
return
}
}
Expand Down
17 changes: 10 additions & 7 deletions client/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func (hosts *HostsController) sendMetric(host config.Host, client *Client) {
hosts.resetDriver(host)
}
for metric, custom := range hosts.Info.Metrics {
driver := hosts.getDriver(host.Address)
initializedMetric, err := inspector.Init(metric, driver, custom)
inspectorDriver := hosts.getDriver(host.Address)
initializedMetric, err := inspector.Init(metric, inspectorDriver, custom)
if err != nil {
log.Error(err)
}
Expand All @@ -86,7 +86,7 @@ func (hosts *HostsController) sendMetric(host config.Host, client *Client) {
message := &SendMessage{
Message: Message{
Host: host.Address,
Platform: (*driver).GetDetails().Name,
Platform: (*inspectorDriver).GetDetails().Name,
Name: metric,
Data: unmarsh,
},
Expand All @@ -99,12 +99,15 @@ func (hosts *HostsController) sendMetric(host config.Host, client *Client) {
// check for error 127 which means command was not found
var errorContent string
if !strings.Contains(fmt.Sprintf("%s", err), "127") {
errorContent = fmt.Sprintf("Could not retrieve metric %s from driver %s with error %s, resetting connection...", metric, host.Address, err)
errorContent = fmt.Sprintf("Could not retrieve metric %s from driver %s with error %s", metric, host.Address, err)
} else {
errorContent = fmt.Sprintf("Command %s not found on driver %s", metric, host.Address)
}
log.Error(errorContent)
hosts.resetDriver(host)
log.Debug(errorContent)
//FIXME: what kind of errors do we especially want to reset driver for
if _, ok := err.(*driver.SSHConnectError); ok {
hosts.resetDriver(host)
}
message := &SendMessage{
Message: ErrorMessage{
Error: errorContent,
Expand All @@ -128,7 +131,7 @@ func (hosts *HostsController) Poll(client *Client) {
go hosts.sendMetric(host, client)
}
}
log.Infof("Delaying for %d seconds", hosts.Info.PollInterval)
log.Debugf("Delaying for %d seconds", hosts.Info.PollInterval)
time.Sleep(time.Duration(hosts.Info.PollInterval) * time.Second)
}
}
Expand Down
46 changes: 46 additions & 0 deletions cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,79 @@ limitations under the License.
package cmd

import (
"embed"
"fmt"
"io/fs"
"net/http"
"os"
"path"
"strconv"

"github.com/bisohns/saido/client"
"github.com/bisohns/saido/config"
"github.com/gorilla/handlers"
"github.com/pkg/browser"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var (
port string
server = http.NewServeMux()

//go:embed build/*
build embed.FS
cfgFile string
cfg *config.Config
)

type fsFunc func(name string) (fs.File, error)

func (f fsFunc) Open(name string) (fs.File, error) {
return f(name)
}

func EmbedHandler(prefix, root string) http.Handler {
handler := fsFunc(func(name string) (fs.File, error) {
assetPath := path.Join(root, name)

// If we can't find the asset, return the default index.html
// build
f, err := build.Open(assetPath)
if os.IsNotExist(err) {
return build.Open(fmt.Sprintf("%s/index.html", root))
}

// Otherwise assume this is a legitimate request routed
// correctly
return f, err
})

return http.StripPrefix(prefix, http.FileServer(http.FS(handler)))
}

var apiCmd = &cobra.Command{
Use: "dashboard",
Short: "Run saido dashboard on a PORT env variable, fallback to set argument",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
cfg = config.LoadConfig(cfgFile)
hosts := client.NewHostsController(cfg)

frontendHandler := EmbedHandler("/", "build")
server.Handle("/", frontendHandler)
server.Handle("/metrics", hosts)
server.Handle("/*filepath", frontendHandler)
log.Info("listening on :", port)
_, err := strconv.Atoi(port)
if err != nil {
log.Fatal(err)
}
go hosts.Run()
loggedRouters := handlers.LoggingHandler(os.Stdout, server)
// Trigger browser open
url := fmt.Sprintf("http://localhost:%s", port)
browser.OpenURL(url)
if err := http.ListenAndServe(":"+port, loggedRouters); err != nil {
log.Fatal(err)
}
Expand All @@ -53,5 +97,7 @@ var apiCmd = &cobra.Command{

func init() {
apiCmd.Flags().StringVarP(&port, "port", "p", "3000", "Port to run application server on")
apiCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "Path to config file")
cobra.MarkFlagRequired(apiCmd.PersistentFlags(), "config")
rootCmd.AddCommand(apiCmd)
}
22 changes: 5 additions & 17 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ import (
)

var (
cfgFile string
cfg *config.Config

// Verbose : Should display verbose logs
verbose bool
dashboardInfo *config.DashboardInfo
Expand All @@ -39,22 +36,21 @@ const appName = "saido"
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "saido",
Short: "TUI for monitoring specific host metrics",
Short: "Tool for monitoring metrics",
Long: ``,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Log only errors except in Verbose mode
if verbose {
log.SetLevel(log.DebugLevel)
} else {
// log.SetLevel(log.InfoLevel)
log.SetLevel(log.DebugLevel)
log.SetLevel(log.InfoLevel)
}
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
fmt.Println("\n\nSaido - Bisoncorp (2020) (https://github.com/bisohns/saido)")
fmt.Println("\n\nSaido - Bisohns (2020) (https://github.com/bisohns/saido)")
},
Run: func(cmd *cobra.Command, args []string) {
log.Info("Saido is running ...")
log.Info("Run dashboard with the [dashboard] subcommand. Feel free to drop a star at https://github.com/bisohns/saido")
},
}

Expand All @@ -68,13 +64,5 @@ func Execute() {
}

func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "Path to config file")

cobra.MarkFlagRequired(rootCmd.PersistentFlags(), "config")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
cfg = config.LoadConfig(cfgFile)
rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Run saido in verbose mode")
}
2 changes: 1 addition & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ metrics:
custom-uptime: "cat /proc/uptime"
custom-dir: 'dir C:\'
custom-echo: 'echo $HOME'
poll-interval: 30
poll-interval: 10
4 changes: 2 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ func GetDashboardInfoConfig(config *Config) *DashboardInfo {
for _, host := range dashboardInfo.Hosts {
log.Debugf("%s: %v", host.Address, host.Connection)
}
if config.PollInterval < 10 {
log.Fatal("Cannot set poll interval below 10 seconds")
if config.PollInterval < 5 {
log.Fatal("Cannot set poll interval below 5 seconds")
}
dashboardInfo.PollInterval = config.PollInterval
return dashboardInfo
Expand Down
Loading

0 comments on commit 4eef6a2

Please sign in to comment.