diff --git a/src/app/backend/resource/container/logs_test.go b/src/app/backend/resource/container/logs_test.go index af3898f2fef5..bbe957002bb7 100644 --- a/src/app/backend/resource/container/logs_test.go +++ b/src/app/backend/resource/container/logs_test.go @@ -15,6 +15,7 @@ package container import ( + "fmt" "reflect" "testing" @@ -47,6 +48,40 @@ var log5 = logs.LogLine{ Content: "log5", } +var details *logs.LogDetails + +func benchmarkGetLogDetails(lines int, timestamp string, b *testing.B) { + // Generate raw logs. + rawLogs := "" + for i := 0; i < lines; i++ { + rawLogs += fmt.Sprintf("%[1]d log%[1]d\n", i) + } + + selector := &logs.Selection{ + ReferencePoint: logs.LogLineId{ + LogTimestamp: logs.LogTimestamp(timestamp), + LineNum: 1, + }, + OffsetFrom: -2, + OffsetTo: 0, + } + + var d *logs.LogDetails + + b.ResetTimer() + for n := 0; n < b.N; n++ { + d = ConstructLogDetails("pod-1", rawLogs, "list", selector) + } + b.StopTimer() + + details = d +} + +func BenchmarkGetLogDetails1(b *testing.B) { benchmarkGetLogDetails(2000, "1999", b) } +func BenchmarkGetLogDetails2(b *testing.B) { benchmarkGetLogDetails(2000, "999", b) } +func BenchmarkGetLogDetails3(b *testing.B) { benchmarkGetLogDetails(2000, "99", b) } +func BenchmarkGetLogDetails4(b *testing.B) { benchmarkGetLogDetails(2000, "9", b) } + func TestGetLogs(t *testing.T) { // for the test cases, the line read limit is reduced to 10 lineReadLimit = int64(10) diff --git a/src/app/backend/resource/logs/logs.go b/src/app/backend/resource/logs/logs.go index 6eb644ae72d6..0804d23ea39a 100644 --- a/src/app/backend/resource/logs/logs.go +++ b/src/app/backend/resource/logs/logs.go @@ -15,6 +15,7 @@ package logs import ( + "sort" "strings" ) @@ -193,18 +194,19 @@ func (self LogLines) getLineIndex(logLineId *LogLineId) int { return 0 } logTimestamp := logLineId.LogTimestamp - linesMatched := 0 + matchingStartedAt := 0 - for idx := range self { - if self[idx].Timestamp == logTimestamp { - if linesMatched == 0 { - matchingStartedAt = idx - } + matchingStartedAt = sort.Search(len(self), func(i int) bool { + return self[i].Timestamp >= logTimestamp + }) + + linesMatched := 0 + if matchingStartedAt < len(self) && self[matchingStartedAt].Timestamp == logTimestamp { // match found + for (matchingStartedAt+linesMatched) < len(self) && self[matchingStartedAt+linesMatched].Timestamp == logTimestamp { linesMatched += 1 - } else if linesMatched > 0 { - break } } + var offset int if logLineId.LineNum < 0 { offset = linesMatched + logLineId.LineNum