github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/kafka/topics.go (about) 1 package kafka 2 3 import ( 4 "errors" 5 "fmt" 6 "regexp" 7 "sort" 8 ) 9 10 type topicClient interface { 11 RefreshMetadata(topics ...string) error 12 Topics() ([]string, error) 13 } 14 15 type topicManager struct { 16 client topicClient 17 18 patterns []*regexp.Regexp 19 matches []string 20 } 21 22 // newTopicManager fetches topics and returns matchings one based on list of requested topics. 23 // If a topic starts with a '^' it is treated as a regexp and can match multiple topics. 24 func newTopicManager(client topicClient, topics []string) (*topicManager, error) { 25 var ( 26 patterns []*regexp.Regexp 27 matches []string 28 ) 29 for _, t := range topics { 30 if len(t) == 0 { 31 return nil, errors.New("invalid empty topic") 32 } 33 if t[0] != '^' { 34 matches = append(matches, t) 35 } 36 re, err := regexp.Compile(t) 37 if err != nil { 38 return nil, fmt.Errorf("invalid topic pattern: %w", err) 39 } 40 patterns = append(patterns, re) 41 } 42 return &topicManager{ 43 client: client, 44 patterns: patterns, 45 matches: matches, 46 }, nil 47 } 48 49 func (tm *topicManager) Topics() ([]string, error) { 50 if err := tm.client.RefreshMetadata(); err != nil { 51 return nil, err 52 } 53 topics, err := tm.client.Topics() 54 if err != nil { 55 return nil, err 56 } 57 58 result := make([]string, 0, len(topics)) 59 60 Outer: 61 for _, topic := range topics { 62 for _, m := range tm.matches { 63 if m == topic { 64 result = append(result, topic) 65 continue Outer 66 } 67 } 68 for _, p := range tm.patterns { 69 if p.MatchString(topic) { 70 result = append(result, topic) 71 continue Outer 72 } 73 } 74 } 75 76 sort.Strings(result) 77 return result, nil 78 }