github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/parser/outputhelpers.go (about) 1 // Copyright 2022-2023 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package parser 16 17 import ( 18 "encoding/json" 19 20 "github.com/inspektor-gadget/inspektor-gadget/pkg/columns/formatter/textcolumns" 21 "github.com/inspektor-gadget/inspektor-gadget/pkg/logger" 22 "github.com/inspektor-gadget/inspektor-gadget/pkg/types" 23 ) 24 25 // TextColumnsFormatter is the interface used for outputHelper 26 type TextColumnsFormatter interface { 27 FormatHeader() string 28 SetShowColumns([]string) error 29 TransformEvent(string) (string, error) 30 EventHandlerFunc() any 31 EventHandlerFuncArray(...func()) any 32 SetEventCallback(eventCallback func(string)) 33 SetEnableExtraLines(bool) 34 } 35 36 type ExtraLines interface { 37 ExtraLines() []string 38 } 39 40 type ErrorGetter interface { 41 GetType() types.EventType 42 GetMessage() string 43 } 44 45 // outputHelpers hides all information about underlying types from the application 46 type outputHelper[T any] struct { 47 parser *parser[T] 48 *textcolumns.TextColumnsFormatter[T] 49 eventCallback func(string) 50 enableExtraLines bool 51 } 52 53 func (oh *outputHelper[T]) forwardEvent(ev *T) { 54 oh.eventCallback(oh.TextColumnsFormatter.FormatEntry(ev)) 55 if !oh.enableExtraLines { 56 return 57 } 58 // Output extra lines if the events support this 59 for _, line := range any(ev).(ExtraLines).ExtraLines() { 60 oh.eventCallback(line) 61 } 62 } 63 64 func (oh *outputHelper[T]) EventHandlerFunc() any { 65 if oh.eventCallback == nil { 66 panic("set event callback before getting the EventHandlerFunc from TextColumnsFormatter") 67 } 68 return func(ev *T) { 69 if getter, ok := any(ev).(ErrorGetter); ok { 70 switch getter.GetType() { 71 case types.ERR: 72 oh.parser.writeLogMessage(logger.ErrorLevel, getter.GetMessage()) 73 return 74 case types.WARN: 75 oh.parser.writeLogMessage(logger.WarnLevel, getter.GetMessage()) 76 return 77 case types.DEBUG: 78 oh.parser.writeLogMessage(logger.DebugLevel, getter.GetMessage()) 79 return 80 case types.INFO: 81 oh.parser.writeLogMessage(logger.InfoLevel, getter.GetMessage()) 82 return 83 } 84 } 85 86 oh.forwardEvent(ev) 87 } 88 } 89 90 func (oh *outputHelper[T]) EventHandlerFuncArray(headerFuncs ...func()) any { 91 if oh.eventCallback == nil { 92 panic("set event callback before getting the EventHandlerFunc from TextColumnsFormatter") 93 } 94 return func(events []*T) { 95 for _, hf := range headerFuncs { 96 hf() 97 } 98 for _, ev := range events { 99 oh.forwardEvent(ev) 100 } 101 } 102 } 103 104 func (oh *outputHelper[T]) SetEventCallback(eventCallback func(string)) { 105 oh.eventCallback = eventCallback 106 } 107 108 // TransformEvent takes a JSON encoded line and transforms it to columns view 109 func (oh *outputHelper[T]) TransformEvent(line string) (string, error) { 110 ev := new(T) 111 err := json.Unmarshal([]byte(line), &ev) 112 if err != nil { 113 return "", err 114 } 115 116 // Apply filters 117 if oh.parser.filterSpecs != nil && !oh.parser.filterSpecs.MatchAll(ev) { 118 return "", nil 119 } 120 121 return oh.FormatEntry(ev), nil 122 } 123 124 func (oh *outputHelper[T]) SetShowColumns(cols []string) error { 125 return oh.TextColumnsFormatter.SetShowColumns(cols) 126 } 127 128 func (oh *outputHelper[T]) SetEnableExtraLines(newVal bool) { 129 // Check, whether the type actually supports extra lines 130 if _, ok := any(new(T)).(ExtraLines); !ok { 131 return 132 } 133 oh.enableExtraLines = newVal 134 }