├── .gitignore ├── pmond ├── pmond │ ├── __init__.py │ ├── pref_test.py │ ├── test.xml │ ├── metric.py │ ├── gparse.py │ ├── daemon.py │ ├── gweb.py │ └── make_graph001.sh └── setup.py ├── gmond-debug ├── spec │ ├── spec_helper.rb │ └── ganglia_xml_spec.rb ├── .gitignore ├── gems │ └── cache │ │ ├── dante-0.1.3.gem │ │ ├── json-1.6.6.gem │ │ ├── rspec-2.9.0.gem │ │ ├── uuid-2.3.5.gem │ │ ├── diff-lcs-1.1.3.gem │ │ ├── macaddr-1.5.0.gem │ │ ├── nokogiri-1.5.2.gem │ │ ├── systemu-2.5.0.gem │ │ ├── rspec-core-2.9.0.gem │ │ ├── rspec-mocks-2.9.0.gem │ │ ├── eventmachine-0.12.10.gem │ │ └── rspec-expectations-2.9.0.gem ├── .rvmrc ├── source.env ├── lib │ ├── gmond-debug │ │ ├── test_zmq_handler.rb │ │ ├── local_gmond_handler.rb │ │ ├── remote_gmond_handler.rb │ │ ├── gmondpacket2.rb │ │ └── gmondpacket.rb │ └── gmond-debug.rb ├── Gemfile ├── Guardfile ├── Rakefile ├── bin │ └── gmond-debug └── README.md ├── ganglia-logtailer ├── debian │ ├── compat │ ├── README │ ├── docs │ ├── dirs │ ├── README.Debian │ ├── ganglia-logtailer.cron.ex │ ├── copyright │ ├── control │ ├── BUGS │ ├── rules │ └── changelog ├── Makefile ├── ganglia-logtailer.spec ├── src │ ├── ganglia_logtailer_helper.py │ └── tailnostate.py └── README ├── ganglia-go ├── .gitignore ├── readme.md ├── gmetric │ ├── example_test.go │ ├── gmc │ │ └── gmc.go │ └── panicky_writer_test.go ├── gmon │ └── gmon.go └── gmondtest │ └── gmondtest.go ├── varnish_web ├── README.md ├── etc_default_varnish └── default.vcl ├── gmetric-java ├── doc │ ├── package-list │ ├── resources │ │ └── inherit.gif │ ├── info │ │ └── ganglia │ │ │ ├── package-frame.html │ │ │ ├── metric │ │ │ ├── type │ │ │ │ ├── package-frame.html │ │ │ │ └── package-use.html │ │ │ └── package-frame.html │ │ │ ├── package-use.html │ │ │ ├── class-use │ │ │ ├── GMonitor.html │ │ │ └── GConnector.html │ │ │ └── package-tree.html │ ├── stylesheet.css │ ├── overview-frame.html │ ├── index.html │ ├── allclasses-noframe.html │ ├── allclasses-frame.html │ ├── deprecated-list.html │ └── overview-summary.html ├── lib │ └── junit-4.1.jar ├── .classpath └── src │ ├── test │ └── info │ │ └── ganglia │ │ ├── UnitTestHelper.java │ │ └── GMetricTest.java │ └── java │ └── info │ └── ganglia │ ├── metric │ ├── Incrementable.java │ ├── Metricable.java │ └── type │ │ ├── GMetricString.java │ │ ├── GMetricInteger.java │ │ ├── GMetricFloat.java │ │ └── GMetricDouble.java │ └── GConnector.java ├── ganglia_ramdisk ├── gmetad_checkpoint_ramdisk.cron ├── README ├── gmetad_checkpoint_ramdisk.sh └── gmetad_checkpoint_ramdisk.init ├── graphite_integration ├── README.textfile ├── ganglia_graphite.rb └── ganglia_graphite_2.rb ├── nagios └── README.rst ├── docker ├── gmond-aggregator │ ├── entrypoint.sh │ ├── Dockerfile │ └── gmond.conf ├── gmetad-gangliaweb │ ├── config │ │ ├── graphite_install.sh │ │ ├── local_settings.py │ │ └── graphite_apache.conf │ └── Dockerfile └── README.md ├── commandline-eventlogger ├── README └── ganglialog.py ├── nagios_stats └── README.txt ├── gmetad_health_checker ├── README └── gmetadXmlChecker.py ├── README ├── ganglia-alert ├── init.d-redhat └── init.d-debian ├── gang2graph ├── README ├── gang2graph.pl └── Ganglia │ └── GraphiteSender.pm └── gmetric-python └── README /.gitignore: -------------------------------------------------------------------------------- 1 | .*.sw* 2 | -------------------------------------------------------------------------------- /pmond/pmond/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gmond-debug/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/README: -------------------------------------------------------------------------------- 1 | See ../README -------------------------------------------------------------------------------- /ganglia-go/.gitignore: -------------------------------------------------------------------------------- 1 | cover.out 2 | gmetric.test 3 | gmon.test 4 | -------------------------------------------------------------------------------- /varnish_web/README.md: -------------------------------------------------------------------------------- 1 | This is Varnish VCL to improve the performance of your Ganglia Web 2 | -------------------------------------------------------------------------------- /gmond-debug/.gitignore: -------------------------------------------------------------------------------- 1 | Gemfile.lock 2 | gems/bin/* 3 | gems/gems/* 4 | gems/specifications/* 5 | -------------------------------------------------------------------------------- /gmetric-java/doc/package-list: -------------------------------------------------------------------------------- 1 | info.ganglia 2 | info.ganglia.metric 3 | info.ganglia.metric.type 4 | -------------------------------------------------------------------------------- /ganglia_ramdisk/gmetad_checkpoint_ramdisk.cron: -------------------------------------------------------------------------------- 1 | 12 * * * * root /usr/local/sbin/gmetad_checkpoint_ramdisk.sh 2 | -------------------------------------------------------------------------------- /gmetric-java/lib/junit-4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmetric-java/lib/junit-4.1.jar -------------------------------------------------------------------------------- /ganglia-logtailer/debian/docs: -------------------------------------------------------------------------------- 1 | debian/BUGS 2 | debian/README 3 | debian/README.Debian 4 | debian/ganglia-logtailer.cron.ex 5 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | usr/share/ganglia-logtailer 3 | var/lib/ganglia-logtailer 4 | var/log/ganglia-logtailer 5 | 6 | -------------------------------------------------------------------------------- /gmetric-java/doc/resources/inherit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmetric-java/doc/resources/inherit.gif -------------------------------------------------------------------------------- /gmond-debug/gems/cache/dante-0.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/dante-0.1.3.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/json-1.6.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/json-1.6.6.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/rspec-2.9.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/rspec-2.9.0.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/uuid-2.3.5.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/uuid-2.3.5.gem -------------------------------------------------------------------------------- /gmond-debug/.rvmrc: -------------------------------------------------------------------------------- 1 | #this uses rvm 2 | #rvm use jruby 3 | rvm use 1.8.7 4 | rvm_gemset_create_on_use_flag=1 5 | rvm gemset use gmon-ruby 6 | -------------------------------------------------------------------------------- /gmond-debug/gems/cache/diff-lcs-1.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/diff-lcs-1.1.3.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/macaddr-1.5.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/macaddr-1.5.0.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/nokogiri-1.5.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/nokogiri-1.5.2.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/systemu-2.5.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/systemu-2.5.0.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/rspec-core-2.9.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/rspec-core-2.9.0.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/rspec-mocks-2.9.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/rspec-mocks-2.9.0.gem -------------------------------------------------------------------------------- /gmond-debug/source.env: -------------------------------------------------------------------------------- 1 | export GEM_PATH=`pwd`/gems 2 | export GEM_HOME=`pwd`/gems 3 | export PATH=$GEM_HOME/bin:$PATH 4 | export RUBYLIB=`pwd`/lib 5 | -------------------------------------------------------------------------------- /gmond-debug/gems/cache/eventmachine-0.12.10.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/eventmachine-0.12.10.gem -------------------------------------------------------------------------------- /gmond-debug/gems/cache/rspec-expectations-2.9.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganglia/ganglia_contrib/master/gmond-debug/gems/cache/rspec-expectations-2.9.0.gem -------------------------------------------------------------------------------- /graphite_integration/README.textfile: -------------------------------------------------------------------------------- 1 | More details on Ganglia Graphite integration please read. 2 | 3 | http://blog.vuksan.com/monitoring/2010/09/29/integrating-graphite-with-ganglia/ 4 | -------------------------------------------------------------------------------- /gmond-debug/spec/ganglia_xml_spec.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require 'tempfile' 3 | 4 | describe "GangliaXML" do 5 | 6 | before(:each) do 7 | end 8 | 9 | after(:each) do 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /ganglia-go/readme.md: -------------------------------------------------------------------------------- 1 | go.ganglia 2 | ========== 3 | 4 | gmetric: http://godoc.org/github.com/ganglia/ganglia_contrib/ganglia-go/gmetric 5 | 6 | gmon: http://godoc.org/github.com/ganglia/ganglia_contrib/ganglia-go/gmon 7 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug/test_zmq_handler.rb: -------------------------------------------------------------------------------- 1 | class TestZmqHandler 2 | attr_reader :received 3 | def on_readable(socket, messages) 4 | messages[1..-1].each do |m| 5 | puts m.copy_out_string 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /nagios/README.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | check_ganglia_metric 3 | ==================== 4 | 5 | `check_ganglia_metric `_ is 6 | a Nagios plugin that allows you to trigger alerts on any Ganglia metric. 7 | -------------------------------------------------------------------------------- /gmond-debug/Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | #gem 'em-zeromq', '0.2.2' 4 | gem 'nokogiri' 5 | gem 'dante' 6 | gem 'json' 7 | gem 'uuid' 8 | 9 | group :development do 10 | gem "warbler" 11 | gem "rake" 12 | gem "rspec" 13 | end 14 | -------------------------------------------------------------------------------- /pmond/pmond/pref_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import psyco 4 | psyco.full() 5 | 6 | from gmetric import Gmetric 7 | 8 | if __name__ == '__main__': 9 | g = Gmetric('localhost', 4001, 'udp') 10 | for i in xrange(100000): 11 | g.send('foo', 'bar') 12 | -------------------------------------------------------------------------------- /varnish_web/etc_default_varnish: -------------------------------------------------------------------------------- 1 | START=yes 2 | NFILES=131072 3 | MEMLOCK=82000 4 | INSTANCE=$(uname -n) 5 | DAEMON_OPTS="-a :6081 \ 6 | -T localhost:6082 \ 7 | -f /etc/varnish/default.vcl \ 8 | -S /etc/varnish/secret \ 9 | -s malloc,1G" 10 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/README.Debian: -------------------------------------------------------------------------------- 1 | For the debian package, ganglia_logtailer_helper.pyc and tailnostate.py are 2 | stored in /usr/share/ganglia-logtailer, along with all base plugins that ship 3 | with ganglia-logtailer. Plugins you create should be put in 4 | /usr/local/share/ganglia-logtailer/. 5 | -------------------------------------------------------------------------------- /docker/gmond-aggregator/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if [ $# -gt 0 ]; then 4 | GANGLIA_CLUSTER=${1} 5 | else 6 | GANGLIA_CLUSTER="cluster1" 7 | fi 8 | 9 | sed "s/GANGLIA_CLUSTER/$GANGLIA_CLUSTER/g" /etc/ganglia/gmond-template.conf > /etc/ganglia/gmond.conf 10 | 11 | /usr/sbin/gmond -f -d1 -------------------------------------------------------------------------------- /commandline-eventlogger/README: -------------------------------------------------------------------------------- 1 | This is a simple script that adds events to Ganglia. We have it installed on 2 | all hosts and whenever we do something we'll log it e.g. 3 | 4 | ganglialog set sysctl xxx = 1000 5 | 6 | This will show up on a graph for that host. 7 | 8 | Keep you messages short and avoid using special characters. I'd stick with 9 | -,.= 10 | -------------------------------------------------------------------------------- /gmetric-java/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/ganglia-logtailer.cron.ex: -------------------------------------------------------------------------------- 1 | # This example cron job gathers metrics using DummyLogtailer every 5 minutes and 2 | # submits them to gmetric. DummyLogtailer is an example plugin that just counts 3 | # the number of lines logged per second. 4 | 5 | */5 * * * * root /usr/bin/ganglia-logtailer --classname DummyLogtailer --log-file /var/log/mail.log --mode cron 6 | 7 | -------------------------------------------------------------------------------- /pmond/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | 5 | setup(name='pmond', 6 | version='1.0', 7 | description='gmond compatible metrics collector/emitter', 8 | author='Nick Galbreath', 9 | author_email='nickg@modp.com', 10 | url='http://code.google.com/p/embeddedgmetric/', 11 | packages = ['pmond'] 12 | ) 13 | -------------------------------------------------------------------------------- /gmond-debug/Guardfile: -------------------------------------------------------------------------------- 1 | guard :rspec, :version => 2, :cli => "--color --format documentation" do 2 | watch(%r{spec/.+_spec\.rb$}) 3 | watch(%r{^lib/(.+)\.rb$}) { "spec" } 4 | #watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 5 | watch(%r{spec/spec_helper\.rb$}) { "spec" } 6 | end 7 | 8 | guard :cucumber, :cli => "-s" do 9 | watch(%r{lib/(.+)\.rb$}) { "features" } 10 | end 11 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | #require 'em-zeromq' 3 | require 'eventmachine' 4 | require 'dante' 5 | require 'socket' 6 | require 'pp' 7 | require 'nokogiri' 8 | require 'json' 9 | require 'uuid' 10 | # requires yum install libxml2-devel 11 | # requires yum install libxslt-devel 12 | 13 | require 'gmond-debug/local_gmond_handler' 14 | require 'gmond-debug/remote_gmond_handler' 15 | require 'gmond-debug/test_zmq_handler' 16 | -------------------------------------------------------------------------------- /ganglia_ramdisk/README: -------------------------------------------------------------------------------- 1 | Ganglia ramdisk is a collection of a cronjob and a start script that help you 2 | set up the gmetad rrds repository on a ramdisk intsead of using physical disk. 3 | This helps as your cluster grows. Missing is grub.conf, which should be 4 | modified to specify the size of the ramdisk you wish to create. Also missing is 5 | switching /var/lib/ganglia/rrds (or wherever your default storage is) to a 6 | symlink and pointing it to the ramdisk. 7 | 8 | -------------------------------------------------------------------------------- /docker/gmetad-gangliaweb/config/graphite_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="/config" 4 | graphite_user="_graphite" 5 | 6 | cp $DIR/local_settings.py /etc/graphite/local_settings.py 7 | 8 | cp $DIR/initial_data.json /usr/share/graphite-web/initial_data.json 9 | 10 | if [ ! -f /var/lib/graphite/graphite.db ] 11 | then 12 | 13 | cd /usr/share/graphite-web 14 | graphite-manage syncdb --noinput 15 | 16 | fi 17 | 18 | chown -R $graphite_user /var/lib/graphite -------------------------------------------------------------------------------- /nagios_stats/README.txt: -------------------------------------------------------------------------------- 1 | Ganglia statistics for nagios 2 | 3 | This script should be called from cron once per minute. It queries nagios for statistics about its process (eg number of checks, average check delay, number of warning / critical problems, etc.) and reports them to ganglia every 15 seconds. 4 | 5 | Note that this is not a script to check ganglia metrics from nagios; for that go to https://github.com/ganglia/monitor-core/wiki/Integrating-Ganglia-with-Nagios 6 | 7 | -------------------------------------------------------------------------------- /gmond-debug/Rakefile: -------------------------------------------------------------------------------- 1 | #require 'warbler' 2 | #Warbler::Task.new 3 | 4 | require 'rake' 5 | require 'rspec/core/rake_task' 6 | 7 | desc 'Default: run specs' 8 | task :default => :spec 9 | 10 | 11 | desc 'Specs' 12 | RSpec::Core::RakeTask.new(:spec) do |t| 13 | t.pattern = './spec/**/*_spec.rb' # don't need this, it's default 14 | t.verbose = true 15 | #t.rspec_opts = "--format documentation --color" 16 | # Put spec opts in a file named .rspec in root 17 | end 18 | -------------------------------------------------------------------------------- /gmetad_health_checker/README: -------------------------------------------------------------------------------- 1 | This script will look for any gmetad.conf files in /etc/gmetad. It will then grab the xml_port, and attempt to connect to each port. 2 | It will grab the first 512 bytes of data. If it retrieves no data, or cannot connect it will then restart gmetad (with -r flag) 3 | 4 | Things to do: 5 | 6 | - Have it restart only the instance that is down 7 | -Have it verify xml tag in the data to verify it is xml 8 | 9 | Email any questions to jim.greene@gmail.com 10 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Lex Linden on 2 | Wed, 21 Oct 2009 15:02:51 -0400. 3 | 4 | Copyright: 5 | 6 | Copyright (C) 2008 Linden Lab 7 | 8 | License: 9 | Released under the GPL v2 or later. 10 | For a full description of the license, please examine: 11 | /usr/share/common-licenses/GPL-2 12 | 13 | 14 | The Debian packaging is: 15 | 16 | Copyright (C) 2009 Linden Lab 17 | 18 | and is licensed under the GPL v2 or later. 19 | 20 | 21 | -------------------------------------------------------------------------------- /docker/gmond-aggregator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie 2 | 3 | MAINTAINER Vladimir Vuksan 4 | 5 | RUN apt-get update 6 | RUN apt-get upgrade -y 7 | 8 | # Install gmond aka ganglia-monitor 9 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y ganglia-monitor 10 | 11 | EXPOSE 8649 12 | 13 | # Copy gmond.conf from the current Dockerfile directory to /etc/ganglia/gmond-template.conf 14 | ADD gmond.conf /etc/ganglia/gmond-template.conf 15 | ADD entrypoint.sh /entrypoint.sh 16 | 17 | # Command to execute when container starts up 18 | ENTRYPOINT ["/entrypoint.sh"] 19 | CMD ["test-cluster"] 20 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the official repository for hosting all other user-contributed tools and programs. 2 | 3 | To have your programs added here, please fork the repository, create separate sub-directories for each program 4 | and submit a pull request. 5 | 6 | If you have any questions, you could reach us at: 7 | 8 | ganglia-developers@lists.sourceforge.net 9 | 10 | (subscription required: http://lists.sourceforge.net/lists/listinfo/ganglia-developers) 11 | 12 | Alternatively, you could join our IRC channel on irc.freenode.net #ganglia and 13 | ping one of the developers. 14 | 15 | Thank you for your contribution! 16 | 17 | -- Ganglia Development Team 18 | -------------------------------------------------------------------------------- /docker/gmond-aggregator/gmond.conf: -------------------------------------------------------------------------------- 1 | globals { 2 | daemonize = no 3 | setuid = no 4 | user = ganglia 5 | debug_level = 0 6 | max_udp_msg_len = 1472 7 | mute = yes 8 | deaf = no 9 | host_dmax = 86400 /* How long to keep dead hosts around in seconds */ 10 | cleanup_threshold = 300 /*secs */ 11 | gexec = no 12 | send_metadata_interval = 60 13 | } 14 | 15 | cluster { 16 | name = "GANGLIA_CLUSTER" 17 | owner = "unspecified" 18 | latlong = "unspecified" 19 | url = "unspecified" 20 | } 21 | 22 | host { 23 | location = "unspecified" 24 | } 25 | 26 | /* You can specify as many udp_recv_channels as you like as well. */ 27 | udp_recv_channel { 28 | port = 8649 29 | } 30 | 31 | /* You can specify as many tcp_accept_channels as you like to share 32 | an xml description of the state of the cluster */ 33 | tcp_accept_channel { 34 | port = 8649 35 | } 36 | -------------------------------------------------------------------------------- /docker/gmetad-gangliaweb/config/local_settings.py: -------------------------------------------------------------------------------- 1 | SECRET_KEY = 'Akjdjwdgferoiuhfreuotiu5fgreuhguhkjhkjfh' 2 | LOG_RENDERING_PERFORMANCE = True 3 | LOG_CACHE_PERFORMANCE = True 4 | LOG_METRIC_ACCESS = True 5 | FLUSHRRDCACHED = 'unix:/tmp/rrdcached.limited.sock' 6 | GRAPHITE_ROOT = '/usr/share/graphite-web' 7 | CONF_DIR = '/etc/graphite' 8 | STORAGE_DIR = '/var/lib/graphite/whisper' 9 | CONTENT_DIR = '/usr/share/graphite-web/static' 10 | RRD_DIR = '/var/lib/ganglia/rrds' 11 | DATA_DIRS = [RRD_DIR] # Default: set from the above variables 12 | LOG_DIR = '/var/log/graphite' 13 | INDEX_FILE = '/var/lib/graphite/search_index' # Search index file 14 | DATABASES = { 15 | 'default': { 16 | 'NAME': '/var/lib/graphite/graphite.db', 17 | 'ENGINE': 'django.db.backends.sqlite3', 18 | 'USER': '', 19 | 'PASSWORD': '', 20 | 'HOST': '', 21 | 'PORT': '' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ganglia_ramdisk/gmetad_checkpoint_ramdisk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH=/bin:$PATH 3 | 4 | # clean up old backups 5 | #find /var/lib/ganglia/ -name "rrds.bak_*" -mtime +7 -prune -exec rm -rf {} \; 6 | # lets test this with an ls, shall we? :) 7 | #find /var/lib/ganglia/ -name "rrds.bak_*" -mtime +7 -prune -exec ls -ld {} \; -exec rm -rf {} \; 8 | # ok, the test passed and it looks good. Delete silently. 9 | #find /var/lib/ganglia/ -name "rrds.bak_*" -mtime +7 -prune -exec rm -rf {} \; 10 | 11 | # find was taking too much disk effort. Switched to rm. 12 | # Note - if this machine is off across one of the cron times, it will 13 | # never delete the directories from 8 days previous. Check every now and again. 14 | olddate=$(date -d'8 days ago' +%Y%m%d.%H) 15 | rm -rf /var/lib/ganglia/rrds.bak_${olddate}???? 16 | 17 | 18 | mydate=`date +%Y%m%d.%H%M%S` 19 | nice -n 5 cp -a --no-preserve=timestamps /mnt/ram0/rrds /var/lib/ganglia/rrds.bak_${mydate} 20 | -------------------------------------------------------------------------------- /pmond/pmond/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ganglia-alert/init.d-redhat: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # chkconfig: 2345 92 8 3 | # 4 | # pbsmom: This script will start and stop the PBS mom 5 | # description: PBS is a batch versitle batch system for SMPs and clusters 6 | 7 | . /etc/init.d/functions 8 | 9 | DAEMON=ganglia-alert 10 | 11 | case "$1" in 12 | start) 13 | echo -n "Starting ganglia-alert: " 14 | daemon $DAEMON -d 15 | RETVAL=$? 16 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$DAEMON || RETVAL=1 17 | echo 18 | ;; 19 | stop) 20 | echo -n "Stopping ganglia-alert: " 21 | killproc $DAEMON 22 | RETVAL=$? 23 | [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$DAEMON 24 | echo 25 | ;; 26 | status) 27 | status $DAEMON 28 | RETVAL=$? 29 | ;; 30 | report) 31 | $DAEMON -r 32 | RETVAL=$? 33 | ;; 34 | restart) 35 | echo "Restarting ganglia-lert: " 36 | $0 stop 37 | $0 start 38 | ;; 39 | *) 40 | echo "Usage: $0 {start|stop|status|restart}" 41 | exit 1 42 | esac 43 | 44 | exit $RETVAL 45 | -------------------------------------------------------------------------------- /ganglia_ramdisk/gmetad_checkpoint_ramdisk.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # script to setup ramdisk for ganglia 4 | # 5 | # chkconfig: 2345 19 01 6 | # description: sets up ramdisk for gmetad 7 | 8 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH 9 | . /etc/rc.d/init.d/functions 10 | 11 | case "$1" in 12 | start) 13 | echo -n "Initializing ramdisk for ganglia: " 14 | 15 | # Formats, mounts, and sets permissions on my 16MB ramdisk 16 | mke2fs -q -m 0 /dev/ram0 17 | mount /dev/ram0 /mnt/ram0 18 | cp -a /var/lib/ganglia/rrds.checkpoint /mnt/ram0/rrds 19 | mydate=`date +%Y%m%d.%H%M%S` 20 | mv /var/lib/ganglia/rrds.checkpoint{,.$mydate} 21 | 22 | echo 23 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/gmetad_ramdisk 24 | ;; 25 | 26 | stop) 27 | echo -n "Checkpointing RAMDISK to real disk: " 28 | cp -a /mnt/ram0/rrds /var/lib/ganglia/rrds.checkpoint 29 | RETVAL=$? 30 | echo 31 | [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/gmetad_ramdisk 32 | ;; 33 | 34 | 35 | *) 36 | echo "Usage: $0 {start|stop)" 37 | exit 1 38 | esac 39 | 40 | exit ${RETVAL:-0} 41 | -------------------------------------------------------------------------------- /docker/gmetad-gangliaweb/config/graphite_apache.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerName graphite.internal 4 | 5 | # Set these headers so we can use it with e.g. Grafana 6 | Header set Access-Control-Allow-Origin "*" 7 | Header set Access-Control-Allow-Methods "GET, OPTIONS" 8 | Header set Access-Control-Allow-Headers "origin, authorization, accept" 9 | WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user=_graphite group=_graphite 10 | WSGIProcessGroup _graphite 11 | WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group=_graphite application-group=%{GLOBAL} 12 | WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi 13 | 14 | Alias /content/ /usr/share/graphite-web/static/ 15 | 16 | SetHandler None 17 | 18 | 19 | ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log 20 | 21 | # Possible values include: debug, info, notice, warn, error, crit, 22 | # alert, emerg. 23 | LogLevel warn 24 | 25 | CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined 26 | 27 | 28 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | info.ganglia 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | info.ganglia 20 | 21 | 22 | 29 | 30 |
23 | Classes  24 | 25 |
26 | GConnector 27 |
28 | GMonitor
31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ganglia-logtailer/Makefile: -------------------------------------------------------------------------------- 1 | SRCDIR=src 2 | 3 | SCRIPTS=${SRCDIR}/ganglia-logtailer 4 | 5 | MODULES=`ls ${SRCDIR}/*.py` 6 | 7 | all: 8 | @echo "======================= WAIT ========================" 9 | @echo "You need to supply a target. Available targets are" 10 | @echo "make (install|deb|source-deb|debclean)" 11 | @echo "Files will be installed in ${DESTDIR}" 12 | @echo "To override type make DESTDIR=/opt install" 13 | @echo "=====================================================" 14 | 15 | install: 16 | install -d ${DESTDIR}/var/lib/ganglia-logtailer 17 | install -d ${DESTDIR}/var/log/ganglia-logtailer 18 | 19 | install -d ${DESTDIR}/usr/sbin 20 | install -m 0755 ${SCRIPTS} ${DESTDIR}/usr/sbin 21 | 22 | install -d ${DESTDIR}/usr/share/ganglia-logtailer 23 | install -m 0644 ${MODULES} ${DESTDIR}/usr/share/ganglia-logtailer 24 | 25 | clean: 26 | -rm -f ganglia-logtailer.tar.gz 27 | 28 | deb: 29 | debuild -uc -us -i -b 30 | 31 | source-deb: 32 | debuild -uc -us -i -S 33 | 34 | debclean: 35 | debuild clean 36 | 37 | dist: 38 | hg archive -t tgz ganglia-logtailer.tar.gz 39 | 40 | source-rpm: dist 41 | rpmbuild -ts ganglia-logtailer.tar.gz 42 | 43 | rpm: dist 44 | rpmbuild -tb ganglia-logtailer.tar.gz 45 | 46 | -------------------------------------------------------------------------------- /gmetric-java/src/test/info/ganglia/UnitTestHelper.java: -------------------------------------------------------------------------------- 1 | package info.ganglia; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | 6 | public class UnitTestHelper { 7 | 8 | @SuppressWarnings("unchecked") 9 | public static Object invokeMethod(Object targetObject, String methodName, Class[] argClasses, Object[] argObjects) { 10 | Object result = null; 11 | try { 12 | Method method = targetObject.getClass().getDeclaredMethod(methodName, argClasses); 13 | // this makes private methods accessible 14 | method.setAccessible(true); 15 | result = method.invoke(targetObject, argObjects); 16 | 17 | } catch (Exception e) { 18 | e.printStackTrace(); 19 | } 20 | return result; 21 | } 22 | 23 | @SuppressWarnings("unchecked") 24 | public static Object invokeMethod(Class targetClass, Object targetObject, String methodName, Class[] argClasses, Object[] argObjects) { 25 | Object result = null; 26 | try { 27 | Method method = targetClass.getDeclaredMethod(methodName, argClasses); 28 | // this makes private methods accessible 29 | method.setAccessible(true); 30 | result = method.invoke(targetObject, argObjects); 31 | 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gang2graph/README: -------------------------------------------------------------------------------- 1 | 2011-10-25 Drew Stephens 2 | Copyright 2011, Clearspring, Inc. 3 | 4 | This is free software; you can redistribute it and/or modify it under 5 | the same terms as the Perl 5 programming language system itself. 6 | 7 | USAGE 8 | 9 | This pulls the XML file from gmetad (localhost:8651 by default) and pumps 10 | it into Graphite (localhost:2023 the carbon-aggregator port by default). 11 | 12 | I run it as a minutely cronjob: 13 | 14 | * * * * * root cd /home/web/gang2graph; perl gang2graph.pl 15 | 16 | With 160 hosts and 38,000 metrics the elapsed time is less than 3 seconds 17 | on a 4100 series AMD Opteron, but it is hobbled by Graphite's disk writing. 18 | For this reason, gang2graph support specify a set of hosts to send to 19 | Graphite, ignoring the rest. Simply set the $host variable in gang2graph.pl 20 | to a set of hosts to copy and only those will be copied. The checking is a 21 | regex, so subsets of hostnames works. To copy metrics from this set of hosts: 22 | 23 | apb00.clearspring.com 24 | apb01.clearspring.com 25 | apw00.clearspring.com 26 | apw01.clearspring.com 27 | 28 | but exclude apm*, adm*, etc. I use this $hosts: 29 | 30 | ['apb', 'apw'] 31 | 32 | Feel free to email me with questions. 33 | -------------------------------------------------------------------------------- /gmetric-java/doc/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Javadoc style sheet */ 2 | 3 | /* Define colors, fonts and other style attributes here to override the defaults */ 4 | 5 | /* Page background color */ 6 | body { background-color: #FFFFFF } 7 | 8 | /* Headings */ 9 | h1 { font-size: 145% } 10 | 11 | /* Table colors */ 12 | .TableHeadingColor { background: #CCCCFF } /* Dark mauve */ 13 | .TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ 14 | .TableRowColor { background: #FFFFFF } /* White */ 15 | 16 | /* Font used in left-hand frame lists */ 17 | .FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } 18 | .FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } 19 | .FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } 20 | 21 | /* Navigation bar fonts and colors */ 22 | .NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ 23 | .NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ 24 | .NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} 25 | .NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} 26 | 27 | .NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} 28 | .NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} 29 | 30 | -------------------------------------------------------------------------------- /gmetric-python/README: -------------------------------------------------------------------------------- 1 | This is a modified version of embedded gmetric written in Python. It has been modified from 2 | 3 | http://code.google.com/p/embeddedgmetric/ 4 | 5 | Main changes are 6 | 7 | - Support for Ganglia 3.1 8 | - Ability to specify metric group which gets grouped in the Ganglia Web UI. 9 | 10 | 11 | Latest version can also be used inside your own Python code with optionally 12 | reading system's gmond.conf e.g. 13 | 14 | ========= CODE ========== 15 | 16 | from gmetric import get_gmetrics 17 | 18 | # Parse the config file to get all gmetric channels 19 | gmetrics = get_gmetrics('/etc/ganglia/gmond.conf') 20 | spoof = "%s:%s" % (hostname, hostname) 21 | 22 | Then you can do thins like these 23 | 24 | for gmetric in gmetrics: 25 | gmetric.send('uptime', uptime, 26 | TYPE='float', UNITS='seconds', SPOOF=spoof, 27 | GROUP='mydaemon', DMAX=20) 28 | gmetric.send('some_count', upstreamCount, 29 | TYPE='float', SPOOF=spoof, UNITS='count', 30 | GROUP='mydaemon', DMAX=3600) 31 | 32 | 33 | Acknowledgements: 34 | 35 | Thanks to Ilya Grigorik for posting Ruby Gmetric 36 | 37 | https://github.com/igrigorik/gmetric 38 | 39 | It was much easier to figure out proper XDR packet packing in his code than looking through the C code 40 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/control: -------------------------------------------------------------------------------- 1 | Source: ganglia-logtailer 2 | Section: admin 3 | Priority: optional 4 | Maintainer: Lex Linden 5 | Build-Depends: debhelper (>= 5), python-support 6 | Standards-Version: 3.7.2 7 | 8 | Package: ganglia-logtailer 9 | Architecture: any 10 | Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.4), logtail, ganglia-monitor | ganglia 11 | Description: framework to crunch data from logfiles and send using gmetric 12 | Many metrics associated with ganglia and gmetric plugins are rather easy to 13 | collect; you poll the relevant application for a value and report it. Examples 14 | are asking MySQL for the number of questions and calculating queries per 15 | second, or asking iostat for the percentage disk I/O currently being used. 16 | However, there are a large number of applications out there that don't support 17 | being queried for interesting data, but do provide a log file which, when 18 | properly parsed, yields the interesting data we desire. An example of the 19 | latter category is Apache, which does not furnish any interface for measuring 20 | queries per second, yet has a log file allowing you to count how many queries 21 | come in over a specific time period. 22 | . 23 | ganglia-logtailer is designed to make it easy to parse any log file, pull out 24 | the information you desire, and plug it into ganglia to make pretty graphs. 25 | -------------------------------------------------------------------------------- /gmetric-java/doc/overview-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Overview 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 |
22 |
25 | 26 | 27 | 28 | 40 | 41 |
All Classes 29 |

30 | 31 | Packages 32 |
33 | info.ganglia 34 |
35 | info.ganglia.metric 36 |
37 | info.ganglia.metric.type 38 |
39 |

42 | 43 |

44 |   45 | 46 | 47 | -------------------------------------------------------------------------------- /ganglia-go/gmetric/example_test.go: -------------------------------------------------------------------------------- 1 | package gmetric_test 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "time" 8 | 9 | "github.com/ganglia/ganglia_contrib/ganglia-go/gmetric" 10 | ) 11 | 12 | func Example() { 13 | // A Client can connect to multiple addresses. 14 | client := &gmetric.Client{ 15 | Addr: []net.Addr{ 16 | &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8649}, 17 | }, 18 | } 19 | 20 | // You only need to Open the connections once on application startup. 21 | if err := client.Open(); err != nil { 22 | fmt.Println(err) 23 | os.Exit(1) 24 | } 25 | 26 | // Defines the Metric. 27 | metric := &gmetric.Metric{ 28 | Name: "web_requests", 29 | Title: "Number of Web Requests", 30 | Host: "web0.app.com", 31 | ValueType: gmetric.ValueUint32, 32 | Units: "count", 33 | Slope: gmetric.SlopeBoth, 34 | TickInterval: 20 * time.Second, 35 | Lifetime: 24 * time.Hour, 36 | } 37 | 38 | // Meta packets only need to be sent every `send_metadata_interval` as 39 | // configured in gmond.conf. 40 | if err := client.WriteMeta(metric); err != nil { 41 | fmt.Println(err) 42 | os.Exit(1) 43 | } 44 | 45 | if err := client.WriteValue(metric, 1); err != nil { 46 | fmt.Println(err) 47 | os.Exit(1) 48 | } 49 | 50 | // Close the connections before terminating your application. 51 | if err := client.Close(); err != nil { 52 | fmt.Println(err) 53 | os.Exit(1) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/metric/type/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | info.ganglia.metric.type 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | info.ganglia.metric.type 20 | 21 | 22 | 33 | 34 |
23 | Classes  24 | 25 |
26 | GMetricDouble 27 |
28 | GMetricFloat 29 |
30 | GMetricInteger 31 |
32 | GMetricString
35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /commandline-eventlogger/ganglialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import syslog 5 | import os 6 | import urllib 7 | import urllib2 8 | import base64 9 | 10 | ######################################################################## 11 | # Make sure you change base Ganglia URL 12 | ######################################################################## 13 | ganglia_events_url = "<%= @ganglia_base_url %>/api/events.php" 14 | 15 | # Optionally set user name and password 16 | #username = "<%= @username %>" 17 | #password = "<%= @password %>" 18 | 19 | if (len(sys.argv) == 1): 20 | print "\nPlease supply a log message. It can be any number of arguments. Exiting....\n" 21 | exit(1) 22 | 23 | for index in range(1,len(sys.argv)): 24 | print sys.argv[index] 25 | 26 | # Log to syslog 27 | syslog.syslog(" ".join(sys.argv)) 28 | 29 | # Remove first argument and join the list of arguments so it can be sent 30 | summary = " ".join(sys.argv[1:]) 31 | 32 | # Get hostname 33 | uname=os.uname() 34 | hostname=uname[1] 35 | 36 | params = urllib.urlencode({'action': 'add', 'start_time': 'now', 37 | 'host_regex': hostname, 'summary': summary}) 38 | 39 | request = urllib2.Request(ganglia_events_url+ "?%s" % params) 40 | 41 | if 'username' in locals(): 42 | base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') 43 | request.add_header("Authorization", "Basic %s" % base64string) 44 | 45 | f = urllib2.urlopen(request) 46 | 47 | print f.read() -------------------------------------------------------------------------------- /gmetric-java/doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Generated Documentation (Untitled) 8 | 9 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | <H2> 29 | Frame Alert</H2> 30 | 31 | <P> 32 | This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. 33 | <BR> 34 | Link to<A HREF="overview-summary.html">Non-frame version.</A> 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/metric/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | info.ganglia.metric 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | info.ganglia.metric 20 | 21 | 22 | 29 | 30 |
23 | Interfaces  24 | 25 |
26 | Incrementable 27 |
28 | Metricable
31 | 32 | 33 | 34 | 35 | 40 | 41 |
36 | Classes  37 | 38 |
39 | GMetric
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/Incrementable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric; 25 | 26 | /** 27 | * Interface for all Metrics which need to increment their value by one 28 | * 29 | * @author Chris Bowling 30 | */ 31 | public interface Incrementable { 32 | 33 | /** 34 | * Increments the GMetric value by one 35 | */ 36 | public void incrementValue(); 37 | } 38 | -------------------------------------------------------------------------------- /gmetric-java/doc/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | All Classes 19 |
20 | 21 | 22 | 23 | 42 | 43 |
GConnector 24 |
25 | GMetric 26 |
27 | GMetricDouble 28 |
29 | GMetricFloat 30 |
31 | GMetricInteger 32 |
33 | GMetricString 34 |
35 | GMonitor 36 |
37 | Incrementable 38 |
39 | Metricable 40 |
41 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/Metricable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric; 25 | 26 | /** 27 | * Interface for all Metrics 28 | * 29 | * @author Chris Bowling 30 | */ 31 | public interface Metricable { 32 | 33 | /** 34 | * Fetches current GMetric value 35 | * @return 36 | */ 37 | public byte[] getValueData(); 38 | /** 39 | * Fetches GMetric metadata 40 | * @return 41 | */ 42 | public byte[] getMetaData(); 43 | /** 44 | * Clears GMetric value 45 | */ 46 | public void clearValue(); 47 | /** 48 | * @return the additive 49 | */ 50 | public boolean isAdditive(); 51 | } 52 | -------------------------------------------------------------------------------- /pmond/pmond/metric.py: -------------------------------------------------------------------------------- 1 | # This is the MIT License 2 | # http://www.opensource.org/licenses/mit-license.php 3 | # 4 | # Copyright (c) 2007,2008 Nick Galbreath 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | import traceback 26 | import sys 27 | 28 | class metric(object): 29 | def __init__(self): 30 | self.tree = None 31 | 32 | def addMetric(self, values): 33 | self.tree.addMetric(values) 34 | 35 | def register(self, s, tree): 36 | if self.tree is None: 37 | self.tree = tree 38 | 39 | self.gather(tree) 40 | s.enter(self.interval(), 1, self.register, [s, tree]) 41 | 42 | def startup(self): 43 | pass 44 | 45 | def interval(self): 46 | return 15 47 | 48 | def gather(self): 49 | pass 50 | 51 | def shutdown(self): 52 | pass 53 | 54 | -------------------------------------------------------------------------------- /gmetric-java/doc/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | All Classes 19 |
20 | 21 | 22 | 23 | 42 | 43 |
GConnector 24 |
25 | GMetric 26 |
27 | GMetricDouble 28 |
29 | GMetricFloat 30 |
31 | GMetricInteger 32 |
33 | GMetricString 34 |
35 | GMonitor 36 |
37 | Incrementable 38 |
39 | Metricable 40 |
41 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/BUGS: -------------------------------------------------------------------------------- 1 | Known Bugs 2 | 3 | ** first run can be too expensive ** 4 | 5 | The logtail upon which ganglia-logtailer relies reads in the entire file if no 6 | statefile exists. This occurs when you run ganglia-logtailer for the first 7 | time. ganglia-logtailer pipes all that data to /dev/null, but it still reads 8 | through the entire file. This can take quite a while on big log files (~30m on 9 | an 8GB log file). If you drop ganglia-logtailer into cron on a system with a 10 | large log file, it is easy to cause it to launch a second copy before the first 11 | has completed. This increases load, which decreases the probability either 12 | will finish, causing a cascading failure. After 150 copies of 13 | ganglia-logtailer are launched or so, the machine dies. 14 | 15 | There are two solutions to this problem, and both should be implemented. 16 | 17 | 1) patch logtail to accept a -s or --skip option, that merely skips to the end 18 | of the file and writes out a statefile instead of reading through the entire 19 | file. Update ganglia-logtailer to use this flag when it detects that it's the 20 | first run. 21 | 22 | 2) make ganglia-logtailer create a lockfile when it starts (including the 23 | module and logfile names in the lockfile to allow multiple simultaneous 24 | instances to run on different data) and immediately bail if it detects a lock 25 | file. (detecting a stale lockfile would be nice too.) This would allow the 26 | first instance to read all the way through a large log file, and then it would 27 | simply pick up where it left off the next time. The second benefit of this 28 | solution is that if you have misaligned the frequency of the cronjob launching 29 | ganglia-logtailer with the amount of time it takes to crunch your log file, 30 | this change will protect your system (though the stat collection will likely be 31 | impaired beyond usefulness, it is less likely to take down your machine). 32 | 33 | 34 | -------------------------------------------------------------------------------- /docker/gmetad-gangliaweb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie 2 | 3 | MAINTAINER Vladimir Vuksan 4 | 5 | COPY config /config 6 | 7 | RUN apt-get update 8 | RUN apt-get upgrade -y 9 | 10 | # Install Apache 11 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 12 | 13 | # Install php 14 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y php5 libapache2-mod-php5 php5-mcrypt php5-mysql 15 | 16 | # Install mod_wsgi 17 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libapache2-mod-wsgi 18 | 19 | # Enable apache mods. 20 | RUN a2enmod php5 21 | RUN a2enmod rewrite 22 | RUN a2enmod headers 23 | 24 | # Manually set up the apache environment variables 25 | ENV APACHE_RUN_USER www-data 26 | ENV APACHE_RUN_GROUP www-data 27 | ENV APACHE_LOG_DIR /var/log/apache2 28 | ENV APACHE_LOCK_DIR /var/lock/apache2 29 | ENV APACHE_PID_FILE /var/run/apache2.pid 30 | 31 | # Install gmetad and ganglia-web 32 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gmetad rrdcached rrdtool ganglia-webfrontend 33 | 34 | # Enable ganglia-webui 35 | RUN ln -s /etc/ganglia-webfrontend/apache.conf /etc/apache2/sites-enabled/002-ganglia.conf 36 | 37 | # Install Graphite pieces 38 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-rrdtool graphite-web 39 | 40 | RUN rm -f /etc/apache2/sites-enabled/000-default.conf 41 | RUN ln -s /config/graphite_apache.conf /etc/apache2/sites-enabled/000-default.conf 42 | 43 | RUN /bin/sh /config/graphite_install.sh 44 | 45 | # Make ganglia and rrdcached talk 46 | RUN sed -i '/#OPTS=""/c\OPTS=" -t 60 -w 300 -z 300 -F -s ganglia -m 664 -l 127.0.0.1:9998 -s ganglia -m 777 -P FLUSH,STATS,HELP -l unix:/tmp/rrdcached.limited.sock -b /var/lib/ganglia/rrds -B -p /var/lib/ganglia/rrdcached.pid"' /etc/default/rrdcached 47 | 48 | ENV RRDCACHED_ADDRESS 127.0.0.1:9998 49 | 50 | # Adjust permissions 51 | RUN touch /var/lib/ganglia-web/conf/events.json 52 | RUN chown ganglia:ganglia /var/lib/ganglia-web/conf/events.json 53 | 54 | EXPOSE 80 55 | 56 | CMD /etc/init.d/rrdcached start & /etc/init.d/gmetad start & /usr/sbin/apache2ctl -D FOREGROUND 57 | -------------------------------------------------------------------------------- /ganglia-logtailer/ganglia-logtailer.spec: -------------------------------------------------------------------------------- 1 | Name: ganglia-logtailer 2 | Version: 1.2 3 | Release: 1%{?dist} 4 | Summary: Framework to crunch data from logfiles and send using gmetric. 5 | 6 | 7 | Group: Applications/Internet 8 | License: GPL2+ 9 | URL: http://bitbucket.org/maplebed/ganglia-logtailer/overview/ 10 | Source0: %{name}.tar.gz 11 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 12 | 13 | BuildRequires: python-devel 14 | Requires: ganglia-gmond 15 | 16 | %description 17 | ganglia-logtailer is a Many metrics associated with ganglia and gmetric 18 | plugins are rather easy to collect; you poll the relevant application for a 19 | value and report it. Examples are asking MySQL for the number of questions and 20 | calculating queries per second, or asking iostat for the percentage disk I/O 21 | currently being used. However, there are a large number of applications out 22 | there that don't support being queried for interesting data, but do provide a 23 | log file which, when properly parsed, yields the interesting data we desire. 24 | An example of the latter category is Apache, which does not furnish any 25 | interface for measuring queries per second, yet has a log file allowing you to 26 | count how many queries come in over a specific time period. 27 | 28 | ganglia-logtailer is designed to make it easy to parse any log file, pull out 29 | the information you desire, and plug it into ganglia to make pretty graphs. 30 | 31 | %prep 32 | %setup -q -n %{name} 33 | 34 | 35 | %install 36 | rm -rf $RPM_BUILD_ROOT 37 | make install DESTDIR=$RPM_BUILD_ROOT 38 | install -d -m 755 $RPM_BUILD_ROOT/var/lib/ganglia-logtailer 39 | install -d -m 755 $RPM_BUILD_ROOT/var/log/ganglia-logtailer 40 | 41 | 42 | %clean 43 | rm -rf $RPM_BUILD_ROOT 44 | 45 | 46 | %files 47 | %defattr(-,root,root,-) 48 | %{_sbindir}/ganglia-logtailer 49 | %{_datadir}/%{name} 50 | %dir %{_localstatedir}/lib/%{name} 51 | %dir %{_localstatedir}/log/%{name} 52 | %doc debian/README debian/BUGS debian/copyright 53 | 54 | 55 | 56 | %changelog 57 | * Wed Mar 20 2010 Paul Nasrat - 1.2-1 58 | - Initial version 59 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug/local_gmond_handler.rb: -------------------------------------------------------------------------------- 1 | require 'uuid' 2 | require 'gmond-debug/gmondpacket' 3 | require 'json' 4 | 5 | Thread.abort_on_exception = true 6 | 7 | # Passing params to an EM Connection 8 | # http://stackoverflow.com/questions/3985092/one-question-with-eventmachine 9 | 10 | class LocalGmondHandler < EM::Connection 11 | attr_accessor :zmq_push_socket 12 | attr_accessor :verbose 13 | 14 | def receive_data packet 15 | 16 | @metadata=Hash.new if @metadata.nil? 17 | 18 | gmonpacket=GmonPacket.new(packet) 19 | if gmonpacket.meta? 20 | # Extract the metadata from the packet 21 | meta=gmonpacket.parse_metadata 22 | # Add it to the global metadata of this connection 23 | @metadata[meta['name']]=meta 24 | elsif gmonpacket.data? 25 | data=gmonpacket.parse_data(@metadata) 26 | 27 | # Check if it was a valid data request 28 | unless data.nil? 29 | # We currently assume this goes fast 30 | # send Topic, Body 31 | # Using the correct helper methods - https://github.com/andrewvc/em-zeromq/blob/master/lib/em-zeromq/connection.rb 32 | 33 | message=Hash.new 34 | message['id'] = UUID.new.generate 35 | message['timestamp'] = Time.now.to_i 36 | message['context'] = "METRIC" 37 | message['source'] = "GMOND" 38 | message['payload'] = data 39 | %w{dmax tmax slope type units}.each do |info| 40 | message['payload'][info] = @metadata[data['name']][info] 41 | end 42 | # message['payload']['meta'] = @metadata[data['name']] 43 | 44 | puts message.to_json 45 | # zmq_push_socket.send_msg('gmond', message.to_json) 46 | end 47 | else 48 | # Skipping unknown packet types 49 | end 50 | 51 | 52 | # If not, we might need to defer the block 53 | # # http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/ 54 | # # Callback block to execute once the parsing is finished 55 | # operation = proc do 56 | # end 57 | # 58 | # callback = proc do |res| 59 | # end 60 | # # Let the thread pool (20 Ruby Threads handle request) 61 | # EM.defer(operation,callback) 62 | 63 | end 64 | 65 | end 66 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | 14 | 15 | 16 | configure: configure-stamp 17 | configure-stamp: 18 | dh_testdir 19 | # Add here commands to configure the package. 20 | 21 | touch configure-stamp 22 | 23 | 24 | build: build-stamp 25 | 26 | build-stamp: configure-stamp 27 | dh_testdir 28 | 29 | # Add here commands to compile the package. 30 | $(MAKE) 31 | #docbook-to-man debian/ganglia-logtailer.sgml > ganglia-logtailer.1 32 | 33 | touch $@ 34 | 35 | clean: 36 | dh_testdir 37 | dh_testroot 38 | rm -f build-stamp configure-stamp 39 | 40 | # Add here commands to clean up after the build process. 41 | $(MAKE) clean 42 | 43 | dh_clean 44 | 45 | install: build 46 | dh_testdir 47 | dh_testroot 48 | #dh_prep 49 | dh_installdirs 50 | 51 | # Add here commands to install the package into debian/ganglia-logtailer. 52 | $(MAKE) DESTDIR=$(CURDIR)/debian/ganglia-logtailer install 53 | 54 | 55 | # Build architecture-independent files here. 56 | binary-indep: install 57 | # We have nothing to do by default. 58 | 59 | # Build architecture-dependent files here. 60 | binary-arch: install 61 | dh_testdir 62 | dh_testroot 63 | dh_installchangelogs 64 | dh_installdocs 65 | dh_installexamples 66 | # dh_install 67 | # dh_installmenu 68 | # dh_installdebconf 69 | # dh_installlogrotate 70 | # dh_installemacsen 71 | # dh_installpam 72 | # dh_installmime 73 | dh_pysupport 74 | # dh_installinit 75 | # dh_installcron 76 | # dh_installinfo 77 | dh_installman 78 | dh_link 79 | dh_strip 80 | dh_compress 81 | dh_fixperms 82 | # dh_perl 83 | # dh_makeshlibs 84 | dh_installdeb 85 | dh_shlibdeps 86 | dh_gencontrol 87 | dh_md5sums 88 | dh_builddeb 89 | 90 | binary: binary-indep binary-arch 91 | .PHONY: build clean binary-indep binary-arch binary install configure 92 | -------------------------------------------------------------------------------- /gang2graph/gang2graph.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Drew Stephens 3 | # Copyright 2011, Clearspring, Inc. 4 | # 5 | # This is free software; you can redistribute it and/or modify it under 6 | # the same terms as the Perl 5 programming language system itself. 7 | use warnings; 8 | use strict; 9 | use v5.10; 10 | package App::Gang2Graph; 11 | 12 | use Getopt::Long; 13 | use IO::Socket::INET; 14 | use XML::SAX::ParserFactory; 15 | 16 | use Ganglia::GraphiteSender; 17 | 18 | my $gangliaHost = 'localhost'; 19 | my $gangliaPort = 8651; 20 | my $graphiteHost = 'localhost'; 21 | my $graphitePort = 2023; 22 | 23 | # Set of hostname regexes that will be sent from Ganglia to Graphite 24 | my $include_hosts = ['.']; 25 | #$include_hosts = ['apw', 'apb', 'aab2[0-9a-d]', 'localhost']; 26 | 27 | # Set of hostname regexes that will be excluded from sending 28 | my $exclude_hosts = []; 29 | #my $exclude_hosts = ['apw00', 'apw01', 'apw02']; 30 | 31 | my $xml = getXMLFromSocket(); 32 | 33 | # Socket for sending to Graphite 34 | my $graphiteSocket = IO::Socket::INET->new( 35 | PeerHost => $graphiteHost, 36 | PeerPort => $graphitePort, 37 | ) or die"Couldn't connect to " . $graphiteHost . ':' . $graphitePort . " - $!\n"; 38 | 39 | my $parser = XML::SAX::ParserFactory->parser( 40 | Handler => Ganglia::GraphiteSender->new( 41 | socket => $graphiteSocket, 42 | include_hosts => $include_hosts, 43 | exclude_hosts => $exclude_hosts, 44 | ), 45 | ); 46 | $parser->parse_string($xml); 47 | $graphiteSocket->close(); 48 | 49 | sub getXMLFromSocket { 50 | my $socket = IO::Socket::INET->new( 51 | PeerHost => $gangliaHost, 52 | PeerPort => $gangliaPort, 53 | ) or die "Couldn't connect to " . $gangliaHost . ':' . $gangliaPort . " - $!\n"; 54 | 55 | my $xml = ''; 56 | my $part = ''; 57 | my $recvSize = 1024; 58 | $socket->recv($part, $recvSize); 59 | 60 | # Accumulate the XML file from the socket 61 | my $chunk = 0; 62 | while ($part ne '' && $chunk < 1_000_000) { 63 | $xml .= $part; 64 | $socket->recv($part, $recvSize); 65 | $chunk++ 66 | } 67 | 68 | return $xml; 69 | } 70 | 71 | 1; 72 | -------------------------------------------------------------------------------- /ganglia-go/gmetric/gmc/gmc.go: -------------------------------------------------------------------------------- 1 | // Package gmc is a light weight clone of the gmetric CLI. It only provides a 2 | // subset of the functionality provided by the official cli. 3 | package main 4 | 5 | import ( 6 | "flag" 7 | "fmt" 8 | "os" 9 | "strings" 10 | "time" 11 | 12 | "github.com/ganglia/ganglia_contrib/ganglia-go/gmetric" 13 | ) 14 | 15 | func main() { 16 | hostname, _ := os.Hostname() 17 | client := gmetric.ClientFromFlag("ganglia") 18 | value := flag.String("value", "", "Value of the metric") 19 | groups := flag.String("group", "", "Group(s) of the metric (comma-separated)") 20 | metric := &gmetric.Metric{} 21 | flag.StringVar(&metric.Name, "name", "", "Name of the metric") 22 | flag.StringVar(&metric.Title, "title", "", "Title of the metric") 23 | flag.StringVar(&metric.Host, "host", hostname, "Hostname") 24 | flag.StringVar((*string)(&metric.ValueType), "type", "", "Either string|int8|uint8|int16|uint16|int32|uint32|float|double") 25 | flag.StringVar(&metric.Units, "units", "", "Unit of measure for the value e.g. Kilobytes, Celcius") 26 | flag.StringVar((*string)(&metric.Slope), "slope", "both", "Either zero|positive|negative|both") 27 | flag.DurationVar(&metric.TickInterval, "tmax", 60*time.Second, "The maximum time between gmetric calls") 28 | flag.DurationVar(&metric.Lifetime, "dmax", 0, "The lifetime in seconds of this metric") 29 | flag.StringVar(&metric.Description, "desc", "", "Description of the metric") 30 | flag.StringVar(&metric.Spoof, "spoof", "", "IP address and name of host/device (colon separated) we are spoofing") 31 | flag.Parse() 32 | 33 | if metric.Name == "" || metric.ValueType == "" || *value == "" { 34 | fmt.Fprintln(os.Stderr, "name, type and value are required") 35 | flag.Usage() 36 | os.Exit(2) 37 | } 38 | 39 | if *groups != "" { 40 | metric.Groups = strings.Split(*groups, ",") 41 | } 42 | 43 | if err := client.Open(); err != nil { 44 | fmt.Fprintln(os.Stderr, err) 45 | os.Exit(2) 46 | } 47 | 48 | if err := client.WriteMeta(metric); err != nil { 49 | fmt.Fprintln(os.Stderr, err) 50 | os.Exit(2) 51 | } 52 | 53 | if err := client.WriteValue(metric, *value); err != nil { 54 | fmt.Fprintln(os.Stderr, err) 55 | os.Exit(2) 56 | } 57 | 58 | if err := client.Close(); err != nil { 59 | fmt.Fprintln(os.Stderr, err) 60 | os.Exit(2) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ganglia-go/gmon/gmon.go: -------------------------------------------------------------------------------- 1 | // Package gmon provides read access to the gmon data. 2 | package gmon 3 | 4 | import ( 5 | "bufio" 6 | "encoding/xml" 7 | "io" 8 | "net" 9 | 10 | "code.google.com/p/go-charset/charset" 11 | _ "code.google.com/p/go-charset/data" 12 | ) 13 | 14 | type ExtraElement struct { 15 | Name string `xml:"NAME,attr"` 16 | Val string `xml:"VAL,attr"` 17 | } 18 | 19 | type ExtraData struct { 20 | ExtraElements []ExtraElement `xml:"EXTRA_ELEMENT"` 21 | } 22 | 23 | type Metric struct { 24 | Name string `xml:"NAME,attr"` 25 | Value string `xml:"VAL,attr"` 26 | Unit string `xml:"UNITS,attr"` 27 | Slope string `xml:"SLOPE,attr"` 28 | Tn int `xml:"TN,attr"` 29 | Tmax int `xml:"TMAX,attr"` 30 | Dmax int `xml:"DMAX,attr"` 31 | ExtraData ExtraData `xml:"EXTRA_DATA"` 32 | } 33 | 34 | type Host struct { 35 | Name string `xml:"NAME,attr"` 36 | Ip string `xml:"IP,attr"` 37 | Tags string `xml:"TAGS,attr"` 38 | Reported int `xml:"REPORTED,attr"` 39 | Tn int `xml:"TN,attr"` 40 | Tmax int `xml:"TMAX,attr"` 41 | Dmax int `xml:"DMAX,attr"` 42 | Location string `xml:"LOCATION,attr"` 43 | GmondStarted int `xml:"GMOND_STARTED,attr"` 44 | Metrics []Metric `xml:"METRIC"` 45 | } 46 | 47 | type Cluster struct { 48 | Name string `xml:"NAME,attr"` 49 | Owner string `xml:"OWNER,attr"` 50 | LatLong string `xml:"LATLONG,attr"` 51 | Url string `xml:"URL,attr"` 52 | Localtime int `xml:"LOCALTIME,attr"` 53 | Hosts []Host `xml:"HOST"` 54 | } 55 | 56 | type Ganglia struct { 57 | XMLNAME xml.Name `xml:"GANGLIA_XML"` 58 | Clusters []Cluster `xml:"CLUSTER"` 59 | } 60 | 61 | // Read the gmond XML output. 62 | func Read(r io.Reader) (*Ganglia, error) { 63 | ganglia := Ganglia{} 64 | decoder := xml.NewDecoder(r) 65 | decoder.CharsetReader = charset.NewReader 66 | if err := decoder.Decode(&ganglia); err != nil { 67 | return nil, err 68 | } 69 | return &ganglia, nil 70 | } 71 | 72 | // Connect to the given network/address and read from it. 73 | func RemoteRead(network, addr string) (*Ganglia, error) { 74 | c, err := net.Dial(network, addr) 75 | if err != nil { 76 | return nil, err 77 | } 78 | defer c.Close() 79 | return Read(bufio.NewReader(c)) 80 | } 81 | -------------------------------------------------------------------------------- /graphite_integration/ganglia_graphite.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby -d 2 | 3 | ################################################################################# 4 | # Parse Ganglia XML stream and send metrics to Graphite 5 | # License: Same as Ganglia 6 | # Author: Vladimir Vuksan 7 | # Modified from script written by: Kostas Georgiou 8 | ################################################################################# 9 | require "rexml/document" 10 | require 'socket' 11 | 12 | # Adjust to the appropriate values 13 | ganglia_hostname = 'localhost' 14 | ganglia_port = 8651 15 | graphite_host = 'localhost' 16 | graphite_port = 2003 17 | Debug = false 18 | 19 | begin 20 | # Open up a socket to gmond 21 | file = TCPSocket.open(ganglia_hostname, ganglia_port) 22 | # Open up a socke to graphite 23 | graphite = TCPSocket.open(graphite_host, graphite_port) 24 | # We need current time stamp in UNIX time 25 | now = Time.now.to_i 26 | # Parse the XML we got from gmond 27 | doc = REXML::Document.new file 28 | #doc.write( $stdout, 0 ) 29 | 30 | grid=nil 31 | doc.elements.each("GANGLIA_XML/GRID") { |element| 32 | grid=element.attributes["NAME"] 33 | } 34 | puts "GRID: #{grid}\n" if Debug 35 | 36 | cluster=nil 37 | doc.elements.each("GANGLIA_XML/GRID/CLUSTER") { |element| 38 | cluster=element.attributes["NAME"] 39 | puts "CLUSTER: #{cluster}\n" if Debug 40 | 41 | doc.elements.each("GANGLIA_XML/GRID[@NAME='#{grid}']/CLUSTER[@NAME='#{cluster}']/HOST") { |host| 42 | metric_prefix=host.attributes["NAME"].gsub(".", "_") 43 | host.elements.each("METRIC") { |metric| 44 | # Set metric prefix to the host name. Graphite uses dots to separate subtrees 45 | # therefore we have to change dots in hostnames to _ 46 | # Do substitution of whitespace after XML parsing to avoid problems with 47 | # pre-exiting whitespace in GRID / CLUSTER names in XML. 48 | grid.gsub!(/\W/, "_") 49 | cluster.gsub!(/\W/, "_") 50 | if metric.attributes["TYPE"] != "string" 51 | graphite.puts "#{grid}.#{cluster}.#{metric_prefix}.#{metric.attributes["NAME"]} #{metric.attributes["VAL"]} #{now}\n" if !Debug 52 | puts "#{grid}.#{cluster}.#{metric_prefix}.#{metric.attributes["NAME"]} #{metric.attributes["VAL"]} #{now}\n" if Debug 53 | end 54 | } 55 | } 56 | } 57 | 58 | graphite.close() 59 | file.close() 60 | rescue 61 | end 62 | -------------------------------------------------------------------------------- /pmond/pmond/gparse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This is the MIT License 4 | # http://www.opensource.org/licenses/mit-license.php 5 | # 6 | # Copyright (c) 2009 Nick Galbreath 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | # THE SOFTWARE. 25 | # 26 | 27 | import socket 28 | from lxml import etree 29 | 30 | def parse(s): 31 | hosts = {} 32 | root = etree.XML(s) 33 | # newer versions could do: 34 | #for host in root.iter('HOST'): 35 | for host in root.findall('HOST'): 36 | name = host.get('NAME') 37 | hosts[name] = {} 38 | metrics = hosts[name] 39 | # new versions of lxml could do 40 | #for m in host.iter('METRIC'): 41 | for m in host.findall('METRIC'): 42 | metrics[m.get('NAME')] = m.attrib.get("VAL") 43 | return hosts 44 | 45 | def read(host, port): 46 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 47 | s.connect((host, port)) 48 | data = "" 49 | while True: 50 | bytes = s.recv(4096) 51 | if len(bytes) == 0: 52 | break; 53 | data += bytes 54 | s.close() 55 | return data 56 | 57 | if __name__ == '__main__': 58 | 59 | s = read('localhost', 8649) 60 | hosts = parse(s) 61 | for h in hosts: 62 | print h 63 | keys = sorted(hosts[h]) 64 | for k in keys: 65 | print " %s = %s" % (k,hosts[h][k]) 66 | 67 | 68 | -------------------------------------------------------------------------------- /ganglia-logtailer/src/ganglia_logtailer_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """class for ganglia metric objects to be passed around""" 3 | import re 4 | 5 | class GangliaMetricObject(object): 6 | def __init__(self, name, value, units='', type='float', tmax=60, dmax=0): 7 | self.name = name 8 | self.value = value 9 | self.units = units 10 | self.type = type 11 | self.tmax = tmax 12 | self.dmax = dmax 13 | def set_value(self, value): 14 | self.value = value 15 | def dump_dict(self): 16 | """serialize this object to a dictionary""" 17 | return self.__dict__ 18 | def set_from_dict(self, hashed_object): 19 | """recreate object from dict""" 20 | self.name = hashed_object["name"] 21 | self.value = hashed_object["value"] 22 | self.units = hashed_object["units"] 23 | self.type = hashed_object["type"] 24 | self.tmax = hashed_object["tmax"] 25 | self.dmax = hashed_object["dmax"] 26 | def sanitize_metric_name(self): 27 | """sanitize metric names by translating all non alphanumerics to underscore""" 28 | self.name = re.sub("[^A-Za-z0-9._-]", "_", self.name) 29 | def __eq__(self, other): 30 | """A ganglia metric object is equivalent if the name is the same.""" 31 | return self.name == other.name 32 | 33 | class LogtailerParsingException(Exception): 34 | """Raise this exception if the parse_line function wants to 35 | throw a 'recoverable' exception - i.e. you want parsing 36 | to continue but want to skip this line and log a failure.""" 37 | pass 38 | 39 | class LogtailerStateException(Exception): 40 | """Raise this exception if the get_state function has failed. Metrics from 41 | this run will not be submitted (since the function did not properly 42 | return), but reset_state() should have been called so that the metrics 43 | are valid next time.""" 44 | pass 45 | 46 | class SavedMetricsException(Exception): 47 | """Raise this exception if there's a problem recovering the saved metric 48 | list from the statedir. This will always happen on the first run, and 49 | should be ignored. On subsequent runs, it probably means a config 50 | problem where the statedir can't be written or something.""" 51 | pass 52 | 53 | class LockingError(Exception): 54 | """ Exception raised for errors creating or destroying lockfiles. """ 55 | 56 | def __init__(self, message): 57 | self.message = message 58 | 59 | 60 | -------------------------------------------------------------------------------- /ganglia-go/gmetric/panicky_writer_test.go: -------------------------------------------------------------------------------- 1 | package gmetric 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | var errFixed = errors.New("fixed error") 10 | 11 | type errWriter int 12 | 13 | func (e errWriter) Write(b []byte) (int, error) { 14 | return 0, errFixed 15 | } 16 | 17 | var panicFixed = "foo42" 18 | 19 | type panicWriter int 20 | 21 | func (e panicWriter) Write(b []byte) (int, error) { 22 | panic(panicFixed) 23 | } 24 | 25 | func TestWriteMetaWriterError(t *testing.T) { 26 | t.Parallel() 27 | c := &Client{} 28 | m := &Metric{ 29 | Name: "write_meta_panic_metric", 30 | Host: "localhost", 31 | ValueType: ValueUint32, 32 | Units: "count", 33 | Slope: SlopeBoth, 34 | TickInterval: 20 * time.Second, 35 | Lifetime: 24 * time.Hour, 36 | } 37 | if err := m.writeMeta(c, errWriter(0)); err != errFixed { 38 | t.Fatalf("was expecting errFixed but got %s", err) 39 | } 40 | } 41 | 42 | func TestWriteValueWriterError(t *testing.T) { 43 | t.Parallel() 44 | c := &Client{} 45 | m := &Metric{ 46 | Name: "string_metric", 47 | Host: "localhost", 48 | ValueType: ValueString, 49 | Units: "count", 50 | Slope: SlopeBoth, 51 | TickInterval: 20 * time.Second, 52 | Lifetime: 24 * time.Hour, 53 | } 54 | if err := m.writeValue(c, errWriter(0), "val"); err != errFixed { 55 | t.Fatalf("was expecting errFixed but got %s", err) 56 | } 57 | } 58 | 59 | func TestWriteMetaWriterPanic(t *testing.T) { 60 | t.Parallel() 61 | c := &Client{} 62 | defer func() { 63 | if r := recover(); r != panicFixed { 64 | t.Fatalf("was expecting panicFixed but got %s", r) 65 | } 66 | }() 67 | m := &Metric{ 68 | Name: "write_meta_panic_metric", 69 | Host: "localhost", 70 | ValueType: ValueUint32, 71 | Units: "count", 72 | Slope: SlopeBoth, 73 | TickInterval: 20 * time.Second, 74 | Lifetime: 24 * time.Hour, 75 | } 76 | if err := m.writeMeta(c, panicWriter(0)); err != errFixed { 77 | t.Fatalf("was expecting errFixed but got %s", err) 78 | } 79 | } 80 | 81 | func TestWriteValueWriterPanic(t *testing.T) { 82 | t.Parallel() 83 | c := &Client{} 84 | defer func() { 85 | if r := recover(); r != panicFixed { 86 | t.Fatalf("was expecting panicFixed but got %s", r) 87 | } 88 | }() 89 | m := &Metric{ 90 | Name: "string_metric", 91 | Host: "localhost", 92 | ValueType: ValueString, 93 | Units: "count", 94 | Slope: SlopeBoth, 95 | TickInterval: 20 * time.Second, 96 | Lifetime: 24 * time.Hour, 97 | } 98 | if err := m.writeValue(c, panicWriter(0), "val"); err != errFixed { 99 | t.Fatalf("was expecting errFixed but got %s", err) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug/remote_gmond_handler.rb: -------------------------------------------------------------------------------- 1 | require 'uuid' 2 | require 'nokogiri' 3 | require 'json' 4 | # Maybe use defer, as this might take awhile 5 | # http://eventmachine.rubyforge.org/EventMachine.html#M000486 6 | # http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/ 7 | # Separate thread 8 | class PostCallbacks < Nokogiri::XML::SAX::Document 9 | 10 | attr_reader :metrics 11 | attr_reader :host 12 | attr_reader :base_timestamp 13 | 14 | def initialize(socket) 15 | @socket=socket 16 | @metrics=Array.new 17 | @host=:unknown 18 | end 19 | 20 | def start_element(element,attributes) 21 | if element == "METRIC" 22 | @metrics << metric_to_message(attributes) 23 | end 24 | 25 | # 26 | if element == "CLUSTER" 27 | attributes.each do |attribute| 28 | if attribute[0] == "LOCALTIME" 29 | @base_timestamp=attribute[1] 30 | 31 | end 32 | end 33 | end 34 | 35 | # Extract the hostname 36 | # # 38 | if element == "HOST" 39 | attributes.each do |attribute| 40 | if attribute[0] == "NAME" 41 | @host=attribute[1] 42 | end 43 | end 44 | end 45 | end 46 | 47 | def metric_to_message(attributes) 48 | message=Hash.new 49 | attributes.each do |attribute| 50 | name=attribute[0] 51 | value=attribute[1] 52 | message[name.downcase]=value 53 | end 54 | message['hostname']=@host 55 | return message 56 | end 57 | 58 | def end_document 59 | # At the end of the document send all metrics 60 | @metrics.each do |metric| 61 | message=Hash.new 62 | message['id']=UUID.new.generate 63 | 64 | # Correct the timestamp based on the time last seen 65 | message['timestamp']=@base_timestamp.to_i-message['tn'].to_i 66 | message['payload']=metric 67 | message['payload'].delete('source') 68 | message['context']="METRIC" 69 | message['source']="GMOND" 70 | 71 | # May have to decide on TMAX and DMAX not to send the metric any more 72 | # http://monami.sourceforge.net/tutorial/ar01s06.html 73 | @socket.send_msg('gmond', message.to_json) 74 | end 75 | end 76 | 77 | end 78 | 79 | class RemoteGmondHandler < EM::Connection 80 | attr_accessor :zmq_push_socket 81 | attr_accessor :verbose 82 | 83 | def receive_data data 84 | begin 85 | parser = Nokogiri::XML::SAX::Parser.new(PostCallbacks.new(zmq_push_socket)) 86 | parser.parse(data) 87 | rescue ::Exception => ex 88 | puts "Error parsing XML: #{ex}" 89 | end 90 | end 91 | 92 | def unbind 93 | #puts "closing connection" 94 | end 95 | end 96 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug/gmondpacket2.rb: -------------------------------------------------------------------------------- 1 | class GmonPacket2 2 | 3 | def initialize(packet) 4 | @unpacked=packet 5 | @result=Hash.new 6 | packet_type=unpack_int 7 | @result['gmetadata_full']=packet_type 8 | case packet_type[0] 9 | when 128 then unpack_meta 10 | when 132 then unpack_heartbeat 11 | when 134,133 then unpack_data 12 | end 13 | end 14 | 15 | def unpack_meta 16 | puts "got meta package" 17 | # This parse is only working correctly with gmetadata_full=128 18 | @result['hostname']=unpack_string 19 | @result['metricname']=unpack_string 20 | @result['spoof']=unpack_int 21 | @result['metrictype']=unpack_string 22 | @result['metricname2']=unpack_string 23 | @result['metricunits']=unpack_string 24 | @result['slope']=unpack_int 25 | @result['tmax']=unpack_int 26 | @result['dmax']=unpack_int 27 | nrelements=unpack_int 28 | @result['nrelements']=nrelements 29 | unless nrelements.nil? 30 | for i in 1..nrelements[0] 31 | name=unpack_string 32 | @result[name]=unpack_string 33 | end 34 | end 35 | end 36 | 37 | def unpack_data 38 | puts "got data package" 39 | unpack_data_blob 40 | end 41 | 42 | def unpack_data_blob 43 | @result['hostname']=unpack_string 44 | @result['metricname']=unpack_string 45 | @result['spoof']=unpack_int 46 | format=unpack_string 47 | @result['format']=format 48 | 49 | # Quick hack here 50 | # Needs real XDR parsing here 51 | # http://ruby-xdr.rubyforge.org/git?p=ruby-xdr.git;a=blob;f=lib/xdr.rb;h=b41177f32ae72f30d31122e5d801e4828a614c79;hb=HEAD 52 | @result['value']=unpack_float if format.include?("f") 53 | @result['value']=unpack_int if format.include?("u") 54 | @result['value']=unpack_string if format.include?("s") 55 | end 56 | 57 | def unpack_heartbeat 58 | puts "got heartbeat" 59 | unpack_data_blob 60 | end 61 | 62 | 63 | def unpack_int 64 | unless @unpacked.nil? 65 | value=@unpacked[0..3].unpack('N') 66 | shift_unpacked(4) 67 | return value 68 | else 69 | return nil 70 | end 71 | end 72 | 73 | def unpack_float 74 | unless @unpacked.nil? 75 | value=@unpacked[0..3].unpack('g') 76 | shift_unpacked(4) 77 | return value 78 | else 79 | return nil 80 | end 81 | end 82 | 83 | def unpack_string 84 | unless @unpacked.nil? 85 | size=@unpacked[0..3].unpack('N').to_s.to_i 86 | shift_unpacked(4) 87 | value=@unpacked[0..size-1] 88 | #The packets are padded 89 | shift_unpacked(size+((4-size) % 4)) 90 | return value 91 | else 92 | return nil 93 | end 94 | end 95 | 96 | def shift_unpacked(count) 97 | @unpacked=@unpacked[count..@unpacked.length] 98 | end 99 | 100 | def to_hash 101 | return @result 102 | end 103 | 104 | end 105 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | Included in the two directories are Dockerfiles to install Ganglia using Docker. 2 | 3 | # Requirements 4 | 5 | You need to have a current version of Docker installed. 6 | 7 | # Build images 8 | 9 | First we'll build the gmetad-ganglia web container. This will run Gmetad and the Web interface 10 | 11 |

12 | sudo docker build -t gmetad-gangliaweb gmetad-gangliaweb/.
13 | 
14 | 15 | Secondly we'll build the gmond-aggregator container which will kick off a single gmond aggregator 16 | 17 |
18 | sudo docker build -t gmond-aggregator gmond-aggregator/.
19 | 
20 | 21 | # Create configuration files and directories 22 | 23 | We are going to create gmetad configuration file and RRD storage outside of the container 24 | and just mount it inside the gmetad container. This is so we can persist it easily 25 | 26 | For example we'll need to do something like this 27 | 28 | ``` 29 | sudo mkdir -p /var/lib/ganglia/rrds /etc/ganglia /etc/ganglia-webfrontend 30 | sudo chown -R 999:999 /var/lib/ganglia 31 | sudo sh -c "cat > /etc/ganglia/gmetad.conf < /etc/ganglia-webfrontend/conf.php < 50 | sudo docker run -d -p 8649:8649/udp --name gmond1 gmond-aggregator web-cluster 51 | 52 | 53 | will start gmond aggregator on port 8649 for web-cluster. Please note we named the container gmond1 54 | so we can easily refer to it later. To invoke further ones you will need to change the 55 | bind port on the left e.g. to invoke second aggregator type 56 | 57 |
58 | sudo docker run -d -p 12001:8649/udp --name gmond2 gmond-aggregator db-cluster
59 | 
60 | 61 | Secondly we start up gmetad-gangliaweb container 62 | 63 |
64 | sudo docker run -d --name gmetad1 \
65 | 	-v /etc/ganglia/gmetad.conf:/etc/ganglia/gmetad.conf \
66 | 	-v /var/lib/ganglia:/var/lib/ganglia \
67 | 	--link gmond1:gmond1 \
68 | 	--link gmond2:gmond2 \
69 | 	-p 0.0.0.0:80:80 gmetad-gangliaweb
70 | 
71 | 72 | # Explanation 73 | 74 | What will happen here is following 75 | 76 | - Gmond aggregator will be started on port 8649. It will expose UDP port 8649 on the host hosting the containers. That host is going to be called gmond1. Same story with 77 | - When we launch gmetad-gangliaweb container it will mount /var/lib/ganglia and /etc/ganglia/gmetad.conf from the docker host inside the container 78 | - In addition gmond1 container will be linked with the gmetad1 container so gmetad1 can access it 79 | - Using --link will assure that /etc/hosts file in gmetad1 container is updated with the internal IP for gmond1 80 | - Ganglia Web will be available on http://localhost/ganglia 81 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/type/GMetricString.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric.type; 25 | 26 | import info.ganglia.metric.GMetric; 27 | import info.ganglia.metric.Metricable; 28 | 29 | import java.io.IOException; 30 | 31 | 32 | /** 33 | * String implementation of GMetric 34 | * 35 | * @author Chris Bowling 36 | */ 37 | public class GMetricString extends GMetric implements Metricable { 38 | private String valueString = ""; 39 | 40 | /** 41 | * Constructor calls super 42 | * @param host 43 | * The hostname of the client server 44 | * @param name 45 | * The name of the metric (e.g. "CPU Usage"). Shows on graph 46 | * @param type 47 | * The type of the value. See GMetric constants. 48 | * @param units 49 | * The units used to measure the metric. Shows on graph 50 | * @param slope 51 | * See GMetric constants. 52 | * @param additive 53 | * If false the GMetric values are reset to 0 after update. If true the GMetric values are additive. 54 | * @throws IOException 55 | */ 56 | public GMetricString(String host, String name, String type, String units, int slope, boolean additive) { 57 | super(host, name, type, units, slope, additive); 58 | } 59 | 60 | /** 61 | * Sets current GMetric value to value argument 62 | * @param value set GMetric to new value 63 | */ 64 | public void setValue(String value) { 65 | if (null != value) { 66 | valueString = value; 67 | } 68 | } 69 | 70 | /* (non-Javadoc) 71 | * @see info.ganglia.metric.Metricable#clearValue() 72 | */ 73 | public void clearValue() { 74 | valueString = ""; 75 | } 76 | 77 | /* (non-Javadoc) 78 | * @see info.ganglia.metric.Metricable#getValueData() 79 | */ 80 | public byte[] getValueData() { 81 | byte[] valueBytes = null; 82 | valueBytes = writeValue(valueString); 83 | return valueBytes; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /gmetad_health_checker/gmetadXmlChecker.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python 2 | 3 | import socket, os, sys, logging 4 | from optparse import OptionParser 5 | 6 | usage = 'usage: %prog [options] arg1 arg2' 7 | parser = OptionParser(usage="%prog [-r] [-q] [-h]", version="%prog 1.0") 8 | parser.add_option("-v", "--verbose", 9 | action="store_true", dest="verbose", default=False, 10 | help="make lots of noise [default]") 11 | parser.add_option("-q", "--quiet", 12 | action="store_false", dest="verbose", default=True, 13 | help="be vewwy quiet (I'm hunting wabbits)") 14 | parser.add_option("-r", "--restart", 15 | action="store_true", dest="restart", default=False, 16 | help="Should I actually restart gmetad") 17 | (options, args) = parser.parse_args() 18 | 19 | LOG_FILENAME = '/var/logs/gmetad.log' 20 | logging.basicConfig(filename=LOG_FILENAME, level=logging.NOTSET) 21 | 22 | def restartGmetad(): 23 | cmd = 'service gmetad restart' 24 | pipe = os.popen(cmd) 25 | results = [l for l in pipe.readlines() if l.find('OK') != -1] 26 | if results: 27 | return True 28 | else: 29 | return False 30 | 31 | def gmetadXmlChecker(port): 32 | try: 33 | client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 34 | client_socket.connect(("localhost", port)) 35 | data = client_socket.recv(512) 36 | if len(data) < 512: 37 | logging.critical('We didn\'t recieve any output from gmetad running on port: %d' % port) 38 | if options.verbose: 39 | print "We didn\'t recieve any output from gmetad running in port: %d" % port 40 | client_socket.close() 41 | return False 42 | else: 43 | #print "RECIEVED:" , data 44 | client_socket.close() 45 | return True 46 | except Exception as e: 47 | logging.critical('Gmetad does not seem to be running on this port') 48 | if options.verbose: 49 | print "Cannot connect to host" 50 | return False 51 | 52 | 53 | def main(): 54 | try: 55 | gmetad_confs = os.listdir('/etc/gmetad') 56 | except: 57 | logging.critical('Directory does not exist') 58 | if options.verbose: 59 | print 'Directory does not exist' 60 | exit() 61 | xml_ports = [] 62 | for conf in gmetad_confs: 63 | for line in open('/etc/gmetad/' + conf): 64 | if 'xml_port' in line: 65 | xml_ports.append(int(line.split(' ')[1].rstrip('\n'))) 66 | 67 | for port in xml_ports: 68 | if gmetadXmlChecker(port) == True: 69 | logging.info('gmetad on port: %d is running correctly, exiting' % port) 70 | if options.verbose: 71 | print "gmetad on port: %d is running correctly, exiting" % port 72 | else: 73 | logging.critical('gmetad on port: %d is not responding, restarting' % port) 74 | if options.verbose: 75 | print "gmetad on port: %d is not responding, restarting" % port 76 | if options.restart: 77 | restartGmetad() 78 | exit() 79 | 80 | if __name__ == '__main__': 81 | main() 82 | -------------------------------------------------------------------------------- /graphite_integration/ganglia_graphite_2.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby -d 2 | 3 | ################################################################################# 4 | # Parse Ganglia XML stream and send metrics to Graphite 5 | # License: Same as Ganglia 6 | # Author: Gilles Devaux 7 | # Modified from script written by: Vladimir Vuksan 8 | # at https://github.com/ganglia/ganglia_contrib/blob/master/graphite_integration/ganglia_graphite.rb 9 | # 10 | # WARNING: Don't be surprised Carbon does not understand COUNTER type. You have to apply a derivative function in the UI. 11 | # 12 | ################################################################################# 13 | require "rubygems" 14 | require "nokogiri" 15 | require 'socket' 16 | 17 | # Adjust to the appropriate values 18 | ganglia_hostname = 'localhost' 19 | ganglia_port = 8651 20 | graphite_host = 'localhost' 21 | graphite_port = 2003 22 | debug = false 23 | 24 | begin 25 | # Open up a socket to gmond 26 | file = TCPSocket.open(ganglia_hostname, ganglia_port) 27 | # Open up a socke to graphite 28 | graphite = TCPSocket.open(graphite_host, graphite_port) 29 | # We need current time stamp in UNIX time 30 | now = Time.now.to_i 31 | # Parse the XML we got from gmond 32 | doc = Nokogiri::XML file 33 | #doc.write( $stdout, 0 ) 34 | 35 | #only one grid for now? 36 | 37 | # Set metric prefix to the host name. Graphite uses dots to separate subtrees 38 | # therefore we have to change dots in hostnames to _ 39 | # Do substitution of whitespace after XML parsing to avoid problems with 40 | # pre-exiting whitespace in GRID / CLUSTER names in XML. 41 | 42 | grid = doc.at('GANGLIA_XML/GRID') 43 | grid_name = grid['NAME'].gsub(/\W/, "_") 44 | puts "GRID: #{grid['NAME']}" if debug 45 | 46 | grid.css('CLUSTER').each do |cluster| 47 | cluster_name=cluster["NAME"].gsub(/\W/, "_") 48 | puts "CLUSTER: #{cluster_name}" if debug 49 | 50 | cluster.css("HOST").each do |host| 51 | 52 | metric_prefix=host["NAME"].gsub(".", "_") 53 | puts "PREFIX: #{metric_prefix}" if debug 54 | 55 | host.css("METRIC").each do |metric| 56 | metric_name = metric["NAME"] 57 | puts "METRIC: #{metric_name}" if debug 58 | 59 | if metric["TYPE"] != "string" 60 | 61 | group = metric.at("EXTRA_DATA/EXTRA_ELEMENT[@NAME=GROUP]") 62 | if group 63 | group_name = group['VAL'].gsub(/\W/, "_") 64 | else 65 | #Trick for gmetric < 3.2 (do not have --group option) 66 | #Name your metric group_metric_name 67 | split = metric_name.split('_') 68 | if split.count == 1 69 | group_name = 'nogroup' 70 | else 71 | group_name = split[0] 72 | metric_name = split[1..-1].join('_') 73 | end 74 | end 75 | 76 | puts "GROUP: #{group_name}" if debug 77 | 78 | cmd = "#{grid_name}.#{cluster_name}.#{metric_prefix}.#{group_name}.#{metric_name} #{metric["VAL"]} #{now}\n" 79 | debug ? puts(cmd) : graphite.puts(cmd) 80 | end 81 | end 82 | end 83 | 84 | end 85 | 86 | graphite.close() 87 | file.close() 88 | rescue 89 | # ignored 90 | end 91 | -------------------------------------------------------------------------------- /varnish_web/default.vcl: -------------------------------------------------------------------------------- 1 | # Specify a backend e.g. your Apache server running Ganglia 2 | backend default { 3 | .host = "127.0.0.1"; 4 | .port = "8080"; 5 | .first_byte_timeout = 60s; 6 | } 7 | 8 | sub vcl_recv { 9 | # We are exposing Ganglia via varnish as /ganglia3/. So we need to rewrite 10 | # the URL we send to the backend since Ganglia lives under /ganglia2 11 | if (req.url ~ "^/ganglia3") { 12 | set req.url = regsub(req.url, "^/ganglia3", "/ganglia2"); 13 | } 14 | return (lookup); 15 | } 16 | 17 | sub vcl_fetch { 18 | 19 | # Front page can be cached for 20 minutes. Cluster list shouldn't 20 | # change that often 21 | if (req.url ~ "^/(ganglia2/)?$" ) { 22 | set beresp.ttl = 1200s; 23 | unset beresp.http.Cache-Control; 24 | unset beresp.http.Expires; 25 | unset beresp.http.Pragma; 26 | unset beresp.http.Set-Cookie; 27 | } 28 | 29 | # Cache CSS and JS for a day 30 | if (req.url ~ "^/(ganglia2/)?(css|js)" || req.url ~ "^/naglite3(.*)\.(css|js)$" ) { 31 | set beresp.ttl = 86400s; 32 | unset beresp.http.Expires; 33 | unset beresp.http.Pragma; 34 | unset beresp.http.Set-Cookie; 35 | set beresp.http.Cache-Control = "public, max-age=86400"; 36 | } 37 | 38 | # By default cache all graphs for 30 seconds however tell the browser to cache it for 15 seconds 39 | if (req.url ~ "/(ganglia2/)?graph.php") { 40 | set beresp.ttl = 15s; 41 | set beresp.http.Cache-Control = "public, max-age=15"; 42 | unset beresp.http.Pragma; 43 | unset beresp.http.Expires; 44 | unset beresp.http.Set-Cookie; 45 | } 46 | 47 | # Yearly graphs show day averages so no need to regenerate that all the time 48 | # Cache for a day. Monthly graphs cache for 2 hours and daily graphs for 5 minutes 49 | if (req.url ~ "/(ganglia2/)?graph.php\?(.*)r=year") { 50 | set beresp.ttl = 86400s; 51 | set beresp.http.Cache-Control = "public, max-age=86400s"; 52 | } else if ( req.url ~ "/(ganglia2/)?graph.php\?(.*)r=month") { 53 | set beresp.ttl = 7200s; 54 | set beresp.http.Cache-Control = "public, max-age=7200s"; 55 | } else if ( req.url ~ "/(ganglia2/)?graph.php\?(.*)r=day") { 56 | set beresp.ttl = 300s; 57 | set beresp.http.Cache-Control = "public, max-age=300s"; 58 | } else if ( req.url ~ "/(ganglia2/)?graph.php\?(.*)r=4hr") { 59 | set beresp.ttl = 60s; 60 | set beresp.http.Cache-Control = "public, max-age=60s"; 61 | } else if ( req.url ~ "^/(ganglia2/)?\?.*vn=(.*)&" ) { 62 | set beresp.ttl = 300s; 63 | set beresp.http.Cache-Control = "public, max-age=300s"; 64 | } else if ( req.url ~ "^/(ganglia2/)?autorotation.php" ) { 65 | set beresp.ttl = 900s; 66 | set beresp.http.Cache-Control = "public, max-age=300s"; 67 | } 68 | 69 | # Graph All periods can be cached for a long time 70 | if (req.url ~ "/(ganglia2/)?graph_all_periods.php") { 71 | set beresp.ttl = 86400s; 72 | set beresp.http.Cache-Control = "public, max-age=600"; 73 | unset beresp.http.Pragma; 74 | unset beresp.http.Expires; 75 | unset beresp.http.Set-Cookie; 76 | } 77 | 78 | return (deliver); 79 | } 80 | 81 | sub vcl_deliver { 82 | if (obj.hits > 0) { 83 | set resp.http.X-Cache = "HIT"; 84 | set resp.http.X-Cache-Hits = obj.hits; 85 | } else { 86 | set resp.http.X-Cache = "MISS"; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/GConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia; 25 | 26 | import java.io.IOException; 27 | import java.net.DatagramPacket; 28 | import java.net.InetAddress; 29 | import java.net.MulticastSocket; 30 | 31 | /** 32 | * Connects and sends packets to Ganglia via a multicast socket connection. If the multicast group is passed in as a constructor argument it will use that address. 33 | * Otherwise it will use the multicast group specified by the system env variable "ganglia.host" 34 | * 35 | * @author Chris Bowling 36 | */ 37 | public class GConnector { 38 | 39 | private final static int DEFAULT_PORT = 8649; 40 | private final InetAddress inetAddress; 41 | private final MulticastSocket socket; 42 | 43 | /** 44 | * Constructor uses multicastAddress specified in the System environment variable "ganglia.host" for its connection to ganglia. 45 | * @throws IOException 46 | */ 47 | public GConnector() throws IOException { 48 | // read system env setting for Ganglia server address 49 | final String gangliaHostAddress = System.getProperty("ganglia.host"); 50 | this.inetAddress = InetAddress.getByName(gangliaHostAddress); 51 | 52 | // create multicast socket, join group, and send meta data packet 53 | socket = new MulticastSocket(DEFAULT_PORT); 54 | } 55 | 56 | /** 57 | * Constructor uses multicastAddress argument for its connection to Ganglia. 58 | * @param multicastAddress address to send metadata and value data packets to 59 | * @throws IOException 60 | */ 61 | public GConnector(String multicastAddress) throws IOException { 62 | this.inetAddress = InetAddress.getByName(multicastAddress); 63 | // create multicast socket, join group, and send meta data packet 64 | socket = new MulticastSocket(DEFAULT_PORT); 65 | } 66 | 67 | /** 68 | * Creates a DatagramPacket using the byte[] argument and sends the packet to Ganglia. 69 | * @param buf data formatted for Ganglia to be sent 70 | * @param length byte[] length 71 | */ 72 | public void sendPacket(byte[] buf, int length) { 73 | try { 74 | final DatagramPacket packet = new DatagramPacket(buf, length, inetAddress, DEFAULT_PORT); 75 | socket.send(packet); 76 | } catch (IOException ioe) { 77 | ioe.printStackTrace(); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /ganglia-logtailer/src/tailnostate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """Tail a file, reopening it if it gets rotated""" 3 | 4 | import time, os, sys, glob 5 | 6 | 7 | class Tail(object): 8 | def __init__(self, filename, start_pos=0): 9 | self.fp = file(filename) 10 | self.filename = filename 11 | 12 | if start_pos < 0: 13 | self.fp.seek(-start_pos-1, 2) 14 | self.pos = self.fp.tell() 15 | else: 16 | self.fp.seek(start_pos) 17 | self.pos = start_pos 18 | 19 | def __iter__(self): 20 | """Return next line. This function will sleep until there *is* a 21 | next line. Works over log rotation.""" 22 | counter = 0 23 | while True: 24 | line = self.next() 25 | if line is None: 26 | counter += 1 27 | if counter >= 5: 28 | counter = 0 29 | self.check_inode() 30 | time.sleep(1.0) 31 | else: 32 | yield line 33 | 34 | def check_inode(self): 35 | """check to see if the filename we expect to tail has the same 36 | inode as our currently open file. This catches log rotation""" 37 | inode = os.stat(self.filename).st_ino 38 | old_inode = os.fstat(self.fp.fileno()).st_ino 39 | if inode != old_inode: 40 | self.fp = file(self.filename) 41 | self.pos = 0 42 | 43 | def next(self): 44 | """Return the next line from the file. Returns None if there are not 45 | currently any lines available, at which point you should sleep before 46 | calling again. Does *not* handle log rotation. If you use next(), you 47 | must also use check_inode to handle log rotation""" 48 | where = self.fp.tell() 49 | line = self.fp.readline() 50 | if line and line[-1] == '\n': 51 | self.pos += len(line) 52 | return line 53 | else: 54 | self.fp.seek(where) 55 | return None 56 | 57 | def close(self): 58 | self.fp.close() 59 | 60 | 61 | 62 | class LogTail(Tail): 63 | def __init__(self, filename): 64 | self.base_filename = filename 65 | super(LogTail, self).__init__(filename, -1) 66 | 67 | def get_file(self, inode, next=False): 68 | files = glob.glob('%s*' % self.base_filename) 69 | files = [(os.stat(f).st_mtime, f) for f in files] 70 | # Sort by modification time 71 | files.sort() 72 | 73 | flag = False 74 | for mtime, f in files: 75 | if flag: 76 | return f 77 | if os.stat(f).st_ino == inode: 78 | if next: 79 | flag = True 80 | else: 81 | return f 82 | else: 83 | return self.base_filename 84 | 85 | def reset(self): 86 | self.fp = file(self.filename) 87 | self.pos = 0 88 | 89 | def advance(self): 90 | self.filename = self.get_file(os.fstat(self.fp.fileno()).st_ino, True) 91 | self.reset() 92 | 93 | def check_inode(self): 94 | if self.filename != self.base_filename or os.stat(self.filename).st_ino != os.fstat(self.fp.fileno()).st_ino: 95 | self.advance() 96 | 97 | 98 | def main(): 99 | import sys 100 | 101 | t = Tail(sys.argv[1], -1) 102 | for line in t: 103 | print line 104 | 105 | 106 | if __name__ == '__main__': 107 | main() 108 | 109 | 110 | -------------------------------------------------------------------------------- /pmond/pmond/daemon.py: -------------------------------------------------------------------------------- 1 | # 2 | # This is the MIT License 3 | # http://www.opensource.org/licenses/mit-license.php 4 | # 5 | # Copyright (c) 2007,2008 Nick Galbreath 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | # 25 | 26 | import os 27 | import sys 28 | 29 | #http://www.noah.org/wiki/Daemonize_Python 30 | def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): 31 | 32 | # Do first fork. 33 | try: 34 | pid = os.fork() 35 | if pid > 0: 36 | sys.exit(0) # Exit first parent. 37 | except OSError, e: 38 | sys.stderr.write ("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror) ) 39 | sys.exit(1) 40 | 41 | # Decouple from parent environment. 42 | os.chdir("/") 43 | os.umask(0) 44 | os.setsid() 45 | 46 | # Do second fork. 47 | try: 48 | pid = os.fork() 49 | if pid > 0: 50 | sys.exit(0) # Exit second parent. 51 | except OSError, e: 52 | sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) ) 53 | sys.exit(1) 54 | 55 | # Now I am a daemon! 56 | 57 | # Redirect standard file descriptors. 58 | si = open(stdin, 'r') 59 | so = open(stdout, 'a+') 60 | se = open(stderr, 'a+', 0) 61 | os.dup2(si.fileno(), sys.stdin.fileno()) 62 | os.dup2(so.fileno(), sys.stdout.fileno()) 63 | os.dup2(se.fileno(), sys.stderr.fileno()) 64 | 65 | 66 | def drop_privileges(uid_name='nobody', gid_name='nogroup'): 67 | import pwd, grp 68 | 69 | starting_uid = os.getuid() 70 | starting_gid = os.getgid() 71 | 72 | starting_uid_name = pwd.getpwuid(starting_uid)[0] 73 | 74 | if os.getuid() != 0: 75 | # We're not root so, like, whatever dude 76 | return 77 | 78 | if starting_uid == 0: 79 | 80 | # Get the uid/gid from the name 81 | running_uid = pwd.getpwnam(uid_name)[2] 82 | #running_gid = grp.getgrnam(gid_name)[2] 83 | 84 | # Try setting the new uid/gid 85 | #os.setgid(running_gid) 86 | os.setuid(running_uid) 87 | 88 | new_umask = 077 89 | old_umask = os.umask(new_umask) 90 | sys.stderr.write('drop_privileges: Old umask: %s, new umask: %s\n' % \ 91 | (oct(old_umask), oct(new_umask))) 92 | 93 | final_uid = os.getuid() 94 | final_gid = os.getgid() 95 | sys.stderr.write('drop_privileges: running as %s/%s\n' % \ 96 | (pwd.getpwuid(final_uid)[0], 97 | grp.getgrgid(final_gid)[0])) 98 | 99 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/type/GMetricInteger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric.type; 25 | 26 | import info.ganglia.metric.GMetric; 27 | import info.ganglia.metric.Incrementable; 28 | import info.ganglia.metric.Metricable; 29 | 30 | import java.io.IOException; 31 | import java.util.concurrent.atomic.AtomicInteger; 32 | 33 | 34 | /** 35 | * Integer implementation of GMetric using AtomicInteger 36 | * 37 | * @author Chris Bowling 38 | */ 39 | public class GMetricInteger extends GMetric implements Metricable, Incrementable { 40 | private AtomicInteger valueInt = new AtomicInteger(0); 41 | 42 | /** 43 | * Contstructor calls super 44 | * @param host 45 | * The hostname of the client server 46 | * @param name 47 | * The name of the metric (e.g. "CPU Usage"). Shows on graph 48 | * @param type 49 | * The type of the value. See GMetric constants. 50 | * @param units 51 | * The units used to measure the metric. Shows on graph 52 | * @param slope 53 | * See GMetric constants. 54 | * @param additive 55 | * If false the GMetric values are reset to 0 after update. If true the GMetric values are additive. 56 | * @throws IOException 57 | */ 58 | public GMetricInteger(String host, String name, String type, String units, int slope, boolean additive) { 59 | super(host, name, type, units, slope, additive); 60 | } 61 | 62 | /* (non-Javadoc) 63 | * @see info.ganglia.metric.Incrementable#incrementValue() 64 | */ 65 | public void incrementValue() { 66 | valueInt.getAndIncrement(); 67 | } 68 | 69 | /** 70 | * Increments current GMetric value by value argument 71 | * @param value increment GMetric value by value argument 72 | */ 73 | public void incrementValue(int value) { 74 | valueInt.addAndGet(value); 75 | } 76 | 77 | /** 78 | * Sets current GMetric value to value argument 79 | * @param value set GMetric to new value 80 | */ 81 | public void setValue(int value) { 82 | valueInt.set(value); 83 | } 84 | 85 | /* (non-Javadoc) 86 | * @see info.ganglia.metric.Metricable#clearValue() 87 | */ 88 | public void clearValue() { 89 | valueInt.set(0); 90 | } 91 | 92 | /* (non-Javadoc) 93 | * @see info.ganglia.metric.Metricable#getValueData() 94 | */ 95 | public byte[] getValueData() { 96 | byte[] valueBytes = null; 97 | valueBytes = writeValue(valueInt.toString()); 98 | return valueBytes; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gmond-debug/bin/gmond-debug: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'pp' 4 | require File.expand_path("../../lib/gmond-debug.rb", __FILE__) 5 | 6 | defaults= { :port => 1234, 7 | :host => "127.0.0.1", 8 | :gmond_host => "127.0.0.1", 9 | :gmond_port => 8649, 10 | :gmond_interval => 0 , 11 | :zmq_host => "127.0.0.1", 12 | :zmq_port => 7777, 13 | :verbose => false, 14 | :test_zmq => false 15 | } 16 | 17 | # Set defaults 18 | runner= Dante::Runner.new('gmond-zmq',defaults) 19 | 20 | # Set description in the help 21 | runner.description = "A gmond UDP receiver that pushes things to a 0mq Pub/Sub" 22 | 23 | # Set custom options 24 | runner.with_options do |opts| 25 | 26 | # Gmond options 27 | opts.on("--gmond-host [HOST]", String, "hostname/ip address of the gmond to poll") do |gmondhost| 28 | options[:gmond_host] = gmondhost 29 | end 30 | opts.on("--gmond-port [PORT]", Integer, "tcp port of the gmond to poll") do |gmonport| 31 | options[:gmond_port] = gmondport 32 | end 33 | opts.on("--gmond-interval [seconds]", Integer, "interval to poll the gmond, 0 = disable") do |gmondinterval| 34 | options[:gmond_interval] = gmondinterval 35 | end 36 | 37 | # Zmq options 38 | opts.on("--zmq-port [PORT]", Integer, "tcp port of the zmq publisher, 7777 default") do |zmqport| 39 | options[:zmq_port] = zmqport 40 | end 41 | opts.on("--zmq-host [HOST]", String, "hostname/ip address of the zmq publisher") do |zmqhost| 42 | options[:zmq_host] = zmqhost 43 | end 44 | 45 | opts.on("-v","--verbose", "more verbose output") do |verbose| 46 | options[:verbose] = verbose 47 | end 48 | 49 | opts.on("-t","--test-zmq", "Starts a test zmq subscriber") do |test_zmq| 50 | options[:test_zmq] = test_zmq 51 | end 52 | 53 | end 54 | 55 | # Main execution loop 56 | runner.execute do |opts| 57 | 58 | puts "With the following options:" 59 | pp opts 60 | 61 | # Overriding the trap from dante 62 | trap("INT") { 63 | puts "Cleanly stopping event machine" 64 | EM.stop() 65 | } 66 | 67 | # opts: host, pid_path, port, daemonize, user, group 68 | begin 69 | EventMachine::run { 70 | 71 | # Process our settings 72 | host,port = opts[:host],opts[:port] 73 | gmond_host,gmond_port = opts[:gmond_host],opts[:gmond_port] 74 | gmond_interval = opts[:gmond_interval] 75 | #zmq_host,zmq_port = opts[:zmq_host],opts[:zmq_port] 76 | verbose=opts[:verbose] 77 | #test_zmq=opts[:test_zmq] 78 | 79 | # Start our ZMQ Publisher 80 | #zmq_ctx = EM::ZeroMQ::Context.new(1) 81 | #zmq_push_socket = zmq_ctx.bind( ZMQ::PUB, "tcp://#{zmq_host}:#{zmq_port}") 82 | 83 | # Start our own Gmond UDP listener 84 | EventMachine::open_datagram_socket(host,port,LocalGmondHandler) do |conn| 85 | #conn.zmq_push_socket = zmq_push_socket 86 | conn.verbose = verbose 87 | end 88 | 89 | # Start poller for another gmond instance 90 | # -> if an interval > 0 91 | if gmond_interval > 0 92 | EventMachine::add_periodic_timer( gmond_interval ) { 93 | EventMachine::connect gmond_host, gmond_port, RemoteGmondHandler do |conn| 94 | #conn.zmq_push_socket = zmq_push_socket 95 | conn.verbose = verbose 96 | end 97 | } 98 | end 99 | 100 | # Start a keep alive output 101 | if verbose 102 | EventMachine::add_periodic_timer( 5 ) { 103 | $stderr.write "*" 104 | } 105 | end 106 | 107 | puts "Now accepting gmond udp connections on address #{host}, port #{port}..." 108 | } 109 | rescue Interrupt 110 | # We never get here 111 | puts "Performing a clean shutdown" 112 | end 113 | 114 | end 115 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/type/GMetricFloat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric.type; 25 | 26 | import info.ganglia.metric.GMetric; 27 | import info.ganglia.metric.Incrementable; 28 | import info.ganglia.metric.Metricable; 29 | 30 | import java.io.IOException; 31 | 32 | 33 | /** 34 | * Float implementation of GMetric. Uses method synchronization for thread safety. 35 | * Performance loss from using this synchronization method is acknowledged and using the methods described in java.util.concurrent.atomic could improve this if necessary. 36 | * 37 | * @author Chris Bowling 38 | */ 39 | public class GMetricFloat extends GMetric implements Metricable, Incrementable { 40 | private float valueFloat = 0; 41 | 42 | /** 43 | * 44 | * @param host 45 | * The hostname of the client server 46 | * @param name 47 | * The name of the metric (e.g. "CPU Usage"). Shows on graph 48 | * @param type 49 | * The type of the value. See GMetric constants. 50 | * @param units 51 | * The units used to measure the metric. Shows on graph 52 | * @param slope 53 | * See GMetric constants. 54 | * @param additive 55 | * If false the GMetric values are reset to 0 after update. If true the GMetric values are additive. 56 | * @throws IOException 57 | */ 58 | public GMetricFloat(String host, String name, String type, String units, int slope, boolean additive) { 59 | super(host, name, type, units, slope, additive); 60 | } 61 | 62 | /* (non-Javadoc) 63 | * @see info.ganglia.metric.Incrementable#incrementValue() 64 | */ 65 | public synchronized void incrementValue() { 66 | valueFloat++; 67 | } 68 | 69 | /** 70 | * Increments current GMetric value by value argument 71 | * @param value increment GMetric value by value argument 72 | */ 73 | public synchronized void incrementValue(float value) { 74 | valueFloat += value; 75 | } 76 | 77 | /** 78 | * Sets current GMetric value to value argument 79 | * @param value set GMetric to new value 80 | */ 81 | public synchronized void setValue(float value) { 82 | valueFloat = value; 83 | } 84 | 85 | /* (non-Javadoc) 86 | * @see info.ganglia.metric.Metricable#clearValue() 87 | */ 88 | public synchronized void clearValue() { 89 | valueFloat = 0; 90 | } 91 | 92 | /* (non-Javadoc) 93 | * @see info.ganglia.metric.Metricable#getValueData() 94 | */ 95 | public byte[] getValueData() { 96 | byte[] valueBytes = null; 97 | valueBytes = writeValue(Float.toString(valueFloat)); 98 | return valueBytes; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gmetric-java/src/java/info/ganglia/metric/type/GMetricDouble.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the MIT License 3 | * http://www.opensource.org/licenses/mit-license.php 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | package info.ganglia.metric.type; 25 | 26 | import info.ganglia.metric.GMetric; 27 | import info.ganglia.metric.Incrementable; 28 | import info.ganglia.metric.Metricable; 29 | 30 | import java.io.IOException; 31 | 32 | 33 | /** 34 | * Double implementation of GMetric. Uses method synchronization for thread safety. 35 | * Performance loss from using this synchronization method is acknowledged and using the methods described in java.util.concurrent.atomic could improve this if necessary. 36 | * 37 | * @author Chris Bowling 38 | */ 39 | public class GMetricDouble extends GMetric implements Metricable, Incrementable { 40 | private double valueDouble = 0; 41 | 42 | /** 43 | * 44 | * @param host 45 | * The hostname of the client server 46 | * @param name 47 | * The name of the metric (e.g. "CPU Usage"). Shows on graph 48 | * @param type 49 | * The type of the value. See GMetric constants. 50 | * @param units 51 | * The units used to measure the metric. Shows on graph 52 | * @param slope 53 | * See GMetric constants. 54 | * @param additive 55 | * If false the GMetric values are reset to 0 after update. If true the GMetric values are additive. 56 | * @throws IOException 57 | */ 58 | public GMetricDouble(String host, String name, String type, String units, int slope, boolean additive) { 59 | super(host, name, type, units, slope, additive); 60 | } 61 | 62 | /* (non-Javadoc) 63 | * @see info.ganglia.metric.Incrementable#incrementValue() 64 | */ 65 | public synchronized void incrementValue() { 66 | valueDouble++; 67 | } 68 | 69 | /** 70 | * Increments current GMetric value by value argument 71 | * @param value increment GMetric value by value argument 72 | */ 73 | public synchronized void incrementValue(double value) { 74 | valueDouble += value; 75 | } 76 | 77 | /** 78 | * Sets current GMetric value to value argument 79 | * @param value set GMetric to new value 80 | */ 81 | public synchronized void setValue(double value) { 82 | valueDouble = value; 83 | } 84 | 85 | /* (non-Javadoc) 86 | * @see info.ganglia.metric.Metricable#clearValue() 87 | */ 88 | public synchronized void clearValue() { 89 | valueDouble = 0; 90 | } 91 | 92 | /* (non-Javadoc) 93 | * @see info.ganglia.metric.Metricable#getValueData() 94 | */ 95 | public byte[] getValueData() { 96 | byte[] valueBytes = null; 97 | valueBytes = writeValue(Double.toString(valueDouble)); 98 | return valueBytes; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gmond-debug/lib/gmond-debug/gmondpacket.rb: -------------------------------------------------------------------------------- 1 | # Inspiration 2 | # https://github.com/fastly/ganglia/blob/master/lib/gm_protocol.x 3 | # https://github.com/igrigorik/gmetric/blob/master/lib/gmetric.rb 4 | # https://github.com/ganglia/monitor-core/blob/master/gmond/gmond.c#L1211 5 | # https://github.com/ganglia/ganglia_contrib/blob/master/gmetric-python/gmetric.py#L107 6 | # https://gist.github.com/1377993 7 | # http://rubyforge.org/projects/ruby-xdr/ 8 | 9 | require 'gmond-debug/xdr' 10 | class GmonPacket 11 | 12 | def initialize(packet) 13 | @xdr=XDR::Reader.new(StringIO.new(packet)) 14 | 15 | # Read packet type 16 | type=@xdr.uint32 17 | case type 18 | when 128 19 | @type=:meta 20 | when 132 21 | @type=:heartbeat 22 | when 133..134 23 | @type=:data 24 | when 135 25 | @type=:gexec 26 | else 27 | @type=:unknown 28 | end 29 | end 30 | 31 | def heartbeat? 32 | @type == :hearbeat 33 | end 34 | 35 | def data? 36 | @type == :data 37 | end 38 | 39 | def meta? 40 | @type == :meta 41 | end 42 | 43 | # Parsing a metadata packet : type 128 44 | def parse_metadata 45 | meta=Hash.new 46 | meta['hostname']=@xdr.string 47 | meta['name']=@xdr.string 48 | meta['spoof']=@xdr.uint32 49 | meta['type']=@xdr.string 50 | meta['name2']=@xdr.string 51 | meta['units']=@xdr.string 52 | slope=@xdr.uint32 53 | 54 | case slope 55 | when 0 56 | meta['slope']= 'zero' 57 | when 1 58 | meta['slope']= 'positive' 59 | when 2 60 | meta['slope']= 'negative' 61 | when 3 62 | meta['slope']= 'both' 63 | when 4 64 | meta['slope']= 'unspecified' 65 | end 66 | 67 | meta['tmax']=@xdr.uint32 68 | meta['dmax']=@xdr.uint32 69 | nrelements=@xdr.uint32 70 | meta['nrelements']=nrelements 71 | unless nrelements.nil? 72 | extra={} 73 | for i in 1..nrelements 74 | name=@xdr.string 75 | extra[name]=@xdr.string 76 | end 77 | meta['extra']=extra 78 | end 79 | return meta 80 | end 81 | 82 | # Parsing a data packet : type 133..135 83 | # Requires metadata to be available for correct parsing of the value 84 | def parse_data(metadata) 85 | data=Hash.new 86 | data['hostname']=@xdr.string 87 | 88 | metricname=@xdr.string 89 | data['name']=metricname 90 | 91 | data['spoof']=@xdr.uint32 92 | data['format']=@xdr.string 93 | 94 | metrictype=name_to_type(metricname,metadata) 95 | 96 | if metrictype.nil? 97 | # Probably we got a data packet before a metadata packet 98 | puts "Received datapacket without metadata packet hostname=" + data['hostname'] + " metric=" + data['name'] + " format=" + data['format'] 99 | return nil 100 | end 101 | 102 | data['val']=parse_value(metrictype) 103 | 104 | # If we received a packet, last update was 0 time ago 105 | data['tn']=0 106 | return data 107 | end 108 | 109 | # Parsing a specific value of type 110 | # https://github.com/ganglia/monitor-core/blob/master/gmond/gmond.c#L1527 111 | def parse_value(type) 112 | value=:unknown 113 | case type 114 | when "int16": 115 | value=@xdr.int16 116 | when "uint16": 117 | value=@xdr.uint16 118 | when "uint32": 119 | value=@xdr.uint32 120 | when "int32": 121 | value=@xdr.int32 122 | when "float": 123 | value=@xdr.float32 124 | when "double": 125 | value=@xdr.float64 126 | when "string": 127 | value=@xdr.string 128 | else 129 | puts "Received unknown type #{type}" 130 | end 131 | return value 132 | end 133 | 134 | # Does lookup of metricname in metadata table to find the correct type 135 | def name_to_type(name,metadata) 136 | # Lookup this metric metadata 137 | meta=metadata[name] 138 | return nil if meta.nil? 139 | 140 | return meta['type'] 141 | end 142 | 143 | end 144 | -------------------------------------------------------------------------------- /ganglia-logtailer/debian/changelog: -------------------------------------------------------------------------------- 1 | ganglia-logtailer (1.9) stable; urgency=low 2 | 3 | * switching from os.system() with string interpolation to subprocess.call 4 | to protect the call out from bad metric names (eg special characters) 5 | * sanitizing the metric name before submission by stripping out all 6 | non-alphanumerics except hyphen, period, and underscore 7 | 8 | -- Ben Hartshorne Mon, 7 Apr 2014 17:48:00 -0700 9 | 10 | ganglia-logtailer (1.8) stable; urgency=low 11 | 12 | * adding missing as zero flag to squash bug where rare data flatlines the graphs 13 | 14 | -- Ben Hartshorne Fri, 4 Apr 2014 16:24:00 -0700 15 | 16 | ganglia-logtailer (1.7) stable; urgency=low 17 | 18 | * changed default logging level from INFO to ERROR. INFO was too verbose 19 | 20 | -- Ben Hartshorne Mon, 31 Oct 2011 16:27:34 -0700 21 | 22 | ganglia-logtailer (1.6) stable; urgency=low 23 | 24 | * added tmax and dmax as arguments to the GangliaMetricObject so that 25 | modules that need a different time period from every minute may tell 26 | gmetric to keep the metric around for longer. 27 | 28 | -- Ben Hartshorne Mon, 31 Oct 2011 16:15:12 -0700 29 | 30 | ganglia-logtailer (1.5) stable; urgency=low 31 | 32 | *submit patch from kazu@lindenlab.com. Add tomcatlogtailer, and import 33 | floor from math for ganglia-logtailer. 34 | 35 | -- Ben O'Connor Wed, 4 May 2011 16:21:15 -0700 36 | 37 | ganglia-logtailer (1.4) stable; urgency=low 38 | 39 | * changing query name in the Slapd module, normalizing to qps instead of 40 | total # queries 41 | * fixing a bug in ganglia-logtailer where the lack of a state file causes an 42 | sys.exit() to get caught by an exception handler and improperly reported 43 | 44 | -- Ben Hartshorne Wed, 13 Jan 2010 13:15:52 -0800 45 | 46 | ganglia-logtailer (1.3-4) stable; urgency=low 47 | 48 | * Added JavaGCLogtailer module for processing Java GC logs 49 | 50 | -- Vladimir Vuksan Tue, 19 Jan 2010 11:09:00 -0500 51 | 52 | ganglia-logtailer (1.3-3) stable; urgency=low 53 | 54 | * caught error in the ApacheVHostLogtailer module - the class was 55 | incorrectly named. Changed the name from WebApacheLogtailer to 56 | ApacheVHostLogtailer. 57 | 58 | -- Ben Hartshorne Fri, 4 Dec 2009 16:22:56 -0800 59 | 60 | ganglia-logtailer (1.3-2) stable; urgency=low 61 | 62 | * Added VarnishLogtailer script to parse out Varnish HTTP accelerator 63 | logs 64 | * Modified Makefile to add *.py from the modules directory 65 | 66 | -- Vladimir Vuksan Tue, 17 Nov 2009 17:50:00 -0500 67 | 68 | ganglia-logtailer (1.3-1) stable; urgency=low 69 | 70 | * Updated Makefile to actually install the two newer modules, 71 | ApacheVhostLogtailer and SlapdLogtailer 72 | 73 | -- Ben Hartshorne Thu, 5 Nov 2009 08:50:34 -0800 74 | 75 | ganglia-logtailer (1.2-1) stable; urgency=low 76 | 77 | * Changed the install target from /usr/bin to /usr/sbin, to match the 78 | filesystem heirarchy standard. 79 | * 80 | 81 | -- Ben Hartshorne Fri, 30 Oct 2009 06:44:09 -0700 82 | 83 | * Added the slapd logtailer module 84 | 85 | -- Jessica Yamasaki Thu, 29 Oct 2009 09:41:24 -0700 86 | 87 | ganglia-logtailer (1.1-2) stable; urgency=low 88 | 89 | * added comment to ganglia-logtailer where logic to include a lockfile would 90 | live. 91 | 92 | -- Ben Hartshorne Wed, 28 Oct 2009 06:42:56 -0700 93 | 94 | ganglia-logtailer (1.1-1) stable; urgency=low 95 | 96 | * Added BUGS file documenting a bug in logtail that can affect ganglia- 97 | logtailer. 98 | * Added VHostApacheLogtailer to crunch apache logs and return per-vhost 99 | metrics. 100 | * Removed creation of /usr/local/share/ganglia-logtailer by debian package. 101 | * Added "make deb" target. 102 | 103 | -- Lex Linden Fri, 23 Oct 2009 14:16:33 -0400 104 | 105 | ganglia-logtailer (1.0-1) stable; urgency=low 106 | 107 | * Initial release 108 | 109 | -- Lex Linden Wed, 21 Oct 2009 15:02:51 -0400 110 | -------------------------------------------------------------------------------- /gang2graph/Ganglia/GraphiteSender.pm: -------------------------------------------------------------------------------- 1 | # Drew Stephens 2 | # Copyright 2011, Clearspring, Inc. 3 | # 4 | # This is free software; you can redistribute it and/or modify it under 5 | # the same terms as the Perl 5 programming language system itself. 6 | use warnings; 7 | use strict; 8 | use v5.10; 9 | package Ganglia::GraphiteSender; 10 | 11 | use base qw(XML::SAX::ExpatXS); 12 | our @ISA = ('XML::SAX::ExpatXS'); 13 | 14 | use Carp qw/croak/; 15 | use IO::Socket::INET; 16 | 17 | my $debug = 0; 18 | 19 | sub new { 20 | my $class = shift; 21 | my %params = @_; 22 | 23 | my $self = { 24 | grid => '', 25 | cluster => '', 26 | host => '', 27 | metric => { 28 | name => '', 29 | val => '', 30 | }, 31 | 32 | skipHost => 0, 33 | 34 | now => time, 35 | socket => $params{socket}, 36 | include_hosts => defined $params{include_hosts} ? $params{include_hosts} : '.', 37 | exclude_hosts => defined $params{exclude_hosts} ? $params{exclude_hosts} : '', 38 | metrics => 0, 39 | }; 40 | 41 | bless $self, $class; 42 | return $self; 43 | } 44 | 45 | sub start_element { 46 | my ($self, $data) = @_; 47 | 48 | # Move along if we're skipping this host 49 | return if ($self->{skipHost} == 1); 50 | 51 | if ($data->{LocalName} eq 'METRIC') { 52 | $self->_handleMetric($data); 53 | } elsif ($data->{LocalName} eq 'HOST') { 54 | # Skip hosts that aren't in the includeHosts list 55 | unless (grep {$data->{Attributes}->{'{}NAME'}->{Value} =~ /$_/} @{$self->{include_hosts}}) { 56 | $self->{skipHost} = 1; 57 | return; 58 | } 59 | # Skip hosts that are in the excludeHosts list 60 | if (grep {$data->{Attributes}->{'{}NAME'}->{Value} =~ /$_/} @{$self->{exclude_hosts}}) { 61 | $self->{skipHost} = 1; 62 | return; 63 | } 64 | 65 | $self->_handleHost($data); 66 | } elsif ($data->{LocalName} eq 'GRID') { 67 | $self->_handleGrid($data); 68 | } elsif ($data->{LocalName} eq 'CLUSTER') { 69 | $self->_handleCluster($data); 70 | } 71 | } 72 | 73 | sub end_element { 74 | my ($self, $data) = @_; 75 | 76 | if ($data->{LocalName} eq 'METRIC') { 77 | } elsif ($data->{LocalName} eq 'HOST') { 78 | # Reset the skipHost flag 79 | $self->{skipHost} = 0 if ($data->{LocalName} eq 'HOST'); 80 | } elsif ($data->{LocalName} eq 'GRID') { 81 | print "Ending grid " . $self->{grid} . "\n" if ($debug); 82 | } elsif ($data->{LocalName} eq 'CLUSTER') { 83 | print " Ending cluster " . $self->{cluster} . "\n" if ($debug); 84 | } 85 | } 86 | 87 | sub end_document { 88 | my ($self, $data) = @_; 89 | $self->{socket}->close(); 90 | print "Processed " . $self->{metrics} . " metrics\n" if ($debug); 91 | } 92 | 93 | sub _handleGrid { 94 | my ($self, $data) = @_; 95 | $self->{grid} = $data->{Attributes}->{'{}NAME'}->{Value}; 96 | $self->{grid} =~ s/ /_/g; 97 | print "Starting grid " . $self->{grid} . "\n" if ($debug); 98 | } 99 | 100 | sub _handleCluster { 101 | my ($self, $data) = @_; 102 | $self->{cluster} = $data->{Attributes}->{'{}NAME'}->{Value}; 103 | $self->{cluster} =~ s/ /_/g; 104 | print " Starting cluster " . $self->{cluster} . "\n" if ($debug); 105 | } 106 | 107 | sub _handleHost { 108 | my ($self, $data) = @_; 109 | $self->{host} = $data->{Attributes}->{'{}NAME'}->{Value}; 110 | $self->{host} =~ s/ /_/g; 111 | print " Host " . $self->{host} . "\n" if ($debug); 112 | } 113 | 114 | sub _handleMetric { 115 | my ($self, $data) = @_; 116 | my $name = $data->{Attributes}->{'{}NAME'}->{Value}; 117 | my $val = $data->{Attributes}->{'{}VAL'}->{Value}; 118 | 119 | # Graphite doesn't do non-numeric things 120 | if ($val !~ /^[0-9.]*$/) { 121 | return; 122 | } 123 | 124 | my $graphiteString = $self->{grid} . '.' . $self->{cluster} . '.' . 125 | $self->{host} . '.' . "$name $val " . $self->{now} . "\n"; 126 | my $socket = $self->{socket}; 127 | print $socket $graphiteString; 128 | print " $graphiteString" if ($debug > 1); 129 | 130 | $self->{metrics}++; 131 | } 132 | 133 | 1; 134 | -------------------------------------------------------------------------------- /ganglia-go/gmondtest/gmondtest.go: -------------------------------------------------------------------------------- 1 | // Package gmondtest provides test helpers for gmond. 2 | package gmondtest 3 | 4 | import ( 5 | "fmt" 6 | "io/ioutil" 7 | "net" 8 | "os" 9 | "os/exec" 10 | "testing" 11 | "text/template" 12 | "time" 13 | 14 | "github.com/daaku/go.freeport" 15 | "github.com/daaku/go.subset" 16 | "github.com/davecgh/go-spew/spew" 17 | 18 | "github.com/ganglia/ganglia_contrib/ganglia-go/gmetric" 19 | "github.com/ganglia/ganglia_contrib/ganglia-go/gmon" 20 | ) 21 | 22 | const localhostIP = "127.0.0.1" 23 | 24 | var configTemplate, configTemplateErr = template.New("config").Parse(` 25 | globals { 26 | daemonize = no 27 | setuid = false 28 | debug_level = 0 29 | max_udp_msg_len = 1472 30 | mute = no 31 | deaf = no 32 | allow_extra_data = yes 33 | host_dmax = 864000 34 | } 35 | 36 | cluster { 37 | name = "gmetric_test" 38 | owner = "gmetric_test" 39 | latlong = "gmetric_test" 40 | url = "gmetric_test" 41 | } 42 | 43 | host { 44 | location = "gmetric_test" 45 | } 46 | 47 | udp_recv_channel { 48 | port = {{.Port}} 49 | family = inet4 50 | } 51 | 52 | udp_recv_channel { 53 | port = {{.Port}} 54 | family = inet6 55 | } 56 | 57 | tcp_accept_channel { 58 | port = {{.Port}} 59 | } 60 | `) 61 | 62 | func init() { 63 | if configTemplateErr != nil { 64 | panic(configTemplateErr) 65 | } 66 | } 67 | 68 | // The Harness provides an unique instance of gmond suitable for use in 69 | // testing. Use NewHarness to create a Harness and start the gmond server, and 70 | // ensure you 'defer h.Stop()' to shutdown the gmond server once the test has 71 | // finished. 72 | type Harness struct { 73 | Client *gmetric.Client 74 | t *testing.T 75 | port int 76 | configPath string 77 | cmd *exec.Cmd 78 | } 79 | 80 | func (h *Harness) start() { 81 | var err error 82 | if h.port == 0 { 83 | if h.port, err = freeport.Get(); err != nil { 84 | h.t.Fatal(err) 85 | } 86 | } 87 | 88 | cf, err := ioutil.TempFile("", "gmetric_test_gmond_conf") 89 | if err != nil { 90 | h.t.Fatal(err) 91 | } 92 | h.configPath = cf.Name() 93 | 94 | td := struct{ Port int }{Port: h.port} 95 | if err := configTemplate.Execute(cf, td); err != nil { 96 | h.t.Fatal(err) 97 | } 98 | 99 | if err := cf.Close(); err != nil { 100 | h.t.Fatal(err) 101 | } 102 | 103 | h.cmd = exec.Command("gmond", "--conf", h.configPath) 104 | h.cmd.Stderr = os.Stderr 105 | h.cmd.Stdout = os.Stdout 106 | if err := h.cmd.Start(); err != nil { 107 | h.t.Fatal(err) 108 | } 109 | 110 | // Wait until TCP socket is active to ensure we don't progress until the 111 | // server is ready to accept. 112 | for { 113 | if c, err := net.Dial("tcp", fmt.Sprintf("%s:%d", localhostIP, h.port)); err == nil { 114 | c.Close() 115 | break 116 | } 117 | } 118 | 119 | h.Client = &gmetric.Client{ 120 | Addr: []net.Addr{ 121 | &net.UDPAddr{IP: net.ParseIP(localhostIP), Port: h.port}, 122 | }, 123 | } 124 | 125 | if err := h.Client.Open(); err != nil { 126 | h.t.Fatal(err) 127 | } 128 | } 129 | 130 | // Stop the associated gmond server. 131 | func (h *Harness) Stop() { 132 | if err := h.Client.Close(); err != nil { 133 | h.t.Fatal(err) 134 | } 135 | 136 | if err := h.cmd.Process.Kill(); err != nil { 137 | h.t.Fatal(err) 138 | } 139 | 140 | if err := os.Remove(h.configPath); err != nil { 141 | h.t.Fatal(err) 142 | } 143 | } 144 | 145 | // Returns the current state of the associated gmond instance. 146 | func (h *Harness) State() *gmon.Ganglia { 147 | addr := fmt.Sprintf("%s:%d", localhostIP, h.port) 148 | ganglia, err := gmon.RemoteRead("tcp", addr) 149 | if err != nil { 150 | h.t.Fatal(err) 151 | } 152 | return ganglia 153 | } 154 | 155 | // Check if associated gmond instance contains the given metric. 156 | func (h *Harness) ContainsMetric(m *gmon.Metric) { 157 | deadline := time.Now().Add(5 * time.Second) 158 | for { 159 | g := h.State() 160 | for _, cluster := range g.Clusters { 161 | for _, host := range cluster.Hosts { 162 | for _, metric := range host.Metrics { 163 | if subset.Check(m, &metric) { 164 | return 165 | } 166 | } 167 | } 168 | } 169 | 170 | if time.Now().After(deadline) { 171 | h.t.Fatalf("did not find metric\n%s\n--in--\n%s", spew.Sdump(m), spew.Sdump(g)) 172 | } 173 | } 174 | } 175 | 176 | // Create a new Harness. It will start the server and initialize the container 177 | // Client. 178 | func NewHarness(t *testing.T) *Harness { 179 | h := &Harness{t: t} 180 | h.start() 181 | return h 182 | } 183 | -------------------------------------------------------------------------------- /pmond/pmond/gweb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # SUPER LOW LEVEL WEBSERVER 5 | # Sorta like CGI if anyone remembers that 6 | # 7 | # 8 | from wsgiref.simple_server import make_server 9 | from wsgiref.util import FileWrapper 10 | from wsgiref.util import shift_path_info 11 | import cgi 12 | import mimetypes 13 | import os.path 14 | import glob 15 | import os.path 16 | import gparse 17 | import ggraph 18 | 19 | static_root = '.' 20 | rrd_root = '/tmp' 21 | img_root = '/tmp' 22 | 23 | def sendfile(fname, start_response): 24 | status = "200 OK" 25 | mtype = 'text/plain' 26 | try: 27 | f = open(fname, 'r'); data = f.read(); f.close() 28 | m = mimetypes.guess_type(fname) 29 | if m[0] is not None: mtype = m[0] 30 | except IOError,e: 31 | data = str(e) + '\n' 32 | status = "404 Not Found" 33 | start_response(status, [('Content-Type', mtype)]) 34 | return [ data ] 35 | 36 | def static(environ, start_response): 37 | # shift PATH_INFO /static/foo ----> /foo 38 | # then skip first '/' 39 | # and merge with static_root 40 | shift_path_info(environ) 41 | filename = os.path.abspath(os.path.join(static_root, 42 | environ['PATH_INFO'][1:])) 43 | return sendfile(fname, start_response) 44 | 45 | def overview(environ, start_response): 46 | qs = cgi.parse_qs(environ['QUERY_STRING']) 47 | host = qs['host'][0] 48 | duration = qs['duration'][0] 49 | width = qs['width'][0] 50 | status = '200 OK' 51 | headers = [('Content-type', 'text/html')] 52 | start_response(status, headers) 53 | html = ["%s
    " % host] 54 | for metric in ('cpu', 'memory', 'load', 'network'): 55 | html.append('' % (host, metric, duration, width)) 56 | html.append("") 57 | return html 58 | 59 | def hostlist(environ, start_response): 60 | # just get everyfile underneath 'rrd_root' and see 61 | # if they are a directorya 62 | hosts = [] 63 | files = glob.glob(rrd_root + '/*') 64 | for f in files: 65 | if os.path.isdir(f): 66 | hosts.append(os.path.basename(f)) 67 | status = '200 OK' 68 | headers = [('Content-type', 'text/html')] 69 | start_response(status, headers) 70 | html = ["HOSTS
      "] 71 | for h in hosts: 72 | html.append('
    • %s
    • \n' % (h,h)) 73 | html.append("""
    """) 74 | return html 75 | 76 | def rrd(environ, start_response): 77 | shift_path_info(environ) 78 | filename = os.path.abspath(os.path.join(static_root, 79 | environ['PATH_INFO'][1:])) 80 | qs = cgi.parse_qs(environ['QUERY_STRING']) 81 | host = qs['host'][0] 82 | metric = qs['metric'][0] 83 | duration = qs['duration'][0] 84 | 85 | # optional 86 | width = 400 87 | if 'width' in qs: 88 | width = int(qs['width'][0]) 89 | 90 | fname = ggraph.make_graph(rrd_root, img_root, host, metric, duration, width) 91 | 92 | return sendfile(fname, start_response) 93 | 94 | # just for debugging 95 | def echo(environ, start_response): 96 | status = '200 OK' 97 | headers = [('Content-type', 'text/plain')] 98 | start_response(status, headers) 99 | text = [] 100 | keys = sorted(environ.keys()) 101 | for k in keys: 102 | text.append("%s = %s\n" % (k,environ[k])) 103 | return text 104 | 105 | def dispatch(environ, start_response): 106 | path = environ['PATH_INFO'] 107 | if path == '/': 108 | return hostlist(environ, start_response) 109 | if path == '/overview': 110 | return overview(environ, start_response) 111 | if path == '/echo': 112 | return echo(environ, start_response) 113 | if path == '/rrd': 114 | return rrd(environ, start_response) 115 | 116 | # remap common webby things into the static directory 117 | if path == '/favicon.txt' or path == '/robots.txt': 118 | path = '/static' + path 119 | environ['PATH_INFO'] = path 120 | if path.startswith('/static'): 121 | return static(environ, start_response) 122 | 123 | # nothing matched, do 404 124 | status = "404 Not Found" 125 | start_response(status, [('Content-Type', 'text/plain')]) 126 | return [ "%s not found" % path ] 127 | 128 | 129 | if __name__ == '__main__': 130 | httpd = make_server('', 8000, dispatch) 131 | print "Serving on port 8000..." 132 | 133 | # Serve until process is killed 134 | httpd.serve_forever() 135 | -------------------------------------------------------------------------------- /ganglia-alert/init.d-debian: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: ganglia-alert 4 | # Required-Start: $network $named $remote_fs $syslog gmetad 5 | # Required-Stop: $network $named $remote_fs $syslog gmetad 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: ganglia-alert 9 | # Description: Sends alerts using metrics from ganglia 10 | ### END INIT INFO 11 | 12 | # Author: Giovanni Toraldo 13 | 14 | # Do NOT "set -e" 15 | 16 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 17 | DESC="ganglia-alert" 18 | NAME=ganglia-alert 19 | DAEMON=/usr/bin/$NAME 20 | DAEMON_ARGS="-d" 21 | PIDFILE=/var/run/$NAME.pid 22 | SCRIPTNAME=/etc/init.d/$NAME 23 | 24 | # Exit if the package is not installed 25 | [ -x "$DAEMON" ] || exit 0 26 | 27 | # Read configuration variable file if it is present 28 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 29 | 30 | # Load the VERBOSE setting and other rcS variables 31 | . /lib/init/vars.sh 32 | 33 | # Define LSB log_* functions. 34 | # Depend on lsb-base (>= 3.2-14) to ensure that this file is present 35 | # and status_of_proc is working. 36 | . /lib/lsb/init-functions 37 | 38 | # 39 | # Function that starts the daemon/service 40 | # 41 | do_start() 42 | { 43 | # Return 44 | # 0 if daemon has been started 45 | # 1 if daemon was already running 46 | # 2 if daemon could not be started 47 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ 48 | || return 1 49 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ 50 | $DAEMON_ARGS \ 51 | || return 2 52 | # Add code here, if necessary, that waits for the process to be ready 53 | # to handle requests from services started subsequently which depend 54 | # on this one. As a last resort, sleep for some time. 55 | } 56 | 57 | # 58 | # Function that stops the daemon/service 59 | # 60 | do_stop() 61 | { 62 | # Return 63 | # 0 if daemon has been stopped 64 | # 1 if daemon was already stopped 65 | # 2 if daemon could not be stopped 66 | # other if a failure occurred 67 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME 68 | RETVAL="$?" 69 | [ "$RETVAL" = 2 ] && return 2 70 | # Wait for children to finish too if this is a daemon that forks 71 | # and if the daemon is only ever run from this initscript. 72 | # If the above conditions are not satisfied then add some other code 73 | # that waits for the process to drop all resources that could be 74 | # needed by services started subsequently. A last resort is to 75 | # sleep for some time. 76 | start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON 77 | [ "$?" = 2 ] && return 2 78 | # Many daemons don't delete their pidfiles when they exit. 79 | rm -f $PIDFILE 80 | return "$RETVAL" 81 | } 82 | 83 | # 84 | # Function that sends a SIGHUP to the daemon/service 85 | # 86 | do_reload() { 87 | # 88 | # If the daemon can reload its configuration without 89 | # restarting (for example, when it is sent a SIGHUP), 90 | # then implement that here. 91 | # 92 | start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME 93 | return 0 94 | } 95 | 96 | case "$1" in 97 | start) 98 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 99 | do_start 100 | case "$?" in 101 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 102 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 103 | esac 104 | ;; 105 | stop) 106 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 107 | do_stop 108 | case "$?" in 109 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 110 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 111 | esac 112 | ;; 113 | status) 114 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 115 | ;; 116 | #reload|force-reload) 117 | # 118 | # If do_reload() is not implemented then leave this commented out 119 | # and leave 'force-reload' as an alias for 'restart'. 120 | # 121 | #log_daemon_msg "Reloading $DESC" "$NAME" 122 | #do_reload 123 | #log_end_msg $? 124 | #;; 125 | restart|force-reload) 126 | # 127 | # If the "reload" option is implemented then remove the 128 | # 'force-reload' alias 129 | # 130 | log_daemon_msg "Restarting $DESC" "$NAME" 131 | do_stop 132 | case "$?" in 133 | 0|1) 134 | do_start 135 | case "$?" in 136 | 0) log_end_msg 0 ;; 137 | 1) log_end_msg 1 ;; # Old process is still running 138 | *) log_end_msg 1 ;; # Failed to start 139 | esac 140 | ;; 141 | *) 142 | # Failed to stop 143 | log_end_msg 1 144 | ;; 145 | esac 146 | ;; 147 | *) 148 | #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 149 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 150 | exit 3 151 | ;; 152 | esac 153 | 154 | : 155 | -------------------------------------------------------------------------------- /gmond-debug/README.md: -------------------------------------------------------------------------------- 1 | GMOND-DEBUG 2 | =========== 3 | 4 | BUILDING 5 | -------- 6 | 7 | ``` 8 | . source.env 9 | for i in gems/cache/*.gem; do gem install $i; done 10 | ``` 11 | 12 | RUNNING 13 | ------- 14 | 15 | ``` 16 | . source.env 17 | ./bin/gmond-debug 18 | ``` 19 | 20 | 21 | OLD DOCUMENTATION 22 | ----------------- 23 | 24 | ### What is this project about: 25 | 26 | There is not one monitoring project to rule them all: 27 | 28 | Ganglia, Graphite, Collectd, Opentsdb, ... they all have their specific unique functionality and their associate unique storage. 29 | 30 | Instead of trying to create one central storage, we want to send the different metric information, to each monitoring solution for their optimized function. 31 | 32 | This project's code will: 33 | 34 | - listen into the gmond UDP protocol 35 | - optionally poll existing gmond's and put the message on to a 0mq (pub/sub). 36 | 37 | From there, other subscribers can pull the information into graphite, collectd, opentsdb etc.. 38 | 39 | We have deliberately chosen not to go for peer to peer communication, but for a bus/queue oriented system. 40 | 41 | It currently doesn't do more than put things on the queue, the next step is to write subscribers for the other monitoring systems. 42 | 43 | And maybe , just maybe, this will evolve into a swiss-army knife of monitoring/metrics conversion .... 44 | 45 | ### Thanks! 46 | 47 | A big thanks to Vladimir Vuksan (@vvuksan) for helping me out with the original proof of concept! 48 | 49 | ### Requirements: 50 | #### Centos 51 | 52 | # yum install libxml2-devel 53 | # yum install libxslt-devel 54 | # yum install zeromq-devel 55 | # yum install uuid-devel 56 | # yum install json-c-devel 57 | 58 | ### Configuring gmond 59 | 60 | Just add another udp send channel for your existing gmond's 61 | 62 | udp_send_channel { 63 | host = 127.0.0.1 64 | port = 1234 65 | } 66 | 67 | ### Running it: 68 | 69 | gmond-zmq - A gmond UDP receiver that pushes things to a 0mq Pub/Sub 70 | 71 | Usage: gmond-zmq [-p port] [-P file] [-d] [-k] 72 | gmond-zmq --help 73 | 74 | -p, --port PORT Specify port 75 | (default: 1234) 76 | -P, --pid FILE save PID in FILE when using -d option. 77 | (default: /var/run/gmond-zmq.pid) 78 | -d, --daemon Daemonize mode 79 | -k, --kill [PORT] Kill specified running daemons - leave blank to kill all. 80 | -u, --user USER User to run as 81 | -G, --group GROUP Group to run as 82 | --gmond-host [HOST] hostname/ip address of the gmond to poll 83 | --gmond-port [PORT] tcp port of the gmond to poll 84 | --gmond-interval [seconds] 85 | interval to poll the gmond, 0 = disable (default) 86 | --zmq-port [PORT] tcp port of the zmq publisher 87 | --zmq-host [HOST] hostname/ip address of the zmq publisher 88 | -v, --verbose more verbose output 89 | -t, --test-zmq Starts a test zmq subscriber 90 | -?, --help Display this usage information. 91 | 92 | ### Message examples 93 | 94 | {"timestamp":1324639623,"payload":{"name":"machine_type","val":"x86_64","slope":"zero","dmax":"0","tn":"809","units":"","type":"string","tmax":"1200","hostname":"localhost"},"id":"f6412a10-0f86-012f-0bdb-080027701f72","context":"METRIC","source":"GMOND"} 95 | {"timestamp":1324639623,"payload":{"name":"proc_total","val":"105","slope":"both","dmax":"0","tn":"89","units":" ","type":"uint32","tmax":"950","hostname":"localhost"},"id":"f6415250-0f86-012f-0bdc-080027701f72","context":"METRIC","source":"GMOND"} 96 | {"timestamp":1324639623,"payload":{"name":"cpu_num","val":"1","slope":"zero","dmax":"0","tn":"809","units":"CPUs","type":"uint16","tmax":"1200","hostname":"localhost"},"id":"f6417410-0f86-012f-0bdd-080027701f72","context":"METRIC","source":"GMOND"} 97 | {"timestamp":1324639623,"payload":{"name":"cpu_speed","val":"2800","slope":"zero","dmax":"0","tn":"809","units":"MHz","type":"uint32","tmax":"1200","hostname":"localhost"},"id":"f64186c0-0f86-012f-0bdf-080027701f72","context":"METRIC","source":"GMOND"} 98 | {"timestamp":1324639623,"payload":{"name":"pkts_out","val":"3.27","slope":"both","dmax":"0","tn":"49","units":"packets/sec","type":"float","tmax":"300","hostname":"localhost"},"id":"f641aa00-0f86-012f-0be0-080027701f72","context":"METRIC","source":"GMOND"} 99 | {"timestamp":1324639623,"payload":{"name":"swap_free","val":"741752","slope":"both","dmax":"0","tn":"89","units":"KB","type":"float","tmax":"180","hostname":"localhost"},"id":"f641c720-0f86-012f-0be1-080027701f72","context":"METRIC","source":"GMOND"} 100 | 101 | ### Some inspiration: 102 | 103 | - [The Ganglia XDR protocol](https://github.com/fastly/ganglia/blob/master/lib/gm_protocol.x) 104 | - [Gmetric library - ruby lib to send ganglia metrics](https://github.com/igrigorik/gmetric/blob/master/lib/gmetric.rb) 105 | - [Gmond Source code](https://github.com/ganglia/monitor-core/blob/master/gmond/gmond.c#L1211) 106 | - [Gmetric Python code](https://github.com/ganglia/ganglia_contrib/blob/master/gmetric-python/gmetric.py#L107) 107 | - [Vladimir Vuksan sample Python Gmond Listener code](https://gist.github.com/1377993) 108 | - [My initial sample Gmond listener code](https://gist.github.com/1376525) 109 | - [Ruby XDR gem](http://rubyforge.org/projects/ruby-xdr/) 110 | -------------------------------------------------------------------------------- /gmetric-java/doc/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Deprecated List 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Deprecated API

    81 |
    82 |
    83 | Contents
      84 |
    85 | 86 |
    87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 109 | 112 | 113 | 114 | 115 | 118 | 134 | 135 |
    110 | 111 |
    136 | 137 | 138 | 139 |
    140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Uses of Package info.ganglia 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Uses of Package
    info.ganglia

    81 |
    82 | No usage of info.ganglia 83 |

    84 |


    85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 107 | 110 | 111 | 112 | 113 | 116 | 132 | 133 |
    108 | 109 |
    134 | 135 | 136 | 137 |
    138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /ganglia-logtailer/README: -------------------------------------------------------------------------------- 1 | Imported from 2 | 3 | https://bitbucket.org/maplebed/ganglia-logtailer 4 | 5 | ################## 6 | ## 7 | ## ganglia-logtailer 8 | ## 9 | ## ganglia-logtailer is a python script that will tail any log file, 10 | ## crunch the data collected, and report summary data to ganglia. 11 | ## 12 | ## This directory contains the script ganglia-logtailer, its required 13 | ## helper classes, and two example classes, one generic and one for 14 | ## parsing Apache logs. 15 | ## 16 | ## Copyright Linden Lab, 2008 17 | ## License to modify and redistribute granted under the GPL v2 or later 18 | ## 19 | ################## 20 | 21 | 22 | 0. Table of Contents 23 | 1. Overview 24 | 2. Installation 25 | 3. License 26 | 27 | 1. Overview 28 | 29 | Many metrics associated with ganglia and gmetric plugins are rather easy to 30 | collect; you poll the relevant application for a value and report it. Examples 31 | are asking MySQL for the number of questions and calculating queries per 32 | second, or asking iostat for the percentage disk I/O currently being used. 33 | However, there are a large number of applications out there that don't support 34 | being queried for interesting data, but do provide a log file which, when 35 | properly parsed, yields the interesting data we desire. An example of the 36 | latter category is Apache, which does not furnish any interface for measuring 37 | queries per second, yet has a log file allowing you to count how many queries 38 | come in over a specific time period. 39 | 40 | ganglia-logtailer is designed to make it easy to parse any log file, pull out 41 | the information you desire, and plug it into ganglia to make pretty graphs. 42 | 43 | ganglia-logtailer is comprised of three parts: 44 | * ganglia-logtailer - the python script doing the real work 45 | * ganglia_logtailer_helper.py and tailnostate.py - supporting python classes 46 | * ApacheLogtailer.py, DummyLogtailer.py, etc. - user modifiable, log-file specific classes 47 | 48 | You must modify DummyLogtailer.py or write new FooLogtailer.py classes for 49 | each of the log files you wish to parse. As every log file has a specific 50 | format, you must write the regular expression to properly pick out interesting 51 | information for your specific application. As each application has different 52 | ways of expressing what might be interesting metrics to graph, you must write 53 | the functions to collect the information present in each line of the log file. 54 | 55 | DummyLogtailer.py is an example file; it does nothing other than count the 56 | number of lines present in the log file and report lines per second. However, 57 | it does have extensive comments explaining the purpose of each of the functions 58 | present in the file. I would recommend reading that file and modifying it to 59 | do more interesting things. 60 | 61 | ApacheLogtailer.py is a fully functional class parsing an Apache log. At 62 | Linden Lab, we use a custom log format (and include the very interesting %D - 63 | time to execute the query in microseconds), so the regular expression included 64 | there will probably have to be changed for your environment. 65 | ApacheLogtailer.py defines and returns the number of Apache requests per 66 | second, also broken out by return code (200, 300, 400, 500), and the average, 67 | maximum, and 90th percentile run time of all queries caught during the sample 68 | period. 69 | 70 | The rest of the *Logtailer.py classes present are customized for different 71 | types of logs (postfix, bind, etc.) 72 | 73 | ganglia-logtailer can be invoked in two different modes, either as a daemon 74 | (which tells it to run as a persistent process) or invoked from cron on a 75 | regular basis. I recommend using daemon mode for testing, but invoking it from 76 | cron every 1-5 minutes for deploy. I make this recommendation because (aside 77 | from minimizing the number of running daemons), there are no start scripts to 78 | invoke daemon mode on system boot, and there is no facility to relaunch the 79 | process if it were to crash or raise an exception. 80 | 81 | ganglia-logtailer will log certain bits of information to 82 | /var/log/ganglia/ganglia_logtailer in case of error. Log level is variable by 83 | modfying ganglia-logtailer and editing the following line: 84 | logger.setLevel(logging.INFO) Look up the 'logging' python module for valid 85 | values. (logging.DEBUG is a good bet) 86 | 87 | 2. Installation 88 | 89 | ganglia-logtailer depends on the 'logtail' package 90 | (http://packages.debian.org/etch/logtail) when run in cron mode. 91 | 92 | i. Copy ganglia-logtailer to /usr/local/bin/ (or wherever you store 93 | unpackaged binaries) 94 | ii. Copy ganglia_logtailer_helper.py and tailnostate.py to 95 | /usr/local/share/ganglia-logtailer (or somewhere in your python search 96 | path) 97 | iii. Copy ApacheLogtailer.py and DummyLogtailer.py to /usr/local/share/ganglia-logtailer 98 | (or somewhere in your python search path) 99 | 100 | Create the directory ganglia-logtailer uses to store state: 101 | /var/lib/ganglia-logtailer/ 102 | 103 | Test the installation by invoking ganglia-logtailer with the DummyLogtailer 104 | class on a log file: 105 | # ganglia-logtailer --classname DummyLogtailer --log_file /var/log/daemon.log --mode daemon 106 | wait 30s to 1m, then check and see whether your new metric is present in 107 | ganglia. 108 | 109 | If all goes well, try out one of the real modules: 110 | # ganglia-logtailer --classname PostfixLogtailer --log_file /var/log/mail.log --mode daemon 111 | 112 | If that works as well, deploy! Add the following to 113 | /etc/cron.d/ganglia-logtailer 114 | * * * * * root /usr/local/bin/ganglia-logtailer --classname PostfixLogtailer --log_file /var/log/mail.log --mode cron 115 | 116 | 3. License 117 | 118 | These scripts are all released under the GPL v2 or later. For a full 119 | description of the licence, please visit http://www.gnu.org/licenses/gpl.txt 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /gmetric-java/src/test/info/ganglia/GMetricTest.java: -------------------------------------------------------------------------------- 1 | package info.ganglia; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assert.fail; 5 | 6 | import info.ganglia.GMonitor; 7 | import info.ganglia.metric.GMetric; 8 | import info.ganglia.metric.type.GMetricDouble; 9 | import info.ganglia.metric.type.GMetricFloat; 10 | import info.ganglia.metric.type.GMetricInteger; 11 | import info.ganglia.metric.type.GMetricString; 12 | 13 | import java.io.ByteArrayOutputStream; 14 | import java.io.DataOutputStream; 15 | import java.io.IOException; 16 | import java.net.InetAddress; 17 | 18 | import org.junit.BeforeClass; 19 | import org.junit.Test; 20 | 21 | 22 | 23 | public class GMetricTest { 24 | public final static String MULTICAST_ADDRESS = "239.0.0.0"; 25 | private static String host; 26 | 27 | @BeforeClass 28 | public static void oneTimeSetUp() throws Exception { 29 | System.setProperty("ganglia.host", "239.0.0.0"); 30 | host = InetAddress.getLocalHost().getHostName(); 31 | } 32 | 33 | @Test 34 | @SuppressWarnings("unused") 35 | public void testMetricTypeConstructor() { 36 | try { 37 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 38 | GMetricInteger testMetric = (GMetricInteger) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_INT, "count", GMetric.SLOPE_UNSPECIFIED, true); 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | fail(); 42 | } 43 | } 44 | @Test 45 | @SuppressWarnings("unused") 46 | public void testMetricTypeConstructor2() { 47 | try { 48 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 49 | GMetricString testMetric = (GMetricString) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_STRING, "count", GMetric.SLOPE_UNSPECIFIED, true); 50 | } catch (IOException e) { 51 | e.printStackTrace(); 52 | fail(); 53 | } 54 | } 55 | @Test 56 | @SuppressWarnings("unused") 57 | public void testMetricTypeConstructor3() { 58 | try { 59 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 60 | GMetricFloat testMetric = (GMetricFloat) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_FLOAT, "count", GMetric.SLOPE_UNSPECIFIED, true); 61 | } catch (IOException e) { 62 | e.printStackTrace(); 63 | fail(); 64 | } 65 | } 66 | @Test 67 | @SuppressWarnings("unused") 68 | public void testMetricTypeConstructor4() { 69 | try { 70 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 71 | GMetricDouble testMetric = (GMetricDouble) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_DOUBLE, "count", GMetric.SLOPE_UNSPECIFIED, true); 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | fail(); 75 | } 76 | } 77 | 78 | @Test 79 | @SuppressWarnings("unused") 80 | public void testMetricTypeConstructor5() { 81 | try { 82 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 83 | GMetricInteger testMetric = (GMetricInteger) gmon.createGMetric(host, "Ganglia Test", "INVALID_TYPE", "count", GMetric.SLOPE_UNSPECIFIED, true); 84 | } catch (IllegalArgumentException e) { 85 | assertTrue(true); 86 | } catch (Exception e) { 87 | fail(); 88 | } 89 | } 90 | 91 | @Test 92 | public void testUpdateInt() { 93 | int value = 10; 94 | try { 95 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 96 | GMetricInteger testMetric = (GMetricInteger) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_INT, "count", GMetric.SLOPE_UNSPECIFIED, true); 97 | testMetric.incrementValue(value); 98 | testMetric.incrementValue(); 99 | testMetric.setValue(value); 100 | } catch (IOException e) { 101 | e.printStackTrace(); 102 | fail(); 103 | } 104 | } 105 | 106 | @Test 107 | public void testUpdateDouble() { 108 | double value = 10.50; 109 | try { 110 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 111 | GMetricDouble testMetric = (GMetricDouble) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_DOUBLE, "count", GMetric.SLOPE_UNSPECIFIED, true); 112 | testMetric.incrementValue(value); 113 | testMetric.incrementValue(); 114 | testMetric.setValue(value); 115 | } catch (IOException e) { 116 | e.printStackTrace(); 117 | fail(); 118 | } 119 | } 120 | 121 | @Test 122 | public void testUpdateFloat() { 123 | float value = 10.50f; 124 | try { 125 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 126 | GMetricFloat testMetric = (GMetricFloat) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_FLOAT, "count", GMetric.SLOPE_UNSPECIFIED, true); 127 | testMetric.incrementValue(value); 128 | testMetric.incrementValue(); 129 | testMetric.setValue(value); 130 | } catch (IOException e) { 131 | e.printStackTrace(); 132 | fail(); 133 | } 134 | } 135 | 136 | @Test 137 | public void testUpdateString() { 138 | String value = "10"; 139 | try { 140 | GMonitor gmon = new GMonitor(MULTICAST_ADDRESS, 30l); 141 | GMetricString testMetric = (GMetricString) gmon.createGMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_STRING, "count", GMetric.SLOPE_UNSPECIFIED, true); 142 | testMetric.setValue(value); 143 | testMetric.setValue(null); 144 | } catch (IOException e) { 145 | e.printStackTrace(); 146 | fail(); 147 | } 148 | } 149 | 150 | @SuppressWarnings("unchecked") 151 | @Test 152 | public void testWriteXDRString() { 153 | try { 154 | GMetric gmetric = new GMetric(host, "Ganglia Test", GMetric.VALUE_TYPE_INT, "count", GMetric.SLOPE_UNSPECIFIED, true); 155 | Class[] inputType = new Class[2]; 156 | Object[] input = new Object[2]; 157 | inputType[0] = DataOutputStream.class; 158 | inputType[1] = String.class; 159 | input[0] = null; 160 | input[1] = null; 161 | UnitTestHelper.invokeMethod(gmetric, "writeXDRString", inputType, input); 162 | input[0] = new DataOutputStream(new ByteArrayOutputStream()); 163 | UnitTestHelper.invokeMethod(gmetric, "writeXDRString", inputType, input); 164 | } catch (Exception e) { 165 | e.printStackTrace(); 166 | fail(); 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/metric/type/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Uses of Package info.ganglia.metric.type 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Uses of Package
    info.ganglia.metric.type

    81 |
    82 | No usage of info.ganglia.metric.type 83 |

    84 |


    85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 107 | 110 | 111 | 112 | 113 | 116 | 132 | 133 |
    108 | 109 |
    134 | 135 | 136 | 137 |
    138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/class-use/GMonitor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Uses of Class info.ganglia.GMonitor 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Uses of Class
    info.ganglia.GMonitor

    81 |
    82 | No usage of info.ganglia.GMonitor 83 |

    84 |


    85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 107 | 110 | 111 | 112 | 113 | 116 | 132 | 133 |
    108 | 109 |
    134 | 135 | 136 | 137 |
    138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/class-use/GConnector.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Uses of Class info.ganglia.GConnector 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Uses of Class
    info.ganglia.GConnector

    81 |
    82 | No usage of info.ganglia.GConnector 83 |

    84 |


    85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 107 | 110 | 111 | 112 | 113 | 116 | 132 | 133 |
    108 | 109 |
    134 | 135 | 136 | 137 |
    138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /pmond/pmond/make_graph001.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PREFIX=/usr/graph001 4 | 5 | BUILD_CONCURRENCY=1 6 | 7 | 8 | 9 | 10 | #------------------------------------------------- 11 | set -e 12 | DOWNLOADS=${PREFIX}/work/tarballs 13 | BUILDS=${PREFIX}/work/builds 14 | RECEIPTS=${PREFIX}/.installed 15 | 16 | # 3 variables inspired by Mozilla's crazy build system 17 | # OS_ARCH e.g.Linux, SunOS, Darwin 18 | # OS_CPUARCH, e.g. i86pc (solaris), x86, x86_64 (linux), i386 (darwin) 19 | # OS_RELEASE, e.g. 2.6.21-2952xen (linux variant), 5.11 (solaris variant) 20 | 21 | OS_ARCH=`uname -s` 22 | OS_CPUARCH=`uname -m` 23 | OS_RELEASE=`uname -r` 24 | 25 | # 26 | # Location of basic files... most of the time this won't need to be changed 27 | # 28 | TAR=tar 29 | MAKE=make 30 | BZCAT=bzcat 31 | GZCAT="gunzip -c" 32 | # some systems don't have sudo and run as root 33 | SUDO=sudo 34 | # something to download files, or curl or wget works 35 | #WGET="curl -A Mozilla -O" 36 | WGET=wget 37 | 38 | # required by 'binutils' -- part of the gnu 'texinfo' package 39 | MAKEINFO=makeinfo 40 | 41 | export PATH=${PREFIX}/bin:${PATH} 42 | export LDFLAGS="-L${PREFIX}/lib" 43 | export CPPFLAGS=-I${PREFIX}/include 44 | export CONFIG_SHELL=/bin/bash 45 | export LD_LIBRARY_PATH=${PREFIX}/lib:${LD_LIBRARY_PATH} 46 | if [ "${OS_ARCH}" = "Darwin" ]; then 47 | export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH 48 | fi 49 | 50 | 51 | function init_directories() { 52 | if [ ! -d $BUILDS ]; then 53 | mkdir -p ${BUILDS} 54 | fi 55 | 56 | if [ ! -d $PREFIX ]; then 57 | ${SUDO} mkdir -p ${PREFIX} 58 | fi 59 | 60 | if [ ! -d $RECEIPTS ]; then 61 | ${SUDO} mkdir -p ${RECEIPTS} 62 | fi 63 | 64 | if [ ! -d $DOWNLOADS ]; then 65 | ${SUDO} mkdir -p ${DOWNLOADS} 66 | fi 67 | } 68 | 69 | function find_receipt() 70 | { 71 | TARFILE=$1 72 | RECEIPT="${RECEIPTS}/${TARFILE}" 73 | if [ -f "${RECEIPT}" ]; then 74 | echo "Found receipt for ${TARFILE}"; 75 | export HAS_RECEIPT=1; 76 | else 77 | export HAS_RECEIPT=0; 78 | fi 79 | return 0; 80 | } 81 | 82 | function write_receipt() 83 | { 84 | RECEIPT="${RECEIPTS}/${TARFILE}" 85 | ${SUDO} touch ${RECEIPT} 86 | } 87 | 88 | function unpacktar() 89 | { 90 | # given FULLFILE=/Downloads/gmp-4.2.4.tar.gz, then... 91 | # TARFILE = gmp.4.2.4.tar.gz 92 | # SUFFIX = 'gz' 93 | # TARDIR = gmp-4.2.4 94 | 95 | TARFILE="$1" 96 | TARDIR="$2" 97 | FULLFILE="${DOWNLOADS}/${TARFILE}"; 98 | SUFFIX=${TARFILE/*./} 99 | if [ -z "${TARDIR}" ]; then 100 | TARDIR=${TARFILE/%.${SUFFIX}/} 101 | TARDIR=${TARDIR/%.tar/} 102 | fi 103 | 104 | UNPACK="" 105 | case ${SUFFIX} in 106 | ('bz2') { UNPACK="$BZCAT $FULLFILE"; } ;; 107 | ('gz' | 'tgz') { UNPACK="$GZCAT $FULLFILE"; } ;; 108 | ('tar') { UNPACK="cat $FULLFILE"; } ;; 109 | esac 110 | echo "UNPACK=${UNPACK}" 111 | # if not match, then exit 112 | if [ -z "${UNPACK}" ]; then 113 | echo "unknown tar file type: $SUFFIX for $FULLFILE"; 114 | exit 1 115 | fi 116 | pushd . 117 | 118 | cd ${BUILDS} 119 | CMD="${UNPACK} | ${TAR} -xf -" 120 | echo "$CMD" 121 | eval $CMD 122 | 123 | cd $TARDIR 124 | CMD="${UNPACK} | tar -xf -" 125 | } 126 | 127 | 128 | function download_file() 129 | { 130 | URL="$1" 131 | TARFILE="`basename $URL`" 132 | # get tarball 133 | if [ ! -f "${DOWNLOADS}/${TARFILE}" ]; then 134 | echo "Downloading ${URL}" 135 | (cd ${DOWNLOADS} && ${WGET} ${URL}) 136 | fi 137 | } 138 | 139 | function installgnu() 140 | { 141 | URL="$1" 142 | TARFILE="`basename $URL`" 143 | 144 | # $2 is 'configure args' 145 | CARGV="$2" 146 | 147 | # $3 is configure env, list as "KEY=VAL KEY2=VAL2...." 148 | CENV="$3" 149 | 150 | # sometimes, the directory created by untar is "non-standard" 151 | ALTDIR="$4" 152 | 153 | find_receipt $TARFILE 154 | if [ $HAS_RECEIPT -eq 1 ]; then 155 | return 156 | fi 157 | 158 | download_file $URL 159 | unpacktar $TARFILE $ALTDIR; 160 | 161 | #if [ ! -d objdir ]; then mkdir objdir; fi 162 | #cd objdir 163 | 164 | # the ${CARGV[@]} -- if string, then use it 165 | # if array, do a 'join' on the argument, with ' ' as separator 166 | CMD="${CENV} ./configure --prefix=${PREFIX} ${CARGV[@]}" 167 | echo $CMD 168 | eval $CMD 169 | 170 | ${MAKE} -j ${BUILD_CONCURRENCY} 171 | ${SUDO} ${MAKE} install 172 | write_receipt $TARFILE 173 | popd 174 | } 175 | 176 | function install_python() { 177 | URL="$1" 178 | TARFILE="`basename $URL`" 179 | # $2 is 'configure args' 180 | CARGV="$2" 181 | 182 | find_receipt $TARFILE 183 | if [ $HAS_RECEIPT -eq 1 ]; then 184 | return 185 | fi 186 | download_file ${URL} 187 | unpacktar ${TARFILE} 188 | ${SUDO} python setup.py build ${CARGV} 189 | ${SUDO} python setup.py install 190 | write_receipt ${TARFILE} 191 | popd 192 | } 193 | 194 | #------------------------------------------------- 195 | init_directories 196 | 197 | installgnu http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz 198 | export PKG_CONFIG=${PREFIX}/bin/pkg-config 199 | 200 | installgnu http://www.python.org/ftp/python/2.6.1/Python-2.6.1.tar.bz2 '--disable-toolbox-glue' 201 | installgnu ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.2.34.tar.bz2 202 | 203 | installgnu http://savannah.inetbridge.net/freetype/freetype-2.3.8.tar.bz2 204 | 205 | installgnu ftp://xmlsoft.org/libxml2/libxml2-2.7.3.tar.gz 206 | installgnu ftp://xmlsoft.org/libxml2/libxslt-1.1.24.tar.gz 207 | 208 | installgnu http://fontconfig.org/release/fontconfig-2.6.0.tar.gz '--enable-libxml2 --disable-docs' 209 | 210 | installgnu http://www.cairographics.org/releases/pixman-0.13.2.tar.gz 211 | installgnu http://ftp.gnome.org/pub/gnome/sources/glib/2.18/glib-2.18.4.tar.bz2 212 | 213 | #installgnu http://cairographics.org/releases/cairo-1.8.6.tar.gz 214 | 215 | 216 | installgnu http://ftp.gnome.org/pub/GNOME/sources/pango/1.23/pango-1.23.0.tar.bz2 217 | 218 | installgnu ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz 219 | 220 | installgnu http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.3.6.tar.gz 221 | 222 | install_python http://www.cython.org/Cython-0.10.3.tar.gz 223 | install_python http://codespeak.net/lxml/lxml-2.1.5.tgz --with-xslt-config=${PREFIX}/bin/xslt-config 224 | 225 | -------------------------------------------------------------------------------- /gmetric-java/doc/info/ganglia/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | info.ganglia Class Hierarchy 8 | 9 | 10 | 11 | 12 | 13 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 47 | 50 | 51 | 52 | 53 | 56 | 72 | 73 |
    48 | 49 |
    74 | 75 | 76 | 77 |
    78 |
    79 |

    80 | Hierarchy For Package info.ganglia 81 |

    82 |
    83 |
    84 |
    Package Hierarchies:
    All Packages
    85 |
    86 |

    87 | Class Hierarchy 88 |

    89 | 93 |
    94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 116 | 119 | 120 | 121 | 122 | 125 | 141 | 142 |
    117 | 118 |
    143 | 144 | 145 | 146 |
    147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /gmetric-java/doc/overview-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Overview 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 48 | 51 | 52 | 53 | 54 | 57 | 73 | 74 |
    49 | 50 |
    75 | 76 | 77 | 78 |
    79 |
    80 |

    81 | GMetric 82 |

    83 |
    84 | 85 | 86 | 87 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
    88 | Packages
    info.ganglia 
    info.ganglia.metric 
    info.ganglia.metric.type 
    103 | 104 |

    105 |  


    106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 128 | 131 | 132 | 133 | 134 | 137 | 153 | 154 |
    129 | 130 |
    155 | 156 | 157 | 158 |
    159 | 160 | 161 | 162 | --------------------------------------------------------------------------------