Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ezrizhu committed Jul 22, 2024
1 parent e89dabc commit d9bbdaa
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 104 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22
require (
github.com/prometheus/client_golang v1.19.1
github.com/rs/zerolog v1.33.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3c
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
91 changes: 91 additions & 0 deletions lg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package main

import (
"encoding/json"
"io/ioutil"
"net/http"
"strconv"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/rs/zerolog/log"
"golang.org/x/exp/slices"
)

var (
asPathGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "as_path",
Help: "AS PATH",
},
[]string{"prefix", "city", "mux"},
)
//bgpCommunitiesGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
// Name: "bgp_communities",
// Help: "BGP Communities",
//},
// []string{"prefix", "city", "mux", "communities"},
//)
)

func (p *PrefixState) checkLGState() {
log.Trace().Str("Prefix", p.Prefix).Msg("checking prefix state")
url := ripestatBase + "/data/looking-glass/data.json?resource=" + p.Prefix + "&sourceapp=" + appId
resp, err := http.Get(url)
if err != nil {
log.Error().Err(err).Msg("Fetching ripestat")
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("reading ripestat resp")
}
defer resp.Body.Close()

var ripeStatLookingGlassResp RIPEStatLookingGlassResp
json.Unmarshal(body, &ripeStatLookingGlassResp)

if statusCode := ripeStatLookingGlassResp.StatusCode; statusCode != 200 {
log.Error().Int("status code", statusCode).
Str("status", ripeStatLookingGlassResp.Status).
Msg("ripestat(lg) resp status code != 200")
}

p.Mu.Lock()
defer p.Mu.Unlock()

for _, rrc := range ripeStatLookingGlassResp.Data.Rrcs {
upstreams := []int{}
//communities := []string{}
for _, peer := range rrc.Peers {
asPathSplit := strings.Split(peer.AsPath, " ")
upstream := 0
if len(asPathSplit) >= 2 {
upstreamStr := asPathSplit[len(asPathSplit)-2]
upstream, err = strconv.Atoi(upstreamStr)
if err != nil {
log.Err(err).Msg("atoi fail")
}
}
upstreams = append(upstreams, upstream)
//communities = append(communities, peer.Community)
}
upstreams = slices.Compact(upstreams)
for _, upstream := range upstreams {
asPathGauge.WithLabelValues(
p.Prefix,
rrc.Location,
prefixes[p.Prefix],
).Set(float64(upstream))
}
//communities = slices.Compact(communities)
//for _, e := range communities {
// bgpCommunitiesGauge.WithLabelValues(
// p.Prefix,
// rrc.Location,
// prefixes[p.Prefix],
// e,
// ).Set(1)
//}
}
}
116 changes: 13 additions & 103 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,159 +2,69 @@ package main

import (
"context"
"encoding/json"
"errors"
"flag"
"io/ioutil"
"net/http"
"os"
"os/signal"
"strconv"
"strings"
"sync"
"syscall"
"time"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

var prefixes = []string{
// PEERING v6
"2804:269c:fe41::/48",
"2804:269c:fe42::/48",
"2804:269c:fe44::/48",
"2804:269c:fe45::/48",
"2804:269c:fe47::/48",
"2804:269c:fe50::/48",
"2804:269c:fe51::/48",
"2804:269c:fe53::/48",
"2804:269c:fe56::/48",
"2804:269c:fe57::/48",
"2804:269c:fe58::/48",
"2804:269c:fe59::/48",
"2804:269c:fe5a::/48",
"2804:269c:fe5b::/48",
"2804:269c:fe5c::/48",
"2804:269c:fe5d::/48",
"2804:269c:fe5e::/48",
"2804:269c:fe5f::/48",
"2804:269c:fe60::/48",
"2804:269c:fe61::/48",
"2804:269c:fe62::/48",
"2804:269c:fe63::/48",
"2804:269c:fe64::/48",
"2804:269c:fe65::/48",
"2804:269c:fe66::/48",
"2804:269c:fe67::/48",
"2804:269c:fe68::/48",
"2804:269c:fe69::/48",
"2804:269c:fe6a::/48",
"2804:269c:fe6b::/48",
"2804:269c:fe6c::/48",
"2804:269c:fe6d::/48",
"2804:269c:fe6e::/48",
"2804:269c:fe6f::/48",
"2804:269c:fe70::/48",
"2804:269c:fe71::/48",
"2804:269c:fe72::/48",
"2804:269c:fe73::/48",
"2804:269c:fe74::/48",
"2804:269c:fe76::/48",

// isbgpsafeyet.com valid
"104.17.224.0/20",
"2606:4700::/44",

// isbgpsafeyet.com invalid
"103.21.244.0/24",
"2606:4700:7000::/48",
}

var prefixStates = []*PrefixState{}

var port int
var appId string
var debug bool

var (
prefixStateGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "prefix_visibility",
Help: "Visibility of the prefix",
}, []string{"prefix", "city"})
)
const ripestatBase = "https://stat.ripe.net"

type PrefixState struct {
Prefix string
State map[string]float32
Mu sync.Mutex
}

func (p *PrefixState) checkState() {
log.Trace().Str("Prefix", p.Prefix).Msg("checking prefix state")
url := "https://stat.ripe.net/data/visibility/data.json?data_overload_limit=ignore&include=peers_seeing&resource=" + p.Prefix + "&sourceapp=" + appId
resp, err := http.Get(url)
if err != nil {
log.Error().Err(err).Msg("Fetching ripestat")
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("reading ripestat resp")
}
defer resp.Body.Close()

var ripeStatResp RIPEStatResp
json.Unmarshal(body, &ripeStatResp)

ipv6 := strings.Contains(p.Prefix, ":")

p.Mu.Lock()
defer p.Mu.Unlock()

for _, probe := range ripeStatResp.Data.Visibilities {
var vis float32
if ipv6 {
vis = float32(len(probe.Ipv6FullTablePeersSeeing)) /
float32(probe.Ipv6FullTablePeerCount)
} else {
vis = float32(len(probe.Ipv4FullTablePeersSeeing)) /
float32(probe.Ipv4FullTablePeerCount)

}
p.State[probe.Probe.City] = vis
prefixStateGauge.WithLabelValues(p.Prefix, probe.Probe.City).Set(float64(vis))
}
}

func updateStates() {
log.Debug().Msg("Updating Prefixes")
for _, ps := range prefixStates {
go ps.checkState()
go ps.checkVisState()
go ps.checkLGState()
}
}

func init() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
zerolog.SetGlobalLevel(zerolog.DebugLevel)

flag.StringVar(&appId, "appid", "exporter", "provide a unique identifier to every data call")
flag.IntVar(&port, "port", 2112, "port")
flag.BoolVar(&debug, "debug", false, "debug")
}

func main() {
flag.Parse()

if debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
log.Debug().Msg("Debug log enabled")
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

log.Info().
Str("appID", appId).
Str("Data Source", "RIPE RIS via RIPEstat API").
Msg("Starting PEERINGMON Exporter")

for _, prefix := range prefixes {
for prefix, _ := range prefixes {
prefixStates = append(prefixStates, &PrefixState{
Prefix: prefix,
State: make(map[string]float32),
Expand Down
54 changes: 54 additions & 0 deletions prefixes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

var prefixes = map[string]string{
"2804:269c:fe41::/48": "seattle01",
"2804:269c:fe42::/48": "isi01",
"2804:269c:fe45::/48": "amsterdam01",
"2804:269c:fe46::/48": "gatech01",
"2804:269c:fe47::/48": "ufmg01",
"2804:269c:fe49::/48": "grnet01",
"2804:269c:fe50::/48": "uw01",
"2804:269c:fe51::/48": "wisc01",
"2804:269c:fe54::/48": "neu01",
"2804:269c:fe56::/48": "clemson01",
"2804:269c:fe57::/48": "utah01",
"2804:269c:fe59::/48": "saopaulo01",
"2804:269c:fe63::/48": "vtrmiami",
"2804:269c:fe64::/48": "vtratlanta",
"2804:269c:fe65::/48": "vtramsterdam",
"2804:269c:fe66::/48": "vtrtokyo",
"2804:269c:fe67::/48": "vtrsydney",
"2804:269c:fe68::/48": "vtrfrankfurt",
"2804:269c:fe69::/48": "vtrseattle",
"2804:269c:fe70::/48": "vtrchicago",
"2804:269c:fe71::/48": "vtrparis",
"2804:269c:fe72::/48": "vtrsingapore",
"2804:269c:fe73::/48": "vtrwarsaw",
"2804:269c:fe74::/48": "vtrnewyork",
"2804:269c:fe75::/48": "vtrdallas",
"2804:269c:fe76::/48": "vtrmexico",
"2804:269c:fe77::/48": "vtrtoronto",
"2804:269c:fe78::/48": "vtrmadrid",
"2804:269c:fe79::/48": "vtrstockholm",
"2804:269c:fe80::/48": "vtrbangalore",
"2804:269c:fe81::/48": "vtrdelhi",
"2804:269c:fe82::/48": "vtrlosangelas",
"2804:269c:fe83::/48": "vtrsilicon",
"2804:269c:fe84::/48": "vtrlondon",
"2804:269c:fe85::/48": "vtrmumbai",
"2804:269c:fe86::/48": "vtrseoul",
"2804:269c:fe87::/48": "vtrmelbourne",
"2804:269c:fe88::/48": "vtrsaopaulo",
"2804:269c:fe89::/48": "vtrjohannesburg",
"2804:269c:fe90::/48": "vtrosaka",
"2804:269c:fe91::/48": "vtrsantiago",
"2804:269c:fe92::/48": "vtrmanchester",
"2804:269c:fe93::/48": "vtrtelaviv",
"2804:269c:fe94::/48": "vtrhonolulu",

"104.17.224.0/20": "cf valid4",
"2606:4700::/44": "cf valid6",

"103.21.244.0/24": "cf invalid4",
"2606:4700:7000::/48": "cf invalid6",
}
42 changes: 41 additions & 1 deletion ripeStruct.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package main

type RIPEStatResp struct {
type RIPEStatVisibilityResp struct {
Messages [][]string `json:"messages"`
SeeAlso []interface{} `json:"see_also"`
Version string `json:"version"`
Expand Down Expand Up @@ -48,3 +48,43 @@ type RIPEStatResp struct {
StatusCode int `json:"status_code"`
Time string `json:"time"`
}

type RIPEStatLookingGlassResp struct {
Messages []interface{} `json:"messages"`
SeeAlso []interface{} `json:"see_also"`
Version string `json:"version"`
DataCallName string `json:"data_call_name"`
DataCallStatus string `json:"data_call_status"`
Cached bool `json:"cached"`
Data struct {
Rrcs []struct {
Rrc string `json:"rrc"`
Location string `json:"location"`
Peers []struct {
AsnOrigin string `json:"asn_origin"`
AsPath string `json:"as_path"`
Community string `json:"community"`
LastUpdated string `json:"last_updated"`
Prefix string `json:"prefix"`
Peer string `json:"peer"`
Origin string `json:"origin"`
NextHop string `json:"next_hop"`
LatestTime string `json:"latest_time"`
} `json:"peers"`
} `json:"rrcs"`
QueryTime string `json:"query_time"`
LatestTime string `json:"latest_time"`
Parameters struct {
Resource string `json:"resource"`
LookBackLimit int `json:"look_back_limit"`
Cache interface{} `json:"cache"`
} `json:"parameters"`
} `json:"data"`
QueryID string `json:"query_id"`
ProcessTime int `json:"process_time"`
ServerID string `json:"server_id"`
BuildVersion string `json:"build_version"`
Status string `json:"status"`
StatusCode int `json:"status_code"`
Time string `json:"time"`
}
Loading

0 comments on commit d9bbdaa

Please sign in to comment.