Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use logrus for logging #94

Merged
merged 4 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ Flags:
--http-tlskey string Private key for server certificate (used with HTTPS).
--http-user string Enable basic auth and set user name for HTTP scrapes.
--jetstream string Listen for JetStream Advisories based on config files in a directory.
--log-level string Log level, one of: trace|debug|info|warn|error|fatal|panic (default "info")
--nkey string Nkey Seed File
--observe string Listen for observation statistics based on config files in a directory.
--password string NATS user password
-p, --port int Port to listen on. (default 7777)
--prefix string Replace the default prefix for all the metrics.
-s, --servers string NATS Cluster url(s) (default "nats://127.0.0.1:4222")
--timeout duration Polling timeout (default 3s)
--tlscacert string Client certificate CA on NATS connecctions.
--tlscacert string Client certificate CA on NATS connections.
--tlscert string Client certificate file for NATS connections.
--tlskey string Client private key for NATS connections.
--user string NATS user name or token
Expand All @@ -58,22 +59,29 @@ At this time, NATS 2.0 System credentials are required for meaningful usage.

### Config Files

Surveyor uses Viper to read configs so it will support all file types that Viper supports (JSON, TOML, YAML, HCL, envfile, and Java properties)
Surveyor uses Viper to read configs, so it will support all file types that Viper supports (JSON, TOML, YAML, HCL, envfile, and Java properties)

To use a config file pass the `--config` flag. The defaults are `/etc/nats-surveyor/nats-surveyor[.ext]` and `./nats-surveyor[.ext]` with one of the supported extensions.

The config is simple, just set each flag in the config file. For example:
The config is simple, just set each flag in the config file. Example `nats-surveyor.yaml`:

```
```yaml
servers: nats://127.0.0.1:4222
accounts: true
log-level: debug
```

### Environment Variables

Environment variables are also taken into account. Any environment variable that is prefixed with `NATS_SURVEYOR` will be read.
Environment variables are also taken into account. Any environment variable that is prefixed with `NATS_SURVEYOR_` will be read.

Each flag has a matching environment variable, flag names should be converted to uppercase and dashes replaced with underscores. Example:

For example to enable accounts set `NATS_SURVEYOR_ACCOUNTS=true`
```
NATS_SURVEYOR_SERVERS=nats://127.0.0.1:4222
NATS_SURVEYOR_ACCOUNTS=true
NATS_SURVEYOR_LOG_LEVEL=debug
```

## Metrics

Expand Down
82 changes: 50 additions & 32 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ package cmd

import (
"fmt"
"log"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"

nested "github.com/antonfisher/nested-logrus-formatter"
"github.com/nats-io/nats-surveyor/surveyor"
"github.com/nats-io/nats.go"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand All @@ -35,11 +37,12 @@ var (
Use: "nats-surveyor",
Short: "Prometheus exporter for NATS",
RunE: run,
Version: "v0.3.1",
Version: "v0.4.0",
}
logger = logrus.New()
)

// long flags that introduced <=v0.2.2 originally used 'flag' package must be parsed as legacy flags
// long flags that were introduced <=v0.2.2 originally used 'flag' package must be parsed as legacy flags
// to preserve the behavior where long flags could be supplied with a single dash
func rootCmdArgs(args []string) []string {
// old flag: new flag
Expand Down Expand Up @@ -79,7 +82,7 @@ func rootCmdArgs(args []string) []string {
argSplit := strings.SplitN(arg, "=", 2)
newArg, exists := legacyFlagMap[argSplit[0]]
if exists {
log.Printf("flag '%s' is deprecated and may be removed in a future relese, use '%s' instead", argSplit[0], newArg)
logger.Warnf("flag '%s' is deprecated and may be removed in a future relese, use '%s' instead", argSplit[0], newArg)
if len(argSplit) == 1 {
newArgs = append(newArgs, newArg)
} else {
Expand All @@ -104,6 +107,7 @@ func Execute() {

func initConfig() {
viper.SetEnvPrefix("nats_surveyor")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()

if cfgFile != "" {
Expand All @@ -116,101 +120,108 @@ func initConfig() {

if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
log.Println(err)
os.Exit(1)
logger.Fatalln(err)
}
} else {
log.Printf("Using config: %s\n", viper.ConfigFileUsed())
logger.Infof("Using config: %s", viper.ConfigFileUsed())
}
}

func init() {
logger.SetFormatter(&nested.Formatter{
TimestampFormat: time.RFC3339,
})

// config
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./nats-surveyor.yaml)")

// servers
rootCmd.Flags().StringP("servers", "s", nats.DefaultURL, "NATS Cluster url(s)")
viper.BindPFlag("servers", rootCmd.Flags().Lookup("servers"))
_ = viper.BindPFlag("servers", rootCmd.Flags().Lookup("servers"))

// creds
rootCmd.Flags().String("creds", "", "Credentials File")
viper.BindPFlag("creds", rootCmd.Flags().Lookup("creds"))
_ = viper.BindPFlag("creds", rootCmd.Flags().Lookup("creds"))

// nkey
rootCmd.Flags().String("nkey", "", "Nkey Seed File")
viper.BindPFlag("nkey", rootCmd.Flags().Lookup("nkey"))
_ = viper.BindPFlag("nkey", rootCmd.Flags().Lookup("nkey"))

// user
rootCmd.Flags().String("user", "", "NATS user name or token")
viper.BindPFlag("user", rootCmd.Flags().Lookup("user"))
_ = viper.BindPFlag("user", rootCmd.Flags().Lookup("user"))

// password
rootCmd.Flags().String("password", "", "NATS user password")
viper.BindPFlag("password", rootCmd.Flags().Lookup("password"))
_ = viper.BindPFlag("password", rootCmd.Flags().Lookup("password"))

// count
rootCmd.Flags().IntP("count", "c", 1, "Expected number of servers")
viper.BindPFlag("count", rootCmd.Flags().Lookup("count"))
_ = viper.BindPFlag("count", rootCmd.Flags().Lookup("count"))

// timeout
rootCmd.Flags().Duration("timeout", surveyor.DefaultPollTimeout, "Polling timeout")
viper.BindPFlag("timeout", rootCmd.Flags().Lookup("timeout"))
_ = viper.BindPFlag("timeout", rootCmd.Flags().Lookup("timeout"))

// port
rootCmd.Flags().IntP("port", "p", surveyor.DefaultListenPort, "Port to listen on.")
viper.BindPFlag("port", rootCmd.Flags().Lookup("port"))
_ = viper.BindPFlag("port", rootCmd.Flags().Lookup("port"))

// addr
rootCmd.Flags().StringP("addr", "a", surveyor.DefaultListenAddress, "Network host to listen on.")
viper.BindPFlag("addr", rootCmd.Flags().Lookup("addr"))
_ = viper.BindPFlag("addr", rootCmd.Flags().Lookup("addr"))

// tlscert
rootCmd.Flags().String("tlscert", "", "Client certificate file for NATS connections.")
viper.BindPFlag("tlscert", rootCmd.Flags().Lookup("tlscert"))
_ = viper.BindPFlag("tlscert", rootCmd.Flags().Lookup("tlscert"))

// tlskey
rootCmd.Flags().String("tlskey", "", "Client private key for NATS connections.")
viper.BindPFlag("tlskey", rootCmd.Flags().Lookup("tlskey"))
_ = viper.BindPFlag("tlskey", rootCmd.Flags().Lookup("tlskey"))

// tlscacert
rootCmd.Flags().String("tlscacert", "", "Client certificate CA on NATS connecctions.")
viper.BindPFlag("tlscacert", rootCmd.Flags().Lookup("tlscacert"))
rootCmd.Flags().String("tlscacert", "", "Client certificate CA on NATS connections.")
_ = viper.BindPFlag("tlscacert", rootCmd.Flags().Lookup("tlscacert"))

// http-tlscert
rootCmd.Flags().String("http-tlscert", "", "Server certificate file (Enables HTTPS).")
viper.BindPFlag("http-tlscert", rootCmd.Flags().Lookup("http-tlscert"))
_ = viper.BindPFlag("http-tlscert", rootCmd.Flags().Lookup("http-tlscert"))

// http-tlskey
rootCmd.Flags().String("http-tlskey", "", "Private key for server certificate (used with HTTPS).")
viper.BindPFlag("http-tlskey", rootCmd.Flags().Lookup("http-tlskey"))
_ = viper.BindPFlag("http-tlskey", rootCmd.Flags().Lookup("http-tlskey"))

// http-tlscacert
rootCmd.Flags().String("http-tlscacert", "", "Client certificate CA for verification (used with HTTPS).")
viper.BindPFlag("http-tlscacert", rootCmd.Flags().Lookup("http-tlscacert"))
_ = viper.BindPFlag("http-tlscacert", rootCmd.Flags().Lookup("http-tlscacert"))

// http-user
rootCmd.Flags().String("http-user", "", "Enable basic auth and set user name for HTTP scrapes.")
viper.BindPFlag("http-user", rootCmd.Flags().Lookup("http-user"))
_ = viper.BindPFlag("http-user", rootCmd.Flags().Lookup("http-user"))

// http-pass
rootCmd.Flags().String("http-pass", "", "Set the password for HTTP scrapes. NATS bcrypt supported.")
viper.BindPFlag("http-pass", rootCmd.Flags().Lookup("http-pass"))
_ = viper.BindPFlag("http-pass", rootCmd.Flags().Lookup("http-pass"))

// prefix
rootCmd.Flags().String("prefix", "", "Replace the default prefix for all the metrics.")
viper.BindPFlag("prefix", rootCmd.Flags().Lookup("prefix"))
_ = viper.BindPFlag("prefix", rootCmd.Flags().Lookup("prefix"))

// observe
rootCmd.Flags().String("observe", "", "Listen for observation statistics based on config files in a directory.")
viper.BindPFlag("observe", rootCmd.Flags().Lookup("observe"))
_ = viper.BindPFlag("observe", rootCmd.Flags().Lookup("observe"))

// jetstream
rootCmd.Flags().String("jetstream", "", "Listen for JetStream Advisories based on config files in a directory.")
viper.BindPFlag("jetstream", rootCmd.Flags().Lookup("jetstream"))
_ = viper.BindPFlag("jetstream", rootCmd.Flags().Lookup("jetstream"))

// accounts
rootCmd.Flags().Bool("accounts", false, "Export per account metrics")
viper.BindPFlag("accounts", rootCmd.Flags().Lookup("accounts"))
_ = viper.BindPFlag("accounts", rootCmd.Flags().Lookup("accounts"))

// log-level
rootCmd.Flags().String("log-level", "info", "Log level, one of: trace|debug|info|warn|error|fatal|panic")
_ = viper.BindPFlag("log-level", rootCmd.Flags().Lookup("log-level"))

cobra.OnInitialize(initConfig)
}
Expand Down Expand Up @@ -239,6 +250,14 @@ func getSurveyorOpts() *surveyor.Options {
opts.JetStreamConfigDir = viper.GetString("jetstream")
opts.Accounts = viper.GetBool("accounts")

logLevel, err := logrus.ParseLevel(viper.GetString("log-level"))
if err == nil {
logger.SetLevel(logLevel)
} else {
logger.Warnln(err)
}
opts.Logger = logger

return opts
}

Expand All @@ -254,7 +273,7 @@ func run(cmd *cobra.Command, args []string) error {
return fmt.Errorf("couldn't start surveyor: %s", err)
}

// Setup the interrupt handler to gracefully exit.
// set up the interrupt handler to gracefully exit.
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGQUIT)
go func() {
Expand All @@ -265,7 +284,7 @@ func run(cmd *cobra.Command, args []string) error {
case syscall.SIGQUIT:
buf := make([]byte, 1<<20)
stacklen := runtime.Stack(buf, true)
fmt.Fprintln(os.Stderr, string(buf[:stacklen]))
logger.Warnln(string(buf[:stacklen]))

default:
s.Stop()
Expand All @@ -275,6 +294,5 @@ func run(cmd *cobra.Command, args []string) error {
}()

runtime.Goexit()

return nil
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ module github.com/nats-io/nats-surveyor
go 1.18

require (
github.com/antonfisher/nested-logrus-formatter v1.3.1
github.com/nats-io/jsm.go v0.0.33
github.com/nats-io/nats-server/v2 v2.8.4
github.com/nats-io/nats.go v1.16.0
github.com/nats-io/nuid v1.0.1
github.com/prometheus/client_golang v1.12.1
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.12.0
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
Expand Down Expand Up @@ -38,7 +40,7 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.3.0 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
google.golang.org/protobuf v1.28.0 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ=
github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -238,6 +240,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
Expand Down Expand Up @@ -415,8 +419,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
Loading