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

     1  package resources
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/apex/up/config"
    10  	"github.com/apex/up/internal/util"
    11  )
    12  
    13  // alertActionID returns the alert action id.
    14  func alertActionID(name string) string {
    15  	return util.Camelcase("alert_action_%s", name)
    16  }
    17  
    18  // alert resources.
    19  func alert(c *Config, a *config.Alert, m Map) {
    20  	period := a.Period.Seconds()
    21  	alertAction := ref(alertActionID(a.Action))
    22  	id := util.Camelcase("alert_%s_%s_%s_period_%d_threshold_%d", a.Namespace, a.Metric, a.Statistic, int(period), a.Threshold)
    23  
    24  	m[id] = Map{
    25  		"Type": "AWS::CloudWatch::Alarm",
    26  		"Properties": Map{
    27  			"ActionsEnabled":     !a.Disable,
    28  			"AlarmDescription":   a.Description,
    29  			"MetricName":         a.Metric,
    30  			"Namespace":          a.Namespace,
    31  			"Statistic":          a.Statistic,
    32  			"TreatMissingData":   a.Missing,
    33  			"Period":             period,
    34  			"EvaluationPeriods":  strconv.Itoa(a.EvaluationPeriods),
    35  			"Threshold":          strconv.Itoa(a.Threshold),
    36  			"ComparisonOperator": a.Operator,
    37  			"OKActions":          []Map{alertAction},
    38  			"AlarmActions":       []Map{alertAction},
    39  			"Dimensions": []Map{
    40  				{
    41  					"Name":  "ApiName",
    42  					"Value": c.Name,
    43  				},
    44  				{
    45  					"Name":  "Stage",
    46  					"Value": "production",
    47  				},
    48  			},
    49  		},
    50  	}
    51  }
    52  
    53  // action resources.
    54  func action(c *Config, a *config.AlertAction, m Map) {
    55  	id := alertActionID(a.Name)
    56  
    57  	m[id] = Map{
    58  		"Type": "AWS::SNS::Topic",
    59  		"Properties": Map{
    60  			"DisplayName": a.Name,
    61  		},
    62  	}
    63  
    64  	v := url.Values{}
    65  	v.Add("type", a.Type)
    66  	v.Add("emails", strings.Join(a.Emails, ","))
    67  	v.Add("numbers", strings.Join(a.Numbers, ","))
    68  	v.Add("url", a.URL)
    69  	v.Add("channel", a.Channel)
    70  
    71  	if a.Gifs {
    72  		v.Add("gifs", "1")
    73  	}
    74  
    75  	sub := util.Camelcase("alert_action_%s_subscription", a.Name)
    76  	url := fmt.Sprintf("https://up.apex.sh/alert?%s", v.Encode())
    77  
    78  	m[sub] = Map{
    79  		"Type": "AWS::SNS::Subscription",
    80  		"Properties": Map{
    81  			"Endpoint": url,
    82  			"Protocol": "https",
    83  			"TopicArn": ref(id),
    84  		},
    85  	}
    86  }
    87  
    88  // actionEmail resource.
    89  func actionEmail(c *Config, a *config.AlertAction, m Map, id string) {
    90  	emails := strings.Join(a.Emails, ",")
    91  	sub := util.Camelcase("alert_action_%s_subscription", a.Name)
    92  	url := fmt.Sprintf("https://up.apex.sh/alert?emails=%s", emails)
    93  
    94  	m[sub] = Map{
    95  		"Type": "AWS::SNS::Subscription",
    96  		"Properties": Map{
    97  			"Endpoint": url,
    98  			"Protocol": "https",
    99  			"TopicArn": ref(id),
   100  		},
   101  	}
   102  }
   103  
   104  // alerting resources.
   105  func alerting(c *Config, m Map) {
   106  	for _, a := range c.Alerting.Alerts {
   107  		alert(c, a, m)
   108  	}
   109  
   110  	for _, a := range c.Alerting.Actions {
   111  		action(c, a, m)
   112  	}
   113  }