github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/logcli/query/tail.go (about)

     1  package query
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"os/signal"
     7  	"strings"
     8  	"syscall"
     9  	"time"
    10  
    11  	"github.com/fatih/color"
    12  	"github.com/gorilla/websocket"
    13  
    14  	"github.com/grafana/loki/pkg/logcli/client"
    15  	"github.com/grafana/loki/pkg/logcli/output"
    16  	"github.com/grafana/loki/pkg/loghttp"
    17  	"github.com/grafana/loki/pkg/util/unmarshal"
    18  )
    19  
    20  // TailQuery connects to the Loki websocket endpoint and tails logs
    21  func (q *Query) TailQuery(delayFor time.Duration, c client.Client, out output.LogOutput) {
    22  	conn, err := c.LiveTailQueryConn(q.QueryString, delayFor, q.Limit, q.Start, q.Quiet)
    23  	if err != nil {
    24  		log.Fatalf("Tailing logs failed: %+v", err)
    25  	}
    26  
    27  	go func() {
    28  		stopChan := make(chan os.Signal, 1)
    29  		signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
    30  		<-stopChan
    31  		if err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")); err != nil {
    32  			log.Println("Error closing websocket:", err)
    33  		}
    34  		os.Exit(0)
    35  	}()
    36  
    37  	tailResponse := new(loghttp.TailResponse)
    38  
    39  	if len(q.IgnoreLabelsKey) > 0 && !q.Quiet {
    40  		log.Println("Ignoring labels key:", color.RedString(strings.Join(q.IgnoreLabelsKey, ",")))
    41  	}
    42  
    43  	if len(q.ShowLabelsKey) > 0 && !q.Quiet {
    44  		log.Println("Print only labels key:", color.RedString(strings.Join(q.ShowLabelsKey, ",")))
    45  	}
    46  
    47  	for {
    48  		err := unmarshal.ReadTailResponseJSON(tailResponse, conn)
    49  		if err != nil {
    50  			log.Println("Error reading stream:", err)
    51  			return
    52  		}
    53  
    54  		labels := loghttp.LabelSet{}
    55  		for _, stream := range tailResponse.Streams {
    56  			if !q.NoLabels {
    57  				if len(q.IgnoreLabelsKey) > 0 || len(q.ShowLabelsKey) > 0 {
    58  
    59  					ls := stream.Labels
    60  
    61  					if len(q.ShowLabelsKey) > 0 {
    62  						ls = matchLabels(true, ls, q.ShowLabelsKey)
    63  					}
    64  
    65  					if len(q.IgnoreLabelsKey) > 0 {
    66  						ls = matchLabels(false, ls, q.ShowLabelsKey)
    67  					}
    68  
    69  					labels = ls
    70  
    71  				} else {
    72  					labels = stream.Labels
    73  				}
    74  			}
    75  
    76  			for _, entry := range stream.Entries {
    77  				out.FormatAndPrintln(entry.Timestamp, labels, 0, entry.Line)
    78  			}
    79  
    80  		}
    81  		if len(tailResponse.DroppedStreams) != 0 {
    82  			log.Println("Server dropped following entries due to slow client")
    83  			for _, d := range tailResponse.DroppedStreams {
    84  				log.Println(d.Timestamp, d.Labels)
    85  			}
    86  		}
    87  	}
    88  }