func heartbeat() { helpers.SendMixpanelEvent("kernel-heartbeat") for _ = range time.Tick(1 * time.Hour) { helpers.SendMixpanelEvent("kernel-heartbeat") } }
func (a *App) Create() error { helpers.SendMixpanelEvent("kernel-app-create-start") formation, err := a.Formation() if err != nil { helpers.SendMixpanelEvent("kernel-app-create-error") return err } params := map[string]string{ "Cluster": os.Getenv("CLUSTER"), "Repository": a.Repository, "Subnets": os.Getenv("SUBNETS"), "Version": os.Getenv("RELEASE"), "VPC": os.Getenv("VPC"), } if os.Getenv("ENCRYPTION_KEY") != "" { params["Key"] = os.Getenv("ENCRYPTION_KEY") } tags := map[string]string{ "System": "convox", "Type": "app", } req := &cloudformation.CreateStackInput{ Capabilities: []*string{aws.String("CAPABILITY_IAM")}, StackName: aws.String(a.Name), TemplateBody: aws.String(formation), } for key, value := range params { req.Parameters = append(req.Parameters, &cloudformation.Parameter{ ParameterKey: aws.String(key), ParameterValue: aws.String(value), }) } for key, value := range tags { req.Tags = append(req.Tags, &cloudformation.Tag{ Key: aws.String(key), Value: aws.String(value), }) } _, err = CloudFormation().CreateStack(req) if err != nil { helpers.SendMixpanelEvent("kernel-app-create-error") return err } helpers.SendMixpanelEvent("kernel-app-create-success") return nil }
func (a *App) Delete() error { helpers.SendMixpanelEvent("kernel-app-delete-start") name := a.Name _, err := CloudFormation().DeleteStack(&cloudformation.DeleteStackInput{StackName: aws.String(name)}) if err != nil { helpers.SendMixpanelEvent("kernel-app-delete-error") return err } go a.Cleanup() helpers.SendMixpanelEvent("kernel-app-delete-success") return nil }
func startClusterMonitor() { var log = logger.New("ns=cluster_monitor") Tick: for _ = range time.Tick(5 * time.Minute) { log.Log("tick") // Ger Rack InstanceCount Parameter instanceCount := 0 instanceType := "unknown" res, err := models.CloudFormation().DescribeStacks( &cloudformation.DescribeStacksInput{ StackName: aws.String(os.Getenv("RACK")), }, ) if err != nil { log.Error(err) continue } for _, p := range res.Stacks[0].Parameters { if *p.ParameterKey == "InstanceCount" { c, err := strconv.Atoi(*p.ParameterValue) if err != nil { log.Error(err) break Tick } instanceCount = c } if *p.ParameterKey == "InstanceType" { instanceType = *p.ParameterValue } } helpers.SendMixpanelEvent("kernel-cluster-monitor", fmt.Sprintf("count=%d type=%s", instanceCount, instanceType)) // List and Describe ECS Container Instances ires, err := models.ECS().ListContainerInstances( &ecs.ListContainerInstancesInput{ Cluster: aws.String(os.Getenv("CLUSTER")), }, ) if err != nil { log.Error(err) continue } dres, err := models.ECS().DescribeContainerInstances( &ecs.DescribeContainerInstancesInput{ Cluster: aws.String(os.Getenv("CLUSTER")), ContainerInstances: ires.ContainerInstanceARNs, }, ) if err != nil { log.Error(err) continue } cInstanceIds := make([]string, 0) cInstanceConnections := make(map[string]bool) for _, i := range dres.ContainerInstances { cInstanceConnections[*i.EC2InstanceID] = *i.AgentConnected if *i.AgentConnected { cInstanceIds = append(cInstanceIds, *i.EC2InstanceID) } } // Get and Describe Rack ASG Resource resources, err := models.ListResources(os.Getenv("RACK")) ares, err := models.AutoScaling().DescribeAutoScalingGroups( &autoscaling.DescribeAutoScalingGroupsInput{ AutoScalingGroupNames: []*string{ aws.String(resources["Instances"].Id), }, }, ) if err != nil { log.Error(err) continue } // Test if ASG Instance is registered and connected in ECS cluster aInstanceIds := []string{} uInstanceIds := []string{} for _, i := range ares.AutoScalingGroups[0].Instances { if connected, exists := cInstanceConnections[*i.InstanceID]; connected && exists { aInstanceIds = append(aInstanceIds, *i.InstanceID) } else { // Not registered or not connected => set Unhealthy if *i.LifecycleState == "InService" { _, err := models.AutoScaling().SetInstanceHealth( &autoscaling.SetInstanceHealthInput{ HealthStatus: aws.String("Unhealthy"), InstanceID: aws.String(*i.InstanceID), ShouldRespectGracePeriod: aws.Boolean(true), }, ) if err != nil { log.Error(err) continue } uInstanceIds = append(uInstanceIds, *i.InstanceID) } } } sort.Strings(aInstanceIds) sort.Strings(cInstanceIds) sort.Strings(uInstanceIds) if len(uInstanceIds) > 0 { helpers.SendMixpanelEvent("kernel-cluster-monitor-mark", strings.Join(uInstanceIds, ",")) } log.Log("InstanceCount=%v connected='%v' healthy='%v' marked='%s'", instanceCount, strings.Join(cInstanceIds, ","), strings.Join(aInstanceIds, ","), strings.Join(uInstanceIds, ",")) } }