From 1f7f833c3a95c0977b8e1f7dd03dc9a4bb73934a Mon Sep 17 00:00:00 2001 From: Kamran Biglari Date: Wed, 12 Jul 2023 17:19:33 +0100 Subject: [PATCH] Add custom metrics --- README.md | 6 +- example/cloudwatch.yaml | 30 ++++++++++ example/main.tf | 10 +++- main.tf | 129 ++++++++++++++++++++++++---------------- versions.tf | 2 +- 5 files changed, 120 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 9561dad..92477dc 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ No providers. | Name | Source | Version | |------|--------|---------| -| [metric-alarm](#module\_metric-alarm) | terraform-aws-modules/cloudwatch/aws//modules/metric-alarm | ~> 4.0 | +| [metric-alarm](#module\_metric-alarm) | terraform-aws-modules/cloudwatch/aws//modules/log-metric-filter | ~> 4.0 | ## Resources @@ -56,8 +56,8 @@ No resources. | [alarm\_name\_prefix](#input\_alarm\_name\_prefix) | Prefix of alarm name | `string` | n/a | yes | | [current\_environment](#input\_current\_environment) | Current environment | `string` | n/a | yes | | [input](#input\_input) | Path to yaml file | `string` | n/a | yes | -| [loop](#input\_loop) | n/a | `map` | `{}` | no | -| [template\_data](#input\_template\_data) | values to replace in template | `map` | `{}` | no | +| [loop](#input\_loop) | n/a | `map(any)` | `{}` | no | +| [template\_data](#input\_template\_data) | values to replace in template | `map(any)` | `{}` | no | ## Outputs diff --git a/example/cloudwatch.yaml b/example/cloudwatch.yaml index 2625c00..71839f8 100644 --- a/example/cloudwatch.yaml +++ b/example/cloudwatch.yaml @@ -66,3 +66,33 @@ Cloudwatch: Environment: - dev - prod + + - Name: websocket-subscriptions + Status: 1 + Description: Check websocket subscriptions. + Namespace: cryptofeed/websocketmonitoring + Metrics: SubscribeCount + CustomMetrics: + Patten: '{$.level = "INFO" && $.message = "Subscribed*"}' + LogGroupName: ${websocketmonitoring.log_group_name} + Dimensions: + - Name: + Value: + EvaluationPeriods: 2 + Period: 60 + Operator: LessThanOrEqualToThreshold + Statistic: Sum + Unit: + Threshold: 30 + TreatMissingData: breaching + AlertLevel: critical + AlarmActions: + OK: + default: + dev: critical + ALARM: + default: + dev: critical + Environment: + - dev + - prod diff --git a/example/main.tf b/example/main.tf index 71a4d63..0185571 100644 --- a/example/main.tf +++ b/example/main.tf @@ -4,7 +4,8 @@ module "cloudwatch-monitor" { alarm_name_prefix = "cloudwatch-monitor" current_environment = "dev" template_data = { - + rediscluster = {} + websocketmonitoring = module.websocketmonitoring # } alarm_actions = { default = { @@ -12,4 +13,11 @@ module "cloudwatch-monitor" { ok = "" } } +} + +module "websocketmonitoring" { + source = "terraform-aws-modules/cloudwatch/aws//modules/log-group" + version = "~> 3.0" + name = "/APP_NAME/websocket-monitoring" + retention_in_days = 14 } \ No newline at end of file diff --git a/main.tf b/main.tf index ab6acd2..660016c 100644 --- a/main.tf +++ b/main.tf @@ -1,93 +1,118 @@ variable "alarm_name_prefix" { - type = string - description = "Prefix of alarm name" + type = string + description = "Prefix of alarm name" } variable "input" { - type = string - description = "Path to yaml file" + type = string + description = "Path to yaml file" } variable "loop" { - type = map - default = {} + type = map(any) + default = {} } variable "current_environment" { - type = string - description = "Current environment" + type = string + description = "Current environment" } variable "template_data" { - type = map - description = "values to replace in template" - default = {} + type = map(any) + description = "values to replace in template" + default = {} } variable "alarm_actions" { - type = map(any) - description = "map of alarm actions" - default = {} + type = map(any) + description = "map of alarm actions" + default = {} } locals { - CloudWatch = yamldecode(templatefile(var.input, var.template_data)) + CloudWatch = yamldecode(templatefile(var.input, var.template_data)) } # CloudWatch Alarms module "metric-alarm" { source = "terraform-aws-modules/cloudwatch/aws//modules/metric-alarm" version = "~> 4.0" - for_each = {for i in flatten([ - for Key, Value in local.CloudWatch["Cloudwatch"]: [ - for loopK, loopV in try(var.loop[Value.Loop],["default"]): { - ServiceKey = loopV - Name = Value.Name - Key = Key - Config = Value + for_each = { for i in flatten([ + for Key, Value in local.CloudWatch["Cloudwatch"] : [ + for loopK, loopV in try(var.loop[Value.Loop], ["default"]) : { + ServiceKey = loopV + Name = Value.Name + Key = Key + Config = Value } ] - ]) : "${i.Name}-${i.ServiceKey}" => i - if contains(i.Config.Environment, var.current_environment) || !can(i.Config.Environment)} + ]) : "${i.Name}-${i.ServiceKey}" => i + if contains(i.Config.Environment, var.current_environment) || !can(i.Config.Environment) } alarm_name = "${var.alarm_name_prefix}-${each.key}" alarm_description = each.value.Config.Description comparison_operator = each.value.Config.Operator evaluation_periods = each.value.Config.EvaluationPeriods threshold = each.value.Config.Threshold - - treat_missing_data = each.value.Config.TreatMissingData + + treat_missing_data = each.value.Config.TreatMissingData namespace = can(each.value.Config.Query) ? null : each.value.Config.Namespace metric_name = can(each.value.Config.Query) ? null : each.value.Config.Metrics statistic = can(each.value.Config.Query) ? null : each.value.Config.Statistic - dimensions = can(each.value.Config.Query) ? null : try(tomap(each.value.Config.Dimensions),{}) - period = can(each.value.Config.Query) ? null : each.value.Config.Period - metric_query = can(each.value.Config.Query) ? [for qK,qV in each.value.Config.Query : { - id = (can(qV.expression)) ? "e${qK}" : "m${qK}" - label = qV.label - return_data = try(qV.return_data,false) - expression = try(qV.expression,null) - period = try(qV.period,null) - - metric = (can(qV.metric)) ? [{ - namespace = qV.metric.namespace - metric_name = qV.metric.metric_name - period = qV.metric.period - stat = qV.metric.stat - unit = try(qV.metric.unit,null) - dimensions = {for dK,dV in try(qV.metric.dimensions,[]) : dK => dV} - }] : [] - + dimensions = can(each.value.Config.Query) ? null : try(tomap(each.value.Config.Dimensions), {}) + period = can(each.value.Config.Query) ? null : each.value.Config.Period + metric_query = can(each.value.Config.Query) ? [for qK, qV in each.value.Config.Query : { + id = (can(qV.expression)) ? "e${qK}" : "m${qK}" + label = qV.label + return_data = try(qV.return_data, false) + expression = try(qV.expression, null) + period = try(qV.period, null) + + metric = (can(qV.metric)) ? [{ + namespace = qV.metric.namespace + metric_name = qV.metric.metric_name + period = qV.metric.period + stat = qV.metric.stat + unit = try(qV.metric.unit, null) + dimensions = { for dK, dV in try(qV.metric.dimensions, []) : dK => dV } }] : [] - - + + }] : [] + + actions_enabled = can(each.value.Config.AlarmActions) ? true : false - alarm_actions = [for aK,aV in each.value.Config.AlarmActions.ALARM : - try(var.alarm_actions[aK]["alarm"][aV[var.current_environment]].arn,"") - if can(var.alarm_actions[aK]["alarm"][aV[var.current_environment]].arn) + alarm_actions = [for aK, aV in each.value.Config.AlarmActions.ALARM : + try(var.alarm_actions[aK]["alarm"][aV[var.current_environment]].arn, "") + if can(var.alarm_actions[aK]["alarm"][aV[var.current_environment]].arn) ] - ok_actions = [for aK,aV in each.value.Config.AlarmActions.OK : - try(var.alarm_actions[aK]["ok"][aV[var.current_environment]].arn,"") - if can(var.alarm_actions[aK]["ok"][aV[var.current_environment]].arn) + ok_actions = [for aK, aV in each.value.Config.AlarmActions.OK : + try(var.alarm_actions[aK]["ok"][aV[var.current_environment]].arn, "") + if can(var.alarm_actions[aK]["ok"][aV[var.current_environment]].arn) ] +} + +#CloudWatch Custom Metrics +module "metric-alarm" { + source = "terraform-aws-modules/cloudwatch/aws//modules/log-metric-filter" + version = "~> 4.0" + for_each = { for i in flatten([ + for Key, Value in local.CloudWatch["Cloudwatch"] : [ + for loopK, loopV in try(var.loop[Value.Loop], ["default"]) : { + ServiceKey = loopV + Name = Value.Name + Key = Key + Config = Value + } + ] + ]) : "${i.Name}-${i.ServiceKey}" => i + if(contains(i.Config.Environment, var.current_environment) || !can(i.Config.Environment)) && can(i.Config.CustomMetrics) } + + log_group_name = each.value.Config.CustomMetrics.LogGroupName + + name = "${each.key}-${each.value.Config.Metrics}-metricfilter" + pattern = each.value.Config.CustomMetrics.Patten + + metric_transformation_namespace = each.value.Config.Namespace + metric_transformation_name = each.value.Config.Metrics } \ No newline at end of file diff --git a/versions.tf b/versions.tf index 2884126..372b5d6 100644 --- a/versions.tf +++ b/versions.tf @@ -1,6 +1,6 @@ terraform { required_version = ">= 1.0.11" required_providers { - aws = ">= 4.8.0" + aws = ">= 4.8.0" } } \ No newline at end of file