Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(cli): Migrate argo logs to use API client. See #2116 #2177

Merged
merged 33 commits into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cc26a3b
chore: Migrate `argo logs` to use API client. See #2116
alexec Feb 5, 2020
664e33a
changes
alexec Feb 5, 2020
b52d20a
fix: Correctly create code from changed protos.
alexec Feb 5, 2020
12eb78e
Merge branch 'codegen' into cli-logs
alexec Feb 5, 2020
587e36d
lint
alexec Feb 5, 2020
b4d49dc
Merge branch 'master' into cli-logs
alexec Feb 6, 2020
75504ed
codegen
alexec Feb 6, 2020
a4b92a0
make codegen
alexec Feb 6, 2020
e379903
logs
alexec Feb 6, 2020
2ab5dde
changes
alexec Feb 6, 2020
0d40d96
oddloading
alexec Feb 6, 2020
cab847e
correct diagnostic output
alexec Feb 6, 2020
271eb45
hopefully the final changes
alexec Feb 6, 2020
7ed136f
changes
alexec Feb 6, 2020
7168d34
Merge branch 'master' into cli-logs
alexec Feb 7, 2020
52e85da
Merge branch 'master' into cli-logs
alexec Feb 10, 2020
88fd4ad
feat(cli-logs): fix merge + make lint
alexec Feb 10, 2020
9420827
lint
alexec Feb 10, 2020
b589a73
Merge branch 'master' into cli-logs
alexec Feb 11, 2020
1f416ff
tidy up
alexec Feb 11, 2020
8078538
Merge branch 'master' into cli-logs
alexec Feb 20, 2020
67e4f53
codegen
alexec Feb 20, 2020
1c23aa4
test(cli): fix test
alexec Feb 20, 2020
50d67aa
Merge branch 'master' into cli-logs
alexec Feb 20, 2020
ecaf440
logs
alexec Feb 21, 2020
5fed826
reinstate vendor
alexec Feb 21, 2020
1ed093a
Merge branch 'master' into cli-logs
alexec Feb 22, 2020
78eeb15
changes
alexec Feb 22, 2020
802c290
Merge branch 'master' into cli-logs
alexec Feb 24, 2020
d868351
interm-2
alexec Feb 24, 2020
67c4ff9
copylocks lint
alexec Feb 24, 2020
0594ddd
Merge branch 'master' into cli-logs
alexec Feb 25, 2020
0ec7417
Merge branch 'master' into cli-logs
alexec Feb 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
make codegen
  • Loading branch information
alexec committed Feb 6, 2020
commit a4b92a001f2275228201f96f3c689af2482377c7
134 changes: 56 additions & 78 deletions cmd/argo/commands/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"math"
"os"
"strings"
"sync"
"time"

"github.com/argoproj/pkg/errors"
Expand All @@ -16,12 +15,10 @@ import (

"github.com/argoproj/argo/cmd/argo/commands/client"
workflowpkg "github.com/argoproj/argo/pkg/apiclient/workflow"
"github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
)

func NewLogsCommand() *cobra.Command {
var (
workflow bool
since time.Duration
sinceTime string
tailLines int64
Expand All @@ -30,21 +27,35 @@ func NewLogsCommand() *cobra.Command {
var command = &cobra.Command{
Use: "logs POD|WORKFLOW",
Short: "view logs of a pod or workflow",
Example: `# Follow the logs of single container in a pod
Example: `# Follow the logs of a workflow:

argo logs my-pod -c my-container
argo logs my-wf

# Follow the logs of single container in a pod

argo logs my-wf my-pod -c my-container

# Follow the logs of a workflow's pods:

argo logs -w my-wf
argo logs my-wf my-pod

# Follow the logs of a pods:

argo logs --since=1h my-pod

`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {

workflow := args[0]
podName := ""

switch len(args) {
case 1:
break
case 2:
podName = args[1]
break
alexec marked this conversation as resolved.
Show resolved Hide resolved
default:
cmd.HelpFunc()(cmd, args)
os.Exit(1)
}
Expand All @@ -62,88 +73,55 @@ func NewLogsCommand() *cobra.Command {
logOptions.SinceTime = &sinceTime
}

// get all the pods we need to list
var podNames []string

ctx, apiClient := client.NewAPIClient()
serviceClient := apiClient.NewWorkflowServiceClient()
namespace := client.Namespace()
if workflow {
// this can (original implementation too) only follow logs for the pods for the workflow
wf, err := serviceClient.GetWorkflow(ctx, &workflowpkg.WorkflowGetRequest{
Name: args[0],
Namespace: namespace,
})
errors.CheckError(err)
for nodeId, node := range wf.Status.Nodes {
if node.Type == v1alpha1.NodeTypePod && node.Phase != v1alpha1.NodeError {
podNames = append(podNames, nodeId)
}
}
} else {
podNames = args
}

// now follow
var wg sync.WaitGroup
wg.Add(len(podNames))
for _, podName := range podNames {
format := "%s: %s"
// only print pod names if we have more than one
if len(podNames) > 0 {
format = fmt.Sprintf("%s %s", podName, format)
}

// color output on pod name
colors := []int{FgRed, FgGreen, FgYellow, FgBlue, FgMagenta, FgCyan, FgWhite, FgDefault}
h := fnv.New32a()
_, err := h.Write([]byte(podName))
errors.CheckError(err)
colorIndex := int(math.Mod(float64(h.Sum32()), float64(len(colors))))

go func(podName string) {
defer wg.Done()
// this outer loop allows us to retry when we can't find pods
for {
var logStream workflowpkg.WorkflowService_PodLogsClient
// keep trying to get the pod logs
for {
logStream, err = serviceClient.PodLogs(ctx, &workflowpkg.WorkflowLogRequest{
Namespace: namespace,
PodName: podName,
LogOptions: &logOptions,
})
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
if strings.Contains(err.Error(), "ContainerCreating") {
time.Sleep(3 * time.Second)
continue // try again in 3s
}
return // give up
}
break // all good - lets start tailing
// color output on pod name
colors := []int{FgRed, FgGreen, FgYellow, FgBlue, FgMagenta, FgCyan, FgWhite, FgDefault}
h := fnv.New32a()
_, err := h.Write([]byte(podName))
errors.CheckError(err)
colorIndex := int(math.Mod(float64(h.Sum32()), float64(len(colors))))

// this outer loop allows us to retry when we can't find pods
for {
var logStream workflowpkg.WorkflowService_PodLogsClient
// keep trying to get the pod logs
for {
logStream, err = serviceClient.PodLogs(ctx, &workflowpkg.WorkflowLogRequest{
Name: workflow,
Namespace: namespace,
PodName: podName,
LogOptions: &logOptions,
})
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
if strings.Contains(err.Error(), "ContainerCreating") {
time.Sleep(3 * time.Second)
continue // try again in 3s
}
// loop on log lines
for {
event, err := logStream.Recv()
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
if strings.Contains(err.Error(), "waiting to start") {
time.Sleep(3 * time.Second)
break // break out of logging loop so we try to connect again in 3s
}
return // give up
}
fmt.Println(ansiFormat(fmt.Sprintf(format, podName, event.Content), colors[colorIndex]))
return // give up
}
break // all good - lets start tailing
}
// loop on log lines
for {
event, err := logStream.Recv()
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
if strings.Contains(err.Error(), "waiting to start") {
time.Sleep(3 * time.Second)
break // break out of logging loop so we try to connect again in 3s
}
return // give up
}
}(podName)
fmt.Println(ansiFormat(fmt.Sprintf("%s %s", event.PodName, event.Content), colors[colorIndex]))
}
}
wg.Wait()
},
}
command.Flags().StringVarP(&logOptions.Container, "container", "c", "main", "Print the logs of this container")
command.Flags().BoolVarP(&workflow, "workflow", "w", false, "Specify that whole workflow logs should be printed")
command.Flags().BoolVarP(&logOptions.Follow, "follow", "f", false, "Specify if the logs should be streamed.")
command.Flags().DurationVar(&since, "since", 0, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.")
command.Flags().StringVar(&sinceTime, "since-time", "", "Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.")
Expand Down
Loading