Skip to content

Commit 8218721

Browse files
authored
Merge pull request #224 from sethcleveland/Support_generic_postgres_custom_metrics
Support generic postgres custom metrics
2 parents aae3488 + efd2531 commit 8218721

4 files changed

Lines changed: 127 additions & 1 deletion

File tree

manifests/integrations/postgres.pp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
# Track per relation/table metrics. Array of strings.
2020
# Warning: this can collect lots of metrics per relation
2121
# (10 + 10 per index)
22+
# $tags
23+
# Optional array of tags
24+
# $custom_metrics
25+
# A hash of custom metrics with the following keys - query, metrics,
26+
# relation, descriptors. Refer to this guide for details on those fields:
27+
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
2228
#
2329
# Sample Usage:
2430
#
@@ -27,6 +33,18 @@
2733
# dbname => 'postgres'
2834
# username => 'datadog',
2935
# password => 'some_pass',
36+
# custom_metrics => {
37+
# a_custom_query => {
38+
# query => "select tag_column, %s from table",
39+
# relation => false,
40+
# metrics => {
41+
# value_column => ["value_column.datadog.tag", "GAUGE"]
42+
# },
43+
# descriptors => [
44+
# ["tag_column", "tag_column.datadog.tag"]
45+
# ]
46+
# }
47+
# }
3048
# }
3149
#
3250
#
@@ -37,7 +55,8 @@
3755
$port = '5432',
3856
$username = 'datadog',
3957
$tags = [],
40-
$tables = []
58+
$tables = [],
59+
$custom_metrics = {},
4160
) inherits datadog_agent::params {
4261
include datadog_agent
4362

@@ -53,4 +72,6 @@
5372
require => Package[$datadog_agent::params::package_name],
5473
notify => Service[$datadog_agent::params::service_name],
5574
}
75+
76+
create_resources('datadog_agent::integrations::postgres_custom_metric', $custom_metrics)
5677
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
##
2+
# The postgres_custom_metric defines a custom sql metric.
3+
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
4+
#
5+
# $query:
6+
# The custom metric SQL query. It must contain a '%s' for defining the metrics.
7+
#
8+
# $metrics:
9+
# a hash of column name to metric definition. a metric definition is an array
10+
# consisting of two columns -- the datadog metric name and the metric type.
11+
#
12+
# $relation:
13+
# ?
14+
#
15+
# $descriptor:
16+
# an array that maps an sql column's to a tag. Each descriptor consists of two
17+
# fields -- column name, and datadog tag.
18+
define datadog_agent::integrations::postgres_custom_metric(
19+
$query,
20+
$metrics,
21+
$relation = false,
22+
$descriptors = [],
23+
) {
24+
validate_re($query, '^.*%s.*$', 'custom_metrics require %s for metric substitution')
25+
validate_hash($metrics)
26+
validate_array($descriptors)
27+
}

spec/classes/datadog_agent_integrations_postgres_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,53 @@
5555
it { should contain_file(conf_file).with_content(%r{username: monitoring}) }
5656
it { should contain_file(conf_file).with_content(%r{^[^#]*tags:\s+- foo\s+- bar\s+- baz}) }
5757
it { should contain_file(conf_file).with_content(%r{^[^#]*relations:\s+- furry\s+- fuzzy\s+- funky}) }
58+
59+
context 'with custom metric query missing %s' do
60+
let(:params) {{
61+
host: 'postgres1',
62+
dbname: 'cats',
63+
port: 4142,
64+
username: 'monitoring',
65+
password: 'abc123',
66+
custom_metrics: {
67+
'query_is_missing_%s' => {
68+
'query' => 'select * from fuzz',
69+
'metrics' => { },
70+
}
71+
}
72+
}}
73+
it do
74+
expect {
75+
is_expected.to compile
76+
}.to raise_error(/custom_metrics require %s for metric substitution/)
77+
end
78+
end
79+
80+
context 'with custom metric query' do
81+
let(:params) {{
82+
host: 'postgres1',
83+
dbname: 'cats',
84+
port: 4142,
85+
username: 'monitoring',
86+
password: 'abc123',
87+
custom_metrics: {
88+
'foo_gooo_bar_query' => {
89+
'query' => 'select foo, %s from bar',
90+
'metrics' => {
91+
"gooo" => ["custom_metric.tag.gooo", "GAUGE"]
92+
},
93+
'descriptors' => [["foo", "custom_metric.tag.foo"]]
94+
}
95+
}
96+
}}
97+
it { is_expected.to compile }
98+
it { should contain_file(conf_file).with_content(%r{^[^#]*custom_metrics:}) }
99+
it { should contain_file(conf_file).with_content(%r{\s+query:\s*['"]?select foo, %s from bar['"]?}) }
100+
it { should contain_file(conf_file).with_content(%r{\s+metrics:}) }
101+
it { should contain_file(conf_file).with_content(%r{\s+"gooo":\s+\[custom_metric.tag.gooo, GAUGE\]}) }
102+
it { should contain_file(conf_file).with_content(%r{\s+query.*\n\s+relation:\s*false}) }
103+
it { should contain_file(conf_file).with_content(%r{\s+descriptors.*\n\s+-\s+\[foo, custom_metric.tag.foo\]}) }
104+
end
58105
end
59106
end
60107

templates/agent-conf.d/postgres.yaml.erb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,34 @@ instances:
4141
<%- end -%>
4242
<%- end -%>
4343
<% end -%>
44+
# https://help.datadoghq.com/hc/en-us/articles/208385813-Postgres-custom-metric-collection-explained
45+
# custom_metrics:
46+
# - # Capture simple data
47+
# 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
48+
# metrics:
49+
# age: [postgresql.employee_age, GAUGE] # the value contained in column "age" will be captured and submitted as a gauge metric named "postgresql.employee.age"
50+
# salary: [postgresql.employee_salary, GAUGE]
51+
# relation: false # when relation is not an empty list, it gathers per-relation metrics on top of that.
52+
# descriptors:
53+
# - [name, name] # captures the content of the "name" column as a tag for the 2 metrics defined
54+
# - [address, localisation] # captures the content of "address" column as a tag and renames this tag "localisation"
55+
#
56+
<% if @custom_metrics and ! @custom_metrics.empty? -%>
57+
custom_metrics:
58+
<%- Array(@custom_metrics).each do |n, custom_metric| -%>
59+
- query: <%= custom_metric["query"] %>
60+
relation: <%= custom_metric["relation"]? "true" : "false" %>
61+
metrics:
62+
<%- Array(custom_metric["metrics"]).each do |metric_name, metric_descriptor| -%>
63+
"<%= metric_name %>": [<%= metric_descriptor[0] %>, <%= metric_descriptor[1] %>]
64+
<%- end -%>
65+
<%- if custom_metric["descriptors"] == nil || custom_metric["descriptors"].empty? -%>
66+
descriptors: []
67+
<%- else -%>
68+
descriptors:
69+
<%- Array(custom_metric["descriptors"]).each do |descriptor| -%>
70+
- [<%=descriptor[0]%>, <%=descriptor[1] %>]
71+
<%- end -%>
72+
<%- end -%>
73+
<%- end -%>
74+
<% end -%>

0 commit comments

Comments
 (0)