Merge "Provide complete set of Neutron metrics"
diff --git a/collectd/_common.sls b/collectd/_common.sls
index 7725520..2480e30 100644
--- a/collectd/_common.sls
+++ b/collectd/_common.sls
@@ -25,10 +25,3 @@
 /usr/lib/collectd-python:
   file.recurse:
   - source: salt://collectd/files/plugin
-
-collectd_client_grains_dir:
-  file.directory:
-  - name: /etc/salt/grains.d
-  - mode: 700
-  - makedirs: true
-  - user: root
diff --git a/collectd/_service.sls b/collectd/_service.sls
index ff915e4..c17e26a 100644
--- a/collectd/_service.sls
+++ b/collectd/_service.sls
@@ -131,7 +131,7 @@
   - group: root
   - mode: 660
   - defaults:
-    backend: {{ backend|yaml }}
+    network_backend: {{ network_backend|yaml }}
   - require:
     - file: {{ client.service }}_client_conf_dir
   - require_in:
diff --git a/collectd/client.sls b/collectd/client.sls
index e0fbf5d..7affb98 100644
--- a/collectd/client.sls
+++ b/collectd/client.sls
@@ -1,4 +1,4 @@
-{%- from "collectd/map.jinja" import client, service_grains with context %}
+{%- from "collectd/map.jinja" import client with context %}
 {%- if client.enabled %}
 
 include:
@@ -12,7 +12,21 @@
   - require:
     - pkg: collectd_client_packages
 
-{%- set plugins = service_grains.collectd.local_plugin %}
+{%- set service_grains = {'collectd': {'remote_plugin': {}, 'local_plugin': {}}} %}
+
+{%- for service_name, service in pillar.items() %}
+  {%- if service.get('_support', {}).get('collectd', {}).get('enabled', False) %}
+    {%- set grains_fragment_file = service_name+'/meta/collectd.yml' %}
+    {%- macro load_grains_file() %}{% include grains_fragment_file ignore missing %}{% endmacro %}
+    {%- set grains_yaml = load_grains_file()|load_yaml %}
+
+    {%- if grains_yaml is mapping %}
+      {%- set service_grains = salt['grains.filter_by']({'default': service_grains}, merge={'collectd': grains_yaml}) %}
+    {%- endif %}
+  {%- endif %}
+{%- endfor %}
+
+{%- set plugins = service_grains.collectd.get('local_plugin', {}) %}
 {%- include "collectd/_service.sls" %}
 
 {%- endif %}
diff --git a/collectd/files/backend/http.conf b/collectd/files/backend/http.conf
index 8787dbc..3bc1bc5 100644
--- a/collectd/files/backend/http.conf
+++ b/collectd/files/backend/http.conf
@@ -3,11 +3,12 @@
 </LoadPlugin>
 
 <Plugin write_http>
-  <URL "http://{{ backend.host }}:{{ backend.port }}">
+  <Node>
+    URL "http://{{ backend.host }}:{{ backend.port }}"
     Format "{{ backend.get('format', 'json')|upper }}"
     StoreRates {{ backend.get('store_rates', True)|lower }}
 {%- if backend.timeout is defined %}
     Timeout {{ backend.timeout }}
 {%- endif %}
-  </URL>
+  </Node>
 </Plugin>
diff --git a/collectd/files/backend/network.conf b/collectd/files/backend/network.conf
index e97c530..e3673a4 100644
--- a/collectd/files/backend/network.conf
+++ b/collectd/files/backend/network.conf
@@ -2,34 +2,14 @@
   Globals false
 </LoadPlugin>
 
-{%- for _, backend in client.backend.iteritems() %}
+{%- for _, backend in network_backend.iteritems() %}
 <Plugin network>
-	{%- if backend.mode == 'client' %}
-	Server "{{ backend.host }}" "{{ backend.port }}"
-#	<Server "{{ backend.host }}" "{{ backend.port }}">
-#		SecurityLevel Encrypt
-#		Username "{{ backend.user }}"
-#		Password "{{ backend.password }}"
-#	</Server>
-	TimeToLive 128
-	{%- endif %}
-	{%- if backend.mode == 'server' %}
-	Listen "{{ backend.host }}" "{{ backend.port }}"
-#	<Listen "{{ backend.host }}" "{{ backend.port }}">
-#		SecurityLevel Sign
-#		AuthFile "/etc/collectd/passwd"
-#		Interface "{{ backend.interface }}"
-#	</Listen>
-	MaxPacketSize 1024
-	{%- endif %}
-
-#	# proxy setup (client and server as above):
-#	Forward true
-#
-#	# statistics about the network backend itself
-#	ReportStats false
-#
-#	# "garbage collection"
-#	CacheFlush 1800
+    {%- if backend.get('mode', 'client') == 'client' %}
+    Server "{{ backend.host }}" "{{ backend.port }}"
+    {%- endif %}
+    {%- if backend.get('mode', 'client') == 'server' %}
+    Listen "{{ backend.host }}" "{{ backend.port }}"
+    MaxPacketSize 1024
+    {%- endif %}
 </Plugin>
 {%- endfor %}
diff --git a/collectd/files/collectd_postgresql.conf b/collectd/files/collectd_postgresql.conf
new file mode 100644
index 0000000..7943623
--- /dev/null
+++ b/collectd/files/collectd_postgresql.conf
@@ -0,0 +1,114 @@
+<LoadPlugin postgresql>
+  Globals false
+</LoadPlugin>
+
+
+<Plugin postgresql>
+    <Query deadlocks>
+      Statement "SELECT deadlocks as num_deadlocks \
+          FROM pg_stat_database \
+          WHERE datname = $1;"
+
+      Param database
+
+      <Result>
+          Type "pg_xact"
+          InstancePrefix "num_deadlocks"
+          ValuesFrom "num_deadlocks"
+      </Result>
+    </Query>
+
+    <Query stream_lag>
+        Statement "SELECT coalesce(round(extract(epoch from (now() - \
+        pg_last_xact_replay_timestamp()))),0) AS time_lag"
+        <Result>
+            Type gauge
+            InstancePrefix "replication_stream_lag"
+            ValuesFrom "time_lag"
+        </Result>
+    </Query>
+
+    <Query row_stats>
+         Statement "SELECT sum(n_tup_ins) AS inserts, \
+             sum(n_tup_upd) AS updates, \
+             sum(n_tup_del) AS deletes \
+             FROM pg_stat_user_tables"
+         <Result>
+             Type derive
+             InstancePrefix "rows_inserted"
+             ValuesFrom "inserts"
+         </Result>
+         <Result>
+             Type derive
+             InstancePrefix "rows_updated"
+             ValuesFrom "updates"
+         </Result>
+         <Result>
+             Type derive
+             InstancePrefix "rows_deleted"
+             ValuesFrom "deletes"
+         </Result>
+    </Query>
+
+    <Query client_activity>
+         Statement "SELECT count(1) AS total, \
+             sum(CASE WHEN state = 'idle' \
+             THEN 1 ELSE 0 END) AS idle, \
+             sum(CASE WHEN state LIKE 'idle in%' \
+             THEN 1 ELSE 0 END) AS trans_idle, \
+             sum(CASE WHEN state = 'active' \
+             THEN 1 ELSE 0 END) AS active, \
+             sum(CASE WHEN now()-query_start > INTERVAL '1s' \
+             AND state = 'active' THEN 1 ELSE 0 END) AS slow \
+             FROM pg_stat_activity;"
+         <Result>
+             Type gauge
+             InstancePrefix "clients_total"
+             ValuesFrom "total"
+         </Result>
+         <Result>
+             Type gauge
+             InstancePrefix "clients_idle"
+             ValuesFrom "idle"
+         </Result>
+         <Result>
+             Type gauge
+             InstancePrefix "clients_idle_transaction"
+             ValuesFrom "trans_idle"
+         </Result>
+         <Result>
+             Type gauge
+             InstancePrefix "clients_active"
+             ValuesFrom "active"
+         </Result>
+         <Result>
+             Type gauge
+             InstancePrefix "clients_slow"
+             ValuesFrom "slow"
+         </Result>
+    </Query>
+
+  {%- for db_name, db in plugin.data.iteritems() %}
+  <Database {{db_name}}>
+    Host "{{db.users.0.host}}"
+    Port "{{db.users.0.get('port', 5432)}}"
+    User "{{db.users.0.name}}"
+    Password "{{db.users.0.password}}"
+    Query row_stats
+    Query client_activity
+    Query stream_lag
+    Query deadlocks
+    Query backends
+    Query transactions
+    Query queries
+    Query queries_by_table
+    Query query_plans
+    Query table_states
+    Query query_plans_by_table
+    Query table_states_by_table
+    Query disk_io
+    Query disk_io_by_table
+    Query disk_usage
+  </Database>
+  {%- endfor %}
+</Plugin>
diff --git a/collectd/map.jinja b/collectd/map.jinja
index 650c640..1077513 100644
--- a/collectd/map.jinja
+++ b/collectd/map.jinja
@@ -51,15 +51,3 @@
         'automatic_starting': True,
     }
 }, merge=salt['pillar.get']('collectd:remote_client')) %}
-
-{%- set service_grains = {'collectd': {'remote_plugin': {}, 'local_plugin': {}}} %}
-{%- for service_name, service in pillar.items() %}
-  {%- if service.get('_support', {}).get('collectd', {}).get('enabled', False) %}
-    {%- set grains_fragment_file = service_name+'/meta/collectd.yml' %}
-    {%- macro load_grains_file() %}{% include grains_fragment_file ignore missing %}{% endmacro %}
-    {%- set grains_yaml = load_grains_file()|load_yaml %}
-    {%- if grains_yaml is mapping %}
-      {%- set service_grains = salt['grains.filter_by']({'default': service_grains}, merge={'collectd': grains_yaml}) %}
-    {%- endif %}
-  {%- endif %}
-{%- endfor %}
diff --git a/collectd/meta/salt.yml b/collectd/meta/salt.yml
index 30f0f1f..67158bb 100644
--- a/collectd/meta/salt.yml
+++ b/collectd/meta/salt.yml
@@ -1,6 +1,18 @@
 grain:
-  {%- if pillar.collectd.client is defined %}
-  {%- from "collectd/map.jinja" import service_grains with context -%}
+  {%- if pillar.get('collectd', {}).get('client') %}
+    {%- set service_grains = {'collectd': {'remote_plugin': {}, 'local_plugin': {}}} %}
+
+    {%- for service_name, service in pillar.items() %}
+      {%- if service.get('_support', {}).get('collectd', {}).get('enabled', False) %}
+        {%- set grains_fragment_file = service_name+'/meta/collectd.yml' %}
+        {%- macro load_grains_file() %}{% include grains_fragment_file ignore missing %}{% endmacro %}
+        {%- set grains_yaml = load_grains_file()|load_yaml %}
+
+        {%- if grains_yaml is mapping %}
+          {%- set service_grains = salt['grains.filter_by']({'default': service_grains}, merge={'collectd': grains_yaml}) %}
+        {%- endif %}
+      {%- endif %}
+    {%- endfor %}
   collectd:
     {{ service_grains|yaml(False)|indent(4) }}
   {%- endif %}