github.com/in4it/ecs-deploy@v0.0.42-0.20240508120354-ed77ff16df25/provider/ecs/cloudwatch.go (about)

     1  package ecs
     2  
     3  import (
     4  	"github.com/aws/aws-sdk-go/aws"
     5  	"github.com/aws/aws-sdk-go/aws/awserr"
     6  	"github.com/aws/aws-sdk-go/aws/session"
     7  	"github.com/aws/aws-sdk-go/service/cloudwatch"
     8  	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
     9  	"github.com/in4it/ecs-deploy/service"
    10  	"github.com/juju/loggo"
    11  
    12  	"time"
    13  )
    14  
    15  type CloudWatchLog struct {
    16  	NextBackwardToken string               `json:"nextBackwardToken"`
    17  	NextForwardToken  string               `json:"nextForwardToken"`
    18  	LogEvents         []CloudWatchLogEvent `json:"logEvents"`
    19  }
    20  type CloudWatchLogEvent struct {
    21  	IngestionTime time.Time `json:"ingestionTime"`
    22  	Message       string    `json:"message"`
    23  	Timestamp     time.Time `json:"timestamp"`
    24  }
    25  
    26  // logging
    27  var cloudwatchLogger = loggo.GetLogger("cloudwatch")
    28  
    29  type CloudWatch struct{}
    30  
    31  func (cloudwatch *CloudWatch) CreateLogGroup(clusterName, logGroup string) error {
    32  	svc := cloudwatchlogs.New(session.New())
    33  	input := &cloudwatchlogs.CreateLogGroupInput{
    34  		LogGroupName: aws.String(logGroup),
    35  	}
    36  	tags := make(map[string]*string)
    37  	tags["Cluster"] = aws.String(clusterName)
    38  	input.SetTags(tags)
    39  
    40  	_, err := svc.CreateLogGroup(input)
    41  	if err != nil {
    42  		if aerr, ok := err.(awserr.Error); ok {
    43  			ecsLogger.Errorf("%v", aerr.Error())
    44  		} else {
    45  			ecsLogger.Errorf("%v", err.Error())
    46  		}
    47  		return err
    48  	}
    49  	return nil
    50  
    51  }
    52  
    53  func (cloudwatch *CloudWatch) DeleteLogGroup(logGroup string) error {
    54  	svc := cloudwatchlogs.New(session.New())
    55  	input := &cloudwatchlogs.DeleteLogGroupInput{
    56  		LogGroupName: aws.String(logGroup),
    57  	}
    58  
    59  	_, err := svc.DeleteLogGroup(input)
    60  	if err != nil {
    61  		if aerr, ok := err.(awserr.Error); ok {
    62  			ecsLogger.Errorf("%v", aerr.Error())
    63  		} else {
    64  			ecsLogger.Errorf("%v", err.Error())
    65  		}
    66  		return err
    67  	}
    68  	return nil
    69  }
    70  
    71  func (cloudwatch *CloudWatch) GetLogEventsByTime(logGroup, logStream string, startTime, endTime time.Time, nextToken string) (CloudWatchLog, error) {
    72  	var logEvents CloudWatchLog
    73  	svc := cloudwatchlogs.New(session.New())
    74  	input := &cloudwatchlogs.GetLogEventsInput{
    75  		LogGroupName:  aws.String(logGroup),
    76  		LogStreamName: aws.String(logStream),
    77  		StartTime:     aws.Int64(startTime.UnixNano() / 1000000),
    78  		EndTime:       aws.Int64(endTime.UnixNano() / 1000000),
    79  	}
    80  	if nextToken != "" {
    81  		input.SetNextToken(nextToken)
    82  	}
    83  
    84  	result, err := svc.GetLogEvents(input)
    85  	if err != nil {
    86  		if aerr, ok := err.(awserr.Error); ok {
    87  			ecsLogger.Errorf("%v", aerr.Error())
    88  		} else {
    89  			ecsLogger.Errorf("%v", err.Error())
    90  		}
    91  		return logEvents, err
    92  	}
    93  	logEvents.NextBackwardToken = aws.StringValue(result.NextBackwardToken)
    94  	logEvents.NextForwardToken = aws.StringValue(result.NextForwardToken)
    95  	for _, v := range result.Events {
    96  		var l CloudWatchLogEvent
    97  		l.IngestionTime = time.Unix(0, aws.Int64Value(v.IngestionTime)*1000000)
    98  		l.Timestamp = time.Unix(0, aws.Int64Value(v.Timestamp)*1000000)
    99  		l.Message = aws.StringValue(v.Message)
   100  		logEvents.LogEvents = append(logEvents.LogEvents, l)
   101  	}
   102  	return logEvents, nil
   103  }
   104  
   105  func (c *CloudWatch) PutMetricAlarm(serviceName, clusterName, alarmName string, alarmActions []string, alarmDescription string, datapointsToAlarm int64, metricName string, namespace string, period int64, threshold float64, comparisonOperator string, statistic string, evaluationPeriods int64) error {
   106  	svc := cloudwatch.New(session.New())
   107  	input := &cloudwatch.PutMetricAlarmInput{
   108  		ActionsEnabled:     aws.Bool(true),
   109  		AlarmActions:       aws.StringSlice(alarmActions),
   110  		AlarmDescription:   aws.String(alarmDescription),
   111  		AlarmName:          aws.String(alarmName),
   112  		ComparisonOperator: aws.String(comparisonOperator),
   113  		DatapointsToAlarm:  aws.Int64(datapointsToAlarm),
   114  		Dimensions: []*cloudwatch.Dimension{
   115  			{Name: aws.String("ClusterName"), Value: aws.String(clusterName)},
   116  			{Name: aws.String("ServiceName"), Value: aws.String(serviceName)},
   117  		},
   118  		EvaluationPeriods: aws.Int64(evaluationPeriods),
   119  		MetricName:        aws.String(metricName),
   120  		Namespace:         aws.String(namespace),
   121  		Period:            aws.Int64(period),
   122  		Threshold:         aws.Float64(threshold),
   123  		Statistic:         aws.String(statistic),
   124  	}
   125  
   126  	_, err := svc.PutMetricAlarm(input)
   127  	if err != nil {
   128  		if aerr, ok := err.(awserr.Error); ok {
   129  			ecsLogger.Errorf("%v", aerr.Error())
   130  		} else {
   131  			ecsLogger.Errorf("%v", err.Error())
   132  		}
   133  		return err
   134  	}
   135  	return nil
   136  }
   137  
   138  func (c *CloudWatch) DescribeAlarms(alarmNames []string) ([]service.AutoscalingPolicy, error) {
   139  	var metricAlarms []*cloudwatch.MetricAlarm
   140  	var aps []service.AutoscalingPolicy
   141  	svc := cloudwatch.New(session.New())
   142  	input := &cloudwatch.DescribeAlarmsInput{
   143  		AlarmNames: aws.StringSlice(alarmNames),
   144  	}
   145  
   146  	pageNum := 0
   147  	err := svc.DescribeAlarmsPages(input,
   148  		func(page *cloudwatch.DescribeAlarmsOutput, lastPage bool) bool {
   149  			pageNum++
   150  			metricAlarms = append(metricAlarms, page.MetricAlarms...)
   151  			return pageNum <= 100
   152  		})
   153  
   154  	if err != nil {
   155  		if aerr, ok := err.(awserr.Error); ok {
   156  			ecsLogger.Errorf("%v", aerr.Error())
   157  		} else {
   158  			ecsLogger.Errorf("%v", err.Error())
   159  		}
   160  		return aps, err
   161  	}
   162  
   163  	for _, v := range metricAlarms {
   164  		ap := service.AutoscalingPolicy{}
   165  		ap.PolicyName = aws.StringValue(v.AlarmName)
   166  		ap.ComparisonOperator = aws.StringValue(v.ComparisonOperator)
   167  		ap.Metric = aws.StringValue(v.MetricName)
   168  		ap.Period = aws.Int64Value(v.Period)
   169  		ap.EvaluationPeriods = aws.Int64Value(v.EvaluationPeriods)
   170  		ap.Threshold = aws.Float64Value(v.Threshold)
   171  		ap.ThresholdStatistic = aws.StringValue(v.Statistic)
   172  		ap.DatapointsToAlarm = aws.Int64Value(v.DatapointsToAlarm)
   173  		aps = append(aps, ap)
   174  	}
   175  	return aps, nil
   176  }
   177  
   178  func (c *CloudWatch) DeleteAlarms(alarmNames []string) error {
   179  	svc := cloudwatch.New(session.New())
   180  
   181  	input := &cloudwatch.DeleteAlarmsInput{
   182  		AlarmNames: aws.StringSlice(alarmNames),
   183  	}
   184  
   185  	_, err := svc.DeleteAlarms(input)
   186  	if err != nil {
   187  		if aerr, ok := err.(awserr.Error); ok {
   188  			ecsLogger.Errorf("%v", aerr.Error())
   189  		} else {
   190  			ecsLogger.Errorf("%v", err.Error())
   191  		}
   192  		return err
   193  	}
   194  	return nil
   195  }