Browse Source

Redact IP addresses from error fields

mirokuratczyk 7 years ago
parent
commit
0e3f7c8020
2 changed files with 49 additions and 28 deletions
  1. 8 1
      Server/logging/analysis/analysis.go
  2. 41 27
      Server/logging/analysis/analysis_test.go

+ 8 - 1
Server/logging/analysis/analysis.go

@@ -33,6 +33,7 @@ import (
 	"log"
 	"os"
 	"reflect"
+	"regexp"
 	"sort"
 
 	"github.com/sirupsen/logrus"
@@ -511,6 +512,11 @@ func (l *LogStats) ParseLogLine(log string) error {
 	return nil
 }
 
+func redactIpAddressesAndPorts(a string) string {
+	ipAddressWithOptionalPort := regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}(:(6553[0-5]|655[0-2][0-9]\d|65[0-4](\d){2}|6[0-4](\d){3}|[1-5](\d){4}|[1-9](\d){0,3}))?`)
+	return ipAddressWithOptionalPort.ReplaceAllString(a, "<redacted>")
+}
+
 // parseLogModel attempts to parse a string into a log model. It is expected
 // that the provided string is valid JSON.
 func parseLogModel(s string) (LogModel, error) {
@@ -554,7 +560,8 @@ func parseLogModel(s string) (LogModel, error) {
 		}
 
 		if val, ok := m["error"]; ok {
-			e := MessageLogError(val.(string))
+			errorWithIpsRedacted := redactIpAddressesAndPorts(val.(string))
+			e := MessageLogError(errorWithIpsRedacted)
 			err = &e
 		}
 

+ 41 - 27
Server/logging/analysis/analysis_test.go

@@ -24,35 +24,31 @@ import (
 	"testing"
 )
 
-func TestLogLinesWithExpectations(t *testing.T) {
-	var l *LogStats
-
-	t.Run("test log model parsing and sorting", func(t *testing.T) {
-		l = parseLogsAndTestExpectations(logLinesWithExpectations(), t)
-
-		logs, _ := l.SortLogModels(true, true, true)
-		var prevLogCount uint
-
-		for _, x := range logs {
-			var count uint
-
-			switch v := x.(type) {
-			case MessageLogModelStats:
-				count = v.Count
-			case MetricsLogModelStats:
-				count = v.Count
-			case UnknownLogModelStats:
-				count = v.Count
-			default:
-				t.Errorf("Encountered unexpected struct of type %v\n", reflect.TypeOf(v))
-			}
+func TestAllLogModelsAndSorting(t *testing.T) {
+	l := parseLogsAndTestExpectations(logLinesWithExpectations(), t)
+
+	logs, _ := l.SortLogModels(true, true, true)
+	var prevLogCount uint
+
+	for _, x := range logs {
+		var count uint
+
+		switch v := x.(type) {
+		case MessageLogModelStats:
+			count = v.Count
+		case MetricsLogModelStats:
+			count = v.Count
+		case UnknownLogModelStats:
+			count = v.Count
+		default:
+			t.Errorf("Encountered unexpected struct of type %v\n", reflect.TypeOf(v))
+		}
 
-			if prevLogCount != 0 && prevLogCount > count {
-				t.Errorf("Expected list to be sorted in ascending order")
-			}
-			prevLogCount = count
+		if prevLogCount != 0 && prevLogCount > count {
+			t.Errorf("Expected list to be sorted in ascending order")
 		}
-	})
+		prevLogCount = count
+	}
 }
 
 func TestMessageLogsWithErrorAndContext(t *testing.T) {
@@ -85,6 +81,24 @@ func TestMessageLogsWithErrorAndContext(t *testing.T) {
 	}
 }
 
+func TestMessageLogsWithRedactedIpAddresses(t *testing.T) {
+	logs := []LogLineWithExpectation{
+		// The following messages should parse into 1 distinct log model
+		messageLogExpectation(`{"msg":"a", "level":"info", "error": "1.1.1.1->2.2.2.2"}`),
+		messageLogExpectation(`{"msg":"a", "level":"info", "error": "3.3.3.3->4.4.4.4"}`),
+		messageLogExpectation(`{"msg":"a", "level":"info", "error": "1.1.1.1->2.2.2.2:1"}`),
+		messageLogExpectation(`{"msg":"a", "level":"info", "error": "1.1.1.1->2.2.2.2:65535"}`),
+	}
+
+	l := parseLogsAndTestExpectations(logs, t)
+
+	numLogModels := len(l.MessageLogModels.modelStats)
+	expectedUniqueModels := 1
+	if numLogModels != expectedUniqueModels {
+		t.Errorf("Expected %d message log models but found %d\n", expectedUniqueModels, numLogModels)
+	}
+}
+
 // Helpers
 
 type LogLineWithExpectation struct {