Skip to content

Commit 18e83d1

Browse files
committed
v 0.4.1
Signed-off-by: peekjf72 <jfpik78@gmail.com>
1 parent 4a3a868 commit 18e83d1

58 files changed

Lines changed: 5440 additions & 809 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,77 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a changelog](https://github.com/olivierlacan/keep-a-changelog).
55

66
<!--next-version-placeholder-->
7-
## 0.4.1 / 2025-03-30 - not release
7+
## 0.4.1 / 2025-06-04
8+
9+
- added: new contrib [apache_exporter configuration](./contribs/apache/README.md). a good example to introduce javascript code to build metrics.
10+
11+
### 2025-05-25 - not release
12+
13+
- added: support for env vars in target_config [see issue #1](https://github.com/peekjef72/httpapi_exporter/issues/1) :
14+
15+
e.g.:
16+
17+
```yaml
18+
targets:
19+
- name: my_target
20+
scheme: https
21+
host: $env:MY_HOST_ENV_VAR_NAME
22+
port: 443
23+
```
24+
25+
### 2025-05-16 - not release
26+
27+
- changed: internal "scope" directive: add error and debug msg.
28+
- added: new parameter 'collector' to '/metrics' entry point. Collect only the specified collector(s). May be use to collect specific metrics in a particular prometheus job.
29+
30+
### 2025-05-07 - not release
31+
32+
#### BREAKING CHANGE
33+
34+
- renamed: variable `results_code` to `status_code`
35+
=> update all config profiles !
36+
- changed: in log line renamed 'collid' to 'coll' and use collector name instead of a sequential number.
37+
38+
### 2025-05-06 - not release
39+
40+
- added: support for `javascript code` in each field, as an alternative to gotemplate. This part is still in development (see examples)
41+
42+
- added: new metric named "query_status" (prefixed by metric_prefix) and labeled by url query stage. The goal is to provide a always generated value for each queried url with the http status code as value. The generation is conditionned by the status attribute from each query action and the default value is false.
43+
44+
```yaml
45+
- name: check api url
46+
query:
47+
url: /api/health
48+
method: GET
49+
status: true
50+
trace: true
51+
```
52+
53+
will provide:
54+
55+
```text
56+
# HELP xxx_query_status query http status label by phase(url): http return code
57+
# TYPE xxx_query_status gauge
58+
xxx_query_status{phase="/api/health"} 200
59+
# HELP xxx_query_perf_seconds query stage duration in seconds
60+
# TYPE xxx_query_perf_seconds gauge
61+
xxx_query_perf_seconds{page="/status",stage="conn_time"} 0.004550086
62+
xxx_query_perf_seconds{page="/status",stage="dns_lookup"} 4.3538e-05
63+
xxx_query_perf_seconds{page="/status",stage="response_time"} 4.5354e-05
64+
xxx_query_perf_seconds{page="/status",stage="server_time"} 0.000361965
65+
xxx_query_perf_seconds{page="/status",stage="tcp_con_time"} 0.000111871
66+
xxx_query_perf_seconds{page="/status",stage="tls_handshake"} 0.004329272
67+
xxx_query_perf_seconds{page="/status",stage="total_time"} 0.004912388
68+
69+
```
70+
71+
If the request timeouts, the status code is 504.
72+
If the request is not perfomed (target is down), the status code is 0.
873

974
### 2025-03-26 - not release
1075

1176
- added: global config parameter tls_version that allows to add old tls ciphers, because of golang change since 1.22: see [config](doc/config.md); update the netscaler default config file to use tls_version: all
12-
- code refactored to use [cast](github.com/spf13/cast) for type conversion in internal functions.
77+
- code refactored to use [cast](http://github.com/spf13/cast) for type conversion in internal functions.
1378
- added: scripting language evolution to allow named var into expr : `$var_name.${another_varname[.attr1]}[.attr2]`
1479
- changed: loglevel trace from warn to debug for metrics not found:
1580

@@ -27,7 +92,7 @@ e.g.:
2792

2893
The same behavior is implemented for variables used in `loop` or `with_items` action.
2994

30-
### BREAKING CHANGE
95+
#### BREAKING CHANGE
3196

3297
- remove feature that allows to set a single text not preceded by $ sign as value for key_labels or values:
3398

README.md

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ The queried url can return data in several format:
1414
- raw text (parse as text-lines)
1515
- prometheus openmetrics
1616

17-
As examples 4 configurations for exporters are provided (see contribs):
17+
As examples, configurations for exporters are provided (see contribs):
1818

1919
- [hp3par_exporter](contribs/hp3par/README.md)
2020
- [veeam_exporter](contribs/veeam/README.md)
2121
- [netscaler_exporter](contribs/netscaler/README.md)
2222
- [aruba_exporter](contribs/arubacx/README.md)
23+
- [apache_exporter](contribs/apache/README.md)
2324

2425
# Build
2526

@@ -231,39 +232,9 @@ How it works:
231232
environment: "DEV"
232233
```
233234

234-
# custom functions for templating
235+
# building custom exporter config
235236

236237
(**still incomplete**)
237-
238-
Go template is used to manipulate data. So templates inherits from go functions and [sprig](https://masterminds.github.io/sprig/) v3 functions.
239-
Because the exporter uses most of the time data of type "any (interface{})" some of the sprig functions failed.
240-
Here is the list of exporter functions:
241-
242-
name| usage | e.g. |
243-
--|---|---|
244-
exporterDecryptPass | | |
245-
exporterGet [varmap] [keyname] | get the keyname from the map. Like sprig/get function but accepts data of type map[any]any | exporterGet .svclb .svc |
246-
exporterSet | | |
247-
exporterKeys | | |
248-
exporterValues | | |
249-
exporterToRawJson | | |
250-
&nsbp; | | |
251-
lookupAddr [varstring] | obtain hostname from string representing an ip address ; like sprig/getHostByName but for string ip | lookupAddr .node.ipaddress |
252-
convertToBytes value unit | convert the value contained in variable to bytes according to the unit string specified: <ul><li>"kilobyte" or "Kb" multiply by 1024 <li>"megabyte" or "Mb" multiply by 1024 * 1024<li>"gigabyte" or "Gb"multiply by 1024 * 1024 * 1024</ul> | '{{ convertToBytes .result.totalMiB "Mb" }}' |
253-
convertBoolToInt value | convert value that may contain a boolean to 0&#124;1 representation. Value can be of any type. If something is <ul><li>like int or float and different from 0 is 1 else 0<li>string and is lower case 'true' or 'yes' or 'ok' is 1 else 0<li>like map or array and length >0 then 1 or 0</ul>| with {"proc": {"loopCrashing": "true",...}}<br> => '{{ convertBoolToInt .proc.loopCrashing }}<br> => 1' |
254-
getHeader [varmap] | | |
255-
LEN [var] | obtain the len of the var. works like sprig/len but accepts data of type any. | |
256-
exporterRegexExtract [regexp var] [search var] : []string | obtain the list of extracted elements from regexp on search string or nil if not found | extract value from line as group 1 of regexp: <br> res: "{{ index (exporterRegexExtract "^status:\s(.+)$" "status:OK") 1 }}" |
257-
258-
## boolean checks
259-
260-
name| usage | e.g. |
261-
---|---|---|
262-
EQ [var1] [var2] | check equality for 2 variables; accepts any type of data; meaning that the second will be converted to the type of the first | EQ .val "2" |
263-
NE [var1] [var2] | not equal | NE 2 .val |
264-
GE [var1] [var2] | greater equal | |
265-
GT [var1] [var2] | greater than | |
266-
LE [var1] [var2] | less equal | |
267-
LT [var1] [var2] | less than | |
268-
exists [var1] | return boolean if variable exists| exists .config.cluster.node |
269-
exporterHasKey [var] [key] | check if variable is a map and has a key | exporterHasKey .config "cluster" |
238+
. see [up/metrics schema](./doc/session.png)
239+
. see [actions](./doc/actions.md)
240+
. see [template/functions](./doc/custom_functions.md)

actions_action.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
// ***************************************************************************************
1414

1515
type ActionsAction struct {
16-
Name *Field `yaml:"name,omitempty" json:"name,omitempty"`
17-
With []any `yaml:"with,omitempty" json:"with,omitempty"`
18-
When []*exporterTemplate `yaml:"when,omitempty" json:"when,omitempty"`
19-
LoopVar string `yaml:"loop_var,omitempty" json:"loop_var,omitempty"`
20-
Vars map[string]any `yaml:"vars,omitempty" json:"vars,omitempty"`
21-
Until []*exporterTemplate `yaml:"until,omitempty" json:"until,omitempty"`
22-
Actions []Action `yaml:"actions,omitempty" json:"actions,omitempty"`
16+
Name *Field `yaml:"name,omitempty" json:"name,omitempty"`
17+
With []any `yaml:"with,omitempty" json:"with,omitempty"`
18+
When []*Field `yaml:"when,omitempty" json:"when,omitempty"`
19+
LoopVar string `yaml:"loop_var,omitempty" json:"loop_var,omitempty"`
20+
Vars map[string]any `yaml:"vars,omitempty" json:"vars,omitempty"`
21+
Until []*Field `yaml:"until,omitempty" json:"until,omitempty"`
22+
Actions []Action `yaml:"actions,omitempty" json:"actions,omitempty"`
2323

2424
vars [][]any
2525

@@ -32,11 +32,11 @@ func (a *ActionsAction) Type() int {
3232
}
3333

3434
func (a *ActionsAction) GetName(symtab map[string]any, logger *slog.Logger) string {
35-
str, err := a.Name.GetValueString(symtab)
35+
str, err := a.Name.GetValueString(symtab, logger)
3636
if err != nil {
3737
logger.Warn(
3838
fmt.Sprintf("invalid action name: %v", err),
39-
"collid", CollectorId(symtab, logger),
39+
"coll", CollectorId(symtab, logger),
4040
"script", ScriptName(symtab, logger))
4141
return ""
4242
}
@@ -57,11 +57,11 @@ func (a *ActionsAction) SetWidth(with []any) {
5757
a.With = with
5858
}
5959

60-
func (a *ActionsAction) GetWhen() []*exporterTemplate {
60+
func (a *ActionsAction) GetWhen() []*Field {
6161
return a.When
6262

6363
}
64-
func (a *ActionsAction) SetWhen(when []*exporterTemplate) {
64+
func (a *ActionsAction) SetWhen(when []*Field) {
6565
a.When = when
6666
}
6767

@@ -79,10 +79,10 @@ func (a *ActionsAction) SetVars(vars [][]any) {
7979
a.vars = vars
8080
}
8181

82-
func (a *ActionsAction) GetUntil() []*exporterTemplate {
82+
func (a *ActionsAction) GetUntil() []*Field {
8383
return a.Until
8484
}
85-
func (a *ActionsAction) SetUntil(until []*exporterTemplate) {
85+
func (a *ActionsAction) SetUntil(until []*Field) {
8686
a.Until = until
8787
}
8888

@@ -95,8 +95,8 @@ func (a *ActionsAction) setBasicElement(
9595
vars [][]any,
9696
with []any,
9797
loopVar string,
98-
when []*exporterTemplate,
99-
until []*exporterTemplate) error {
98+
when []*Field,
99+
until []*Field) error {
100100
return setBasicElement(a, nameField, vars, with, loopVar, when, until)
101101
}
102102

@@ -141,7 +141,7 @@ func (a *ActionsAction) SetPlayAction(script map[string]*YAMLScript) error {
141141
func (a *ActionsAction) CustomAction(script *YAMLScript, symtab map[string]any, logger *slog.Logger) error {
142142
logger.Debug(
143143
fmt.Sprintf("[Type: ActionsAction] - %d Actions to play", len(a.Actions)),
144-
"collid", CollectorId(symtab, logger),
144+
"coll", CollectorId(symtab, logger),
145145
"script", ScriptName(symtab, logger),
146146
"name", a.GetName(symtab, logger))
147147
for _, cur_act := range a.Actions {

0 commit comments

Comments
 (0)