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 }