Loading collector.go +14 −9 Original line number Diff line number Diff line Loading @@ -10,20 +10,21 @@ import ( "log" "net/http" "os" "sort" "strings" "sync" "time" ) const ( collectorResolution = 24 * time.Hour collectorResolution = time.Hour expireDuration = 24 * time.Hour collectorTempExtension = ".tmp" ) type bridgeTestResult struct { Functional bool FingerprintHash string Time time.Time } // CollectorMetrics stores the metrics to produce a metrics document for CollecTor Loading @@ -32,7 +33,7 @@ type CollectorMetrics struct { filename string CachedRequests uint BridgeTests []bridgeTestResult BridgeTests map[string]bridgeTestResult LastPublished time.Time //synchronization for access to bridgestrap collector Loading @@ -45,6 +46,7 @@ var collectorMetrics *CollectorMetrics // it must be called once before the variable is being used func InitCollectorMetrics(metricsFilename string) error { collectorMetrics = new(CollectorMetrics) collectorMetrics.BridgeTests = make(map[string]bridgeTestResult) err := loadCollectorMetrics(metricsFilename + collectorTempExtension) if err != nil { return err Loading Loading @@ -89,9 +91,10 @@ func (m *CollectorMetrics) IncCacheRequests() { // AddBridgeTest adds the functional status of the bridge to the metrics // fingerprint can be an empty string, and the fingerprint will be retrieved if possible from the bridgeLine func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, bridgeLine string) { func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, bridgeLine string, lastTested time.Time) { test := bridgeTestResult{ Functional: functional, Time: lastTested, } fp := "" Loading @@ -112,7 +115,7 @@ func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, br m.lock.Lock() defer m.lock.Unlock() m.BridgeTests = append(m.BridgeTests, test) m.BridgeTests[fp] = test } func (m *CollectorMetrics) Save() { Loading Loading @@ -154,10 +157,12 @@ func (m *CollectorMetrics) publishMetrics() { m.logger.Println("bridgestrap-stats-end", time.Now().UTC().Format("2006-01-02 15:04:05"), fmt.Sprintf("(%d s)", int(collectorResolution.Seconds()))) m.logger.Println("bridgestrap-cached-requests", m.CachedRequests) sort.Slice(m.BridgeTests, func(i, j int) bool { return m.BridgeTests[i].FingerprintHash < m.BridgeTests[j].FingerprintHash }) for _, test := range m.BridgeTests { expireDate := time.Now().UTC().Add(-expireDuration) for fp, test := range m.BridgeTests { if test.Time.Before(expireDate) { delete(m.BridgeTests, fp) continue } m.logger.Println("bridgestrap-test", test.Functional, test.FingerprintHash) } Loading collector_test.go +43 −3 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import ( "strconv" "strings" "testing" "time" ) func TestCachedRequests(t *testing.T) { Loading Loading @@ -65,9 +66,9 @@ func TestBridgeTests(t *testing.T) { t.Fatalf("Failed to initialize the collector metrics: %s", err) } collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1) collectorMetrics.AddBridgeTest(false, "", "4.3.2.1:443 "+fingerprint2) collectorMetrics.AddBridgeTest(false, "", "8.7.6.4:443") collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC()) collectorMetrics.AddBridgeTest(false, "", "4.3.2.1:443 "+fingerprint2, time.Now().UTC()) collectorMetrics.AddBridgeTest(false, "", "8.7.6.4:443", time.Now().UTC()) collectorMetrics.publishMetrics() content, err := ioutil.ReadAll(tmpFh) Loading Loading @@ -113,6 +114,45 @@ func TestBridgeTests(t *testing.T) { } } func TestCollectorTwiceBridge(t *testing.T) { const fingerprint1 = "0123456789ABCDEF0123456789ABCDEF01234567" tmpFh, err := ioutil.TempFile(os.TempDir(), "cache-file-") if err != nil { t.Fatalf("Could not create temporary file for test: %s", err) } defer os.Remove(tmpFh.Name()) err = InitCollectorMetrics(tmpFh.Name()) if err != nil { t.Fatalf("Failed to initialize the collector metrics: %s", err) } collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC().Add(-1*time.Minute)) collectorMetrics.AddBridgeTest(false, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC()) collectorMetrics.publishMetrics() content, err := ioutil.ReadAll(tmpFh) if err != nil { t.Fatalf("Failed to read the collected metrics: %s", err) } re := regexp.MustCompile(`bridgestrap-test ([a-z]*) (.+)\n`) fpTests := re.FindAll(content, -1) if len(fpTests) != 1 { t.Fatalf("Found %d tests with fingerprint", len(fpTests)) } sp := strings.Split(string(fpTests[0]), " ") functional, err := strconv.ParseBool(sp[1]) if err != nil { t.Errorf("Can't parse the status of the bridge to bool: %s", err) } if functional { t.Errorf("Not the expected functional %v for %s", functional, string(sp[2])) } } func TestHashFingerprint(t *testing.T) { fp := "C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C" expectedHash := "997B6FEB5A02B1F08A36CECCE9B5B3997C0A4680" Loading handlers.go +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ func testBridgeLines(req *TestRequest) *TestResult { } else { metrics.BridgeStatus.With(prometheus.Labels{"status": "dysfunctional"}).Inc() } collectorMetrics.AddBridgeTest(bridgeTest.Functional, bridgeTest.fingerprint, bridgeLine) collectorMetrics.AddBridgeTest(bridgeTest.Functional, bridgeTest.fingerprint, bridgeLine, bridgeTest.LastTested) result.Bridges[bridgeLine] = bridgeTest } } else { Loading Loading
collector.go +14 −9 Original line number Diff line number Diff line Loading @@ -10,20 +10,21 @@ import ( "log" "net/http" "os" "sort" "strings" "sync" "time" ) const ( collectorResolution = 24 * time.Hour collectorResolution = time.Hour expireDuration = 24 * time.Hour collectorTempExtension = ".tmp" ) type bridgeTestResult struct { Functional bool FingerprintHash string Time time.Time } // CollectorMetrics stores the metrics to produce a metrics document for CollecTor Loading @@ -32,7 +33,7 @@ type CollectorMetrics struct { filename string CachedRequests uint BridgeTests []bridgeTestResult BridgeTests map[string]bridgeTestResult LastPublished time.Time //synchronization for access to bridgestrap collector Loading @@ -45,6 +46,7 @@ var collectorMetrics *CollectorMetrics // it must be called once before the variable is being used func InitCollectorMetrics(metricsFilename string) error { collectorMetrics = new(CollectorMetrics) collectorMetrics.BridgeTests = make(map[string]bridgeTestResult) err := loadCollectorMetrics(metricsFilename + collectorTempExtension) if err != nil { return err Loading Loading @@ -89,9 +91,10 @@ func (m *CollectorMetrics) IncCacheRequests() { // AddBridgeTest adds the functional status of the bridge to the metrics // fingerprint can be an empty string, and the fingerprint will be retrieved if possible from the bridgeLine func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, bridgeLine string) { func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, bridgeLine string, lastTested time.Time) { test := bridgeTestResult{ Functional: functional, Time: lastTested, } fp := "" Loading @@ -112,7 +115,7 @@ func (m *CollectorMetrics) AddBridgeTest(functional bool, fingerprint string, br m.lock.Lock() defer m.lock.Unlock() m.BridgeTests = append(m.BridgeTests, test) m.BridgeTests[fp] = test } func (m *CollectorMetrics) Save() { Loading Loading @@ -154,10 +157,12 @@ func (m *CollectorMetrics) publishMetrics() { m.logger.Println("bridgestrap-stats-end", time.Now().UTC().Format("2006-01-02 15:04:05"), fmt.Sprintf("(%d s)", int(collectorResolution.Seconds()))) m.logger.Println("bridgestrap-cached-requests", m.CachedRequests) sort.Slice(m.BridgeTests, func(i, j int) bool { return m.BridgeTests[i].FingerprintHash < m.BridgeTests[j].FingerprintHash }) for _, test := range m.BridgeTests { expireDate := time.Now().UTC().Add(-expireDuration) for fp, test := range m.BridgeTests { if test.Time.Before(expireDate) { delete(m.BridgeTests, fp) continue } m.logger.Println("bridgestrap-test", test.Functional, test.FingerprintHash) } Loading
collector_test.go +43 −3 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import ( "strconv" "strings" "testing" "time" ) func TestCachedRequests(t *testing.T) { Loading Loading @@ -65,9 +66,9 @@ func TestBridgeTests(t *testing.T) { t.Fatalf("Failed to initialize the collector metrics: %s", err) } collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1) collectorMetrics.AddBridgeTest(false, "", "4.3.2.1:443 "+fingerprint2) collectorMetrics.AddBridgeTest(false, "", "8.7.6.4:443") collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC()) collectorMetrics.AddBridgeTest(false, "", "4.3.2.1:443 "+fingerprint2, time.Now().UTC()) collectorMetrics.AddBridgeTest(false, "", "8.7.6.4:443", time.Now().UTC()) collectorMetrics.publishMetrics() content, err := ioutil.ReadAll(tmpFh) Loading Loading @@ -113,6 +114,45 @@ func TestBridgeTests(t *testing.T) { } } func TestCollectorTwiceBridge(t *testing.T) { const fingerprint1 = "0123456789ABCDEF0123456789ABCDEF01234567" tmpFh, err := ioutil.TempFile(os.TempDir(), "cache-file-") if err != nil { t.Fatalf("Could not create temporary file for test: %s", err) } defer os.Remove(tmpFh.Name()) err = InitCollectorMetrics(tmpFh.Name()) if err != nil { t.Fatalf("Failed to initialize the collector metrics: %s", err) } collectorMetrics.AddBridgeTest(true, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC().Add(-1*time.Minute)) collectorMetrics.AddBridgeTest(false, fingerprint1, "1.2.3.4:443 "+fingerprint1, time.Now().UTC()) collectorMetrics.publishMetrics() content, err := ioutil.ReadAll(tmpFh) if err != nil { t.Fatalf("Failed to read the collected metrics: %s", err) } re := regexp.MustCompile(`bridgestrap-test ([a-z]*) (.+)\n`) fpTests := re.FindAll(content, -1) if len(fpTests) != 1 { t.Fatalf("Found %d tests with fingerprint", len(fpTests)) } sp := strings.Split(string(fpTests[0]), " ") functional, err := strconv.ParseBool(sp[1]) if err != nil { t.Errorf("Can't parse the status of the bridge to bool: %s", err) } if functional { t.Errorf("Not the expected functional %v for %s", functional, string(sp[2])) } } func TestHashFingerprint(t *testing.T) { fp := "C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C" expectedHash := "997B6FEB5A02B1F08A36CECCE9B5B3997C0A4680" Loading
handlers.go +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ func testBridgeLines(req *TestRequest) *TestResult { } else { metrics.BridgeStatus.With(prometheus.Labels{"status": "dysfunctional"}).Inc() } collectorMetrics.AddBridgeTest(bridgeTest.Functional, bridgeTest.fingerprint, bridgeLine) collectorMetrics.AddBridgeTest(bridgeTest.Functional, bridgeTest.fingerprint, bridgeLine, bridgeTest.LastTested) result.Bridges[bridgeLine] = bridgeTest } } else { Loading