Skip to content

Commit

Permalink
Merge pull request DataDog#224 from sethcleveland/Support_generic_pos…
Browse files Browse the repository at this point in the history
…tgres_custom_metrics

Support generic postgres custom metrics
  • Loading branch information
truthbk authored Sep 20, 2016
2 parents af70852 + 7e5d8c1 commit abffbda
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
23 changes: 22 additions & 1 deletion manifests/integrations/postgres.pp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
# Track per relation/table metrics. Array of strings.
# Warning: this can collect lots of metrics per relation
# (10 + 10 per index)
# $tags
# Optional array of tags
# $custom_metrics
# A hash of custom metrics with the following keys - query, metrics,
# relation, descriptors. Refer to this guide for details on those fields:
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
#
# Sample Usage:
#
Expand All @@ -27,6 +33,18 @@
# dbname => 'postgres'
# username => 'datadog',
# password => 'some_pass',
# custom_metrics => {
# a_custom_query => {
# query => "select tag_column, %s from table",
# relation => false,
# metrics => {
# value_column => ["value_column.datadog.tag", "GAUGE"]
# },
# descriptors => [
# ["tag_column", "tag_column.datadog.tag"]
# ]
# }
# }
# }
#
#
Expand All @@ -37,7 +55,8 @@
$port = '5432',
$username = 'datadog',
$tags = [],
$tables = []
$tables = [],
$custom_metrics = {},
) inherits datadog_agent::params {
include datadog_agent

Expand All @@ -53,4 +72,6 @@
require => Package[$datadog_agent::params::package_name],
notify => Service[$datadog_agent::params::service_name],
}

create_resources('datadog_agent::integrations::postgres_custom_metric', $custom_metrics)
}
27 changes: 27 additions & 0 deletions manifests/integrations/postgres_custom_metric.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
##
# The postgres_custom_metric defines a custom sql metric.
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
#
# $query:
# The custom metric SQL query. It must contain a '%s' for defining the metrics.
#
# $metrics:
# a hash of column name to metric definition. a metric definition is an array
# consisting of two columns -- the datadog metric name and the metric type.
#
# $relation:
# ?
#
# $descriptor:
# an array that maps an sql column's to a tag. Each descriptor consists of two
# fields -- column name, and datadog tag.
define datadog_agent::integrations::postgres_custom_metric(
$query,
$metrics,
$relation = false,
$descriptors = [],
) {
validate_re($query, '^.*%s.*$', 'custom_metrics require %s for metric substitution')
validate_hash($metrics)
validate_array($descriptors)
}
47 changes: 47 additions & 0 deletions spec/classes/datadog_agent_integrations_postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,53 @@
it { should contain_file(conf_file).with_content(%r{username: monitoring}) }
it { should contain_file(conf_file).with_content(%r{^[^#]*tags:\s+- foo\s+- bar\s+- baz}) }
it { should contain_file(conf_file).with_content(%r{^[^#]*relations:\s+- furry\s+- fuzzy\s+- funky}) }

context 'with custom metric query missing %s' do
let(:params) {{
host: 'postgres1',
dbname: 'cats',
port: 4142,
username: 'monitoring',
password: 'abc123',
custom_metrics: {
'query_is_missing_%s' => {
'query' => 'select * from fuzz',
'metrics' => { },
}
}
}}
it do
expect {
is_expected.to compile
}.to raise_error(/custom_metrics require %s for metric substitution/)
end
end

context 'with custom metric query' do
let(:params) {{
host: 'postgres1',
dbname: 'cats',
port: 4142,
username: 'monitoring',
password: 'abc123',
custom_metrics: {
'foo_gooo_bar_query' => {
'query' => 'select foo, %s from bar',
'metrics' => {
"gooo" => ["custom_metric.tag.gooo", "GAUGE"]
},
'descriptors' => [["foo", "custom_metric.tag.foo"]]
}
}
}}
it { is_expected.to compile }
it { should contain_file(conf_file).with_content(%r{^[^#]*custom_metrics:}) }
it { should contain_file(conf_file).with_content(%r{\s+query:\s*['"]?select foo, %s from bar['"]?}) }
it { should contain_file(conf_file).with_content(%r{\s+metrics:}) }
it { should contain_file(conf_file).with_content(%r{\s+"gooo":\s+\[custom_metric.tag.gooo, GAUGE\]}) }
it { should contain_file(conf_file).with_content(%r{\s+query.*\n\s+relation:\s*false}) }
it { should contain_file(conf_file).with_content(%r{\s+descriptors.*\n\s+-\s+\[foo, custom_metric.tag.foo\]}) }
end
end
end

Expand Down
31 changes: 31 additions & 0 deletions templates/agent-conf.d/postgres.yaml.erb
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,34 @@ instances:
<%- end -%>
<%- end -%>
<% end -%>
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
# custom_metrics:
# - # Capture simple data
# query: SELECT name, address, %s from company where name = 'Paul'; # this query will be run and "%s" replaced with the parameters defined in the metrics section just below
# metrics:
# age: [postgresql.employee_age, GAUGE] # the value contained in column "age" will be captured and submitted as a gauge metric named "postgresql.employee.age"
# salary: [postgresql.employee_salary, GAUGE]
# relation: false # when relation is not an empty list, it gathers per-relation metrics on top of that.
# descriptors:
# - [name, name] # captures the content of the "name" column as a tag for the 2 metrics defined
# - [address, localisation] # captures the content of "address" column as a tag and renames this tag "localisation"
#
<% if @custom_metrics and ! @custom_metrics.empty? -%>
custom_metrics:
<%- Array(@custom_metrics).each do |n, custom_metric| -%>
- query: <%= custom_metric["query"] %>
relation: <%= custom_metric["relation"]? "true" : "false" %>
metrics:
<%- Array(custom_metric["metrics"]).each do |metric_name, metric_descriptor| -%>
"<%= metric_name %>": [<%= metric_descriptor[0] %>, <%= metric_descriptor[1] %>]
<%- end -%>
<%- if custom_metric["descriptors"] == nil || custom_metric["descriptors"].empty? -%>
descriptors: []
<%- else -%>
descriptors:
<%- Array(custom_metric["descriptors"]).each do |descriptor| -%>
- [<%=descriptor[0]%>, <%=descriptor[1] %>]
<%- end -%>
<%- end -%>
<%- end -%>
<% end -%>

0 comments on commit abffbda

Please sign in to comment.