@@ -63,6 +63,8 @@ const (
6363 tunnelHealthStatusMetricName MetricName = "cloudflare_tunnel_health_status"
6464 tunnelConnectorInfoMetricName MetricName = "cloudflare_tunnel_connector_info"
6565 tunnelConnectorActiveConnectionsMetricName MetricName = "cloudflare_tunnel_connector_active_connections"
66+ zoneRequestASNMetricName MetricName = "cloudflare_zone_requests_asn"
67+ zoneBandwidthASNMetricName MetricName = "cloudflare_zone_bandwidth_asn"
6668 zoneEdgeErrorsByPathMetricName MetricName = "cloudflare_zone_edge_errors_by_path"
6769)
6870
@@ -336,6 +338,16 @@ var (
336338 Help : "Reports number of active connections for a Cloudflare Tunnel connector" ,
337339 }, []string {"account" , "tunnel_id" , "client_id" })
338340
341+ zoneRequestASN = prometheus .NewCounterVec (prometheus.CounterOpts {
342+ Name : zoneRequestASNMetricName .String (),
343+ Help : "Number of requests per ASN (Autonomous System Number)" ,
344+ }, []string {"zone" , "account" , "asn" , "asn_description" })
345+
346+ zoneBandwidthASN = prometheus .NewCounterVec (prometheus.CounterOpts {
347+ Name : zoneBandwidthASNMetricName .String (),
348+ Help : "Bandwidth per ASN (Autonomous System Number) in bytes" ,
349+ }, []string {"zone" , "account" , "asn" , "asn_description" })
350+
339351 zoneEdgeErrorsByPath = prometheus .NewCounterVec (prometheus.CounterOpts {
340352 Name : zoneEdgeErrorsByPathMetricName .String (),
341353 Help : "Number of edge errors (4xx and 5xx) by request path" ,
@@ -386,6 +398,8 @@ func buildAllMetricsSet() MetricsSet {
386398 allMetricsSet .Add (tunnelHealthStatusMetricName )
387399 allMetricsSet .Add (tunnelConnectorInfoMetricName )
388400 allMetricsSet .Add (tunnelConnectorActiveConnectionsMetricName )
401+ allMetricsSet .Add (zoneRequestASNMetricName )
402+ allMetricsSet .Add (zoneBandwidthASNMetricName )
389403 allMetricsSet .Add (zoneEdgeErrorsByPathMetricName )
390404 return allMetricsSet
391405}
@@ -533,6 +547,12 @@ func mustRegisterMetrics(deniedMetrics MetricsSet) {
533547 if ! deniedMetrics .Has (tunnelConnectorActiveConnectionsMetricName ) {
534548 prometheus .MustRegister (tunnelConnectorActiveConnections )
535549 }
550+ if ! deniedMetrics .Has (zoneRequestASNMetricName ) {
551+ prometheus .MustRegister (zoneRequestASN )
552+ }
553+ if ! deniedMetrics .Has (zoneBandwidthASNMetricName ) {
554+ prometheus .MustRegister (zoneBandwidthASN )
555+ }
536556 if ! deniedMetrics .Has (zoneEdgeErrorsByPathMetricName ) {
537557 prometheus .MustRegister (zoneEdgeErrorsByPath )
538558 }
@@ -1099,3 +1119,48 @@ func getCloudflareTunnelStatusValue(status string) uint8 {
10991119 return 255
11001120 }
11011121}
1122+
1123+ func fetchZoneASNAnalytics (zones []cfzones.Zone , wg * sync.WaitGroup ) {
1124+ defer wg .Done ()
1125+
1126+ // ASN metrics are not available in free tier
1127+ if viper .GetBool ("free_tier" ) {
1128+ return
1129+ }
1130+
1131+ zoneIDs := extractZoneIDs (zones )
1132+ if len (zoneIDs ) == 0 {
1133+ return
1134+ }
1135+
1136+ r , err := fetchASNTotals (zoneIDs )
1137+ if err != nil {
1138+ return
1139+ }
1140+
1141+ for _ , z := range r .Viewer .Zones {
1142+ name , account := findZoneAccountName (zones , z .ZoneTag )
1143+ addASNGroups (& z , name , account )
1144+ }
1145+ }
1146+
1147+ func addASNGroups (z * zoneRespASN , name string , account string ) {
1148+ if len (z .HttpRequestsASNGroups ) == 0 {
1149+ return
1150+ }
1151+
1152+ for _ , g := range z .HttpRequestsASNGroups {
1153+ asn := g .Dimensions .ClientASN
1154+ asnDesc := g .Dimensions .ClientASNDescription
1155+ if asnDesc == "" {
1156+ asnDesc = "unknown"
1157+ }
1158+
1159+ zoneRequestASN .With (prometheus.Labels {
1160+ "zone" : name , "account" : account , "asn" : asn , "asn_description" : asnDesc ,
1161+ }).Add (float64 (g .Count ))
1162+ zoneBandwidthASN .With (prometheus.Labels {
1163+ "zone" : name , "account" : account , "asn" : asn , "asn_description" : asnDesc ,
1164+ }).Add (float64 (g .Sum .EdgeResponseBytes ))
1165+ }
1166+ }
0 commit comments