From 565d53bb4addff9ac35b4a8fc6ead432b0252944 Mon Sep 17 00:00:00 2001
From: Andrea Dell'Amico <adellam@isti.cnr.it>
Date: Thu, 28 Jul 2016 18:31:53 +0200
Subject: [PATCH] library/roles/ganglia/handlers/main.yml: Set a timeout for
 the restart handler. library/roles/couchbase: Add support for a specific
 ganglia plugin.

---
 couchbase/defaults/main.yml             |   6 +
 couchbase/tasks/couchbase.yml           |  29 ++++
 couchbase/tasks/ganglia-plugin.yml      |  15 +++
 couchbase/tasks/main.yml                |  30 +----
 couchbase/templates/couchbase.py.j2     |  54 ++++++++
 couchbase/templates/couchbase.pyconf.j2 | 171 ++++++++++++++++++++++++
 ganglia/handlers/main.yml               |   5 +-
 7 files changed, 282 insertions(+), 28 deletions(-)
 create mode 100644 couchbase/tasks/couchbase.yml
 create mode 100644 couchbase/tasks/ganglia-plugin.yml
 create mode 100755 couchbase/templates/couchbase.py.j2
 create mode 100644 couchbase/templates/couchbase.pyconf.j2

diff --git a/couchbase/defaults/main.yml b/couchbase/defaults/main.yml
index ed09cdf0..4eaece17 100644
--- a/couchbase/defaults/main.yml
+++ b/couchbase/defaults/main.yml
@@ -1,7 +1,10 @@
 ---
 couchbase_install_packages: True
 couchbase_start_server: True
+couchbase_repo_pkg: couchbase-release-1.0-2-amd64.deb
+couchbase_repo_pkg_url: 'http://packages.couchbase.com/releases/couchbase-release/{{ couchbase_repo_pkg }}'
 
+couchbase_default_host: localhost
 couchbase_console_port: 8091
 couchbase_xdcr_port: 8092
 couchbase_query_port: 8093
@@ -39,3 +42,6 @@ couchbase_allowed_hosts:
   - '{{ network.nmis }}'
   - '{{ ansible_default_ipv4.address }}/32'
 
+#couchbase_ganglia_url_username:
+#couchbase_ganglia_url_password:
+couchbase_monitored_buckets:
diff --git a/couchbase/tasks/couchbase.yml b/couchbase/tasks/couchbase.yml
new file mode 100644
index 00000000..21e15ad3
--- /dev/null
+++ b/couchbase/tasks/couchbase.yml
@@ -0,0 +1,29 @@
+---
+- name: Get the meta package for the couchbase repository
+  get_url: url={{ couchbase_repo_pkg_url }} dest=/root/{{ couchbase_repo_pkg }}
+  register: couchbase_repository
+  tags: couchbase
+
+- name: Install the package source and the Couchbase public keys
+  shell: /usr/bin/dpkg -i /root/couchbase-release-1.0-2-amd64.deb
+  when: ( couchbase_repository | changed )
+  tags: couchbase
+
+- name: Install the latest version of couchbase community server
+  apt: pkg={{ item }} state=latest update_cache=yes
+  with_items:
+    - couchbase-server-community
+  when:
+    - couchbase_install_packages
+  tags: couchbase
+
+- name: Ensure couchbase is started and enabled
+  service: name=couchbase-server state=started enabled=yes
+  when: couchbase_start_server
+  tags: couchbase
+
+- name: Ensure couchbase is stopped and disabled
+  service: name=couchbase-server state=stopped enabled=no
+  when: not couchbase_start_server
+  tags: couchbase
+
diff --git a/couchbase/tasks/ganglia-plugin.yml b/couchbase/tasks/ganglia-plugin.yml
new file mode 100644
index 00000000..a4395281
--- /dev/null
+++ b/couchbase/tasks/ganglia-plugin.yml
@@ -0,0 +1,15 @@
+---
+# 
+# The ganglia plugin comes from https://github.com/ganglia/gmond_python_modules
+#
+- name: Install the ganglia plugin for Couchbase. One instance per bucket
+  template: src=couchbase.py.j2 dest=/usr/lib/ganglia/python_modules/couchbase_{{ item }}.py owner=root group=ganglia mode=0440
+  with_items: '{{ couchbase_monitored_buckets }}'
+  notify: Restart ganglia monitor
+  tags: [ 'ganglia', 'couchbase' ]
+
+- name: Distribute the ganglia (gmond) configuration for the Couchbase plugin
+  template: src=couchbase.pyconf.j2 dest=/etc/ganglia/conf.d/couchbase_{{ item }}.pyconf owner=root group=ganglia mode=0440
+  with_items: '{{ couchbase_monitored_buckets }}'
+  notify: Restart ganglia monitor
+  tags: [ 'ganglia', 'couchbase' ]
diff --git a/couchbase/tasks/main.yml b/couchbase/tasks/main.yml
index 98b6213b..c2c927e1 100644
--- a/couchbase/tasks/main.yml
+++ b/couchbase/tasks/main.yml
@@ -1,29 +1,5 @@
 ---
-- name: Get the meta package for the couchbase repository
-  get_url: url=http://packages.couchbase.com/releases/couchbase-release/couchbase-release-1.0-2-amd64.deb dest=/root/couchbase-release-1.0-2-amd64.deb
-  register: couchbase_repository
-  tags: couchbase
-
-- name: Install the package source and the Couchbase public keys
-  shell: /usr/bin/dpkg -i /root/couchbase-release-1.0-2-amd64.deb
-  when: ( couchbase_repository | changed )
-  tags: couchbase
-
-- name: Install the latest version of couchbase community server
-  apt: pkg={{ item }} state=latest update_cache=yes
-  with_items:
-    - couchbase-server-community
-  when:
-    - couchbase_install_packages
-  tags: couchbase
-
-- name: Ensure couchbase is started and enabled
-  service: name=couchbase-server state=started enabled=yes
-  when: couchbase_start_server
-  tags: couchbase
-
-- name: Ensure couchbase is stopped and disabled
-  service: name=couchbase-server state=stopped enabled=no
-  when: not couchbase_start_server
-  tags: couchbase
+- include: couchbase.yml
+- include: ganglia-plugin.yml
+  when: ganglia_enabled
 
diff --git a/couchbase/templates/couchbase.py.j2 b/couchbase/templates/couchbase.py.j2
new file mode 100755
index 00000000..7c64979f
--- /dev/null
+++ b/couchbase/templates/couchbase.py.j2
@@ -0,0 +1,54 @@
+import requests
+import random
+import json
+
+HOST = "{{ couchbase_default_host }}"
+PORT = "{{ couchbase_console_port }}"
+BCKT = "{{ item }}"
+USERNAME = "{{ couchbase_ganglia_url_username }}"
+PASSWORD = "{{ couchbase_ganglia_url_password }}"
+PREFIX = ""
+
+def get_descriptor(name):
+    d = {'name': name,
+        'call_back': temp_handler,
+        'time_max': 90,
+        'value_type': 'uint',
+        'units': 'number',
+        'slope': 'both',
+        'format': '%d',
+        'description': '%s metric' %name,
+        'groups': 'cb bucket %s' %BCKT}
+
+    return d
+
+def temp_handler(name):
+    global s
+    return int(s[name[len(PREFIX):]].pop())
+
+
+def metric_init(params):
+    global s
+    descriptors = []
+
+    url = 'http://%s:%s/pools/default/buckets/%s/stats/' %(HOST, PORT, BCKT)
+    r = requests.get(url, auth=(USERNAME, PASSWORD))
+    j = json.loads(r.content)
+    s = j['op']['samples']
+    for i in s:
+        name = PREFIX + str(i)
+        d = get_descriptor(name)
+        descriptors.append(d)
+    return descriptors
+
+
+def metric_cleanup():
+    '''Clean up the metric module.'''
+    pass
+
+
+if __name__ == '__main__':
+    dd = metric_init({})
+    for d in dd:
+        print (('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name']))
+
diff --git a/couchbase/templates/couchbase.pyconf.j2 b/couchbase/templates/couchbase.pyconf.j2
new file mode 100644
index 00000000..1b6e7e8b
--- /dev/null
+++ b/couchbase/templates/couchbase.pyconf.j2
@@ -0,0 +1,171 @@
+modules {
+  module {
+    name = "couchbase_{{ item }}"
+    language = "python"
+  }
+}
+
+collection_group {
+  collect_every = 40
+  time_threshold = 50
+  metric {
+    name  = "avg_disk_commit_time"
+    title = "{{ item }}_avg_disk_commit_time"
+  }
+  metric {
+    name  = "avg_disk_update_time"
+    title = "{{ item }}_avg_disk_update_time"
+  }
+  metric {
+    name  = "cas_hits"
+    title = "{{ item }}_cas_hits"
+  }
+  metric {
+    name  = "cas_misses"
+    title = "{{ item }}_cas_misses"
+  }
+  metric {
+    name  = "couch_docs_actual_disk_size"
+    title = "{{ item }}_couch_docs_actual_disk_size"
+  }
+  metric {
+    name  = "couch_views_disk_size"
+    title = "{{ item }}_couch_views_disk_size"
+  }
+  metric {
+    name  = "couch_views_ops"
+    title = "{{ item }}_couch_views_ops"
+  }
+  metric {
+    name  = "cpu_idle_ms"
+    title = "{{ item }}_cpu_idle_ms"
+  }
+  metric {
+    name  = "cpu_utilization_rate"
+    title = "{{ item }}_cpu_utilization_rate"
+  }
+  metric {
+    name  = "curr_connections"
+    title = "{{ item }}_curr_connections"
+  }
+  metric {
+    name  = "curr_items"
+    title = "{{ item }}_curr_items"
+  }
+  metric {
+    name  = "curr_items_tot"
+    title = "{{ item }}_curr_items_tot"
+  }
+  metric {
+    name  = "decr_hits"
+    title = "{{ item }}_decr_hits"
+  }
+  metric {
+    name  = "decr_misses"
+    title = "{{ item }}_decr_misses"
+  }
+  metric {
+    name  = "delete_hits"
+    title = "{{ item }}_delete_hits"
+  }
+  metric {
+    name  = "delete_misses"
+    title = "{{ item }}_delete_misses"
+  }
+  metric {
+    name  = "disk_commit_count"
+    title = "{{ item }}_disk_commit_count"
+  }
+  metric {
+    name  = "disk_commit_total"
+    title = "{{ item }}_disk_commit_total"
+  }
+  metric {
+    name  = "disk_update_count"
+    title = "{{ item }}_disk_update_count"
+  }
+  metric {
+    name  = "disk_update_total"
+    title = "{{ item }}_disk_update_total"
+  }
+  metric {
+    name  = "disk_write_queue"
+    title = "{{ item }}_disk_write_queue"
+  }
+  metric {
+    name  = "evictions"
+    title = "{{ item }}_evictions"
+  }
+  metric {
+    name  = "get_hits"
+    title = "{{ item }}_get_hits"
+  }
+  metric {
+    name  = "get_misses"
+    title = "{{ item }}_get_misses"
+  }
+  metric {
+    name  = "hibernated_requests"
+    title = "{{ item }}_hibernated_requests"
+  }
+  metric {
+    name  = "hibernated_waked"
+    title = "{{ item }}_hibernated_waked"
+  }
+  metric {
+    name  = "hit_ratio"
+    title = "{{ item }}_hit_ratio"
+  }
+  metric {
+    name  = "incr_hits"
+    title = "{{ item }}_incr_hits"
+  }
+  metric {
+    name  = "incr_misses"
+    title = "{{ item }}_incr_misses"
+  }
+  metric {
+    name  = "mem_actual_free"
+    title = "{{ item }}_mem_actual_free"
+  }
+  metric {
+    name  = "mem_actual_used"
+    title = "{{ item }}_mem_actual_used"
+  }
+  metric {
+    name  = "mem_free"
+    title = "{{ item }}_mem_free"
+  }
+  metric {
+    name  = "mem_total"
+    title = "{{ item }}_mem_total"
+  }
+  metric {
+    name  = "mem_used"
+    title = "{{ item }}_mem_used"
+  }
+  metric {
+    name  = "misses"
+    title = "{{ item }}_misses"
+  }
+  metric {
+    name  = "ops"
+    title = "{{ item }}_ops"
+  }
+  metric {
+    name  = "swap_total"
+    title = "{{ item }}_swap_total"
+  }
+  metric {
+    name  = "swap_used"
+    title = "{{ item }}_swap_used"
+  }
+  metric {
+    name  = "vb_total_queue_age"
+    title = "{{ item }}_vb_total_queue_age"
+  }
+  metric {
+    name  = "xdc_ops"
+    title = "{{ item }}_xdc_ops"
+  }
+}
diff --git a/ganglia/handlers/main.yml b/ganglia/handlers/main.yml
index 7f6dc7ea..b52765be 100644
--- a/ganglia/handlers/main.yml
+++ b/ganglia/handlers/main.yml
@@ -1,2 +1,5 @@
+---
 - name: Restart ganglia monitor
-  service: name=ganglia-monitor state=restarted
+  service: name=ganglia-monitor state=restarted sleep=20
+  when: ganglia_enabled
+