github.com/projectriff/riff-cli@v0.0.5-0.20180301104501-5db7a3bd9fc1/cmd/logs.go (about)

     1  /*
     2   * Copyright 2018 the original author or authors.
     3   *
     4   *   Licensed under the Apache License, Version 2.0 (the "License");
     5   *   you may not use this file except in compliance with the License.
     6   *   You may obtain a copy of the License at
     7   *  
     8   *        http://www.apache.org/licenses/LICENSE-2.0
     9   *  
    10   *   Unless required by applicable law or agreed to in writing, software
    11   *   distributed under the License is distributed on an "AS IS" BASIS,
    12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *   See the License for the specific language governing permissions and
    14   *   limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"fmt"
    21  	"os/exec"
    22  	"os"
    23  	"bufio"
    24  
    25  	"github.com/spf13/cobra"
    26  	"github.com/projectriff/riff-cli/pkg/ioutils"
    27  	"github.com/projectriff/riff-cli/pkg/kubectl"
    28  	"github.com/projectriff/riff-cli/cmd/utils"
    29  )
    30  
    31  type LogsOptions struct {
    32  	function  string
    33  	container string
    34  	namespace string
    35  	tail      bool
    36  }
    37  
    38  var logsOptions LogsOptions
    39  
    40  // logsCmd represents the logs command
    41  var logsCmd = &cobra.Command{
    42  	Use:   "logs",
    43  	Short: "Display the logs for a running function",
    44  	Long: `Display the logs for a running function For example:
    45  
    46      riff logs -n myfunc -t
    47  
    48  will tail the logs from the 'sidecar' container for the function 'myfunc'
    49  
    50  `,
    51  	Run: func(cmd *cobra.Command, args []string) {
    52  
    53  		// get the viper value from env var, config file or flag option
    54  		logsOptions.namespace = utils.GetStringValueWithOverride("namespace", *cmd.Flags())
    55  
    56  		fmt.Printf("Displaying logs for container %v of function %v in namespace %v\n\n", logsOptions.container, logsOptions.function, logsOptions.namespace)
    57  
    58  		cmdArgs := []string{"--namespace", logsOptions.namespace, "get", "pod", "-l", "function=" + logsOptions.function, "-o", "jsonpath={.items[0].metadata.name}"}
    59  
    60  		output, err := kubectl.ExecForString(cmdArgs)
    61  
    62  		if err != nil {
    63  			ioutils.Errorf("Error %v - Function %v may not be currently active\n\n", err, logsOptions.function)
    64  			return
    65  		}
    66  
    67  		pod := output
    68  
    69  		if logsOptions.tail {
    70  
    71  			cmdArgs = []string{"--namespace", logsOptions.namespace, "logs", "-c", logsOptions.container, "-f", pod}
    72  
    73  			kubectlCmd := exec.Command("kubectl", cmdArgs...)
    74  			cmdReader, err := kubectlCmd.StdoutPipe()
    75  			if err != nil {
    76  				fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for kubectlCmd", err)
    77  				return
    78  			}
    79  
    80  			scanner := bufio.NewScanner(cmdReader)
    81  			go func() {
    82  				for scanner.Scan() {
    83  					fmt.Printf("%s\n\n", scanner.Text())
    84  				}
    85  			}()
    86  
    87  			err = kubectlCmd.Start()
    88  			if err != nil {
    89  				fmt.Fprintln(os.Stderr, "Error starting kubectlCmd", err)
    90  				return
    91  			}
    92  
    93  			err = kubectlCmd.Wait()
    94  			if err != nil {
    95  				fmt.Fprintln(os.Stderr, "Error waiting for kubectlCmd", err)
    96  				return
    97  			}
    98  
    99  		} else {
   100  
   101  			cmdArgs = []string{"--namespace", logsOptions.namespace, "logs", "-c", logsOptions.container, pod}
   102  
   103  			output, err := kubectl.ExecForString(cmdArgs)
   104  
   105  			if err != nil {
   106  				ioutils.Errorf("Error: %v\n", err)
   107  				return
   108  			}
   109  
   110  			fmt.Printf("%v\n", output)
   111  		}
   112  
   113  	},
   114  }
   115  
   116  func init() {
   117  	rootCmd.AddCommand(logsCmd)
   118  
   119  	logsCmd.Flags().StringVarP(&logsOptions.function, "name", "n", "", "the name of the function")
   120  	logsCmd.Flags().StringVarP(&logsOptions.container, "container", "c", "sidecar", "the name of the function container (sidecar or main)")
   121  	logsCmd.Flags().BoolVarP(&logsOptions.tail, "tail", "t", false, "tail the logs")
   122  
   123  	logsCmd.Flags().StringP("namespace", "", "default", "the namespace used for the deployed resources")
   124  
   125  	logsCmd.MarkFlagRequired("name")
   126  }