github.com/tilt-dev/tilt@v0.36.0/internal/hud/log_filter.go (about) 1 package hud 2 3 import ( 4 "strings" 5 6 "github.com/tilt-dev/tilt/pkg/logger" 7 "github.com/tilt-dev/tilt/pkg/model" 8 "github.com/tilt-dev/tilt/pkg/model/logstore" 9 ) 10 11 type FilterSource string 12 13 const ( 14 FilterSourceAll FilterSource = "all" 15 FilterSourceBuild FilterSource = "build" 16 FilterSourceRuntime FilterSource = "runtime" 17 ) 18 19 func (s FilterSource) String() string { return string(s) } 20 21 type FilterResources []model.ManifestName 22 23 func (r FilterResources) Matches(name model.ManifestName) bool { 24 if len(r) == 0 { 25 return true 26 } 27 28 for _, n := range r { 29 if n == name { 30 return true 31 } 32 } 33 34 return false 35 } 36 37 type FilterLevel logger.Level 38 39 func NewLogFilter( 40 source FilterSource, 41 resources FilterResources, 42 level FilterLevel, 43 ) LogFilter { 44 return LogFilter{ 45 source: source, 46 resources: resources, 47 level: logger.Level(level), 48 } 49 } 50 51 type LogFilter struct { 52 source FilterSource 53 resources FilterResources 54 level logger.Level 55 } 56 57 // The implementation is identical to isBuildSpanId in web/src/logs.ts. 58 func isBuildSpanID(spanID logstore.SpanID) bool { 59 return strings.HasPrefix(string(spanID), "build:") || strings.HasPrefix(string(spanID), "cmdimage:") 60 } 61 62 // The implementation is identical to matchesLevelFilter in web/src/OverviewLogPane.tsx 63 func (f LogFilter) matchesLevelFilter(line logstore.LogLine) bool { 64 if !f.level.AsSevereAs(logger.WarnLvl) { 65 return true 66 } 67 68 return f.level == line.Level 69 } 70 71 // if printing logs for only one resource, don't need resource name prefix 72 func (f LogFilter) SuppressPrefix() bool { 73 return len(f.resources) == 1 74 } 75 76 // Matches Checks if this line matches the current filter. 77 // The implementation is identical to matchesFilter in web/src/OverviewLogPane.tsx. 78 // except for term filtering as tools like grep can be used from the CLI. 79 func (f LogFilter) Matches(line logstore.LogLine) bool { 80 if line.BuildEvent != "" { 81 // Always leave in build event logs. 82 // This makes it easier to see which logs belong to which builds. 83 return true 84 } 85 86 if !f.resources.Matches(line.ManifestName) { 87 return false 88 } 89 90 isBuild := isBuildSpanID(line.SpanID) 91 if f.source == FilterSourceRuntime && isBuild { 92 return false 93 } 94 95 if f.source == FilterSourceBuild && !isBuild { 96 return false 97 } 98 99 return f.matchesLevelFilter(line) 100 } 101 102 func (f LogFilter) Apply(lines []logstore.LogLine) []logstore.LogLine { 103 filtered := []logstore.LogLine{} 104 for _, line := range lines { 105 if f.Matches(line) { 106 filtered = append(filtered, line) 107 } 108 } 109 110 return filtered 111 }