Path: blob/main/component/common/loki/client/multi.go
4096 views
package client12// This code is copied from Promtail. The client package is used to configure3// and run the clients that can send log entries to a Loki instance.45import (6"errors"7"fmt"8"strings"9"sync"1011"github.com/go-kit/log"1213"github.com/grafana/agent/component/common/loki"14)1516// MultiClient is client pushing to one or more loki instances.17type MultiClient struct {18clients []Client19entries chan loki.Entry20wg sync.WaitGroup2122once sync.Once23}2425// NewMulti creates a new client26func NewMulti(metrics *Metrics, streamLagLabels []string, logger log.Logger, maxStreams int, cfgs ...Config) (Client, error) {27var fake struct{}2829if len(cfgs) == 0 {30return nil, errors.New("at least one client config should be provided")31}32clientsCheck := make(map[string]struct{})33clients := make([]Client, 0, len(cfgs))34for _, cfg := range cfgs {35client, err := New(metrics, cfg, streamLagLabels, maxStreams, logger)36if err != nil {37return nil, err38}3940// Don't allow duplicate clients, we have client specific metrics that need at least one unique label value (name).41if _, ok := clientsCheck[client.Name()]; ok {42return nil, fmt.Errorf("duplicate client configs are not allowed, found duplicate for URL: %s", cfg.URL)43}4445clientsCheck[client.Name()] = fake46clients = append(clients, client)47}48multi := &MultiClient{49clients: clients,50entries: make(chan loki.Entry),51}52multi.start()53return multi, nil54}5556func (m *MultiClient) start() {57m.wg.Add(1)58go func() {59defer m.wg.Done()60for e := range m.entries {61for _, c := range m.clients {62c.Chan() <- e63}64}65}()66}6768func (m *MultiClient) Chan() chan<- loki.Entry {69return m.entries70}7172// Stop implements Client73func (m *MultiClient) Stop() {74m.once.Do(func() { close(m.entries) })75m.wg.Wait()76for _, c := range m.clients {77c.Stop()78}79}8081// StopNow implements Client82func (m *MultiClient) StopNow() {83for _, c := range m.clients {84c.StopNow()85}86}8788func (m *MultiClient) Name() string {89var sb strings.Builder90sb.WriteString("multi:")91for i, c := range m.clients {92sb.WriteString(c.Name())93if i != len(m.clients)-1 {94sb.WriteString(",")95}96}97return sb.String()98}99100101