Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: smart agent pm2 detectors #573

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions modules/smart-agent_pm2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# PM2 SignalFx detectors

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
:link: **Contents**

- [How to use this module?](#how-to-use-this-module)
- [What are the available detectors in this module?](#what-are-the-available-detectors-in-this-module)
- [How to collect required metrics?](#how-to-collect-required-metrics)
- [Metrics](#metrics)
- [Related documentation](#related-documentation)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## How to use this module?

This directory defines a [Terraform](https://www.terraform.io/)
[module](https://www.terraform.io/docs/modules/usage.html) you can use in your
existing [stack](https://github.com/claranet/terraform-signalfx-detectors/wiki/Getting-started#stack) by adding a
`module` configuration and setting its `source` parameter to URL of this folder:

```hcl
module "signalfx-detectors-smart-agent-pm2" {
source = "github.com/claranet/terraform-signalfx-detectors.git//modules/smart-agent_pm2?ref={revision}"

environment = var.environment
notifications = local.notifications
}
```

Note the following parameters:

* `source`: Use this parameter to specify the URL of the module. The double slash (`//`) is intentional and required.
Terraform uses it to specify subfolders within a Git repo (see [module
sources](https://www.terraform.io/docs/modules/sources.html)). The `ref` parameter specifies a specific Git tag in
this repository. It is recommended to use the latest "pinned" version in place of `{revision}`. Avoid using a branch
like `master` except for testing purpose. Note that every modules in this repository are available on the Terraform
[registry](https://registry.terraform.io/modules/claranet/detectors/signalfx) and we recommend using it as source
instead of `git` which is more flexible but less future-proof.

* `environment`: Use this parameter to specify the
[environment](https://github.com/claranet/terraform-signalfx-detectors/wiki/Getting-started#environment) used by this
instance of the module.
Its value will be added to the `prefixes` list at the start of the [detector
name](https://github.com/claranet/terraform-signalfx-detectors/wiki/Templating#example).
In general, it will also be used in the `filtering` internal sub-module to [apply
[filters](https://github.com/claranet/terraform-signalfx-detectors/wiki/Guidance#filtering) based on our default
[tagging convention](https://github.com/claranet/terraform-signalfx-detectors/wiki/Tagging-convention) by default.

* `notifications`: Use this parameter to define where alerts should be sent depending on their severity. It consists
of a Terraform [object](https://www.terraform.io/docs/configuration/types.html#object-) where each key represents an
available [detector rule severity](https://docs.signalfx.com/en/latest/detect-alert/set-up-detectors.html#severity)
and its value is a list of recipients. Every recipients must respect the [detector notification
format](https://registry.terraform.io/providers/splunk-terraform/signalfx/latest/docs/resources/detector#notification-format).
Check the [notification binding](https://github.com/claranet/terraform-signalfx-detectors/wiki/Notifications-binding)
documentation to understand the recommended role of each severity.

These 3 parameters alongs with all variables defined in [common-variables.tf](common-variables.tf) are common to all
[modules](../) in this repository. Other variables, specific to this module, are available in
[variables-gen.tf](variables-gen.tf).
In general, the default configuration "works" but all of these Terraform
[variables](https://www.terraform.io/docs/configuration/variables.html) make it possible to
customize the detectors behavior to better fit your needs.

Most of them represent usual tips and rules detailled in the
[guidance](https://github.com/claranet/terraform-signalfx-detectors/wiki/Guidance) documentation and listed in the
common [variables](https://github.com/claranet/terraform-signalfx-detectors/wiki/Variables) dedicated documentation.

Feel free to explore the [wiki](https://github.com/claranet/terraform-signalfx-detectors/wiki) for more information about
general usage of this repository.

## What are the available detectors in this module?

This module creates the following SignalFx detectors which could contain one or multiple alerting rules:

|Detector|Critical|Major|Minor|Warning|Info|
|---|---|---|---|---|---|
|Pm2 heartbeat|X|-|-|-|-|
|Pm2 up application|X|-|-|-|-|
|Pm2 restarts counter|X|X|-|-|-|

## How to collect required metrics?

This module uses metrics available from
[monitors](https://docs.signalfx.com/en/latest/integrations/agent/monitors/_monitor-config.html)
available in the [SignalFx Smart
Agent](https://github.com/signalfx/signalfx-agent). Check the "Related documentation" section for more
information including the official documentation of this monitor.




### Metrics


To filter only required metrics for the detectors of this module, add the
[datapointsToExclude](https://docs.signalfx.com/en/latest/integrations/agent/filtering.html) parameter to
the corresponding monitor configuration:

```yaml
datapointsToExclude:
- metricNames:
- '*'
- '!pm2_restarts'
- '!pm2_up'

```



## Related documentation

* [Terraform SignalFx provider](https://registry.terraform.io/providers/splunk-terraform/signalfx/latest/docs)
* [Terraform SignalFx detector](https://registry.terraform.io/providers/splunk-terraform/signalfx/latest/docs/resources/detector)
1 change: 1 addition & 0 deletions modules/smart-agent_pm2/common-filters.tf
1 change: 1 addition & 0 deletions modules/smart-agent_pm2/common-locals.tf
1 change: 1 addition & 0 deletions modules/smart-agent_pm2/common-modules.tf
1 change: 1 addition & 0 deletions modules/smart-agent_pm2/common-variables.tf
1 change: 1 addition & 0 deletions modules/smart-agent_pm2/common-versions.tf
14 changes: 14 additions & 0 deletions modules/smart-agent_pm2/conf/00-heartbeat.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Example
module: pm2
name: heartbeat

transformation: false
aggregation: true
filtering: "(not filter('name', 'pm2-metrics'))"
exclude_not_running_vm: true

signals:
signal:
metric: "pm2_up"
rules:
critical:
15 changes: 15 additions & 0 deletions modules/smart-agent_pm2/conf/01-up.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module: pm2
name: "up application"

id: up
transformation: ".min(over='5min')"
filtering: "(not filter('name', 'pm2-metrics'))"
exclude_not_running_vm: true

signals:
signal:
metric: pm2_up
rules:
critical:
threshold: 1
comparator: ">"
18 changes: 18 additions & 0 deletions modules/smart-agent_pm2/conf/02-restarts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module: pm2
name: "restarts counter"

id: restarts
transformation: ".min(over='5min')"
filtering: "(not filter('name', 'pm2-metrics'))"
exclude_not_running_vm: true

signals:
signal:
metric: pm2_restarts
rules:
critical:
threshold: 5
comparator: ">"
major:
threshold: 3
comparator: ">="
3 changes: 3 additions & 0 deletions modules/smart-agent_pm2/conf/readme.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
documentations:

source_doc:
95 changes: 95 additions & 0 deletions modules/smart-agent_pm2/detectors-gen.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
resource "signalfx_detector" "heartbeat" {
name = format("%s %s", local.detector_name_prefix, "Pm2 heartbeat")

authorized_writer_teams = var.authorized_writer_teams
teams = try(coalescelist(var.teams, var.authorized_writer_teams), null)
tags = compact(concat(local.common_tags, local.tags, var.extra_tags))

max_delay = 900

program_text = <<-EOF
from signalfx.detectors.not_reporting import not_reporting
base_filtering = (not filter('name', 'pm2-metrics'))
signal = data('pm2_up', filter=${local.not_running_vm_filters} and base_filtering and ${module.filtering.signalflow})${var.heartbeat_aggregation_function}.publish('signal')
not_reporting.detector(stream=signal, resource_identifier=None, duration='${var.heartbeat_timeframe}', auto_resolve_after='${local.heartbeat_auto_resolve_after}').publish('CRIT')
EOF

rule {
description = "has not reported in ${var.heartbeat_timeframe}"
severity = "Critical"
detect_label = "CRIT"
disabled = coalesce(var.heartbeat_disabled, var.detectors_disabled)
notifications = coalescelist(lookup(var.heartbeat_notifications, "critical", []), var.notifications.critical)
runbook_url = try(coalesce(var.heartbeat_runbook_url, var.runbook_url), "")
tip = var.heartbeat_tip
parameterized_subject = var.message_subject == "" ? local.rule_subject_novalue : var.message_subject
parameterized_body = var.message_body == "" ? local.rule_body : var.message_body
}
}

resource "signalfx_detector" "up" {
name = format("%s %s", local.detector_name_prefix, "Pm2 up application")

authorized_writer_teams = var.authorized_writer_teams
teams = try(coalescelist(var.teams, var.authorized_writer_teams), null)
tags = compact(concat(local.common_tags, local.tags, var.extra_tags))

program_text = <<-EOF
base_filtering = (not filter('name', 'pm2-metrics'))
signal = data('pm2_up', filter=${local.not_running_vm_filters} and base_filtering and ${module.filtering.signalflow})${var.up_aggregation_function}${var.up_transformation_function}.publish('signal')
detect(when(signal > ${var.up_threshold_critical})).publish('CRIT')
EOF

rule {
description = "is too high > ${var.up_threshold_critical}"
severity = "Critical"
detect_label = "CRIT"
disabled = coalesce(var.up_disabled, var.detectors_disabled)
notifications = coalescelist(lookup(var.up_notifications, "critical", []), var.notifications.critical)
runbook_url = try(coalesce(var.up_runbook_url, var.runbook_url), "")
tip = var.up_tip
parameterized_subject = var.message_subject == "" ? local.rule_subject : var.message_subject
parameterized_body = var.message_body == "" ? local.rule_body : var.message_body
}
}

resource "signalfx_detector" "restarts" {
name = format("%s %s", local.detector_name_prefix, "Pm2 restarts counter")

authorized_writer_teams = var.authorized_writer_teams
teams = try(coalescelist(var.teams, var.authorized_writer_teams), null)
tags = compact(concat(local.common_tags, local.tags, var.extra_tags))

program_text = <<-EOF
base_filtering = (not filter('name', 'pm2-metrics'))
A = data('pm2_restarts', filter=${local.not_running_vm_filters} and base_filtering and ${module.filtering.signalflow})${var.restarts_aggregation_function}${var.restarts_transformation_function}
signal = (A - A.timeshift("${var.restarts_counter_timeshift}")).publish('signal')
detect(when(signal > ${var.restarts_threshold_critical})).publish('CRIT')
detect(when(signal >= ${var.restarts_threshold_major})).publish('MAJOR')
EOF

rule {
description = "is too high > ${var.restarts_threshold_critical}"
severity = "Critical"
detect_label = "CRIT"
disabled = coalesce(var.restarts_disabled_critical, var.restarts_disabled, var.detectors_disabled)
notifications = coalescelist(lookup(var.restarts_notifications, "critical", []), var.notifications.critical)
runbook_url = try(coalesce(var.restarts_runbook_url, var.runbook_url), "")
tip = var.restarts_tip
parameterized_subject = var.message_subject == "" ? local.rule_subject : var.message_subject
parameterized_body = var.message_body == "" ? local.rule_body : var.message_body
}

rule {
description = "is too high >= ${var.restarts_threshold_major}"
severity = "Major"
detect_label = "MAJOR"
disabled = coalesce(var.restarts_disabled_major, var.restarts_disabled, var.detectors_disabled)
notifications = coalescelist(lookup(var.restarts_notifications, "major", []), var.notifications.major)
runbook_url = try(coalesce(var.restarts_runbook_url, var.runbook_url), "")
tip = var.restarts_tip
parameterized_subject = var.message_subject == "" ? local.rule_subject : var.message_subject
parameterized_body = var.message_body == "" ? local.rule_body : var.message_body
}
}

15 changes: 15 additions & 0 deletions modules/smart-agent_pm2/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "heartbeat" {
description = "Detector resource for heartbeat"
value = signalfx_detector.heartbeat
}

output "restarts" {
description = "Detector resource for restarts"
value = signalfx_detector.restarts
}

output "up" {
description = "Detector resource for up"
value = signalfx_detector.up
}

4 changes: 4 additions & 0 deletions modules/smart-agent_pm2/tags.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
locals {
tags = ["smart-agent", "pm2"]
}

Loading
Loading