diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 05afd0bf..e518931a 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -46,6 +46,9 @@ type Config struct { OtelPushInterval uint8 `toml:"push_interval"` OtelServerStatFetchInterval uint8 `toml:"server_stat_fetch_interval"` } `toml:"OpenTelemetry"` + + IsKubernetes bool + KubernetesPodName string } `toml:"Agent"` Aerospike struct { @@ -200,6 +203,27 @@ func (c *Config) FetchCloudInfo(md toml.MetaData) { } } +func (c *Config) FetchKubernetesInfo(md toml.MetaData) { + // use kubectl to fetch required Kubernetes context and find the required Kubenetes environment variables + envKubeServiceHost := os.Getenv("KUBERNETES_SERVICE_HOST") + + Cfg.Agent.IsKubernetes = false + + if envKubeServiceHost != "" && len(strings.TrimSpace(envKubeServiceHost)) > 0 { + Cfg.Agent.IsKubernetes = true + log.Info("Exporter is running in Kubernetes") + + // get host-name + var err error + Cfg.Agent.KubernetesPodName, err = os.Hostname() + if err != nil { + log.Errorln(err) + return + } + + } +} + // Initialize exporter configuration func InitConfig(configFile string) { // to print everything out regarding reading the config in app init @@ -225,6 +249,8 @@ func InitConfig(configFile string) { Cfg.ValidateAndUpdate(md) Cfg.FetchCloudInfo(md) + + Cfg.FetchKubernetesInfo(md) } // Set log file path diff --git a/internal/pkg/executors/otel_metrics.go b/internal/pkg/executors/otel_metrics.go index 691e05fc..8254810d 100644 --- a/internal/pkg/executors/otel_metrics.go +++ b/internal/pkg/executors/otel_metrics.go @@ -18,6 +18,10 @@ func sendNodeUp(meter metric.Meter, ctx context.Context, commonLabels []attribut metric.WithDescription("Aerospike node active status"), ) + if config.Cfg.Agent.IsKubernetes { + statprocessors.Service = config.Cfg.Agent.KubernetesPodName + } + labels := []attribute.KeyValue{ attribute.String("cluster_name", statprocessors.ClusterName), attribute.String("service", statprocessors.Service), diff --git a/internal/pkg/executors/prometheus.go b/internal/pkg/executors/prometheus.go index 055f0040..ed2b28f5 100644 --- a/internal/pkg/executors/prometheus.go +++ b/internal/pkg/executors/prometheus.go @@ -63,6 +63,10 @@ func (o *PrometheusImpl) Collect(ch chan<- prometheus.Metric) { return } + // if kubernetes then send host-name/pod-name else send server-ip as-isnh + if config.Cfg.Agent.IsKubernetes { + statprocessors.Service = config.Cfg.Agent.KubernetesPodName + } ch <- prometheus.MustNewConstMetric(nodeActiveDesc, prometheus.GaugeValue, 1.0, statprocessors.ClusterName, statprocessors.Service, statprocessors.Build) for _, wm := range refreshed_metrics { diff --git a/internal/pkg/statprocessors/sp_host_systeminfo.go b/internal/pkg/statprocessors/sp_host_systeminfo.go index 104c6c0e..26e7bbe5 100644 --- a/internal/pkg/statprocessors/sp_host_systeminfo.go +++ b/internal/pkg/statprocessors/sp_host_systeminfo.go @@ -121,8 +121,6 @@ func getNetworkInfo() []AerospikeStat { arrReceiveStats, arrTransferStats := dataprovider.GetSystemProvider().GetNetDevStats() // netdev receive - clusterName := ClusterName - service := Service for _, stats := range arrReceiveStats { deviceName := stats["device_name"] statName := "receive_bytes_total" @@ -132,7 +130,7 @@ func getNetworkInfo() []AerospikeStat { continue } - labelValues := []string{clusterName, service, deviceName} + labelValues := []string{ClusterName, Service, deviceName} allowed := isMetricAllowed(commons.CTX_SYSINFO_NETWORK_STATS, statName) sysMetric := NewAerospikeStat(commons.CTX_SYSINFO_NETWORK_STATS, statName, allowed) @@ -154,7 +152,7 @@ func getNetworkInfo() []AerospikeStat { continue } - labelValues := []string{clusterName, service, deviceName} + labelValues := []string{ClusterName, Service, deviceName} allowed := isMetricAllowed(commons.CTX_SYSINFO_NETWORK_STATS, statName) sysMetric := NewAerospikeStat(commons.CTX_SYSINFO_NETWORK_STATS, statName, allowed) sysMetric.Labels = networkLabels diff --git a/internal/pkg/statprocessors/sp_latency.go b/internal/pkg/statprocessors/sp_latency.go index 614a7e09..d38dd0a2 100644 --- a/internal/pkg/statprocessors/sp_latency.go +++ b/internal/pkg/statprocessors/sp_latency.go @@ -4,7 +4,7 @@ import ( "strings" commons "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/commons" - "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/config" + config "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/config" log "github.com/sirupsen/logrus" ) diff --git a/internal/pkg/statprocessors/sp_namespaces.go b/internal/pkg/statprocessors/sp_namespaces.go index de364b65..93998bc3 100644 --- a/internal/pkg/statprocessors/sp_namespaces.go +++ b/internal/pkg/statprocessors/sp_namespaces.go @@ -123,7 +123,7 @@ func (nw *NamespaceStatsProcessor) refreshIndexPressure(singleInfoKey string, in nsName := values[0] labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_NS} - labelValues := []string{rawMetrics[Infokey_ClusterName], rawMetrics[Infokey_Service], nsName} + labelValues := []string{ClusterName, Service, nsName} // Server index-pressure output: test:0:0;bar_device:0:0;materials:0:0 // ignore first element - namespace @@ -182,7 +182,7 @@ func (nw *NamespaceStatsProcessor) refreshNamespaceStats(singleInfoKey string, i // default: aerospike_namespace_ constructedStatname = stat labels = []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_NS} - labelValues = []string{rawMetrics[Infokey_ClusterName], rawMetrics[Infokey_Service], nsName} + labelValues = []string{ClusterName, Service, nsName} if isArrayType { constructedStatname, labels, labelValues = nw.handleArrayStats(nsName, stat, pv, stats, deviceType, rawMetrics) @@ -287,7 +287,7 @@ func (nw *NamespaceStatsProcessor) handleArrayStats(nsName string, statToProcess compositeStatName := deviceType + "_" + statType + "_" + statName deviceOrFileName := allNamespaceStats[deviceType+"."+statType+"["+statIndex+"]"] labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_NS, statType + "_index", statType} - labelValues := []string{rawMetrics[Infokey_ClusterName], rawMetrics[Infokey_Service], nsName, statIndex, deviceOrFileName} + labelValues := []string{ClusterName, Service, nsName, statIndex, deviceOrFileName} return compositeStatName, labels, labelValues diff --git a/internal/pkg/statprocessors/sp_node_stats.go b/internal/pkg/statprocessors/sp_node_stats.go index f1355a90..6282a912 100644 --- a/internal/pkg/statprocessors/sp_node_stats.go +++ b/internal/pkg/statprocessors/sp_node_stats.go @@ -42,17 +42,14 @@ func (sw *NodeStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]s log.Tracef("node-configs:%s", nodeConfigs) log.Tracef("node-stats:%s", nodeStats) - clusterName := rawMetrics[Infokey_ClusterName] - service := rawMetrics[Infokey_Service] - // we are sending configs and stats in same refresh call, as both are being sent to prom, instead of doing prom-push in 2 functions // handle configs var allMetricsToSend = []AerospikeStat{} - lCfgMetricsToSend := sw.handleRefresh(nodeConfigs, clusterName, service) + lCfgMetricsToSend := sw.handleRefresh(nodeConfigs) // handle stats - lStatMetricsToSend := sw.handleRefresh(nodeStats, clusterName, service) + lStatMetricsToSend := sw.handleRefresh(nodeStats) // merge both array into single allMetricsToSend = append(allMetricsToSend, lCfgMetricsToSend...) @@ -61,7 +58,7 @@ func (sw *NodeStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]s return allMetricsToSend, nil } -func (sw *NodeStatsProcessor) handleRefresh(nodeRawMetrics string, clusterName string, service string) []AerospikeStat { +func (sw *NodeStatsProcessor) handleRefresh(nodeRawMetrics string) []AerospikeStat { stats := commons.ParseStats(nodeRawMetrics, ";") @@ -81,7 +78,7 @@ func (sw *NodeStatsProcessor) handleRefresh(nodeRawMetrics string, clusterName s } labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE} - labelValues := []string{clusterName, service} + labelValues := []string{ClusterName, Service} // pushToPrometheus(asMetric, pv, labels, labelsValues) asMetric.updateValues(pv, labels, labelValues) diff --git a/internal/pkg/statprocessors/sp_sets.go b/internal/pkg/statprocessors/sp_sets.go index 8a938d5a..562cad65 100644 --- a/internal/pkg/statprocessors/sp_sets.go +++ b/internal/pkg/statprocessors/sp_sets.go @@ -41,9 +41,6 @@ func (sw *SetsStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]s var allMetricsToSend = []AerospikeStat{} for i := range setStats { - clusterName := rawMetrics[Infokey_ClusterName] - service := rawMetrics[Infokey_Service] - stats := commons.ParseStats(setStats[i], ":") for stat, value := range stats { pv, err := commons.TryConvert(value) @@ -59,7 +56,7 @@ func (sw *SetsStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]s } labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_NS, commons.METRIC_LABEL_SET} - labelValues := []string{clusterName, service, stats["ns"], stats["set"]} + labelValues := []string{ClusterName, Service, stats["ns"], stats["set"]} // pushToPrometheus(asMetric, pv, labels, labelsValues, ch) asMetric.updateValues(pv, labels, labelValues) diff --git a/internal/pkg/statprocessors/sp_sindex.go b/internal/pkg/statprocessors/sp_sindex.go index 0bc5ee2d..f680c47c 100644 --- a/internal/pkg/statprocessors/sp_sindex.go +++ b/internal/pkg/statprocessors/sp_sindex.go @@ -72,9 +72,6 @@ func (siw *SindexStatsProcessor) Refresh(infoKeys []string, rawMetrics map[strin sindexName := sindexInfoKeySplit[1] log.Tracef("sindex-stats:%s:%s:%s", nsName, sindexName, rawMetrics[sindex]) - clusterName := rawMetrics[Infokey_ClusterName] - service := rawMetrics[Infokey_Service] - stats := commons.ParseStats(rawMetrics[sindex], ";") for stat, value := range stats { pv, err := commons.TryConvert(value) @@ -90,7 +87,7 @@ func (siw *SindexStatsProcessor) Refresh(infoKeys []string, rawMetrics map[strin } labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_NS, commons.METRIC_LABEL_SINDEX} - labelValues := []string{clusterName, service, nsName, sindexName} + labelValues := []string{ClusterName, Service, nsName, sindexName} asMetric.updateValues(pv, labels, labelValues) allMetricsToSend = append(allMetricsToSend, asMetric) diff --git a/internal/pkg/statprocessors/sp_users.go b/internal/pkg/statprocessors/sp_users.go index f623489a..8fb774cc 100644 --- a/internal/pkg/statprocessors/sp_users.go +++ b/internal/pkg/statprocessors/sp_users.go @@ -122,21 +122,21 @@ func (uw *UserStatsProcessor) refreshUserStats(infoKeys []string, rawMetrics map readInfoStats := []string{"read_quota", "read_single_record_tps", "read_scan_query_rps", "limitless_read_scan_query"} writeInfoStats := []string{"write_quota", "write_single_record_tps", "write_scan_query_rps", "limitless_write_scan_query"} - asMetric, labels, labelValues := internalCreateLocalAerospikeStat(rawMetrics, "conns_in_use", user.User) + asMetric, labels, labelValues := internalCreateLocalAerospikeStat("conns_in_use", user.User) asMetric.updateValues(float64(user.ConnsInUse), labels, labelValues) allMetricsToSend = append(allMetricsToSend, asMetric) if len(user.ReadInfo) >= 4 && len(user.WriteInfo) >= 4 { for idxReadinfo := 0; idxReadinfo < len(user.ReadInfo); idxReadinfo++ { - riAeroMetric, riLabels, riLabelValues := internalCreateLocalAerospikeStat(rawMetrics, readInfoStats[idxReadinfo], user.User) + riAeroMetric, riLabels, riLabelValues := internalCreateLocalAerospikeStat(readInfoStats[idxReadinfo], user.User) riAeroMetric.updateValues(float64(user.ReadInfo[idxReadinfo]), riLabels, riLabelValues) allMetricsToSend = append(allMetricsToSend, riAeroMetric) } for idxWriteinfo := 0; idxWriteinfo < len(user.WriteInfo); idxWriteinfo++ { - wiAeroMetric, wiLabels, wiLabelValues := internalCreateLocalAerospikeStat(rawMetrics, writeInfoStats[idxWriteinfo], user.User) + wiAeroMetric, wiLabels, wiLabelValues := internalCreateLocalAerospikeStat(writeInfoStats[idxWriteinfo], user.User) wiAeroMetric.updateValues(float64(user.WriteInfo[idxWriteinfo]), wiLabels, wiLabelValues) allMetricsToSend = append(allMetricsToSend, wiAeroMetric) @@ -147,9 +147,9 @@ func (uw *UserStatsProcessor) refreshUserStats(infoKeys []string, rawMetrics map return allMetricsToSend, nil } -func internalCreateLocalAerospikeStat(rawMetrics map[string]string, pStatName string, username string) (AerospikeStat, []string, []string) { +func internalCreateLocalAerospikeStat(pStatName string, username string) (AerospikeStat, []string, []string) { labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_USER} - labelValues := []string{rawMetrics[Infokey_ClusterName], rawMetrics[Infokey_Service], username} + labelValues := []string{ClusterName, Service, username} allowed := isMetricAllowed(commons.CTX_USERS, pStatName) asMetric := NewAerospikeStat(commons.CTX_USERS, pStatName, allowed) diff --git a/internal/pkg/statprocessors/sp_xdr.go b/internal/pkg/statprocessors/sp_xdr.go index 40af77b0..c3d074e6 100644 --- a/internal/pkg/statprocessors/sp_xdr.go +++ b/internal/pkg/statprocessors/sp_xdr.go @@ -61,9 +61,6 @@ func (xw *XdrStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]st xw.xdrMetrics = make(map[string]AerospikeStat) } - clusterName := rawMetrics[Infokey_ClusterName] - service := rawMetrics[Infokey_Service] - var allMetricsToSend = []AerospikeStat{} for _, key := range infoKeys { @@ -71,7 +68,7 @@ func (xw *XdrStatsProcessor) Refresh(infoKeys []string, rawMetrics map[string]st xdrRawMetrics := rawMetrics[key] // find and construct metric name dcName, ns, metricPrefix := xw.constructMetricNamePrefix(key) - tmpXdrMetricsToSend := xw.handleRefresh(key, xdrRawMetrics, clusterName, service, dcName, ns, metricPrefix) + tmpXdrMetricsToSend := xw.handleRefresh(key, xdrRawMetrics, dcName, ns, metricPrefix) allMetricsToSend = append(allMetricsToSend, tmpXdrMetricsToSend...) } @@ -108,7 +105,7 @@ func (xw *XdrStatsProcessor) constructMetricNamePrefix(infoKeyToProcess string) } func (xw *XdrStatsProcessor) handleRefresh(infoKeyToProcess string, xdrRawMetrics string, - clusterName string, service string, dcName string, ns string, metricPrefix string) []AerospikeStat { + dcName string, ns string, metricPrefix string) []AerospikeStat { log.Tracef("xdr-%s:%s", infoKeyToProcess, xdrRawMetrics) stats := commons.ParseStats(xdrRawMetrics, ";") @@ -129,12 +126,12 @@ func (xw *XdrStatsProcessor) handleRefresh(infoKeyToProcess string, xdrRawMetric } labels := []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_DC_NAME} - labelValues := []string{clusterName, service, dcName} + labelValues := []string{ClusterName, Service, dcName} // if namespace exists, add it to the label and label-values array if len(ns) > 0 { labels = []string{commons.METRIC_LABEL_CLUSTER_NAME, commons.METRIC_LABEL_SERVICE, commons.METRIC_LABEL_DC_NAME, commons.METRIC_LABEL_NS} - labelValues = []string{clusterName, service, dcName, ns} + labelValues = []string{ClusterName, Service, dcName, ns} } // pushToPrometheus(asMetric, pv, labels, labelsValues, ch) diff --git a/internal/pkg/statprocessors/statsrefresh.go b/internal/pkg/statprocessors/statsrefresh.go index ba36f3eb..1982bcc4 100644 --- a/internal/pkg/statprocessors/statsrefresh.go +++ b/internal/pkg/statprocessors/statsrefresh.go @@ -2,6 +2,7 @@ package statprocessors import ( commons "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/commons" + "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/config" "github.com/aerospike/aerospike-prometheus-exporter/internal/pkg/dataprovider" log "github.com/sirupsen/logrus" ) @@ -68,6 +69,9 @@ func Refresh() ([]AerospikeStat, error) { // set global values ClusterName, Service, Build = rawMetrics[Infokey_ClusterName], rawMetrics[Infokey_Service], rawMetrics[Infokey_Build] + if config.Cfg.Agent.IsKubernetes { + Service = config.Cfg.Agent.KubernetesPodName + } // sanitize the utf8 strings before sending them to watchers for k, v := range rawMetrics {