Skip to content

Commit f620125

Browse files
committed
Show previous logs for failed API pods
1 parent 5024769 commit f620125

File tree

2 files changed

+54
-39
lines changed

2 files changed

+54
-39
lines changed

pkg/lib/k8s/pod.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,17 @@ var podTypeMeta = metav1.TypeMeta{
3232
Kind: "Pod",
3333
}
3434

35+
type PodStatus string
36+
3537
const (
36-
PodStatusUnknown = "Unknown"
37-
PodStatusPending = "Pending"
38-
PodStatusRunning = "Running"
39-
PodStatusTerminating = "Terminating"
40-
PodStatusSucceeded = "Succeeded"
41-
PodStatusFailed = "Failed"
42-
PodStatusKilled = "Killed"
43-
PodStatusKilledOOM = "Out of Memory"
38+
PodStatusUnknown PodStatus = "Unknown"
39+
PodStatusPending PodStatus = "Pending"
40+
PodStatusRunning PodStatus = "Running"
41+
PodStatusTerminating PodStatus = "Terminating"
42+
PodStatusSucceeded PodStatus = "Succeeded"
43+
PodStatusFailed PodStatus = "Failed"
44+
PodStatusKilled PodStatus = "Killed"
45+
PodStatusKilledOOM PodStatus = "Out of Memory"
4446
)
4547

4648
var killStatuses = map[int32]bool{
@@ -95,7 +97,7 @@ func GetPodLastContainerStartTime(pod *corev1.Pod) *time.Time {
9597
return startTime
9698
}
9799

98-
func GetPodStatus(pod *corev1.Pod) string {
100+
func GetPodStatus(pod *corev1.Pod) PodStatus {
99101
if pod == nil {
100102
return PodStatusUnknown
101103
}
@@ -190,7 +192,7 @@ func (c *Client) WaitForPodRunning(name string, numSeconds int) error {
190192
if err != nil {
191193
return err
192194
}
193-
if pod != nil && pod.Status.Phase == "Running" {
195+
if pod != nil && pod.Status.Phase == corev1.PodRunning {
194196
return nil
195197
}
196198
time.Sleep(time.Duration(numSeconds) * time.Second)

pkg/operator/workloads/logs.go

+42-29
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func ReadLogs(appName string, workloadID string, verbose bool, socket *websocket
4545
wrotePending := false
4646

4747
for true {
48-
allPods, err := config.Kubernetes.ListPodsByLabels(map[string]string{
48+
pods, err := config.Kubernetes.ListPodsByLabels(map[string]string{
4949
"appName": appName,
5050
"workloadID": workloadID,
5151
"userFacing": "true",
@@ -55,34 +55,42 @@ func ReadLogs(appName string, workloadID string, verbose bool, socket *websocket
5555
return
5656
}
5757

58-
// Prefer running API pods if any exist
59-
var pods []corev1.Pod
60-
for _, pod := range allPods {
61-
if pod.Labels["workloadType"] == WorkloadTypeAPI && k8s.GetPodStatus(&pod) != k8s.PodStatusRunning {
62-
continue
58+
if len(pods) > 0 {
59+
if len(pods) > 1 {
60+
if !writeSocket(fmt.Sprintf("%d pods available, streaming logs for one of them:", len(pods)), socket) {
61+
return
62+
}
6363
}
64-
pods = append(pods, pod)
65-
}
66-
if len(pods) == 0 {
67-
pods = allPods
68-
}
69-
70-
if len(pods) == 1 {
71-
getKubectlLogs(&pods[0], verbose, wrotePending, socket)
72-
return
73-
}
7464

75-
if len(pods) > 1 {
76-
if !writeSocket(fmt.Sprintf("%d pods available, streaming logs for one of them:", len(pods)), socket) {
77-
return
78-
}
65+
podMap := make(map[k8s.PodStatus][]corev1.Pod)
7966
for _, pod := range pods {
80-
if pod.Status.Phase != "Pending" {
81-
getKubectlLogs(&pod, verbose, wrotePending, socket)
82-
return
67+
podMap[k8s.GetPodStatus(&pod)] = append(podMap[k8s.GetPodStatus(&pod)], pod)
68+
}
69+
70+
switch {
71+
case len(podMap[k8s.PodStatusSucceeded]) > 0:
72+
getKubectlLogs(&podMap[k8s.PodStatusSucceeded][0], verbose, wrotePending, false, socket)
73+
case len(podMap[k8s.PodStatusRunning]) > 0:
74+
getKubectlLogs(&podMap[k8s.PodStatusRunning][0], verbose, wrotePending, false, socket)
75+
case len(podMap[k8s.PodStatusPending]) > 0:
76+
getKubectlLogs(&podMap[k8s.PodStatusPending][0], verbose, wrotePending, false, socket)
77+
case len(podMap[k8s.PodStatusKilled]) > 0:
78+
getKubectlLogs(&podMap[k8s.PodStatusKilled][0], verbose, wrotePending, false, socket)
79+
case len(podMap[k8s.PodStatusKilledOOM]) > 0:
80+
getKubectlLogs(&podMap[k8s.PodStatusKilledOOM][0], verbose, wrotePending, false, socket)
81+
case len(podMap[k8s.PodStatusFailed]) > 0:
82+
previous := false
83+
if pods[0].Labels["workloadType"] == WorkloadTypeAPI {
84+
previous = true
8385
}
86+
getKubectlLogs(&podMap[k8s.PodStatusFailed][0], verbose, wrotePending, previous, socket)
87+
case len(podMap[k8s.PodStatusTerminating]) > 0:
88+
getKubectlLogs(&podMap[k8s.PodStatusTerminating][0], verbose, wrotePending, false, socket)
89+
case len(podMap[k8s.PodStatusUnknown]) > 0:
90+
getKubectlLogs(&podMap[k8s.PodStatusUnknown][0], verbose, wrotePending, false, socket)
91+
default: // unexpected
92+
getKubectlLogs(&pods[0], verbose, wrotePending, false, socket)
8493
}
85-
getKubectlLogs(&pods[0], verbose, wrotePending, socket)
8694
return
8795
}
8896

@@ -110,7 +118,7 @@ func ReadLogs(appName string, workloadID string, verbose bool, socket *websocket
110118
if !writeSocket("\nFailed to start:\n", socket) {
111119
return
112120
}
113-
getKubectlLogs(failedArgoPod, true, false, socket)
121+
getKubectlLogs(failedArgoPod, true, false, false, socket)
114122
return
115123
}
116124

@@ -125,10 +133,10 @@ func ReadLogs(appName string, workloadID string, verbose bool, socket *websocket
125133
}
126134
}
127135

128-
func getKubectlLogs(pod *corev1.Pod, verbose bool, wrotePending bool, socket *websocket.Conn) {
136+
func getKubectlLogs(pod *corev1.Pod, verbose bool, wrotePending bool, previous bool, socket *websocket.Conn) {
129137
cmdPath := "/usr/local/bin/kubectl"
130138

131-
if pod.Status.Phase == "Pending" {
139+
if k8s.GetPodStatus(pod) == k8s.PodStatusPending {
132140
if !wrotePending {
133141
if !writeSocket("\nPending", socket) {
134142
return
@@ -137,9 +145,14 @@ func getKubectlLogs(pod *corev1.Pod, verbose bool, wrotePending bool, socket *we
137145
config.Kubernetes.WaitForPodRunning(pod.Name, 1)
138146
}
139147

140-
args := []string{"kubectl", "-n=" + config.Cortex.Namespace, "logs", "--follow=true", pod.Name}
148+
args := []string{"kubectl", "-n=" + config.Cortex.Namespace, "logs", "--follow=true"}
149+
if previous {
150+
args = append(args, "--previous")
151+
}
152+
153+
args = append(args, pod.Name)
141154
if pod.Labels["workloadType"] == WorkloadTypeAPI && pod.Labels["userFacing"] == "true" {
142-
args = []string{"kubectl", "-n=" + config.Cortex.Namespace, "logs", "--follow=true", pod.Name, apiContainerName}
155+
args = append(args, apiContainerName)
143156
}
144157

145158
outr, outw, err := os.Pipe()

0 commit comments

Comments
 (0)