-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiscovery.go
More file actions
150 lines (121 loc) · 3.54 KB
/
Copy pathdiscovery.go
File metadata and controls
150 lines (121 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
//"github.com/nxadm/tail"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
log "github.com/sirupsen/logrus"
)
var (
// For: projectcontour_envoy-l5sqg_49fa45e4-e70c-4a4e-ac56-1e99cb6d36fb
// or default_chopper-f5b66c6bf-l5sqg_49fa45e4-e70c-4a4e-ac56-1e99cb6d36fb
// K8s seems to do all kinds of craziness here. Not clear to me why.
podNameRegexp = regexp.MustCompile("(-[a-f0-9]+)?(-[a-z0-9]{5})?_([a-f0-9-]+){5}$")
// default_kmtest_abe513f2-8a73-46f6-bd98-ec94e3de4012
)
// A Pod represents all the info we care about for a Kubernetes Pod
type Pod struct {
Name string
Namespace string
ServiceName string
Environment string
LogFormat string
Logs []string
}
// A Discoverer finds Pods
type Discoverer interface {
Discover() ([]*Pod, error)
LogFiles(pod string) ([]string, error)
}
// A DiscoveryFilter only passes through Pods that we should allow
type DiscoveryFilter interface {
ShouldTailLogs(pod *Pod) (bool, error)
}
// A DirListDiscoverer finds new pods to potentitally tail by watching the logs
// filesystem.
type DirListDiscoverer struct {
Dir string
Environment string
}
func NewDirListDiscoverer(path, environment string) *DirListDiscoverer {
return &DirListDiscoverer{
Dir: path,
Environment: environment,
}
}
func (d *DirListDiscoverer) Discover() ([]*Pod, error) {
discovered, err := dirList(d.Dir)
if err != nil {
return nil, fmt.Errorf("discovery failed: %w", err)
}
var pods []*Pod
for _, entry := range discovered {
namespace, serviceName, err := d.namesFor(entry)
if err != nil {
log.Errorf("Error parsing pod directory name: %s", err)
continue
}
// Don't discover ourselves if we're running as a Pod!
if serviceName == "logtailer" {
continue
}
pods = append(pods, &Pod{
Name: entry,
Namespace: namespace,
ServiceName: serviceName,
Environment: d.Environment,
})
}
return pods, nil
}
// LogFiles retrievs all the current logs for the pod requested
func (d *DirListDiscoverer) LogFiles(podName string) ([]string, error) {
baseDir := fmt.Sprintf("%s/%s", d.Dir, podName)
var logs []string
err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("Failed to find logs for %s: %w", podName, err)
}
if info == nil {
return fmt.Errorf("Failed to find logs for %s: %w", podName, err)
}
// All the *current* log files are named "0.log"
if !info.IsDir() && strings.HasSuffix(info.Name(), ".log") {
logs = append(logs, path)
}
return nil
})
if err != nil {
return nil, err
}
return logs, nil
}
// namesFor parses apart the pod filename and gets the pod name and namespace
func (d *DirListDiscoverer) namesFor(podName string) (string, string, error) {
if !podNameRegexp.MatchString(podName) {
return "", "", fmt.Errorf("failed to parse podName (doesn't match regexp): %s", podName)
}
podName = podNameRegexp.ReplaceAllString(podName, "")
// Underscores are not legal in K8s pod names
nameFields := strings.Split(podName, "_")
if len(nameFields) < 2 {
return "", "", fmt.Errorf("failed to parse podName (splitting namespace): %s", podName)
}
namespace := nameFields[0]
serviceName := nameFields[1]
return namespace, serviceName, nil
}
func dirList(dir string) ([]string, error) {
var foundFiles []string
files, err := ioutil.ReadDir(dir)
if err != nil {
return nil, fmt.Errorf("failed to read dir %s: %w", dir, err)
}
for _, file := range files {
foundFiles = append(foundFiles, file.Name())
}
return foundFiles, nil
}