diff --git a/collector/collector.go b/collector/collector.go index 4895f30..7c9b279 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -171,6 +171,56 @@ func GetServerIDFromVarz(endpoint string, retryInterval time.Duration) string { return id } +func GetServerNameFromVarz(endpoint string, retryInterval time.Duration) string { + getServerName := func() (string, error) { + resp, err := http.DefaultClient.Get(endpoint + "/varz") + if err != nil { + return "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + var response map[string]interface{} + err = json.Unmarshal(body, &response) + if err != nil { + return "", err + } + serverName, ok := response["server_name"] + if !ok { + Fatalf("Could not find server name in /varz") + } + id, ok := serverName.(string) + if !ok { + Fatalf("Invalid server_name type in /varz: %+v", serverName) + } + + return id, nil + } + + var id string + var err error + id, err = getServerName() + if err == nil { + return id + } + + // Retry periodically until available, in case it never starts + // then a liveness check against the NATS Server itself should + // detect that an restart the server, in terms of the exporter + // we just wait for it to eventually be available. + for range time.NewTicker(retryInterval).C { + id, err = getServerName() + if err != nil { + Errorf("Could not find server id: %s", err) + continue + } + break + } + return id +} + // Describe the metric to the Prometheus server. func (nc *NATSCollector) Describe(ch chan<- *prometheus.Desc) { nc.Lock() diff --git a/exporter/exporter.go b/exporter/exporter.go index 2a475f0..acb6a0c 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -41,31 +41,32 @@ const ( // NATSExporterOptions are options to configure the NATS collector type NATSExporterOptions struct { collector.LoggerOptions - ListenAddress string - ListenPort int - ScrapePath string - GetHealthz bool - GetConnz bool - GetConnzDetailed bool - GetVarz bool - GetSubz bool - GetRoutez bool - GetGatewayz bool - GetLeafz bool - GetReplicatorVarz bool - GetStreamingChannelz bool - GetStreamingServerz bool - GetJszFilter string - RetryInterval time.Duration - CertFile string - KeyFile string - CaFile string - NATSServerURL string - NATSServerTag string - HTTPUser string // User in metrics scrape by prometheus. - HTTPPassword string - Prefix string - UseInternalServerID bool + ListenAddress string + ListenPort int + ScrapePath string + GetHealthz bool + GetConnz bool + GetConnzDetailed bool + GetVarz bool + GetSubz bool + GetRoutez bool + GetGatewayz bool + GetLeafz bool + GetReplicatorVarz bool + GetStreamingChannelz bool + GetStreamingServerz bool + GetJszFilter string + RetryInterval time.Duration + CertFile string + KeyFile string + CaFile string + NATSServerURL string + NATSServerTag string + HTTPUser string // User in metrics scrape by prometheus. + HTTPPassword string + Prefix string + UseInternalServerID bool + UseInternalServerName bool } // NATSExporter collects NATS metrics @@ -175,7 +176,7 @@ func (ne *NATSExporter) InitializeCollectors() error { } getJsz := opts.GetJszFilter != "" - if !opts.GetHealthz && !opts.GetConnz && !opts.GetConnzDetailed && !opts.GetRoutez && + if !opts.GetConnz && !opts.GetRoutez && !opts.GetSubz && !opts.GetVarz && !opts.GetGatewayz && !opts.GetLeafz && !opts.GetStreamingChannelz && !opts.GetStreamingServerz && !opts.GetReplicatorVarz && !getJsz { return fmt.Errorf("no Collectors specfied") diff --git a/main.go b/main.go index a6138c3..4c5254e 100644 --- a/main.go +++ b/main.go @@ -130,6 +130,7 @@ func main() { flag.StringVar(&opts.HTTPPassword, "http_pass", "", "Set the password for HTTP scrapes. NATS bcrypt supported.") flag.StringVar(&opts.Prefix, "prefix", "", "Replace the default prefix for all the metrics.") flag.BoolVar(&opts.UseInternalServerID, "use_internal_server_id", false, "Enables using ServerID from /varz") + flag.BoolVar(&opts.UseInternalServerName, "use_internal_server_name", false, "Enables using ServerName from /varz") flag.Parse() opts.RetryInterval = time.Duration(retryInterval) * time.Second @@ -165,6 +166,13 @@ necessary.`) if err := exp.AddServer(id, url); err != nil { collector.Fatalf("Unable to setup server in exporter: %s, %s: %v", id, url, err) } + } else if len(args) == 1 && opts.UseInternalServerID { + // Pick the server id from the /varz endpoint info. + url := flag.Args()[0] + id := collector.GetServerNameFromVarz(url, opts.RetryInterval) + if err := exp.AddServer(id, url); err != nil { + collector.Fatalf("Unable to setup server in exporter: %s, %s: %v", id, url, err) + } } else { // For each URL specified, add the NATS server with the optional ID. for _, arg := range args {