Skip to content

Commit 6d2d53a

Browse files
author
Jason Gellatly
authored
Merge pull request #2 from bigcommerce/infra_21584
INFRA-21482: Add CF DNS Firewall metrics
2 parents 9a1cc45 + a81f973 commit 6d2d53a

3 files changed

Lines changed: 106 additions & 3 deletions

File tree

cloudflare.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,24 @@ type lbResp struct {
221221
ZoneTag string `json:"zoneTag"`
222222
}
223223

224+
type cloudflareResponseDnsFirewall struct {
225+
Viewer struct {
226+
Accounts []dnsFirewallAccountResp `json:"accounts"`
227+
} `json:"viewer"`
228+
}
229+
230+
type dnsFirewallAccountResp struct {
231+
DnsFirewallAnalyticsAdaptiveGroups []struct {
232+
Count uint64 `json:"count"`
233+
Dimensions struct {
234+
ClusterTag string `json:"clusterTag"`
235+
QueryType string `json:"queryType"`
236+
ResponseCode string `json:"responseCode"`
237+
} `json:"dimensions"`
238+
} `json:"dnsFirewallAnalyticsAdaptiveGroups"`
239+
AccountTag string `json:"accountTag"`
240+
}
241+
224242
func fetchZones() []cloudflare.Zone {
225243
var api *cloudflare.API
226244
var err error
@@ -607,3 +625,52 @@ func filterNonFreePlanZones(zones []cloudflare.Zone) (filteredZones []cloudflare
607625
}
608626
return
609627
}
628+
629+
func fetchDnsFirewallTotals(accountID string) (*cloudflareResponseDnsFirewall, error) {
630+
now := time.Now().Add(-time.Duration(cfgScrapeDelay) * time.Second).UTC()
631+
s := 60 * time.Second
632+
now = now.Truncate(s)
633+
oneHourAgo := now.Add(-60 * time.Minute)
634+
635+
request := graphql.NewRequest(`
636+
query ($accountID: string, $mintime: Time!, $maxtime: Time!, $limit: Int!) {
637+
viewer {
638+
accounts(filter: { accountTag: $accountID }) {
639+
accountTag
640+
dnsFirewallAnalyticsAdaptiveGroups(
641+
limit: $limit
642+
filter: { datetime_geq: $mintime, datetime_lt: $maxtime }
643+
) {
644+
count
645+
dimensions {
646+
clusterTag
647+
queryType
648+
responseCode
649+
}
650+
}
651+
}
652+
}
653+
}
654+
`)
655+
if len(cfgCfAPIToken) > 0 {
656+
request.Header.Set("Authorization", "Bearer "+cfgCfAPIToken)
657+
} else {
658+
request.Header.Set("X-AUTH-EMAIL", cfgCfAPIEmail)
659+
request.Header.Set("X-AUTH-KEY", cfgCfAPIKey)
660+
}
661+
request.Var("limit", 9999)
662+
request.Var("maxtime", now)
663+
request.Var("mintime", oneHourAgo)
664+
request.Var("accountID", accountID)
665+
666+
ctx := context.Background()
667+
graphqlClient := graphql.NewClient(cfGraphQLEndpoint)
668+
669+
var resp cloudflareResponseDnsFirewall
670+
if err := graphqlClient.Run(ctx, request, &resp); err != nil {
671+
log.Error(err)
672+
return nil, err
673+
}
674+
675+
return &resp, nil
676+
}

main.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
"github.com/cloudflare/cloudflare-go"
1111
"github.com/namsral/flag"
12-
"github.com/nelkinda/health-go"
12+
health "github.com/nelkinda/health-go"
1313
"github.com/prometheus/client_golang/prometheus/promhttp"
1414
log "github.com/sirupsen/logrus"
1515
)
@@ -106,8 +106,9 @@ func fetchMetrics(deniedMetricsSet MetricsSet) {
106106
accounts := fetchAccounts()
107107
filteredZones := filterExcludedZones(filterZones(zones, getTargetZones()), getExcludedZones())
108108

109-
for _, a := range accounts {
110-
go fetchWorkerAnalytics(a, &wg)
109+
for _, account := range accounts {
110+
go fetchWorkerAnalytics(account, &wg)
111+
go fetchDnsFirewallAnalytics(account, &wg, deniedMetricsSet)
111112
}
112113

113114
// Make requests in groups of cfgBatchSize to avoid rate limit

prometheus.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const (
4747
workerDurationMetricName MetricName = "cloudflare_worker_duration"
4848
poolHealthStatusMetricName MetricName = "cloudflare_zone_pool_health_status"
4949
poolRequestsTotalMetricName MetricName = "cloudflare_zone_pool_requests_total"
50+
dnsFirewallQueryCountMetricName MetricName = "cloudflare_dns_firewall_query_count"
5051
)
5152

5253
type MetricsSet map[MetricName]struct{}
@@ -243,6 +244,12 @@ var (
243244
},
244245
[]string{"zone", "load_balancer_name", "pool_name", "origin_name"},
245246
)
247+
248+
dnsFirewallQueryCount = prometheus.NewGaugeVec(prometheus.GaugeOpts{
249+
Name: dnsFirewallQueryCountMetricName.String(),
250+
Help: "DNS Firewall query count by query type and response code",
251+
}, []string{"account_id", "account_name", "dns_firewall_id", "query_type", "response_code"},
252+
)
246253
)
247254

248255
func buildAllMetricsSet() MetricsSet {
@@ -277,6 +284,7 @@ func buildAllMetricsSet() MetricsSet {
277284
allMetricsSet.Add(workerDurationMetricName)
278285
allMetricsSet.Add(poolHealthStatusMetricName)
279286
allMetricsSet.Add(poolRequestsTotalMetricName)
287+
allMetricsSet.Add(dnsFirewallQueryCountMetricName)
280288
return allMetricsSet
281289
}
282290

@@ -383,6 +391,9 @@ func mustRegisterMetrics(deniedMetrics MetricsSet) {
383391
if !deniedMetrics.Has(poolRequestsTotalMetricName) {
384392
prometheus.MustRegister(poolRequestsTotal)
385393
}
394+
if !deniedMetrics.Has(dnsFirewallQueryCountMetricName) {
395+
prometheus.MustRegister(dnsFirewallQueryCount)
396+
}
386397
}
387398

388399
func fetchWorkerAnalytics(account cloudflare.Account, wg *sync.WaitGroup) {
@@ -410,6 +421,30 @@ func fetchWorkerAnalytics(account cloudflare.Account, wg *sync.WaitGroup) {
410421
}
411422
}
412423

424+
func fetchDnsFirewallAnalytics(account cloudflare.Account, wg *sync.WaitGroup, deniedMetricsSet MetricsSet) {
425+
wg.Add(1)
426+
defer wg.Done()
427+
428+
r, err := fetchDnsFirewallTotals(account.ID)
429+
if err != nil {
430+
return
431+
}
432+
433+
for _, a := range r.Viewer.Accounts {
434+
for _, d := range a.DnsFirewallAnalyticsAdaptiveGroups {
435+
if !deniedMetricsSet.Has(dnsFirewallQueryCountMetricName) {
436+
dnsFirewallQueryCount.WithLabelValues(
437+
account.ID,
438+
account.Name,
439+
d.Dimensions.ClusterTag,
440+
d.Dimensions.QueryType,
441+
d.Dimensions.ResponseCode,
442+
).Set(float64(d.Count))
443+
}
444+
}
445+
}
446+
}
447+
413448
func fetchZoneColocationAnalytics(zones []cloudflare.Zone, wg *sync.WaitGroup, deniedMetricsSet MetricsSet) {
414449
wg.Add(1)
415450
defer wg.Done()

0 commit comments

Comments
 (0)