github.com/observiq/bindplane-agent@v1.51.0/internal/report/snapshot/filter.go (about)

     1  // Copyright observIQ, Inc.
     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 snapshot
    16  
    17  import (
    18  	"strings"
    19  
    20  	"go.opentelemetry.io/collector/pdata/pcommon"
    21  )
    22  
    23  func queryMatchesValue(v pcommon.Value, searchQuery string) bool {
    24  	switch v.Type() {
    25  	case pcommon.ValueTypeMap:
    26  		// Recursively query for a match in the map (depth first search)
    27  		return queryMatchesMap(v.Map(), searchQuery)
    28  	case pcommon.ValueTypeSlice:
    29  		// Iterate each element of the slice
    30  		return queryMatchesSlice(v.Slice(), searchQuery)
    31  	case pcommon.ValueTypeEmpty:
    32  		// Cannot match empty value
    33  		return false
    34  	default:
    35  		// We might be able to actually get away with just doing this for slices/maps, but could lead to
    36  		// weird edgecases since those slices/maps would be json-ified
    37  		// Note: Bytes will be base64 encoded and searched that way.
    38  		return strings.Contains(v.AsString(), searchQuery)
    39  	}
    40  }
    41  
    42  func queryMatchesMap(m pcommon.Map, searchQuery string) bool {
    43  	matches := false
    44  
    45  	m.Range(func(k string, v pcommon.Value) bool {
    46  		// check if key matches
    47  		matches = strings.Contains(k, searchQuery)
    48  		if matches {
    49  			// Return false to cancel iterating, since we know this map matches
    50  			return false
    51  		}
    52  
    53  		// Check if the value matches
    54  		matches = queryMatchesValue(v, searchQuery)
    55  		if matches {
    56  			// Return false to cancel iterating, since we know this map matches
    57  			return false
    58  		}
    59  
    60  		// Continue iterating since we haven't found a match
    61  		return true
    62  	})
    63  
    64  	return matches
    65  }
    66  
    67  func queryMatchesSlice(s pcommon.Slice, searchQuery string) bool {
    68  	for i := 0; i < s.Len(); i++ {
    69  		elem := s.At(i)
    70  
    71  		if queryMatchesValue(elem, searchQuery) {
    72  			return true
    73  		}
    74  	}
    75  
    76  	return false
    77  }