Skip to content

Commit fdb0d3a

Browse files
authored
Feature/dns latency (#334)
* Network latency implementation, tested in 7.4 --------- Signed-off-by: Örnfeldt Philip (66140321) <[email protected]>
1 parent cdb8db5 commit fdb0d3a

File tree

6 files changed

+151
-34
lines changed

6 files changed

+151
-34
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Supported metrics right now as follows.
3737

3838
Global:
3939

40+
* _Network/Dns/Latency_
41+
* `fortigate_network_dns_latency_`
4042
* _System/SensorInfo_
4143
* `fortigate_sensor_alarm_status`
4244
* `fortigate_sensor_fan_rpm`
@@ -440,6 +442,7 @@ To improve security, limit permissions to required ones only (least privilege pr
440442
|Log/Fortianalyzer/Status | loggrp.config |api/v2/monitor/log/fortianalyzer |
441443
|Log/Fortianalyzer/Queue | loggrp.config |api/v2/monitor/log/fortianalyzer-queue |
442444
|Log/DiskUsage | loggrp.config |api/v2/monitor/log/current-disk-usage |
445+
|Network/Dns/Latency | sysgrp.cfg |api/v2/monitor/network/dns/latency |
443446
|System/AvailableCertificates | *any* |api/v2/monitor/system/available-certificates |
444447
|System/Fortimanager/Status | sysgrp.cfg |api/v2/monitor/system/fortimanager/status |
445448
|System/HAStatistics | sysgrp.cfg |api/v2/monitor/system/ha-statistics<br>api/v2/cmdb/system/ha |

pkg/probe/network_dns_latency.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2025 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package probe
15+
16+
import (
17+
"log"
18+
19+
"github.com/prometheus/client_golang/prometheus"
20+
21+
"github.com/prometheus-community/fortigate_exporter/pkg/http"
22+
)
23+
24+
func probeNetworkDNSLatency(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric, bool) {
25+
dnsLatency := prometheus.NewDesc(
26+
"fortigate_network_dns_latency_seconds",
27+
"Network dns latency",
28+
[]string{"service", "ip"}, nil,
29+
)
30+
31+
type DNSLatencty struct {
32+
Service string `json:"service"`
33+
Latency float64 `json:"latency"`
34+
LastUpdate float64 `json:"last_update"`
35+
IP string `json:"ip"`
36+
}
37+
38+
type DNSLatencyResult struct {
39+
Results []DNSLatencty `json:"results"`
40+
}
41+
42+
var res DNSLatencyResult
43+
if err := c.Get("api/v2/monitor/network/dns/latency", "", &res); err != nil {
44+
log.Printf("Warning: %v", err)
45+
return nil, false
46+
}
47+
m := []prometheus.Metric{}
48+
for _, r := range res.Results {
49+
m = append(m, prometheus.MustNewConstMetric(dnsLatency, prometheus.GaugeValue, r.Latency*0.001, r.Service, r.IP))
50+
}
51+
52+
return m, true
53+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2025 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
package probe
14+
15+
import (
16+
"strings"
17+
"testing"
18+
19+
"github.com/prometheus/client_golang/prometheus"
20+
"github.com/prometheus/client_golang/prometheus/testutil"
21+
)
22+
23+
func TestNetworkDnsLatency(t *testing.T) {
24+
c := newFakeClient()
25+
c.prepare("api/v2/monitor/network/dns/latency", "testdata/network-dns-latency.jsonnet")
26+
r := prometheus.NewPedanticRegistry()
27+
if !testProbe(probeNetworkDNSLatency, c, r) {
28+
t.Errorf("probeNetworkDNSLatency() returned non-success")
29+
}
30+
31+
em := `
32+
# HELP fortigate_network_dns_latency_seconds Network dns latency
33+
# TYPE fortigate_network_dns_latency_seconds gauge
34+
fortigate_network_dns_latency_seconds{ip="8.8.8.8",service="dns_server"} 0.01
35+
`
36+
37+
if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil {
38+
t.Fatalf("metric compare: err %v", err)
39+
}
40+
}

pkg/probe/probe.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func (p *Collector) Probe(ctx context.Context, target map[string]string, hc *htt
143143
{"Log/Fortianalyzer/Status", probeLogAnalyzer},
144144
{"Log/Fortianalyzer/Queue", probeLogAnalyzerQueue},
145145
{"Log/DiskUsage", probeLogCurrentDiskUsage},
146+
{"Network/Dns/Latency", probeNetworkDNSLatency},
146147
{"System/AvailableCertificates", probeSystemAvailableCertificates},
147148
{"System/Fortimanager/Status", probeSystemFortimanagerStatus},
148149
{"System/HAStatistics", probeSystemHAStatistics},
@@ -155,7 +156,7 @@ func (p *Collector) Probe(ctx context.Context, target map[string]string, hc *htt
155156
{"System/SDNConnector", probeSystemSDNConnector},
156157
{"System/SensorInfo", probeSystemSensorInfo},
157158
{"System/Status", probeSystemStatus},
158-
{"System/VDOMResource",probeSystemVdomResource},
159+
{"System/VDOMResource", probeSystemVdomResource},
159160
{"System/HAChecksum", probeSystemHAChecksum},
160161
{"User/Fsso", probeUserFsso},
161162
{"VPN/IPSec", probeVPNIPSec},

pkg/probe/system_vdom-resource.go

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ package probe
1616
import (
1717
"log"
1818

19-
"github.com/prometheus-community/fortigate_exporter/pkg/http"
2019
"github.com/prometheus/client_golang/prometheus"
20+
21+
"github.com/prometheus-community/fortigate_exporter/pkg/http"
2122
)
2223

23-
func probeSystemVdomResource(c http.FortiHTTP, meta *TargetMetadata) ([]prometheus.Metric, bool) {
24-
24+
func probeSystemVdomResource(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric, bool) {
2525
vdomDesc := make(map[string]*prometheus.Desc)
2626
vdomDesc["cpu"] = prometheus.NewDesc(
2727
"fortigate_vdom_resource_cpu_usage_ratio",
@@ -46,12 +46,12 @@ func probeSystemVdomResource(c http.FortiHTTP, meta *TargetMetadata) ([]promethe
4646
vdomDesc["id"] = prometheus.NewDesc(
4747
"fortigate_vdom_resource_object_id",
4848
"Object Resource ID",
49-
[]string{"vdom", "object"},nil,
49+
[]string{"vdom", "object"}, nil,
5050
)
5151
vdomDesc["custom_max"] = prometheus.NewDesc(
5252
"fortigate_vdom_resource_object_custom_max",
5353
"Object Custom Max",
54-
[]string{"vdom", "object"},nil,
54+
[]string{"vdom", "object"}, nil,
5555
)
5656
vdomDesc["min_custom_value"] = prometheus.NewDesc(
5757
"fortigate_vdom_resource_object_custom_min_value",
@@ -61,42 +61,42 @@ func probeSystemVdomResource(c http.FortiHTTP, meta *TargetMetadata) ([]promethe
6161
vdomDesc["max_custom_value"] = prometheus.NewDesc(
6262
"fortigate_vdom_resource_object_custom_max_value",
6363
"Object Maximum custom value",
64-
[]string{"vdom", "object"},nil,
64+
[]string{"vdom", "object"}, nil,
6565
)
6666
vdomDesc["guaranteed"] = prometheus.NewDesc(
6767
"fortigate_vdom_resource_object_guaranteed",
6868
"Object Guaranteed",
69-
[]string{"vdom", "object"},nil,
69+
[]string{"vdom", "object"}, nil,
7070
)
7171
vdomDesc["min_guaranteed_value"] = prometheus.NewDesc(
7272
"fortigate_vdom_resource_object_guaranteed_max_value",
7373
"Object Minimum guaranteed value",
74-
[]string{"vdom", "object"},nil,
74+
[]string{"vdom", "object"}, nil,
7575
)
7676
vdomDesc["max_guaranteed_value"] = prometheus.NewDesc(
7777
"fortigate_vdom_resource_object_guaranteed_min_value",
7878
"Object Maximum guaranteed value",
79-
[]string{"vdom", "object"},nil,
79+
[]string{"vdom", "object"}, nil,
8080
)
8181
vdomDesc["global_max"] = prometheus.NewDesc(
8282
"fortigate_vdom_resource_object_global_max",
8383
"Object Global max",
84-
[]string{"vdom", "object"},nil,
84+
[]string{"vdom", "object"}, nil,
8585
)
8686
vdomDesc["current_usage"] = prometheus.NewDesc(
8787
"fortigate_vdom_resource_object_current_usage",
8888
"Object Current usage",
89-
[]string{"vdom", "object"},nil,
89+
[]string{"vdom", "object"}, nil,
9090
)
9191
vdomDesc["usage_percent"] = prometheus.NewDesc(
9292
"fortigate_vdom_resource_object_usage_ratio",
9393
"Object Usage percentage",
94-
[]string{"vdom", "object"},nil,
94+
[]string{"vdom", "object"}, nil,
9595
)
9696

9797
type VDOMResourceResult struct {
98-
Result interface{} `json:"results"`
99-
Vdom string `json:"vdom"`
98+
Result any `json:"results"`
99+
Vdom string `json:"vdom"`
100100
}
101101

102102
var res []VDOMResourceResult
@@ -107,7 +107,7 @@ func probeSystemVdomResource(c http.FortiHTTP, meta *TargetMetadata) ([]promethe
107107

108108
m := []prometheus.Metric{}
109109
for _, result := range res {
110-
for k, elem := range result.Result.(map[string]interface{}) {
110+
for k, elem := range result.Result.(map[string]any) {
111111
switch k {
112112
case "cpu", "memory", "setup_rate":
113113
m = append(m, prometheus.MustNewConstMetric(vdomDesc[k], prometheus.GaugeValue, elem.(float64), result.Vdom))
@@ -118,24 +118,24 @@ func probeSystemVdomResource(c http.FortiHTTP, meta *TargetMetadata) ([]promethe
118118
m = append(m, prometheus.MustNewConstMetric(vdomDesc[k], prometheus.GaugeValue, 0, result.Vdom))
119119
}
120120
case "session",
121-
"ipsec-phase1",
122-
"ipsec-phase2",
123-
"ipsec-phase1-interface",
124-
"ipsec-phase2-interface",
125-
"dialup-tunnel",
126-
"firewall-policy",
127-
"firewall-address",
128-
"firewall-addrgrp",
129-
"custom-service",
130-
"service-group",
131-
"onetime-schedule",
132-
"recurring-schedule",
133-
"user",
134-
"user-group",
135-
"sslvpn",
136-
"proxy",
137-
"log-disk-quota":
138-
for val, e := range elem.(map[string]interface{}) {
121+
"ipsec-phase1",
122+
"ipsec-phase2",
123+
"ipsec-phase1-interface",
124+
"ipsec-phase2-interface",
125+
"dialup-tunnel",
126+
"firewall-policy",
127+
"firewall-address",
128+
"firewall-addrgrp",
129+
"custom-service",
130+
"service-group",
131+
"onetime-schedule",
132+
"recurring-schedule",
133+
"user",
134+
"user-group",
135+
"sslvpn",
136+
"proxy",
137+
"log-disk-quota":
138+
for val, e := range elem.(map[string]any) {
139139
m = append(m, prometheus.MustNewConstMetric(vdomDesc[val], prometheus.GaugeValue, e.(float64), result.Vdom, k))
140140
}
141141
default:
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# api/v2/monitor/network/dns/latency
2+
{
3+
"http_method": "GET",
4+
"results": [
5+
{
6+
"service": "dns_server",
7+
"latency": 10,
8+
"last_update": 1040,
9+
"ip": "8.8.8.8"
10+
}
11+
],
12+
"vdom": "root",
13+
"path": "network",
14+
"name": "dns",
15+
"action": "latency",
16+
"status": "success",
17+
"serial": "FTK",
18+
"version": "v7.4.8",
19+
"build": 2795
20+
}

0 commit comments

Comments
 (0)