Skip to content

Issue 58 discovery #68

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

Merged
merged 43 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
80d2312
feat: add service discovery of the nodes that are part of the fabric
thenodon May 10, 2024
7ef0bda
fix: add configurable target field and refactoring
thenodon May 11, 2024
04c17de
fix: formatting
thenodon May 11, 2024
da8bad5
fix: Errorf format
thenodon May 11, 2024
d152486
Merge pull request #59 from opsdis/master
thenodon May 11, 2024
6d99f87
feat: enable node queries
thenodon May 13, 2024
edf9e46
feat: example of using node queries and service discovery
thenodon May 13, 2024
8232ad2
fix: adding the __meta_aci_exporter_fabric label to the discovery tha…
thenodon May 14, 2024
2399c3f
fix: move the discovery config by fabric to the init step of the fabric.
thenodon May 19, 2024
2ace354
fix: add discovery for the fabric itself to be used for the apic base…
thenodon May 19, 2024
2d01bb8
fix: log field from Node to node
thenodon May 19, 2024
316a948
Merge pull request #62 from opsdis/master
thenodon Jun 22, 2024
c2223ad
fix: the comment for different roles
thenodon Jun 22, 2024
0e3f000
fix: refactor cacheConnection to have an entry for each node, aci fab…
thenodon Jul 5, 2024
82e7902
fix: issue 64 - loglevel is not set if passed from config File
thenodon Jul 5, 2024
1dfc5d3
fix: issue #63 - queries parameter validation. Add trim function to r…
thenodon Jul 5, 2024
94bba85
fix: add __meta_fabricDomain to the target that is of __meta_role "ac…
thenodon Jul 7, 2024
e3d2f03
fix: for node queries the login is done directly on the node instead …
thenodon Jul 7, 2024
c9b46d5
docs: update discovery
thenodon Jul 7, 2024
436fe50
fix service Discovery Crash
camrossi Jul 7, 2024
55c8888
fix service Discovery Crash
camrossi Jul 7, 2024
41ca091
Merge pull request #66 from camrossi/issue_58_discovery
thenodon Jul 8, 2024
cd4b9bb
fix: requestid is fixed to be correct for a request. The "bug" wa rel…
thenodon Jul 9, 2024
5efded1
feat: add support for different access methods using the interface Ac…
thenodon Jul 10, 2024
4a52e1f
fix: import formattimg
thenodon Jul 10, 2024
ace2c5a
fix: tidy
thenodon Jul 10, 2024
e165ff2
fix: enable to set config_dir in the config.yaml file
thenodon Jul 12, 2024
ca62f5d
docs: update
thenodon Jul 12, 2024
0417c37
fix: license text
thenodon Jul 12, 2024
2ee7158
docs: update
thenodon Jul 12, 2024
01cc905
docs: link to camrossi
thenodon Jul 13, 2024
eb3c220
fix: correct error handling for cliQuery
thenodon Jul 16, 2024
b7e48a2
fix: add additional error handling
thenodon Jul 17, 2024
7967132
fix: when doing /sd without a target the whole discovery will fail if…
thenodon Jul 18, 2024
e1b052a
fix: change some Info to Debug
thenodon Jul 18, 2024
b5f595c
fix: add link to "ACI Monitor Stack"
thenodon Jul 19, 2024
3c98d42
docs: format
thenodon Jul 20, 2024
21fa04f
docs: fix grammar
thenodon Jul 20, 2024
c3a452c
fix: replace a number of common log strings with constants
thenodon Jul 20, 2024
e689057
fix: replace a number of common log strings with constants
thenodon Jul 20, 2024
97d260d
fix: correct relabeling
thenodon Jul 21, 2024
f484e19
fix: add support for multiple query parameters of the key queries
thenodon Jul 21, 2024
4fd55e8
fix: add a config directory with node based queries
thenodon Jul 21, 2024
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
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# aci-exporter authors
# List alphabetically by surname

Anders Håål <anders@opsdis.com>
Anders Håål <anders.haal@ingby.com>
259 changes: 249 additions & 10 deletions README.md

Large diffs are not rendered by default.

116 changes: 59 additions & 57 deletions aci-api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// Copyright 2020-2023 Opsdis

package main

Expand All @@ -19,7 +17,6 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"time"

"github.com/umisama/go-regexpcache"
Expand All @@ -32,60 +29,31 @@ import (

var arrayExtension = regexpcache.MustCompile("^(?P<stage_1>.*)\\.\\[(?P<child_name>.*)\\](?P<stage_2>.*)")

func newAciAPI(ctx context.Context, fabricConfig *Fabric, configQueries AllQueries, queryFilter string) *aciAPI {

executeQueries := configQueries
queryArray := strings.Split(queryFilter, ",")
if queryArray[0] != "" {
// If there are some queries named
executeQueries.ClassQueries = ClassQueries{}
executeQueries.CompoundClassQueries = CompoundClassQueries{}
executeQueries.GroupClassQueries = GroupClassQueries{}
// Find the named queries for the different type
for _, queryName := range queryArray {
for configQueryName := range configQueries.ClassQueries {
if queryName == configQueryName {
executeQueries.ClassQueries[configQueryName] = configQueries.ClassQueries[configQueryName]
}
}
for k := range configQueries.CompoundClassQueries {
if queryName == k {
executeQueries.CompoundClassQueries[k] = configQueries.CompoundClassQueries[k]
}
}
for k := range configQueries.GroupClassQueries {
if queryName == k {
executeQueries.GroupClassQueries[k] = configQueries.GroupClassQueries[k]
}
}
}
} else {
// Use all configured
executeQueries = configQueries
}
func newAciAPI(ctx context.Context, fabricConfig *Fabric, configQueries AllQueries, queryArray []string, node *string) *aciAPI {
executeQueries := queriesToExecute(configQueries, queryArray)

api := &aciAPI{
ctx: ctx,
connection: newAciConnection(ctx, fabricConfig),
connection: newAciConnection(fabricConfig, node),
metricPrefix: viper.GetString("prefix"),
configQueries: executeQueries.ClassQueries,
configCompoundQueries: executeQueries.CompoundClassQueries,
configGroupQueries: executeQueries.GroupClassQueries,
confgBuiltInQueries: BuiltinQueries{},
configBuiltInQueries: BuiltinQueries{},
}

// Make sure all built in queries are handled
if queryArray[0] != "" {
if queryArray != nil {
// If query parameter queries is used
for _, v := range queryArray {
if v == "faults" {
api.confgBuiltInQueries["faults"] = api.faults
api.configBuiltInQueries["faults"] = api.faults
}
// Add all other builtin with if statements
}
} else {
// If query parameter queries is NOT used, include all
api.confgBuiltInQueries["faults"] = api.faults
api.configBuiltInQueries["faults"] = api.faults
}

return api
Expand All @@ -98,7 +66,38 @@ type aciAPI struct {
configQueries ClassQueries
configCompoundQueries CompoundClassQueries
configGroupQueries GroupClassQueries
confgBuiltInQueries BuiltinQueries
configBuiltInQueries BuiltinQueries
}

func queriesToExecute(configQueries AllQueries, queryArray []string) AllQueries {
if queryArray == nil {
// Default is all configured queries to execute
return configQueries
}
executeQueries := AllQueries{}
executeQueries.ClassQueries = ClassQueries{}
executeQueries.CompoundClassQueries = CompoundClassQueries{}
executeQueries.GroupClassQueries = GroupClassQueries{}

// Find the named queries for the different type
for _, queryName := range queryArray {
for configQueryName := range configQueries.ClassQueries {
if queryName == configQueryName {
executeQueries.ClassQueries[configQueryName] = configQueries.ClassQueries[configQueryName]
}
}
for k := range configQueries.CompoundClassQueries {
if queryName == k {
executeQueries.CompoundClassQueries[k] = configQueries.CompoundClassQueries[k]
}
}
for k := range configQueries.GroupClassQueries {
if queryName == k {
executeQueries.GroupClassQueries[k] = configQueries.GroupClassQueries[k]
}
}
}
return executeQueries
}

// CollectMetrics Gather all aci metrics and return name of the aci fabric, slice of metrics and status of
Expand All @@ -107,7 +106,7 @@ func (p aciAPI) CollectMetrics() (string, []MetricDefinition, error) {
var metrics []MetricDefinition
start := time.Now()

err := p.connection.login()
err := p.connection.login(p.ctx)
// defer p.connection.logout()

if err != nil {
Expand Down Expand Up @@ -145,9 +144,9 @@ func (p aciAPI) CollectMetrics() (string, []MetricDefinition, error) {
metrics = append(metrics, *p.scrape(end.Seconds()))
metrics = append(metrics, *p.up(1.0))
log.WithFields(log.Fields{
"requestid": p.ctx.Value("requestid"),
"exec_time": end.Microseconds(),
"fabric": fmt.Sprintf("%v", p.ctx.Value("fabric")),
LogFieldRequestID: p.ctx.Value(LogFieldRequestID),
LogFieldExecTime: end.Microseconds(),
LogFieldFabric: fmt.Sprintf("%v", p.ctx.Value(LogFieldFabric)),
}).Info("total scrape time ")
return aciName, metrics, nil
}
Expand Down Expand Up @@ -192,23 +191,23 @@ func (p aciAPI) up(state float64) *MetricDefinition {
func (p aciAPI) configuredBuiltInMetrics(chall chan []MetricDefinition) {
var metricDefinitions []MetricDefinition
ch := make(chan []MetricDefinition)
for _, fun := range p.confgBuiltInQueries {
for _, fun := range p.configBuiltInQueries {
go fun(ch)
}

for range p.confgBuiltInQueries {
for range p.configBuiltInQueries {
metricDefinitions = append(metricDefinitions, <-ch...)
}

chall <- metricDefinitions
}

func (p aciAPI) faults(ch chan []MetricDefinition) {
data, err := p.connection.getByQuery("faults")
data, err := p.connection.GetByQuery(p.ctx, "faults")
if err != nil {
log.WithFields(log.Fields{
"requestid": p.ctx.Value("requestid"),
"fabric": fmt.Sprintf("%v", p.ctx.Value("fabric")),
LogFieldRequestID: p.ctx.Value(LogFieldRequestID),
LogFieldFabric: fmt.Sprintf("%v", p.ctx.Value(LogFieldFabric)),
}).Error("faults not supported", err)
ch <- nil
return
Expand Down Expand Up @@ -308,11 +307,15 @@ func (p aciAPI) faults(ch chan []MetricDefinition) {
}

func (p aciAPI) getAciName() (string, error) {
// Do not query aci name when query a node
if p.connection.Node != nil {
return "", nil
}
if p.connection.fabricConfig.AciName != "" {
return p.connection.fabricConfig.AciName, nil
}

data, err := p.connection.getByClassQuery("infraCont", "?query-target=self")
data, err := p.connection.GetByClassQuery(p.ctx, "infraCont", "?query-target=self")

if err != nil {
return "", err
Expand Down Expand Up @@ -350,7 +353,7 @@ func (p aciAPI) getCompoundMetrics(ch chan []MetricDefinition, v *CompoundClassQ
var metrics []Metric
for _, classLabel := range v.ClassNames {
metric := Metric{}
data, _ := p.connection.getByClassQuery(classLabel.Class, classLabel.QueryParameter)
data, _ := p.connection.GetByClassQuery(p.ctx, classLabel.Class, classLabel.QueryParameter)
if classLabel.ValueName == "" {
metric.Value = p.toFloat(gjson.Get(data, fmt.Sprintf("imdata.0.%s", v.Metrics[0].ValueName)).Str)
} else {
Expand Down Expand Up @@ -441,12 +444,12 @@ func (p aciAPI) getGroupClassMetrics(ch chan []MetricDefinition, v GroupClassQue
func (p aciAPI) getClassMetrics(ch chan []MetricDefinition, v *ClassQuery) {

var metricDefinitions []MetricDefinition
data, err := p.connection.getByClassQuery(v.ClassName, v.QueryParameter)
data, err := p.connection.GetByClassQuery(p.ctx, v.ClassName, v.QueryParameter)

if err != nil {
log.WithFields(log.Fields{
"requestid": p.ctx.Value("requestid"),
"fabric": fmt.Sprintf("%v", p.ctx.Value("fabric")),
LogFieldRequestID: p.ctx.Value(LogFieldRequestID),
LogFieldFabric: fmt.Sprintf("%v", p.ctx.Value(LogFieldFabric)),
}).Error(fmt.Sprintf("%s not supported", v.ClassName), err)
ch <- nil
return
Expand Down Expand Up @@ -630,16 +633,15 @@ func (p aciAPI) toRatio(value string) float64 {
func (p aciAPI) toFloat(value string) float64 {
rate, err := strconv.ParseFloat(value, 64)
if err != nil {
// if the value a date time convert to timestamp
// if the value is a date time convert to timestamp
t, err := time.Parse(time.RFC3339, value)
rate = float64(t.Unix())
if err != nil {
log.WithFields(log.Fields{
"value": value,
}).Info("could not convert value to float, will return 0.0 ")
return 0.0
}

rate = float64(t.Unix())
}
return rate
}
Expand Down
Loading
Loading