Skip to content

Commit

Permalink
Follow logs (#1)
Browse files Browse the repository at this point in the history
* Follow logs

* Added following of job

* Added proper follow job
  • Loading branch information
ingeknudsen authored Jan 3, 2020
1 parent 8a3b4ec commit e0e499a
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 87 deletions.
74 changes: 60 additions & 14 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"APP_SERVICE_ACCOUNT_TOKEN": "token"
},
"args": [
"--from-config",
"--cluster",
"weekly-47",
"--api-environment",
"qa",
"--token-environment",
"--context",
"playground",
"build-deploy",
"--application",
"echo",
"-b",
"master"
"master",
"-f"
]
},
{
Expand All @@ -40,22 +44,64 @@
"APP_SERVICE_ACCOUNT_TOKEN": "token"
},
"args": [
"--from-config",
"--token-environment",
"--cluster",
"weekly-47",
"--api-environment",
"dev",
"--from-config",
"set",
"environment-secret",
"--context",
"playground",
"-b",
"master",
"--component",
"auth-proxy",
"api",
"-s",
"OAUTH2_PROXY_CLIENT_SECRET",
"APPINSIGHTS_INSTRUMENTATIONKEY",
"-v",
"my-pass"
"iknu-test"
]
},
{
"name": "Lauch radix-cli follow component",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"APP_SERVICE_ACCOUNT_TOKEN": "token"
},
"args": [
"--token-environment",
"follow",
"component",
"--application",
"radix-api",
"--context",
"playground",
"-e",
"prod",
"--component",
"server"
]
},
{
"name": "Lauch radix-cli follow job",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"APP_SERVICE_ACCOUNT_TOKEN": "token"
},
"args": [
"--token-environment",
"--context",
"playground",
"follow",
"job",
"--application",
"echo",
"-j",
"radix-pipeline-20191227190153-aysdr"
]
}
]
Expand Down
75 changes: 2 additions & 73 deletions cmd/buildDeployApplication.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,13 @@ package cmd

import (
"errors"
"fmt"
"strings"
"time"

"github.com/equinor/radix-cli/generated-client/client/application"
"github.com/equinor/radix-cli/generated-client/client/job"
"github.com/equinor/radix-cli/generated-client/models"
"github.com/equinor/radix-cli/pkg/client"
"github.com/fatih/color"
"github.com/spf13/cobra"
)

const deltaRefreshApplication = 3 * time.Second
const deltaRefreshOutput = 50 * time.Millisecond

var (
yellow = color.New(color.FgHiYellow, color.BgBlack, color.Bold).SprintFunc()
green = color.New(color.FgHiGreen, color.BgBlack, color.Bold).SprintFunc()
blue = color.New(color.FgHiBlue, color.BgBlack, color.Underline).SprintFunc()
cyan = color.New(color.FgCyan, color.BgBlack).SprintFunc()
red = color.New(color.FgHiRed, color.BgBlack).Add(color.Italic).SprintFunc()
)

// buildDeployApplicationCmd represents the buildApplication command
var buildDeployApplicationCmd = &cobra.Command{
Use: "build-deploy",
Expand Down Expand Up @@ -75,64 +59,9 @@ var buildDeployApplicationCmd = &cobra.Command{
return err
}

jobName := newJob.GetPayload().Name
if follow {
jobName := newJob.GetPayload().Name

jobParameters := job.NewGetApplicationJobParams()
jobParameters.SetAppName(*appName)
jobParameters.SetJobName(jobName)

fmt.Fprintf(cmd.OutOrStdout(), "\r%s", fmt.Sprintf("Building %s on branch %s with name %s", cyan(appName), yellow(branch), yellow(jobName)))

buildComplete := false

numLogLinesOutput := 0
refreshApplication := time.Tick(deltaRefreshApplication)

for {
select {
case <-refreshApplication:
jobLogParameters := job.NewGetApplicationJobLogsParams()
jobLogParameters.SetAppName(*appName)
jobLogParameters.SetJobName(jobName)

respJobLog, _ := apiClient.Job.GetApplicationJobLogs(jobLogParameters, nil)
if respJobLog != nil {
numLogLines := 0

stepsLog := respJobLog.Payload
for _, stepLog := range stepsLog {
stepLogLines := strings.Split(strings.Replace(stepLog.Log, "\r\n", "\n", -1), "\n")

for _, stepLogLine := range stepLogLines {
if numLogLinesOutput <= numLogLines {
fmt.Fprintf(cmd.OutOrStdout(), "\r\n%s", stepLogLine)
numLogLinesOutput++
}

numLogLines++
}
}
}

respJob, _ := apiClient.Job.GetApplicationJob(jobParameters, nil)
if respJob != nil {
jobSummary := respJob.Payload
if jobSummary.Status == "Succeeded" {
fmt.Fprintf(cmd.OutOrStdout(), fmt.Sprintf("%s", green("\nBuild complete\n")))
buildComplete = true
} else if jobSummary.Status == "Failed" {
fmt.Fprintf(cmd.OutOrStdout(), fmt.Sprintf("%s", red("\nBuild failed\n")))
buildComplete = true
}

if buildComplete {
return nil
}
}
}

}
followJob(cmd, apiClient, *appName, jobName)
}

return nil
Expand Down
44 changes: 44 additions & 0 deletions cmd/follow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright © 2019 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"errors"
"time"

"github.com/spf13/cobra"
)

const (
deltaRefreshApplication = 3 * time.Second
deltaTimeout = 30 * time.Second
deltaRefreshOutput = 50 * time.Millisecond
)

// followCmd represents the list command
var followCmd = &cobra.Command{
Use: "follow",
Short: "Follow Radix resources",
Long: `A longer description .`,
RunE: func(cmd *cobra.Command, args []string) error {
return errors.New("Please specify the resource you want to follow")
},
}

func init() {
rootCmd.AddCommand(followCmd)
followCmd.AddCommand(followEnvironmentComponentCmd)
followCmd.AddCommand(followJobCmd)
}
137 changes: 137 additions & 0 deletions cmd/followEnvironmentComponent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright © 2019 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"errors"
"strings"
"time"

apiclient "github.com/equinor/radix-cli/generated-client/client"
"github.com/equinor/radix-cli/generated-client/client/component"
"github.com/equinor/radix-cli/generated-client/client/environment"
"github.com/equinor/radix-cli/pkg/client"
"github.com/equinor/radix-cli/pkg/utils/log"
"github.com/spf13/cobra"
)

// followEnvironmentComponentCmd represents the followEnvironmentComponentCmd command
var followEnvironmentComponentCmd = &cobra.Command{
Use: "component",
Short: "Will follow a component in an environment",
Long: `Will follow a component in an environment`,
RunE: func(cmd *cobra.Command, args []string) error {
appName, err := getAppNameFromConfigOrFromParameter(cmd, "application")
if err != nil {
return err
}

if appName == nil || *appName == "" {
return errors.New("Application name is required")
}

environmentName, _ := cmd.Flags().GetString("environment")
componentName, _ := cmd.Flags().GetString("component")

if environmentName == "" || componentName == "" {
return errors.New("Both `environment` and `component` are required")
}

apiClient, err := client.GetForCommand(cmd)
if err != nil {
return err
}

deploymentName, replicas, err := getReplicasForComponent(apiClient, *appName, environmentName, componentName)
if err != nil {
return err
}

refreshLog := time.Tick(deltaRefreshApplication)
loggedForReplica := make(map[string]int)

for {
select {
case <-refreshLog:

for i, replica := range replicas {
logParameters := component.NewLogParams()
logParameters.WithAppName(*appName)
logParameters.WithDeploymentName(*deploymentName)
logParameters.WithComponentName(componentName)
logParameters.WithPodName(replica)

logData, err := apiClient.Component.Log(logParameters, nil)
if err != nil {
// Replicas may have died
deploymentName, replicas, err = getReplicasForComponent(apiClient, *appName, environmentName, componentName)
if err != nil {
return err
}

} else {
totalLinesLogged := 0

if _, contained := loggedForReplica[replica]; contained {
totalLinesLogged = loggedForReplica[replica]
}

logLines := strings.Split(strings.Replace(logData.Payload, "\r\n", "\n", -1), "\n")
logged := log.From(cmd, replica, totalLinesLogged, logLines, log.GetColor(i))

totalLinesLogged += logged
loggedForReplica[replica] = totalLinesLogged
}
}
}

}
},
}

func getReplicasForComponent(apiClient *apiclient.Radixapi, appName, environmentName, componentName string) (*string, []string, error) {
// Get active deployment
environmentParams := environment.NewGetEnvironmentParams()
environmentParams.SetAppName(appName)
environmentParams.SetEnvName(environmentName)
environmentDetails, err := apiClient.Environment.GetEnvironment(environmentParams, nil)

if err != nil {
return nil, nil, err
}

var deploymentName string
if environmentDetails == nil || environmentDetails.Payload.ActiveDeployment == nil {
return nil, nil, errors.New("Active deployment was not found in environment")
}

var replicas []string
deploymentName = environmentDetails.Payload.ActiveDeployment.Name
for _, component := range environmentDetails.Payload.ActiveDeployment.Components {
if component.Name != nil &&
*component.Name == componentName {
replicas = component.Replicas
break
}
}

return &deploymentName, replicas, nil
}

func init() {
followEnvironmentComponentCmd.Flags().StringP("application", "a", "", "Name of the application owning the component")
followEnvironmentComponentCmd.Flags().StringP("environment", "e", "", "Environment the component runs in")
followEnvironmentComponentCmd.Flags().String("component", "", "The component to follow")
}
Loading

0 comments on commit e0e499a

Please sign in to comment.