github.com/jcarley/cli@v0.0.0-20180201210820-966d90434c30/commands/metrics/metrics.go (about)

     1  package metrics
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/csv"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  	"github.com/daticahealth/cli/commands/services"
    11  	"github.com/daticahealth/cli/models"
    12  )
    13  
    14  var blacklist = map[string]struct{}{
    15  	"logging":       struct{}{},
    16  	"service_proxy": struct{}{},
    17  	"monitoring":    struct{}{},
    18  }
    19  
    20  // Transformer specifies that all concrete implementations should be
    21  // able to transform an entire environments metrics data (group) or a single
    22  // service metrics data (single).
    23  type Transformer interface {
    24  	TransformGroupCPU(*[]models.Metrics)
    25  	TransformGroupMemory(*[]models.Metrics)
    26  	TransformGroupNetworkIn(*[]models.Metrics)
    27  	TransformGroupNetworkOut(*[]models.Metrics)
    28  	TransformSingleCPU(*models.Metrics)
    29  	TransformSingleMemory(*models.Metrics)
    30  	TransformSingleNetworkIn(*models.Metrics)
    31  	TransformSingleNetworkOut(*models.Metrics)
    32  }
    33  
    34  // CmdMetrics prints out metrics for a given service or if the service is not
    35  // specified, metrics for the entire environment are printed.
    36  func CmdMetrics(svcName string, metricType MetricType, jsonFlag, csvFlag, textFlag, streamFlag bool, mins int, im IMetrics, is services.IServices) error {
    37  	if streamFlag && (jsonFlag || csvFlag || mins != 1) {
    38  		return fmt.Errorf("--stream cannot be used with CSV or JSON formats and multiple records")
    39  	}
    40  	if mins > 1440 {
    41  		return fmt.Errorf("--mins cannot be greater than 1440")
    42  	}
    43  	var mt Transformer
    44  	if jsonFlag {
    45  		mt = &JSONTransformer{}
    46  	} else if csvFlag {
    47  		buffer := &bytes.Buffer{}
    48  		mt = &CSVTransformer{
    49  			HeadersWritten: false,
    50  			GroupMode:      false,
    51  			Buffer:         buffer,
    52  			Writer:         csv.NewWriter(buffer),
    53  		}
    54  	} else if textFlag {
    55  		mt = &TextTransformer{}
    56  	}
    57  	if svcName != "" {
    58  		service, err := is.RetrieveByLabel(svcName)
    59  		if err != nil {
    60  			return err
    61  		}
    62  		if service == nil {
    63  			return fmt.Errorf("Could not find a service with the label \"%s\"", svcName)
    64  		}
    65  		return CmdServiceMetrics(metricType, streamFlag, mins, service, mt, im)
    66  	}
    67  	return CmdEnvironmentMetrics(metricType, streamFlag, mins, mt, im)
    68  }
    69  
    70  func CmdEnvironmentMetrics(metricType MetricType, stream bool, mins int, t Transformer, im IMetrics) error {
    71  	for {
    72  		metrics, err := im.RetrieveEnvironmentMetrics(mins)
    73  		if err != nil {
    74  			logrus.Fatal(err.Error())
    75  		}
    76  		switch metricType {
    77  		case CPU:
    78  			t.TransformGroupCPU(metrics)
    79  		case Memory:
    80  			t.TransformGroupMemory(metrics)
    81  		case NetworkIn:
    82  			t.TransformGroupNetworkIn(metrics)
    83  		case NetworkOut:
    84  			t.TransformGroupNetworkOut(metrics)
    85  		}
    86  		if !stream {
    87  			break
    88  		}
    89  		time.Sleep(time.Minute)
    90  	}
    91  	return nil
    92  }
    93  
    94  func CmdServiceMetrics(metricType MetricType, stream bool, mins int, service *models.Service, t Transformer, im IMetrics) error {
    95  	for {
    96  		metrics, err := im.RetrieveServiceMetrics(mins, service.ID)
    97  		if err != nil {
    98  			logrus.Fatal(err.Error())
    99  		}
   100  		switch metricType {
   101  		case CPU:
   102  			t.TransformSingleCPU(metrics)
   103  		case Memory:
   104  			t.TransformSingleMemory(metrics)
   105  		case NetworkIn:
   106  			t.TransformSingleNetworkIn(metrics)
   107  		case NetworkOut:
   108  			t.TransformSingleNetworkOut(metrics)
   109  		}
   110  		if !stream {
   111  			break
   112  		}
   113  		time.Sleep(time.Minute)
   114  	}
   115  	return nil
   116  }
   117  
   118  func metricsTypeToString(metricType MetricType) string {
   119  	switch metricType {
   120  	case CPU:
   121  		return "CPU"
   122  	case Memory:
   123  		return "Memory"
   124  	case NetworkIn:
   125  		return "Network In"
   126  	case NetworkOut:
   127  		return "Network Out"
   128  	default:
   129  		return ""
   130  	}
   131  }
   132  
   133  // RetrieveEnvironmentMetrics retrieves metrics data for all services in
   134  // the associated environment.
   135  func (m *SMetrics) RetrieveEnvironmentMetrics(mins int) (*[]models.Metrics, error) {
   136  	headers := m.Settings.HTTPManager.GetHeaders(m.Settings.SessionToken, m.Settings.Version, m.Settings.Pod, m.Settings.UsersID)
   137  	resp, statusCode, err := m.Settings.HTTPManager.Get(nil, fmt.Sprintf("%s%s/environments/%s/metrics?time=%dm", m.Settings.PaasHost, m.Settings.PaasHostVersion, m.Settings.EnvironmentID, mins), headers)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  	var metrics []models.Metrics
   142  	err = m.Settings.HTTPManager.ConvertResp(resp, statusCode, &metrics)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  	return &metrics, nil
   147  }
   148  
   149  // RetrieveServiceMetrics retrieves metrics data for the given service.
   150  func (m *SMetrics) RetrieveServiceMetrics(mins int, svcID string) (*models.Metrics, error) {
   151  	headers := m.Settings.HTTPManager.GetHeaders(m.Settings.SessionToken, m.Settings.Version, m.Settings.Pod, m.Settings.UsersID)
   152  	resp, statusCode, err := m.Settings.HTTPManager.Get(nil, fmt.Sprintf("%s%s/environments/%s/services/%s/metrics?time=%dm", m.Settings.PaasHost, m.Settings.PaasHostVersion, m.Settings.EnvironmentID, svcID, mins), headers)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	var metrics models.Metrics
   157  	err = m.Settings.HTTPManager.ConvertResp(resp, statusCode, &metrics)
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  	return &metrics, nil
   162  }