github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/lokipush/pushtarget_test.go (about)

     1  package lokipush
     2  
     3  import (
     4  	"bytes"
     5  	"flag"
     6  	"fmt"
     7  	"net"
     8  	"net/http"
     9  	"os"
    10  	"strconv"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/go-kit/log"
    15  	"github.com/grafana/dskit/flagext"
    16  	"github.com/prometheus/client_golang/prometheus"
    17  	"github.com/prometheus/common/model"
    18  	"github.com/prometheus/prometheus/model/relabel"
    19  	"github.com/stretchr/testify/require"
    20  	"github.com/weaveworks/common/server"
    21  
    22  	"github.com/grafana/loki/clients/pkg/promtail/api"
    23  	"github.com/grafana/loki/clients/pkg/promtail/client"
    24  	"github.com/grafana/loki/clients/pkg/promtail/client/fake"
    25  	"github.com/grafana/loki/clients/pkg/promtail/scrapeconfig"
    26  
    27  	"github.com/grafana/loki/pkg/logproto"
    28  )
    29  
    30  const localhost = "127.0.0.1"
    31  
    32  func TestLokiPushTarget(t *testing.T) {
    33  	w := log.NewSyncWriter(os.Stderr)
    34  	logger := log.NewLogfmtLogger(w)
    35  
    36  	//Create PushTarget
    37  	eh := fake.New(func() {})
    38  	defer eh.Stop()
    39  
    40  	// Get a randomly available port by open and closing a TCP socket
    41  	addr, err := net.ResolveTCPAddr("tcp", localhost+":0")
    42  	require.NoError(t, err)
    43  	l, err := net.ListenTCP("tcp", addr)
    44  	require.NoError(t, err)
    45  	port := l.Addr().(*net.TCPAddr).Port
    46  	err = l.Close()
    47  	require.NoError(t, err)
    48  
    49  	// Adjust some of the defaults
    50  	defaults := server.Config{}
    51  	defaults.RegisterFlags(flag.NewFlagSet("empty", flag.ContinueOnError))
    52  	defaults.HTTPListenAddress = localhost
    53  	defaults.HTTPListenPort = port
    54  	defaults.GRPCListenAddress = localhost
    55  	defaults.GRPCListenPort = 0 // Not testing GRPC, a random port will be assigned
    56  
    57  	config := &scrapeconfig.PushTargetConfig{
    58  		Server: defaults,
    59  		Labels: model.LabelSet{
    60  			"pushserver": "pushserver1",
    61  			"dropme":     "label",
    62  		},
    63  		KeepTimestamp: true,
    64  	}
    65  
    66  	rlbl := []*relabel.Config{
    67  		{
    68  			Action: relabel.LabelDrop,
    69  			Regex:  relabel.MustNewRegexp("dropme"),
    70  		},
    71  	}
    72  
    73  	pt, err := NewPushTarget(logger, eh, rlbl, "job1", config)
    74  	require.NoError(t, err)
    75  
    76  	// Build a client to send logs
    77  	serverURL := flagext.URLValue{}
    78  	err = serverURL.Set("http://" + localhost + ":" + strconv.Itoa(port) + "/loki/api/v1/push")
    79  	require.NoError(t, err)
    80  
    81  	ccfg := client.Config{
    82  		URL:       serverURL,
    83  		Timeout:   1 * time.Second,
    84  		BatchWait: 1 * time.Second,
    85  		BatchSize: 100 * 1024,
    86  	}
    87  	m := client.NewMetrics(prometheus.DefaultRegisterer, nil)
    88  	pc, err := client.New(m, ccfg, nil, logger)
    89  	require.NoError(t, err)
    90  	defer pc.Stop()
    91  
    92  	// Send some logs
    93  	labels := model.LabelSet{
    94  		"stream":             "stream1",
    95  		"__anotherdroplabel": "dropme",
    96  	}
    97  	for i := 0; i < 100; i++ {
    98  		pc.Chan() <- api.Entry{
    99  			Labels: labels,
   100  			Entry: logproto.Entry{
   101  				Timestamp: time.Unix(int64(i), 0),
   102  				Line:      "line" + strconv.Itoa(i),
   103  			},
   104  		}
   105  	}
   106  
   107  	// Wait for them to appear in the test handler
   108  	countdown := 10000
   109  	for len(eh.Received()) != 100 && countdown > 0 {
   110  		time.Sleep(1 * time.Millisecond)
   111  		countdown--
   112  	}
   113  
   114  	// Make sure we didn't timeout
   115  	require.Equal(t, 100, len(eh.Received()))
   116  
   117  	// Verify labels
   118  	expectedLabels := model.LabelSet{
   119  		"pushserver": "pushserver1",
   120  		"stream":     "stream1",
   121  	}
   122  	// Spot check the first value in the result to make sure relabel rules were applied properly
   123  	require.Equal(t, expectedLabels, eh.Received()[0].Labels)
   124  
   125  	// With keep timestamp enabled, verify timestamp
   126  	require.Equal(t, time.Unix(99, 0).Unix(), eh.Received()[99].Timestamp.Unix())
   127  
   128  	_ = pt.Stop()
   129  
   130  }
   131  
   132  func TestPlaintextPushTarget(t *testing.T) {
   133  	w := log.NewSyncWriter(os.Stderr)
   134  	logger := log.NewLogfmtLogger(w)
   135  
   136  	//Create PushTarget
   137  	eh := fake.New(func() {})
   138  	defer eh.Stop()
   139  
   140  	// Get a randomly available port by open and closing a TCP socket
   141  	addr, err := net.ResolveTCPAddr("tcp", localhost+":0")
   142  	require.NoError(t, err)
   143  	l, err := net.ListenTCP("tcp", addr)
   144  	require.NoError(t, err)
   145  	port := l.Addr().(*net.TCPAddr).Port
   146  	err = l.Close()
   147  	require.NoError(t, err)
   148  
   149  	// Adjust some of the defaults
   150  	defaults := server.Config{}
   151  	defaults.RegisterFlags(flag.NewFlagSet("empty", flag.ContinueOnError))
   152  	defaults.HTTPListenAddress = localhost
   153  	defaults.HTTPListenPort = port
   154  	defaults.GRPCListenAddress = localhost
   155  	defaults.GRPCListenPort = 0 // Not testing GRPC, a random port will be assigned
   156  
   157  	config := &scrapeconfig.PushTargetConfig{
   158  		Server: defaults,
   159  		Labels: model.LabelSet{
   160  			"pushserver": "pushserver2",
   161  			"keepme":     "label",
   162  		},
   163  		KeepTimestamp: true,
   164  	}
   165  
   166  	pt, err := NewPushTarget(logger, eh, []*relabel.Config{}, "job2", config)
   167  	require.NoError(t, err)
   168  
   169  	// Send some logs
   170  	ts := time.Now()
   171  	body := new(bytes.Buffer)
   172  	for i := 0; i < 100; i++ {
   173  		body.WriteString("line" + strconv.Itoa(i))
   174  		_, err := http.Post(fmt.Sprintf("http://%s:%d/promtail/api/v1/raw", localhost, port), "text/json", body)
   175  		require.NoError(t, err)
   176  		body.Reset()
   177  	}
   178  
   179  	// Wait for them to appear in the test handler
   180  	countdown := 10000
   181  	for len(eh.Received()) != 100 && countdown > 0 {
   182  		time.Sleep(1 * time.Millisecond)
   183  		countdown--
   184  	}
   185  
   186  	// Make sure we didn't timeout
   187  	require.Equal(t, 100, len(eh.Received()))
   188  
   189  	// Verify labels
   190  	expectedLabels := model.LabelSet{
   191  		"pushserver": "pushserver2",
   192  		"keepme":     "label",
   193  	}
   194  	// Spot check the first value in the result to make sure relabel rules were applied properly
   195  	require.Equal(t, expectedLabels, eh.Received()[0].Labels)
   196  
   197  	// Timestamp is always set in the handler, we expect received timestamps to be slightly higher than the timestamp when we started sending logs.
   198  	require.GreaterOrEqual(t, eh.Received()[99].Timestamp.Unix(), ts.Unix())
   199  
   200  	_ = pt.Stop()
   201  
   202  }