Skip to content
Merged
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Supported metrics right now as follows.

Global:

* _Network/Dns/Latency_
* `fortigate_network_dns_latency`
* `fortigate_network_dns_latest_update`
* _System/SensorInfo_
* `fortigate_sensor_fan_rpm`
* `fortigate_sensor_temperature_celsius`
Expand Down Expand Up @@ -411,6 +414,7 @@ To improve security, limit permissions to required ones only (least privilege pr
|Log/Fortianalyzer/Status | loggrp.config |api/v2/monitor/log/fortianalyzer |
|Log/Fortianalyzer/Queue | loggrp.config |api/v2/monitor/log/fortianalyzer-queue |
|Log/DiskUsage | loggrp.config |api/v2/monitor/log/current-disk-usage |
|Network/Dns/Latency | sysgrp.cfg |api/v2/monitor/network/dns/latency |
|System/AvailableCertificates | *any* |api/v2/monitor/system/available-certificates |
|System/Fortimanager/Status | sysgrp.cfg |api/v2/monitor/system/fortimanager/status |
|System/HAStatistics | sysgrp.cfg |api/v2/monitor/system/ha-statistics<br>api/v2/cmdb/system/ha |
Expand Down
60 changes: 60 additions & 0 deletions pkg/probe/network_dns_latency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2025 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package probe

import (
"log"

"github.com/prometheus-community/fortigate_exporter/pkg/http"
"github.com/prometheus/client_golang/prometheus"
)

func probeNetworkDnsLatency(c http.FortiHTTP, meta *TargetMetadata) ([]prometheus.Metric, bool) {
var (
dnsLatency = prometheus.NewDesc(
"fortigate_network_dns_latency",
Comment thread
Philldomd marked this conversation as resolved.
Outdated
"Network dns latency",
[]string{"service", "ip"}, nil,
)
dnsLastUpdate = prometheus.NewDesc(
"fortigate_network_dns_latest_update",
Comment thread
Philldomd marked this conversation as resolved.
Outdated
"Network dns last update",
[]string{"service", "ip"}, nil,
)
)

type DnsLatencty struct {
Service string `json:"service"`
Latency float64 `json:"latency"`
LastUpdate float64 `json:"last_update"`
Ip string `json:"ip"`
}

type DnsLatencyResult struct {
Results []DnsLatencty `json:"results"`
}

var res DnsLatencyResult
if err := c.Get("api/v2/monitor/network/dns/latency", "", &res); err != nil {
log.Printf("Warning: %v", err)
return nil, false
}
m := []prometheus.Metric{}
for _, r := range res.Results {
m = append(m, prometheus.MustNewConstMetric(dnsLatency, prometheus.GaugeValue, r.Latency, r.Service, r.Ip))
m = append(m, prometheus.MustNewConstMetric(dnsLastUpdate, prometheus.GaugeValue, r.LastUpdate, r.Service, r.Ip))
}

return m, true
}
43 changes: 43 additions & 0 deletions pkg/probe/network_dns_latency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2025 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package probe

import (
"strings"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
)

func TestNetworkDnsLatency(t *testing.T) {
c := newFakeClient()
c.prepare("api/v2/monitor/network/dns/latency", "testdata/network-dns-latency.jsonnet")
r := prometheus.NewPedanticRegistry()
if !testProbe(probeNetworkDnsLatency, c, r) {
t.Errorf("probeNetworkDnsLatency() returned non-success")
}

em := `
# HELP fortigate_network_dns_latency Network dns latency
# TYPE fortigate_network_dns_latency gauge
fortigate_network_dns_latency{ip="8.8.8.8",service="dns_server"} 10
# HELP fortigate_network_dns_latest_update Network dns last update
# TYPE fortigate_network_dns_latest_update gauge
fortigate_network_dns_latest_update{ip="8.8.8.8",service="dns_server"} 1040
`

if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil {
t.Fatalf("metric compare: err %v", err)
}
}
1 change: 1 addition & 0 deletions pkg/probe/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func (p *ProbeCollector) Probe(ctx context.Context, target map[string]string, hc
{"Log/Fortianalyzer/Status", probeLogAnalyzer},
{"Log/Fortianalyzer/Queue", probeLogAnalyzerQueue},
{"Log/DiskUsage", probeLogCurrentDiskUsage},
{"Network/Dns/Latency", probeNetworkDnsLatency},
{"System/AvailableCertificates", probeSystemAvailableCertificates},
{"System/Fortimanager/Status", probeSystemFortimanagerStatus},
{"System/HAStatistics", probeSystemHAStatistics},
Expand Down
20 changes: 20 additions & 0 deletions pkg/probe/testdata/network-dns-latency.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# api/v2/monitor/network/dns/latency
{
"http_method": "GET",
"results": [
{
"service": "dns_server",
"latency": 10,
"last_update": 1040,
"ip": "8.8.8.8"
}
],
"vdom": "root",
"path": "network",
"name": "dns",
"action": "latency",
"status": "success",
"serial": "FTK",
"version": "v7.4.8",
"build": 2795
}