lumber/main.go

84 lines
1.7 KiB
Go

package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"path/filepath"
"sync"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
var (
home = homedir.HomeDir()
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
namespace = flag.String("namespace", "apps", "namespace for the pods")
stream = flag.Bool("stream", false, "if set, livestream logs")
)
func main() {
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
podsClient := clientset.CoreV1().Pods(*namespace)
pods, err := podsClient.List(metav1.ListOptions{})
if err != nil {
panic(err)
}
var wg sync.WaitGroup
wg.Add(len(pods.Items))
for _, pod := range pods.Items {
if len(pod.Spec.Containers) != 1 {
wg.Add(len(pod.Spec.Containers) - 1)
}
for _, ctr := range pod.Spec.Containers {
go dumpLogs(podsClient, &wg, pod.Name, ctr.Name)
}
}
wg.Wait()
}
func dumpLogs(podsClient corev1.PodExpansion, wg *sync.WaitGroup, podName, ctrName string) {
defer wg.Done()
w := lineSplittingWriter{
writer: prefixWriter(fmt.Sprintf("%25s | ", ctrName), os.Stdout),
}
req := podsClient.GetLogs(podName, &v1.PodLogOptions{
Container: ctrName,
Follow: *stream,
})
st, err := req.Stream()
if err != nil {
log.Printf("can't get logs for pod %s container %s: %v", podName, ctrName, err)
return
}
defer st.Close()
io.Copy(w, st)
}