diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b0d7f32..22acb022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,20 +29,21 @@ The **patch** part changes incrementally at each release. ### Changed -* lxc-php: Do --no-install-recommends for ssmtp/opensmtpd -* packweb-apache: Don't turn on mod-evasive emails by default +* certbot: install certbot dependencies non-interactively for jessie +* evoacme: upstream release 20.06.1 +* evoacme: read values from environment before defaults file * haproxy: deport SSL tuning to Mozilla SSL generator * haproxy: chroot and socket path are configurable * haproxy: adapt backports installed package list to distibution * haproxy: split stats variables * haproxy: rotate logs with date extension and immediate compression +* lxc-php: Do --no-install-recommends for ssmtp/opensmtpd +* mongodb: install custom munin plugins * nginx: read server-status values before changing the config +* packweb-apache: Don't turn on mod-evasive emails by default * redis: create sudoers file if missing * redis: new syntax for match filter * redis: raise an error is port 6379 is used in "instance" mode -* evoacme: upstream release 20.06.1 -* evoacme: read values from environment before defaults file -* certbot: install certbot dependencies non-interactively for jessie ### Fixed diff --git a/mongodb/files/munin/mongo_btree b/mongodb/files/munin/mongo_btree new file mode 100755 index 00000000..32173814 --- /dev/null +++ b/mongodb/files/munin/mongo_btree @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + +def get(): + return getServerStatus()["indexCounters"] + +def doData(): + for k,v in get().iteritems(): + print( str(k) + ".value " + str(int(v)) ) + +def doConfig(): + + print "graph_title MongoDB btree stats" + print "graph_args --base 1000 -l 0" + print "graph_vlabel mb ${graph_period}" + print "graph_category MongoDB" + + for k in get(): + print k + ".label " + k + print k + ".min 0" + print k + ".type COUNTER" + print k + ".max 500000" + print k + ".draw LINE1" + + + + + + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_collections b/mongodb/files/munin/mongo_collections new file mode 100755 index 00000000..ca70c715 --- /dev/null +++ b/mongodb/files/munin/mongo_collections @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) +import re +FIELD_ESCAPE = re.compile("[^A-Za-z_]") + + +def escape_field(name): + return FIELD_ESCAPE.sub("_", name) + + +def need_multigraph(): + if 'MUNIN_CAP_MULTIGRAPH' not in os.environ: + sys.stderr.write('MUNIN_CAP_MULTIGRAPH not found in environment\n') + sys.exit(1) + + +def collections(include_stats=False): + c = getClient() + for db in c.database_names(): + for collection in c[db].collection_names(): + name = db + "." + collection + if include_stats: + yield name, c[db].command("collstats", collection) + else: + yield name + + +def doData(): + need_multigraph() + data = list(collections(True)) + + print "multigraph collection_count" + for name, stats in data: + print(escape_field(name) + ".value " + str(stats["count"])) + + print "multigraph collection_size" + for name, stats in data: + print(escape_field(name) + ".value " + str(stats["size"])) + + +def doConfig(): + need_multigraph() + names = list(collections()) + + print "multigraph collection_count" + print "graph_title MongoDB collection document count" + print "graph_args --base 1000 -l 0" + print "graph_vlabel collection document count" + print "graph_category MongoDB" + print "graph_total total" + + for name in names: + field_name = escape_field(name) + print field_name + ".label " + name + print field_name + ".min 0" + print field_name + ".type GAUGE" + print field_name + ".draw LINE1" + + print "multigraph collection_size" + print "graph_title MongoDB collection size" + print "graph_args --base 1024 -l 0" + print "graph_vlabel collection size" + print "graph_category MongoDB" + print "graph_total total" + + for name in names: + field_name = escape_field(name) + print field_name + ".label " + name + print field_name + ".min 0" + print field_name + ".type GAUGE" + print field_name + ".draw LINE1" + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_conn b/mongodb/files/munin/mongo_conn new file mode 100755 index 00000000..fc8e5f3c --- /dev/null +++ b/mongodb/files/munin/mongo_conn @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + +name = "connections" + + +def doData(): + print name + ".value " + str( getServerStatus()["connections"]["current"] ) + +def doConfig(): + + print "graph_title MongoDB current connections" + print "graph_args --base 1000 -l 0" + print "graph_vlabel connections" + print "graph_category MongoDB" + + print name + ".label " + name + + + + + + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_docs b/mongodb/files/munin/mongo_docs new file mode 100755 index 00000000..f8daa21f --- /dev/null +++ b/mongodb/files/munin/mongo_docs @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + +def getDatabasesStats(): + host = "127.0.0.1" + port = 27017 + c = getClient() + + dbs = {} + for k in c.database_names(): + if k != "admin" and k != "local" and k != "": + db = c[k] + dbs[k] = {} + for coll in db.collection_names(): + if '.' not in coll: + dbs[k][coll] = db[coll].count() + + return dbs + +def doData(): + ss = getDatabasesStats() + for k,v in ss.iteritems(): + for a,b in v.iteritems(): + print(str(k)+str(a) + ".value " + str(b)) + + +def doConfig(): + + print "graph_title MongoDB documents count" + print "graph_args --base 1000 -l 0 --vertical-label Docs" + print "graph_category MongoDB" + + ss = getDatabasesStats() + for k,v in ss.iteritems(): + for a,b in v.iteritems(): + print str(k)+str(a) + ".label " + str(k) + " " + str(a) + print str(k)+str(a) + ".draw LINE1" + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_lock b/mongodb/files/munin/mongo_lock new file mode 100755 index 00000000..8d219d73 --- /dev/null +++ b/mongodb/files/munin/mongo_lock @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + +name = "locked" + +def doData(): + print name + ".value " + str( 100 * (getServerStatus()["globalLock"]["lockTime"]/getServerStatus()["globalLock"]["totalTime"]) ) + +def doConfig(): + + print "graph_title MongoDB global write lock percentage" + print "graph_args --base 1000 -l 0 " + print "graph_vlabel percentage" + print "graph_category MongoDB" + + print name + ".label " + name + + + + + + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_mem b/mongodb/files/munin/mongo_mem new file mode 100755 index 00000000..0a5ca22c --- /dev/null +++ b/mongodb/files/munin/mongo_mem @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + +def ok(s): + return s == "resident" or s == "virtual" or s == "mapped" + +def doData(): + for k,v in getServerStatus()["mem"].iteritems(): + if ok(k): + print( str(k) + ".value " + str(v * 1024 * 1024) ) + +def doConfig(): + + print "graph_title MongoDB memory usage" + print "graph_args --base 1024 -l 0 --vertical-label Bytes" + print "graph_category MongoDB" + + for k in getServerStatus()["mem"]: + if ok( k ): + print k + ".label " + k + print k + ".draw LINE1" + + + + + + + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_ops b/mongodb/files/munin/mongo_ops new file mode 100755 index 00000000..4a29b411 --- /dev/null +++ b/mongodb/files/munin/mongo_ops @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + + +def getClient(): + if 'MONGO_DB_URI' in os.environ: + return pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + return pymongo.MongoClient() + + +def getServerStatus(): + c = getClient() + return c.admin.command('serverStatus', workingSet=True) + + +def doData(): + ss = getServerStatus() + for k,v in ss["opcounters"].iteritems(): + print( str(k) + ".value " + str(v) ) + +def doConfig(): + + print "graph_title MongoDB ops" + print "graph_args --base 1000 -l 0" + print "graph_vlabel ops / ${graph_period}" + print "graph_category MongoDB" + print "graph_total total" + + for k in getServerStatus()["opcounters"]: + print k + ".label " + k + print k + ".min 0" + print k + ".type COUNTER" + print k + ".max 500000" + print k + ".draw LINE1" + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/files/munin/mongo_page_faults b/mongodb/files/munin/mongo_page_faults new file mode 100755 index 00000000..8d96cf2b --- /dev/null +++ b/mongodb/files/munin/mongo_page_faults @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +## GENERATED FILE - DO NOT EDIT + +import urllib2 +import sys +import os +import pymongo + +def getServerStatus(): + if 'MONGO_DB_URI' in os.environ: + c = pymongo.MongoClient(os.environ['MONGO_DB_URI']) + else: + c = pymongo.MongoClient() + + return c.admin.command('serverStatus', workingSet=True) + +name = "page_faults" + +def get(): + return getServerStatus()["extra_info"][name] + + +def doData(): + print(name + ".value " + str(get())) + + +def doConfig(): + + print "graph_title MongoDB page faults" + print "graph_args --base 1000 -l 0" + print "graph_vlabel faults / ${graph_period}" + print "graph_category MongoDB" + print "graph_total total" + + print name + ".label " + name + print name + ".min 0" + print name + ".type COUNTER" + print name + ".max 10000" + print name + ".draw LINE1" + +if __name__ == "__main__": + + from os import environ + if 'HOST' in environ: + host = environ['HOST'] + if 'PORT' in environ: + port = environ['PORT'] + if 'USER' in environ: + user = environ['USER'] + if 'PASSWORD' in environ: + password = environ['PASSWORD'] + +if len(sys.argv) > 1 and sys.argv[1] == "config": + doConfig() +else: + doData() diff --git a/mongodb/handlers/main.yml b/mongodb/handlers/main.yml index 62ff5f28..15f70437 100644 --- a/mongodb/handlers/main.yml +++ b/mongodb/handlers/main.yml @@ -9,3 +9,8 @@ service: name: mongodb state: restarted + +- name: restart munin-node + systemd: + name: munin-node + state: restarted diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index b04047e0..253fde91 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -44,3 +44,36 @@ dest: /etc/logrotate.d/mongodb force: yes backup: no + +- name: Munin plugins are present + copy: + src: "munin/{{ item }}" + dest: '/usr/local/share/munin/plugins/{{ item }}' + force: yes + state: present + with_items: + - mongo_btree + - mongo_collections + - mongo_conn + - mongo_docs + - mongo_lock + - mongo_mem + - mongo_ops + - mongo_page_faults + notify: restart munin-node + +- name: Enable core Munin plugins + file: + src: '/usr/local/share/munin/plugins/{{ item }}' + dest: /etc/munin/plugins/{{ item }} + state: link + with_items: + - mongo_btree + - mongo_collections + - mongo_conn + - mongo_docs + - mongo_lock + - mongo_mem + - mongo_ops + - mongo_page_faults + notify: restart munin-node