Filippo Giunchedi has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/240358

Change subject: WIP: report swift containers aggregated stats
......................................................................

WIP: report swift containers aggregated stats

Change-Id: Icb7605dbb334ccf225a05ffe54370b33decd090c
---
A modules/swift/files/swift-container-stats
M modules/swift/manifests/stats/accounts.pp
A modules/swift/manifests/stats/stats_container.pp
3 files changed, 145 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/58/240358/1

diff --git a/modules/swift/files/swift-container-stats 
b/modules/swift/files/swift-container-stats
new file mode 100755
index 0000000..fcbbd60
--- /dev/null
+++ b/modules/swift/files/swift-container-stats
@@ -0,0 +1,117 @@
+#!/usr/bin/python
+
+# report swift container statistics, by default on stdout and optionally to
+# a statsd server via UDP.
+
+import argparse
+import os
+import re
+import sys
+
+import swiftclient
+
+try:
+    import statsd
+    statsd_found = True
+except ImportError:
+    statsd_found = False
+
+
+# map a container set name to a dict of:
+#   container_regexp: bucket_name
+# each container matching the given regex will have its stats reported under 
bucket_name
+CONTAINER_SETS = {
+    # MediaWiki containers used for media storage
+    'mw-media': {
+        re.compile('-thumb(\.[a-z0-9][a-z0-9])?$'):      'thumb',
+        re.compile('-public(\.[a-z0-9][a-z0-9])?$'):     'originals',
+        re.compile('-temp(\.[a-z0-9][a-z0-9])?$'):       'temp',
+        re.compile('-deleted(\.[a-z0-9][a-z0-9])?$'):    'deleted',
+        re.compile('-transcoded(\.[a-z0-9][a-z0-9])?$'): 'transcoded',
+        re.compile('-render(\.[a-z0-9][a-z0-9])?$'):     'render',
+    },
+}
+
+
+def container_bucket(name, bucket_map):
+    for container_re, bucket in bucket_map.iteritems():
+        if container_re.search(name):
+            return bucket
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Print swift container 
statistics")
+    parser.add_argument('-A', '--auth', dest='auth',
+        default=os.environ.get('ST_AUTH', None),
+        help='URL for obtaining an auth token')
+    parser.add_argument('-U', '--user', dest='user',
+        default=os.environ.get('ST_USER', None),
+        help='User name for obtaining an auth token')
+    parser.add_argument('-K', '--key', dest='key',
+        default=os.environ.get('ST_KEY', None),
+        help='Key for obtaining an auth token')
+    parser.add_argument('--prefix', dest='prefix',
+        default='',
+        help='Prefix to use when reporting metrics')
+    parser.add_argument('--container-set', dest='container_set',
+        default='', choices=CONTAINER_SETS.keys(),
+        help='Report aggregated container statistics from this set')
+    parser.add_argument('--ignore-unknown', dest='ignore_unknown',
+        default=False, action='store_true',
+        help='Do not report unknown containers')
+    parser.add_argument('--statsd-host', dest='statsd_host',
+        default='', metavar="HOST",
+        help='Send metrics to this statsd host as well')
+    parser.add_argument('--statsd-port', dest='statsd_port',
+        default='8125', metavar="PORT", type=int,
+        help='Send metrics to this statsd port')
+    args = parser.parse_args()
+
+    if None in (args.auth, args.user, args.key):
+        parser.error("please provide auth, user and key")
+        return 1
+
+    if not args.container_set:
+        parser.error("please provide a container set")
+        return 1
+
+    container_stats = {}
+    output_stats = []
+    container_buckets = CONTAINER_SETS[args.container_set]
+
+    connection = swiftclient.Connection(args.auth, args.user, args.key)
+    headers, containers = connection.get_account(full_listing=True)
+    for container in containers:
+        bucket = container_bucket(container['name'], container_buckets)
+        if bucket is None:
+            if not args.ignore_unknown:
+                print >>sys.stderr, "Cannot find bucket for container %r" % 
container['name']
+            continue
+
+        bucket_stats = container_stats.setdefault(
+                           bucket, {'bytes': 0, 'objects': 0})
+        bucket_stats['bytes'] += container['bytes']
+        bucket_stats['objects'] += container['count']
+
+    for bucket, stats in container_stats.iteritems():
+        for stat in ('bytes', 'objects'):
+            prefix = '.'.join([args.prefix, bucket, stat])
+            output_stats.append((prefix, stats[stat]))
+
+    for name, value in output_stats:
+        print "%s: %s" % (name, value)
+
+    if args.statsd_host:
+        if not statsd_found:
+            print >>sys.stderr, "statsd module not found, unable to send"
+            return 1
+        client = statsd.StatsClient(args.statsd_host, args.statsd_port)
+        for name, value in output_stats:
+            try:
+                client.gauge(name, float(value))
+            except ValueError:
+                print >>sys.stderr, "failed to send %r %r" % (name, value)
+
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/modules/swift/manifests/stats/accounts.pp 
b/modules/swift/manifests/stats/accounts.pp
index 7cb8096..59de325 100644
--- a/modules/swift/manifests/stats/accounts.pp
+++ b/modules/swift/manifests/stats/accounts.pp
@@ -21,6 +21,16 @@
         require => $required_packages,
     }
 
+    # report container stats to graphite
+    file { '/usr/local/bin/swift-container-stats':
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0555',
+        source  => 'puppet:///modules/swift/swift-container-stats',
+        require => $required_packages,
+    }
+
     $account_names = sort(keys($accounts))
     swift::stats::stats_account { $account_names:
         accounts      => $accounts,
diff --git a/modules/swift/manifests/stats/stats_container.pp 
b/modules/swift/manifests/stats/stats_container.pp
new file mode 100644
index 0000000..2b667d2
--- /dev/null
+++ b/modules/swift/manifests/stats/stats_container.pp
@@ -0,0 +1,18 @@
+define swift::stats::stats_container (
+    $account_name,
+    $statsd_prefix,
+    $statsd_host,
+) {
+    $account_file = "/etc/swift/account_${account_name}.env"
+    $container_statsd_prefix = "${statsd_prefix}.${account_name}"
+
+    cron { "swift-container-stats_${account_name}":
+        ensure  => present,
+        command => ". ${account_file} && /usr/local/bin/swift-container-stats 
--prefix ${container_statsd_prefix} --statsd-host ${statsd_host} 
--ignore-unknown 1>/dev/null",
+        user    => 'root',
+        hour    => '*',
+        minute  => '*',
+        require => [File[$account_file],
+                    File['/usr/local/bin/swift-container-stats']],
+    }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/240358
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icb7605dbb334ccf225a05ffe54370b33decd090c
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Filippo Giunchedi <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to