Skip to content

Commit

Permalink
redo everything
Browse files Browse the repository at this point in the history
  • Loading branch information
jbvmio committed Apr 10, 2019
1 parent c7ff4af commit a18c779
Show file tree
Hide file tree
Showing 3,302 changed files with 537 additions and 1,580,850 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,30 @@ All pods that contain the search terms as a substring will be returned.
**Examples:**
```
kubetail -i apache nginx // Tails logs from pods containing "apache" or "nginx", adding an id header.
kubetail -i pod1 pod2 --tail-lines 20 // Tails pod1 and pod2 beginning with the last 20 lines.
kubetail -i pod1 pod2 --tail 20 // Tails pod1 and pod2 beginning with the last 20 lines.
kubetail --in-cluster pod1 // Use --in-cluster flag if running within a Pod itself.
```

**Using white-list and black-list filters:**
**Using white-list (--grep) and black-list (--vgrep) filters:**
```
kubetail -i apache nginx -w "example.com,mysite.com" -b POST
kubetail -i apache nginx --vgrep 'GET,connection refused'
kubetail -i apache nginx --grep "example.com,mysite.com" --vgrep POST
```
This will tail logs from any pod with "apache" or "nginx" in it's name, filtering for anything containing
The latter will tail logs from any pod with "apache" or "nginx" in it's name, filtering for anything containing
either example.com or mysite.com but not containing the word POST.

**Flags:**
**Filter order is determined by the order entered on the command line:**
```
-b, --black-list strings exclude any lines matching the specified text. Use a comma seperated string for multiple args.
-h, --help help for kubetail
-i, --id display the pod name as a header along with the output.
-k, --k8s enables kubetail to be used inside a pod.
-t, --tail-lines int start tail with defined no. of lines. (default 10)
-w, --white-list strings only display lines matching the specified text. Use a comma seperated string for multiple args.
kubetail -i apache nginx --grep example.com --vgrep POST // Filters for lines containing example.com first, then filters out any lines containing POST
kubetail -i apache nginx --vgrep POST --grep example.com // Filters out any lines containing POST first, then filters for lines containing example.com
```

This was written for functionality and troubleshooting purposes, testing out the [channelrouter](https://github.com/jbvmio/channelrouter) package and mostly for fun.

**Flags:**
```
--in-cluster enables kubetail to be used inside a pod.
-i, --id display the pod name as a header along with the output.
--grep strings only display lines matching the specified text. Use a comma seperated string for multiple args.
--vgrep strings exclude any lines matching the specified text. Use a comma seperated string for multiple args.
--tail int start tail with defined no. of lines. (default 2)
-h, --help help for kubetail
```
177 changes: 21 additions & 156 deletions cmd/kubetail.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
package cmd

import (
"bytes"
"fmt"
"io"
"log"
"os"
"reflect"
"strings"
"time"

"github.com/fatih/color"
"github.com/jbvmio/channelrouter"
cv1 "k8s.io/api/core/v1"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
rest "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)

type tailFlags struct {
inCluster bool
displayHeader bool
tailLines int64
targetPods RegexList
blackRegex RegexList
whiteRegex RegexList
}

func checkFlags(f *pflag.Flag) {
switch f.Name {
case "grep":
regexOrder = append(regexOrder, &flags.whiteRegex)
case "vgrep":
regexOrder = append(regexOrder, &flags.blackRegex)
}
}

// K8sSelfLink struct contains a mapping of a K8s resource and its selflink url.
type k8sSelfLink struct {
Name string
Expand Down Expand Up @@ -114,160 +127,12 @@ type podLogStreamer struct {
ReadCloser io.ReadCloser
}

type pod struct {
key channelrouter.Key
cr *channelrouter.ChannelRouter
name string
}

// GetPodLogs streams pod logs to the given io.Writer.
func getPodLogs(wr io.Writer, rd io.ReadCloser) {
defer rd.Close()
wg.Wait()
//wg.Wait()
_, err := io.Copy(wr, rd)
if err != nil {
log.Fatalf("Error encountered reading tailing logs: %v\n", err)
}
}

//TailPodLogs Here.
//func TailPodLogs(cr *channelrouter.ChannelRouter, k channelrouter.Key) {
func tailPodLogs(pd pod, stringChan channelrouter.Key, sigChan chan os.Signal) {
//var stop bool
var errdStop bool
var more bool
var errd error
var b []byte
var line string
buf := bytes.NewBuffer(b)
buf.Reset()
defer func() {
if errdStop {
fmt.Println(pd.name, "Error:", errd)
}
fmt.Println(pd.name, "stopped.")
}()

wg.Wait()

for {
if mainStop {
break
}
select {
case sig := <-sigChan:
fmt.Printf("Caught signal %v: terminating\n", sig)
mainStop = true
break
default:
if buf.Len() > 256 {
//fmt.Println(pd.name, "Buf Length", buf.Len())
line, errd = buf.ReadString(10)
if errd != nil {
if errd.Error() == "EOF" {
//fmt.Println(pd.name, "EOF Here.")
more = true
} else {
mainStop = true
errdStop = true
}
}
if line == "" {
more = true
}

if !more {
if line != "" {
if id {
var s string
head := color.YellowString("[%v]", pd.name)
s = fmt.Sprintf("%v\n%v", head, line)
pd.cr.Send(stringChan, s)
} else {
pd.cr.Send(stringChan, line)
}
line = ""
if buf.Len() > 256 {
more = false
}
}

} else {
//fmt.Println(pd.name, "spooling up")
//fmt.Println(pd.name, "Buffer Length", buf.Len())
time.Sleep(time.Millisecond * 300)
if buf.Len() > 256 {
more = false
}
}

} else {
if pd.cr.Available(pd.key) > 256 {
var bits []byte
var i uint32 = 0
var available = pd.cr.Available(pd.key)
//fmt.Println(pd.name, available)
for i < available {
bits = append(bits, byte(pd.cr.Receive(pd.key).ToInt()))
i++
}
_, err := buf.Write(bits)
if err != nil {
fmt.Println("buffer error", err)
mainStop = true
break
}
more = false
}
}
}
}
}

func logDefaults() *cv1.PodLogOptions {
var tl int64 = 10
o := cv1.PodLogOptions{}
o.Follow = true
o.TailLines = &tl
return &o
}

func matchWhite(s string, list []string) bool {
for _, l := range list {
if strings.Contains(s, l) {
return true
}
}
return false
}

func matchWhiteBytes(s string, list []string) bool {
sb := []byte(s)
for _, l := range list {
lb := []byte(l)
if bytes.Contains(sb, lb) {
return true
}
}
return false
}

func matchBlack(s string, list []string) bool {
for _, l := range list {
if strings.Contains(s, l) {
return true
}
}
return false
}

func matchBlackBytes(s string, list []string) bool {
sb := []byte(s)
for _, l := range list {
lb := []byte(l)
if bytes.Contains(sb, lb) {
return true
}
}
return false
}
Loading

0 comments on commit a18c779

Please sign in to comment.