github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/platform/lambda/metrics.go (about)

     1  package lambda
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/aws/aws-sdk-go/aws"
     7  	"github.com/aws/aws-sdk-go/aws/session"
     8  	"github.com/aws/aws-sdk-go/service/cloudwatch"
     9  	"github.com/golang/sync/errgroup"
    10  
    11  	"github.com/apex/up/internal/metrics"
    12  	"github.com/apex/up/platform/event"
    13  )
    14  
    15  // TODO: write a higher level pkg in tj/aws
    16  // TODO: move the metrics pkg to tj/aws
    17  
    18  type stat struct {
    19  	Namespace string
    20  	Name      string
    21  	Metric    string
    22  	Stat      string
    23  	point     *cloudwatch.Datapoint
    24  }
    25  
    26  // Value returns the metric value.
    27  func (s *stat) Value() int {
    28  	if s.point == nil {
    29  		return 0
    30  	}
    31  
    32  	switch s.Stat {
    33  	case "Sum":
    34  		return int(*s.point.Sum)
    35  	case "Average":
    36  		return int(*s.point.Average)
    37  	case "Minimum":
    38  		return int(*s.point.Minimum)
    39  	case "Maximum":
    40  		return int(*s.point.Maximum)
    41  	default:
    42  		return 0
    43  	}
    44  }
    45  
    46  // stats to fetch.
    47  var stats = []*stat{
    48  	{"AWS/ApiGateway", "Requests", "Count", "Sum", nil},
    49  	{"AWS/ApiGateway", "Duration min", "Latency", "Minimum", nil},
    50  	{"AWS/ApiGateway", "Duration avg", "Latency", "Average", nil},
    51  	{"AWS/ApiGateway", "Duration max", "Latency", "Maximum", nil},
    52  	{"AWS/Lambda", "Duration sum", "Duration", "Sum", nil},
    53  	{"AWS/ApiGateway", "Errors 4xx", "4XXError", "Sum", nil},
    54  	{"AWS/ApiGateway", "Errors 5xx", "5XXError", "Sum", nil},
    55  	{"AWS/Lambda", "Invocations", "Invocations", "Sum", nil},
    56  	{"AWS/Lambda", "Errors", "Errors", "Sum", nil},
    57  	{"AWS/Lambda", "Throttles", "Throttles", "Sum", nil},
    58  }
    59  
    60  // ShowMetrics implementation.
    61  func (p *Platform) ShowMetrics(region, stage string, start time.Time) error {
    62  	s := session.New(aws.NewConfig().WithRegion(region))
    63  	c := cloudwatch.New(s)
    64  	var g errgroup.Group
    65  	name := p.config.Name
    66  
    67  	d := time.Now().UTC().Sub(start)
    68  
    69  	for _, s := range stats {
    70  		s := s
    71  		g.Go(func() error {
    72  			m := metrics.New().
    73  				Namespace(s.Namespace).
    74  				TimeRange(time.Now().Add(-d), time.Now()).
    75  				Period(int(d.Seconds() * 2)).
    76  				Stat(s.Stat).
    77  				Metric(s.Metric)
    78  
    79  			switch s.Namespace {
    80  			case "AWS/ApiGateway":
    81  				m = m.Dimension("ApiName", name).Dimension("Stage", stage)
    82  			case "AWS/Lambda":
    83  				m = m.Dimension("FunctionName", name).Dimension("Resource", name+":"+stage)
    84  			}
    85  
    86  			res, err := c.GetMetricStatistics(m.Params())
    87  			if err != nil {
    88  				return err
    89  			}
    90  
    91  			if len(res.Datapoints) > 0 {
    92  				s.point = res.Datapoints[0]
    93  			}
    94  
    95  			return nil
    96  		})
    97  	}
    98  
    99  	if err := g.Wait(); err != nil {
   100  		return err
   101  	}
   102  
   103  	for _, s := range stats {
   104  		p.events.Emit("metrics.value", event.Fields{
   105  			"name":   s.Name,
   106  			"value":  s.Value(),
   107  			"memory": p.config.Lambda.Memory,
   108  		})
   109  	}
   110  
   111  	return nil
   112  }