nordugrid-arc-gangliarc-1.0.2/0000755000175000002070000000000013071532015016674 5ustar mockbuildmockbuildnordugrid-arc-gangliarc-1.0.2/gangliarc-start0000755000175000002070000000510612753551023021714 0ustar mockbuildmockbuild#!/bin/sh prog=gangliarc RUN=yes # sysconfig files if [ -r /etc/sysconfig/nordugrid ]; then . /etc/sysconfig/nordugrid elif [ -r /etc/default/nordugrid ]; then . /etc/default/nordugrid fi if [ -r /etc/sysconfig/${prog} ]; then . /etc/sysconfig/${prog} elif [ -r /etc/default/${prog} ]; then . /etc/default/${prog} fi readconfigvar() { fname=$1 if [ ! -r "$fname" ]; then return fi bname="[$2]" vname=$3 value= cat "$fname" | grep -e '^\[' -e "^${vname}=" | { while true; do read line if [ ! $? = 0 ] ; then return fi if [ "$line" = "$bname" ] ; then while true ; do read line if [ ! $? = 0 ] ; then return fi lstart=`echo "$line" | head -c 1` if [ "$lstart" = '[' ] ; then return fi vlname=`echo "$line" | sed 's/=.*//;t;s/.*//'` if [ "$vlname" = "$vname" ] ; then val=`echo "$line" | sed 's/[^=]*=//'` eval "echo $val" return fi done fi done } } # ARC_CONFIG if [ "x$ARC_CONFIG" = "x" ]; then if [ -r $ARC_LOCATION/etc/arc.conf ]; then ARC_CONFIG=$ARC_LOCATION/etc/arc.conf elif [ -r /etc/arc.conf ]; then ARC_CONFIG=/etc/arc.conf fi fi if [ ! -r "$ARC_CONFIG" ]; then echo "ARC configuration not found (usually /etc/arc.conf)" exit 1 fi CMD=`readconfigvar "$ARC_CONFIG" gangliarc python_bin_path` if [ "x$CMD" = "x" ]; then CMD=/usr/bin/python fi if [ ! -x "$CMD" ]; then echo "Cannot find python executable" exit 1 fi PID_FILE=`readconfigvar "$ARC_CONFIG" gangliarc pidfile` LOG_FILE=`readconfigvar "$ARC_CONFIG" gangliarc logfile` if [ `id -u` = 0 ] ; then if [ "x$PID_FILE" = "x" ]; then PID_FILE=/var/run/$prog.pid fi if [ "x$LOG_FILE" = "x" ]; then LOG_FILE=/var/log/arc/$prog.log fi else if [ "x$PID_FILE" = "x" ]; then PID_FILE=$HOME/$prog.pid fi if [ "x$LOG_FILE" = "x" ]; then LOG_FILE=$HOME/$prog.log fi fi CMD="$CMD -c 'import gangliarc; gangliarc.run(\"$ARC_CONFIG\", \"$PID_FILE\", \"$LOG_FILE\")'" if [ "$RUN" != "yes" ] ; then echo "gangliarc disabled, please adjust the configuration to your needs " echo "and then set RUN to 'yes' in /etc/default/gangliarc to enable it." return 0 fi exec "$CMD" nordugrid-arc-gangliarc-1.0.2/Makefile0000644000175000002070000000062512246501177020347 0ustar mockbuildmockbuildPACKAGE_NAME = nordugrid-arc-gangliarc VERSION = $(shell cat VERSION) TARBALL = dist/$(PACKAGE_NAME)-$(VERSION).tar.gz default: @echo "No default target - try make dist" dist: $(TARBALL) $(TARBALL): setup.py python $< sdist config: setup.py python $< $@ clean: rm -f $(TARBALL) MANIFEST $(PACKAGE_NAME).spec test -d dist && rmdir dist || : rm -fr $(CURDIR)/build rm -fr $(CURDIR)/__pycache__ nordugrid-arc-gangliarc-1.0.2/nordugrid-arc-gangliarc.spec0000644000175000002070000000662313071532015024244 0ustar mockbuildmockbuild%if 0%{?rhel} && 0%{?rhel} <= 5 || 0%{?fedora} <= 12 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(0)")} %endif %if %{?fedora}%{!?fedora:0} >= 25 || %{?rhel}%{!?rhel:0} >= 8 %global use_systemd 1 %else %global use_systemd 0 %endif Name: nordugrid-arc-gangliarc Version: 1.0.2 Release: 1%{?dist} Summary: Ganglia monitoring for ARC services Group: Development/Libraries License: ASL 2.0 URL: http://wiki.nordugrid.org/index.php/Gangliarc Source0: https://dcameron.web.cern.ch/dcameron/dev/rpmbuild/SOURCES/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch BuildRequires: python-devel BuildRequires: python-setuptools %if %{use_systemd} BuildRequires: systemd-units %endif Requires: nordugrid-arc-arex Requires: ganglia-gmond >= 3.0 Requires: python >= 2.4 %if %{use_systemd} Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units %else Requires(post): chkconfig Requires(preun): chkconfig Requires(preun): initscripts Requires(postun): initscripts %endif %description gangliarc provides a way to monitor ARC services through an existing ganglia installation. Running gangliarc adds various ARC metrics to ganglia which can then be viewed along with regular ganglia metrics for the ARC host. %prep %setup -q %build %{__python} -c 'import setuptools; execfile("setup.py")' build %install rm -rf %{buildroot} # /etc/init.d is hard-coded in setup.py so create a symlink to /etc/rc.d/init.d # before installing mkdir -p %{buildroot}/etc/rc.d/init.d && ln -s %{buildroot}/etc/rc.d/init.d %{buildroot}/etc/init.d %{__python} -c 'import setuptools; execfile("setup.py")' install -O1 --skip-build --root %{buildroot} # remove symlink rm -f %{buildroot}/etc/init.d %if %{use_systemd} rm -rf %{buildroot}/etc/rc.d/init.d mkdir -p %{buildroot}%{_unitdir} install -m 644 gangliarc.service %{buildroot}%{_unitdir} mkdir -p %{buildroot}%{_datadir}/arc install -m 755 gangliarc-start %{buildroot}%{_datadir}/arc %endif %clean rm -rf %{buildroot} %if %{use_systemd} %post %systemd_post gangliarc.service %preun %systemd_preun gangliarc.service %postun %systemd_postun_with_restart gangliarc.service %else %post /sbin/chkconfig --add gangliarc %preun if [ $1 -eq 0 ]; then /sbin/service gangliarc stop > /dev/null 2>&1 /sbin/chkconfig --del gangliarc fi %postun if [ $1 -ge 1 ]; then /sbin/service gangliarc condrestart > /dev/null 2>&1 fi %endif %files %defattr(-,root,root,-) %doc README LICENSE NOTICE %{python_sitelib}/gangliarc.* %{python_sitelib}/nordugrid_arc_gangliarc-%{version}-py?.?.egg-info %if %{use_systemd} %{_unitdir}/gangliarc.service %{_datadir}/arc/gangliarc-start %else %if 0%{?rhel} <= 5 || 0%{?fedora} <= 9 %{_initrddir}/gangliarc %else %{_initdir}/gangliarc %endif %endif %changelog * Thu Apr 06 2017 Anders Waananen - 1.0.2-1 - 1.0.2 Final Release * Mon Sep 05 2016 Anders Waananen - 1.0.1-1 - 1.0.1 Final Release * Sun Dec 01 2013 Anders Waananen - 1.0.0-1 - 1.0.0 Final release * Wed Jul 18 2012 David Cameron 0.1.0-1 - Initial version nordugrid-arc-gangliarc-1.0.2/gangliarc0000755000175000002070000001371012245661057020566 0ustar mockbuildmockbuild#!/bin/sh # # gangliarc Ganglia monitoring for ARC services # # chkconfig: - 75 25 # description: Ganglia monitoring for ARC services # # config: /etc/sysconfig/nordugrid # config: /etc/arc.conf ### BEGIN INIT INFO # Provides: gangliarc # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Default-Start: # Default-Stop: # Short-Description: Ganglia monitoring for ARC services # Description: gangliarc adds ARC service-related information to Ganglia ### END INIT INFO # source function library if [ -f /etc/init.d/functions ]; then . /etc/init.d/functions log_success_msg() { echo -n "$@" success "$@" echo } log_warning_msg() { echo -n "$@" warning "$@" echo } log_failure_msg() { echo -n "$@" failure "$@" echo } elif [ -f /lib/lsb/init-functions ]; then . /lib/lsb/init-functions else echo "Error: Cannot source neither init.d nor lsb functions" exit 1 fi prog=gangliarc RUN=yes # sysconfig files if [ -r /etc/sysconfig/nordugrid ]; then . /etc/sysconfig/nordugrid elif [ -r /etc/default/nordugrid ]; then . /etc/default/nordugrid fi if [ -r /etc/sysconfig/${prog} ]; then . /etc/sysconfig/${prog} elif [ -r /etc/default/${prog} ]; then . /etc/default/${prog} fi readconfigvar() { fname=$1 if [ ! -r "$fname" ]; then return fi bname="[$2]" vname=$3 value= cat "$fname" | grep -e '^\[' -e "^${vname}=" | { while true; do read line if [ ! $? = 0 ] ; then return fi if [ "$line" = "$bname" ] ; then while true ; do read line if [ ! $? = 0 ] ; then return fi lstart=`echo "$line" | head -c 1` if [ "$lstart" = '[' ] ; then return fi vlname=`echo "$line" | sed 's/=.*//;t;s/.*//'` if [ "$vlname" = "$vname" ] ; then val=`echo "$line" | sed 's/[^=]*=//'` eval "echo $val" return fi done fi done } } # ARC_CONFIG if [ "x$ARC_CONFIG" = "x" ]; then if [ -r $ARC_LOCATION/etc/arc.conf ]; then ARC_CONFIG=$ARC_LOCATION/etc/arc.conf elif [ -r /etc/arc.conf ]; then ARC_CONFIG=/etc/arc.conf fi fi if [ ! -r "$ARC_CONFIG" ]; then log_error_msg "ARC configuration not found (usually /etc/arc.conf)" exit 1 fi CMD=`readconfigvar "$ARC_CONFIG" gangliarc python_bin_path` if [ "x$CMD" = "x" ]; then CMD=/usr/bin/python fi if [ ! -x "$CMD" ]; then log_failure_msg "Cannot find python executable" exit 1 fi PID_FILE=`readconfigvar "$ARC_CONFIG" gangliarc pidfile` LOG_FILE=`readconfigvar "$ARC_CONFIG" gangliarc logfile` if [ `id -u` = 0 ] ; then # Debian does not have /var/lock/subsys if [ -d /var/lock/subsys ]; then LOCKFILE=/var/lock/subsys/$prog else LOCKFILE=/var/lock/$prog fi if [ "x$PID_FILE" = "x" ]; then PID_FILE=/var/run/$prog.pid fi if [ "x$LOG_FILE" = "x" ]; then LOG_FILE=/var/log/arc/$prog.log fi else LOCKFILE=$HOME/$prog.lock if [ "x$PID_FILE" = "x" ]; then PID_FILE=$HOME/$prog.pid fi if [ "x$LOG_FILE" = "x" ]; then LOG_FILE=$HOME/$prog.log fi fi CMD="$CMD -c 'import gangliarc; gangliarc.run(\"$ARC_CONFIG\", \"$PID_FILE\", \"$LOG_FILE\")'" start() { if [ "$RUN" != "yes" ] ; then echo "gangliarc disabled, please adjust the configuration to your needs " echo "and then set RUN to 'yes' in /etc/default/gangliarc to enable it." return 0 fi echo -n "Starting $prog: " # Check if we are already running if [ -f $PID_FILE ]; then read pid < $PID_FILE if [ "x$pid" != "x" ]; then ps -p "$pid" -o comm 2>/dev/null | grep "^python$" 1>/dev/null 2>/dev/null if [ $? -eq 0 ] ; then log_success_msg "already running (pid $pid)" return 0 fi fi rm -f "$PID_FILE" "$LOCKFILE" fi eval "$CMD" RETVAL=$? if [ $RETVAL -eq 0 ]; then touch $LOCKFILE log_success_msg else log_failure_msg fi return $RETVAL } stop() { echo -n "Stopping $prog: " if [ -f "$PID_FILE" ]; then read pid < "$PID_FILE" if [ ! -z "$pid" ] ; then kill "$pid" RETVAL=$? if [ $RETVAL -eq 0 ]; then log_success_msg else log_failure_msg fi sleep 1 kill -9 "$pid" 1>/dev/null 2>&1 rm -f "$PID_FILE" "$LOCKFILE" else RETVAL=1 log_failure_msg "$prog shutdown - pidfile is empty" fi else RETVAL=0 log_success_msg "$prog shutdown - already stopped" fi return $RETVAL } status() { if [ -f "$PID_FILE" ]; then read pid < "$PID_FILE" if [ "$pid" != "" ]; then if ps -p "$pid" > /dev/null; then echo "$1 (pid $pid) is running..." return 0 fi echo "$1 stopped but pid file exists" return 1 fi fi if [ -f $LOCKFILE ]; then echo "$1 stopped but lockfile exists" return 2 fi echo "$1 is stopped" return 3 } restart() { stop start } case "$1" in start) start ;; stop) stop ;; status) status $prog ;; restart | force-reload) restart ;; reload) ;; condrestart | try-restart) [ -f $LOCKFILE ] && restart || : ;; *) echo "Usage: $0 {start|stop|status|restart|force-reload|reload|condrestart|try-restart}" exit 1 ;; esac exit $? nordugrid-arc-gangliarc-1.0.2/setup.py0000644000175000002070000000254012246510567020422 0ustar mockbuildmockbuildimport sys from distutils.core import setup try: from distutils.command.build_py import build_py_2to3 except ImportError: pass fd = open('VERSION','r') version = fd.read().strip() fd.close() from distutils.command.config import config class CustomConfigCommand(config): def run(self): fd = open('nordugrid-arc-gangliarc.spec.in', 'r') lines = fd.readlines() fd.close() fd = open('nordugrid-arc-gangliarc.spec', 'w') for line in lines: line = line.replace("@VERSION@", version) fd.write(line) fd.close() config.run(self) COMMANDS = {'config' : CustomConfigCommand } if sys.version_info[0] == 3: COMMANDS['build_py'] = build_py_2to3 setup(name='nordugrid-arc-gangliarc', version = version, description = 'Ganglia monitoring for the ARC server', author = 'David Cameron', author_email = 'cameron@ndgf.org', url = 'http://www.nordugrid.org/', license = 'Apache 2.0 license', long_description = "gangliarc provides a way to monitor ARC services through an existing ganglia installation. Running gangliarc adds various ARC metrics to ganglia which can then be viewed along with regular ganglia metrics for the ARC host.", cmdclass = COMMANDS, py_modules = ['gangliarc'], data_files = [('/etc/init.d/', ['gangliarc'])] ) nordugrid-arc-gangliarc-1.0.2/MANIFEST.in0000644000175000002070000000042312753551023020437 0ustar mockbuildmockbuildinclude gangliarc include gangliarc.service include gangliarc-start include MANIFEST.in include LICENSE include NOTICE include VERSION include nordugrid-arc-gangliarc.spec.in include nordugrid-arc-gangliarc.spec include Makefile include debian/* include debian/source/format nordugrid-arc-gangliarc-1.0.2/debian/0000755000175000002070000000000013071532015020116 5ustar mockbuildmockbuildnordugrid-arc-gangliarc-1.0.2/debian/rules0000755000175000002070000000216412245661057021214 0ustar mockbuildmockbuild#!/usr/bin/make -f -include /usr/share/dpkg/buildflags.mk configure: configure-stamp : configure-stamp: dh_testdir touch $@ build: build-arch build-indep : build-arch: build-stamp : build-indep: build-stamp python setup.py build build-stamp: configure-stamp : touch $@ clean: dh_testdir dh_testroot dh_clean configure-stamp build-stamp install: build-stamp dh_testdir dh_testroot dh_clean -k python setup.py install --prefix=/usr --root=debian/tmp --skip-build find debian/tmp -name \*.egg-info -exec rm -f '{}' \; mv debian/tmp/etc/init.d/gangliarc debian/nordugrid-arc-gangliarc.gangliarc.init binary-indep: dh_testdir dh_testroot dh_installdirs dh_installdocs dh_install --fail-missing dh_installchangelogs dh_installinit nordugrid-arc-gangliarc --name gangliarc [ -x /usr/bin/dh_python2 ] && dh_python2 || dh_pysupport [ -x /usr/bin/dh_lintian ] && dh_lintian || : dh_link dh_fixperms dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary-arch: install : binary: binary-arch binary-indep : .PHONY: build-arch build-indep build clean binary-arch binary-indep binary install configure nordugrid-arc-gangliarc-1.0.2/debian/nordugrid-arc-gangliarc.default0000644000175000002070000000021612245661057026163 0ustar mockbuildmockbuild# To enable gangliarc, i.e. to indicate that a readily usable # configuration is in place, comment out or delete the # following line. RUN=no nordugrid-arc-gangliarc-1.0.2/debian/source/0000755000175000002070000000000013071532015021416 5ustar mockbuildmockbuildnordugrid-arc-gangliarc-1.0.2/debian/source/format0000644000175000002070000000001412245661057022637 0ustar mockbuildmockbuild3.0 (quilt) nordugrid-arc-gangliarc-1.0.2/debian/copyright0000644000175000002070000000221712246055272022063 0ustar mockbuildmockbuildThis package was debianized by Anders Wäänänen on Thu, 28 Nov 2013 17:00:00 +0100. Upstream Authors: David Cameron Dmytro Karpenko Copyright: Copyright (C) 2012-2013 by the respective employers of the the above authors: University of Oslo, Norway License: Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. On Debian systems, the complete text of the Apache version 2.0 license can be found in `/usr/share/common-licenses/Apache-2.0'. The Debian packaging was prepared by Anders Wäänänen of the upstream developers and is also licensed under the Apache 2.0 license. nordugrid-arc-gangliarc-1.0.2/debian/compat0000644000175000002070000000000212245661057021327 0ustar mockbuildmockbuild5 nordugrid-arc-gangliarc-1.0.2/debian/nordugrid-arc-gangliarc.docs0000644000175000002070000000001612246055272025462 0ustar mockbuildmockbuildREADME NOTICE nordugrid-arc-gangliarc-1.0.2/debian/control0000644000175000002070000000156212763533611021537 0ustar mockbuildmockbuildSource: nordugrid-arc-gangliarc Section: net Priority: optional Maintainer: Mattias Ellert Uploaders: Anders Waananen Build-Depends: debhelper (>= 5), python, python-setuptools, dh-python | python-support X-Python-Version: >= 2.4 Standards-Version: 3.9.2 Vcs-Browser: http://svn.nordugrid.org/trac/nordugrid/browser/contrib/gangliarc Vcs-Svn: http://svn.nordugrid.org/repos/nordugrid/contrib/gangliarc Homepage: http://www.nordugrid.org Package: nordugrid-arc-gangliarc Architecture: all Depends: ${misc:Depends}, python, nordugrid-arc-arex, ganglia-monitor Description: Ganglia monitoring for ARC services gangliarc provides a way to monitor ARC services through an existing ganglia installation. Running gangliarc adds various ARC metrics to ganglia which can then be viewed along with regular ganglia metrics for the ARC host. nordugrid-arc-gangliarc-1.0.2/debian/changelog0000644000175000002070000000046512246502745022007 0ustar mockbuildmockbuildnordugrid-arc-gangliarc (1.0.0-1) unstable; urgency=low * 1.0.0 Final release -- Anders Waananen Sun, 01 Dec 2013 00:39:11 +0000 nordugrid-arc-gangliarc (0.1.0-1) unstable; urgency=low * 0.1.0 Initial release -- Anders Waananen Thu, 28 Nov 2013 16:08:40 +0100 nordugrid-arc-gangliarc-1.0.2/debian/nordugrid-arc-gangliarc.install0000644000175000002070000000006712245661057026211 0ustar mockbuildmockbuilddebian/tmp/usr/lib/python*/site-packages/gangliarc.py* nordugrid-arc-gangliarc-1.0.2/nordugrid-arc-gangliarc.spec.in0000644000175000002070000000662713071531105024654 0ustar mockbuildmockbuild%if 0%{?rhel} && 0%{?rhel} <= 5 || 0%{?fedora} <= 12 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(0)")} %endif %if %{?fedora}%{!?fedora:0} >= 25 || %{?rhel}%{!?rhel:0} >= 8 %global use_systemd 1 %else %global use_systemd 0 %endif Name: nordugrid-arc-gangliarc Version: @VERSION@ Release: 1%{?dist} Summary: Ganglia monitoring for ARC services Group: Development/Libraries License: ASL 2.0 URL: http://wiki.nordugrid.org/index.php/Gangliarc Source0: https://dcameron.web.cern.ch/dcameron/dev/rpmbuild/SOURCES/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch BuildRequires: python-devel BuildRequires: python-setuptools %if %{use_systemd} BuildRequires: systemd-units %endif Requires: nordugrid-arc-arex Requires: ganglia-gmond >= 3.0 Requires: python >= 2.4 %if %{use_systemd} Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units %else Requires(post): chkconfig Requires(preun): chkconfig Requires(preun): initscripts Requires(postun): initscripts %endif %description gangliarc provides a way to monitor ARC services through an existing ganglia installation. Running gangliarc adds various ARC metrics to ganglia which can then be viewed along with regular ganglia metrics for the ARC host. %prep %setup -q %build %{__python} -c 'import setuptools; execfile("setup.py")' build %install rm -rf %{buildroot} # /etc/init.d is hard-coded in setup.py so create a symlink to /etc/rc.d/init.d # before installing mkdir -p %{buildroot}/etc/rc.d/init.d && ln -s %{buildroot}/etc/rc.d/init.d %{buildroot}/etc/init.d %{__python} -c 'import setuptools; execfile("setup.py")' install -O1 --skip-build --root %{buildroot} # remove symlink rm -f %{buildroot}/etc/init.d %if %{use_systemd} rm -rf %{buildroot}/etc/rc.d/init.d mkdir -p %{buildroot}%{_unitdir} install -m 644 gangliarc.service %{buildroot}%{_unitdir} mkdir -p %{buildroot}%{_datadir}/arc install -m 755 gangliarc-start %{buildroot}%{_datadir}/arc %endif %clean rm -rf %{buildroot} %if %{use_systemd} %post %systemd_post gangliarc.service %preun %systemd_preun gangliarc.service %postun %systemd_postun_with_restart gangliarc.service %else %post /sbin/chkconfig --add gangliarc %preun if [ $1 -eq 0 ]; then /sbin/service gangliarc stop > /dev/null 2>&1 /sbin/chkconfig --del gangliarc fi %postun if [ $1 -ge 1 ]; then /sbin/service gangliarc condrestart > /dev/null 2>&1 fi %endif %files %defattr(-,root,root,-) %doc README LICENSE NOTICE %{python_sitelib}/gangliarc.* %{python_sitelib}/nordugrid_arc_gangliarc-%{version}-py?.?.egg-info %if %{use_systemd} %{_unitdir}/gangliarc.service %{_datadir}/arc/gangliarc-start %else %if 0%{?rhel} <= 5 || 0%{?fedora} <= 9 %{_initrddir}/gangliarc %else %{_initdir}/gangliarc %endif %endif %changelog * Thu Apr 06 2017 Anders Waananen - 1.0.2-1 - 1.0.2 Final Release * Mon Sep 05 2016 Anders Waananen - 1.0.1-1 - 1.0.1 Final Release * Sun Dec 01 2013 Anders Waananen - 1.0.0-1 - 1.0.0 Final release * Wed Jul 18 2012 David Cameron 0.1.0-1 - Initial version nordugrid-arc-gangliarc-1.0.2/LICENSE0000644000175000002070000002367612246055272017727 0ustar mockbuildmockbuild Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS nordugrid-arc-gangliarc-1.0.2/gangliarc.service0000644000175000002070000000034412753551023022214 0ustar mockbuildmockbuild[Unit] Description=Ganglia monitoring for ARC services After=local_fs.target remote_fs.target [Service] Type=forking PIDFile=/var/run/gangliarc.pid ExecStart=/usr/share/arc/gangliarc-start [Install] WantedBy=multi-user.target nordugrid-arc-gangliarc-1.0.2/PKG-INFO0000644000175000002070000000074613071532015020000 0ustar mockbuildmockbuildMetadata-Version: 1.0 Name: nordugrid-arc-gangliarc Version: 1.0.2 Summary: Ganglia monitoring for the ARC server Home-page: http://www.nordugrid.org/ Author: David Cameron Author-email: cameron@ndgf.org License: Apache 2.0 license Description: gangliarc provides a way to monitor ARC services through an existing ganglia installation. Running gangliarc adds various ARC metrics to ganglia which can then be viewed along with regular ganglia metrics for the ARC host. Platform: UNKNOWN nordugrid-arc-gangliarc-1.0.2/NOTICE0000644000175000002070000000203712246055272017612 0ustar mockbuildmockbuildGanglia monitoring for the Advanced Resource Connector (ARC) - gangliarc This product includes gangliarc which provides a way to monitor an ARC Computing Element through an existing ganglia installation. The software was developed by: David Cameron Dmytro Karpenko during their employment at the University of Oslo, Norway. The Copyright is collectively owned by the above individuals and the University of Oslo, Norway. The software is licensed under the Apache License, Version 2.0 (the "License"); you may not use files from this software distribution except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. nordugrid-arc-gangliarc-1.0.2/VERSION0000644000175000002070000000000613071531105017737 0ustar mockbuildmockbuild1.0.2 nordugrid-arc-gangliarc-1.0.2/gangliarc.py0000644000175000002070000006053413050563662021216 0ustar mockbuildmockbuild# Copyright 2012 David Cameron, Dmytro Karpenko # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # gangliarc collects ARC-related information and provides info to ganglia # through gmetric. """gangliarc collects ARC-related information and provides info to ganglia through gmetric.""" import os import re import sys import time import signal import subprocess import logging import traceback # Default gangliarc parameters # - path to arc configuration file # - frequency (in s) at which to gather info # - expiration period of monitored metrics (in s) # - path to gmetric executable # - path to gm-jobs executable (should eventually be filled by autotools) # - metrics to report gangliarc_conf = {'conffile' : '/etc/arc.conf', 'frequency' : '20', 'dmax' : '180', 'gmetric_exec' : '/usr/bin/gmetric', 'metrics' : 'all'} # job states arex_job_states = [ "ACCEPTED", "PREPARING", "SUBMIT", "INLRMS", "FINISHING", "FINISHED", "DELETED", "CANCELLING" ] # where to get data staging info data_staging_info = "dtrstate.log" # dictionary of configuration information, filled by parseConf() conf = {} def daemonize(pidfile): ''' Do double fork to create daemon process ''' try: pid = os.fork() if pid > 0: # exit first parent sys.exit(0) except OSError: e = sys.exc_info()[1] sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # decouple from parent environment os.chdir("/") os.setsid() os.umask(0) # do second fork try: pid = os.fork() if pid > 0: # exit from second parent sys.exit(0) except OSError: e = sys.exc_info()[1] sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() si = open('/dev/null', 'r') so = open('/dev/null', 'a+') se = open('/dev/null', 'a+') os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # write pidfile pid = str(os.getpid()) f = open(pidfile,'w+') f.write("%s\n" % pid) f.close() def parseConf(conffile): ''' Parse arc.conf and fill the conf dictionary of parameters in the format {section : {parameter : [value(s)]}} eg {"gangliarc" : {"logfile" : ["/tmp/gangliarc.log"], "pidfile" : ["/tmp/gangliarc.pid"]}} Value is a list since some parameters can be used multiple times ''' try: f = open(conffile) except IOError: e = sys.exc_info()[1] logging.error("Cannot open file %s: %s", conffile, str(e)) return current_section = '' for line in f: line = line.strip() # strip new line and leading/trailing spaces if len(line) == 0 or line[0] == '#': continue if line[0] == '[': # new section if line[-1] != ']': logging.error("Bad format of section name in line "+line) continue current_section = line[1:-1] conf[current_section] = {} else: if len(current_section) == 0: logging.error("Found configuration parameter %s outside a defined section", line) continue # here we have param="value" (sometimes without quotes) equals_pos = line.find('=') if equals_pos == -1 or equals_pos == len(line)-1: logging.error("Bad format for parameter %s", line) continue param = line[:equals_pos] value = line[equals_pos+1:] # remove surrounding quotes if value[0] == '"': if value[-1] != '"': logging.error("Bad format for parameter %s", line) continue value = value[1:-1] elif value[0] == "'": if value[-1] != "'": logging.error("Bad format for parameter %s", line) continue value = value[1:-1] # check if already stored if param in conf[current_section]: conf[current_section][param].append(value) else: conf[current_section][param] = [value] f.close() def parseURL(url): """ Split url into (protocol, host, port, path) and return this tuple. """ match = re.match(r'(\w*)://([^/?#:]*):?(\d*)/?(.*)', url) if match is None: return (None, None, None, None) port_s = match.group(3) if (len(port_s) > 0): port = int(port_s) else: port = None urltuple = (match.group(1), match.group(2), port, '/'+match.group(4)) return urltuple def runGmetric(metric, value, unit, unit_type): ''' Run the gmetric executable for the given metric. ''' try: res = subprocess.call([gangliarc_conf['gmetric_exec'], "-n", metric, "-v", str(value), "-t", unit_type, "-u", unit, "-d", gangliarc_conf['dmax']]) except OSError: e = sys.exc_info()[1] logging.error("Error calling gmetric process: %s", str(e)) return if res != 0: logging.error("Error returned from gmetric") def getDataStagingInfo(): ''' Pull out number of files in each data staging state from the info dumped by A-REX ''' # most important states to monitor data_staging_important_states = [ "TRANSFER_WAIT", "CACHE_WAIT", "STAGE_PREPARE", "STAGING_PREPARING_WAIT", ] # get possible staging hosts for TRANSFERRING state if 'data-staging' in conf: if 'deliveryservice' in conf['data-staging']: for url in conf['data-staging']['deliveryservice']: (protocol, host, port, path) = parseURL(url) if host is not None: data_staging_important_states.append('TRANSFERRING_' + host) # there is always a chance local transfer is used so always display it data_staging_important_states.append('TRANSFERRING_local') # get DTR log location if 'data-staging' in conf and 'dtrlog' in conf['data-staging']: dtrlog = conf['data-staging']['dtrlog'][0] elif 'controldir' in conf['grid-manager']: control = conf['grid-manager']['controldir'][0] dtrlog = control+'/'+data_staging_info else: logging.error("No control dir or DTR log found in configuration") return try: f = open(dtrlog) except IOError: e = sys.exc_info()[1] logging.error("Cannot open file %s: %s", dtrlog, str(e)) return states = {} num_lines = 0 for line in f: l = line.split() state = l[1] # if TRANSFERRING, get the host doing the transfer if state == 'TRANSFERRING': if len(l) == 6: state = state + '_' + l[5] else: state = state + '_local' if state in states: states[state] = states[state] + 1 else: states[state] = 1 num_lines = num_lines + 1 f.close() for state in data_staging_important_states: if state == 'STAGE_PREPARE' and 'PRE_CLEANED' in states: # In arc > 2.0.0 files waiting to be staged are in STAGE_PREPARE # instead of PRE_CLEANED value = states['PRE_CLEANED'] if state in states: value += states[state] elif state == 'TRANSFER_WAIT' and 'TRANSFER' in states: # In arc > 1.1.0 TRANSFER_WAIT was merged into TRANSFER but calling # the metric TRANSFER_WAIT is more intuitive value = states['TRANSFER'] elif state in states: value = states[state] else: value = 0 state = 'ARC_STAGING_' + state logging.info("%s %s", state, value) runGmetric(state, value, 'files', 'int32') runGmetric('ARC_STAGING_TOTAL', num_lines, 'files', 'int32') def getJobsStatesInfo(): ''' Pull out number of jobs in each A-REX internal state by scanning job.id.status files in control subdirectories. ''' if 'controldir' in conf['grid-manager']: control = conf['grid-manager']['controldir'][0] else: logging.error("No control dir found in configuration") return control_subdirs = ['accepting', 'finished', 'processing', 'restarting'] states = {} for control_subdir in control_subdirs: subdir = os.path.join(control, control_subdir) # subdirs only exist in versions >= 1.0.0 if not os.path.isdir(subdir): logging.warning('Control sub-directory %s not found. ' \ 'Job state information is only supported in ARC >= 1.0.0', subdir) return # scan files in the sub dir try: for status_file in os.listdir(subdir): try: f = open(os.path.join(subdir, status_file)) except IOError: e = sys.exc_info()[1] logging.warning('Could not open status file %s: %s', status_file, str(e)) continue status = f.readline().strip() if status in states: states[status] += 1 else: states[status] = 1 f.close() except OSError: e = sys.exc_info()[1] logging.warning('Could not list status files in %s: %s', subdir, str(e)) # first get total jobs including pending totaljobs = 0 for state in states: totaljobs += states[state] logging.info('ARC_JOBS_TOTAL %i', totaljobs) runGmetric('ARC_JOBS_TOTAL', totaljobs, 'jobs', 'int32') # now number for each specific state we are interested in for state in arex_job_states: if state in states: value = states[state] else: value = 0 state = 'ARC_JOBS_' + state logging.info("%s %s", state, value) runGmetric(state, value, 'jobs', 'int32') def getHeartBeatInfo(): ''' use the modification timestamp of the gm-heartbeat file to send to gmetric the time since the last heartbeat ''' if 'controldir' in conf['grid-manager']: control = conf['grid-manager']['controldir'][0] else: logging.error("No control dir found in configuration") return heartbeat = control + "/gm-heartbeat" try: statinfo = os.stat(heartbeat) except OSError: e = sys.exc_info()[1] logging.error("Error with heartbeat file: %s", str(e)) return mtime = statinfo.st_mtime now = time.time() heartbeat_time = now - mtime logging.info("heartbeat time %s", heartbeat_time) runGmetric('ARC_AREX_HEARTBEAT_LAST_SEEN', heartbeat_time, 'sec', 'int32') def getCacheFree(): ''' go through each cache dir and find the free space on the filesystem ''' if 'cachedir' not in conf['grid-manager']: logging.warn('No caches defined in configuration') return caches = conf['grid-manager']['cachedir'] totalfree = 0 for cache in caches: if cache.find(' ') != -1: cache = cache[:cache.find(' ')] # If substitutions are present, truncate the path if cache.find('%') != -1: cache = cache[:cache.find('%')] logging.info('cache dir with substitution truncated to %s', cache) # Note: Not portable! try: s = os.statvfs(cache) except OSError: e = sys.exc_info()[1] logging.error("Error finding space in cache %s: %s", cache, str(e)) continue free = float(s.f_bsize) * float(s.f_bavail) / float(1024) / float(1024) / float(1024) # space in GiB totalfree += free logging.info('cache %s free space %s GB', cache, free) # ganglia doesn't allow slashes in metric names cache = cache.replace('/', '_') runGmetric('ARC_CACHE_FREE'+cache, free, 'GB', 'float') if len(caches) > 1: runGmetric('ARC_CACHE_FREE_TOTAL', totalfree, 'GB', 'float') def getSessionFree(): ''' go through each session dir and find the free space on the filesystem ''' if 'sessiondir' not in conf['grid-manager']: logging.warn('No sessiondir defined in configuration') return sessiondirs = conf['grid-manager']['sessiondir'] totalfree = 0 for session in sessiondirs: if session.find(' ') != -1: session = session[:session.find(' ')] # If substitutions are present, truncate the path if session.find('%') != -1: session = session[:session.find('%')] logging.info('session dir with substitution truncated to %s', session) # Special case of session dirs in users' home directories # Guessing that /home is ok if session == '*': session = '/home' logging.info('using /home for session dir info') # Note: Not portable! try: s = os.statvfs(session) except OSError: e = sys.exc_info()[1] logging.error("Error finding space in session dir %s: %s", session, str(e)) continue free = float(s.f_bsize) * float(s.f_bavail) / float(1024) / float(1024) / float(1024) # space in GiB totalfree += free logging.info('session dir %s free space %s GB', session, free) # ganglia doesn't allow slashes in metric names session = session.replace('/', '_') runGmetric('ARC_SESSION_FREE'+session, free, 'GB', 'float') if len(sessiondirs) > 1: runGmetric('ARC_SESSION_FREE_TOTAL', totalfree, 'GB', 'float') def getJobsINLRMS(): ''' Checks jobs in the 'processing' subdir of the control dir. This will only work on ARC1 clusters. ''' if 'controldir' in conf['grid-manager']: controldir = conf['grid-manager']['controldir'][0] else: logging.error("No control dir found in configuration") return processing_dir = controldir + "/processing" entries = [] try: entries = [stat_file for stat_file in os.listdir(processing_dir) if '.status' in stat_file] except OSError: e = sys.exc_info()[1] logging.error("Error listing dir %s: %s", processing_dir, str(e)) '''extract the number of cores for this running job from the job..grami file''' cores={} for status_file in entries: ''' open the status file and check that the job is actually processing (INLRMS), if not go to next job ''' try: with open(controldir + '/processing/' + status_file) as f:state=f.read() if 'INLRMS' not in state: continue except IOError: e = sys.exc_info()[1] logging.error('Error opening file %s: %s', status_file, str(e)) jobid = status_file[4:-7] gramifN = controldir +'/job.'+jobid+'.grami' try: f=open(gramifN) except IOError: e = sys.exc_info()[1] logging.error("Cannot open file %s: %s. Skipping.", gramifN, str(e)) continue ''' extract info about cores from grami file ''' for line in f: if 'coreCount' in line: parts = line.split('&') for part in parts: if 'coreCount' in part: try: cN = int(part.split('=')[-1]) except ValueError: e = sys.exc_info()[1] logging.error("Problems finding number of cores %s. Skipping",str(e)) continue if cN in cores: cores[cN] += 1 else: cores[cN] = 1 f.close() ''' publish info on number of jobs using certain number of cores''' for corenum,jobs in cores.iteritems(): logging.info("%i job(s) INLRMS use %i core(s)",jobs, corenum) corestr = 'ARC_JOBS_INLRMS_' + str(corenum) + 'CORES' runGmetric(corestr, jobs, 'jobs', 'int32') ''' get total amount of cores for all jobs ''' totalcores = 0 for corenum, jobs in cores.iteritems(): totalcores += jobs*corenum if totalcores: logging.info("Total number of cores INLRMS %s",totalcores) runGmetric('ARC_JOBS_INLRMS_TOTALCORES', totalcores, 'cores', 'int32') def getProcessingJobs(): ''' Count the number of jobs in the 'processing' subdir of the control dir. This will only work on ARC1 clusters. ''' if 'controldir' in conf['grid-manager']: controldir = conf['grid-manager']['controldir'][0] else: logging.error("No control dir found in configuration") return processing = 0 processing_dir = controldir + "/processing" entries = [] try: entries = os.listdir(processing_dir) except OSError: e = sys.exc_info()[1] logging.error("Error listing dir %s: %s", processing_dir, str(e)) return processing += len(entries) ''' display processing info ''' logging.info("%i jobs in processing", processing) runGmetric('ARC_JOBS_PROCESSING', processing, 'jobs', 'int32') '''extract the number of cores for this running job from the job..grami file''' cores={} for status_file in entries: if status_file.endswith('.status'): ''' open the status file and check that the job is actually processing (INLRMS), if not go to next job ''' try: with open(controldir + '/processing/' + status_file) as f:state=f.read() if 'INLRMS' not in state: print 'not counting ', state, status_file continue else: print state except IOError: e = sys.exc_info()[1] logging.error('Error opening file %s: %s', status_file, str(e)) jobid = status_file[4:-7] gramifN = controldir +'/job.'+jobid+'.grami' print status_file , '\n' try: f=open(gramifN) except IOError: e = sys.exc_info()[1] logging.error("Cannot open file %s: %s. Skipping.", gramifN, str(e)) continue for line in f: if 'coreCount' in line: parts = line.split('&') for part in parts: if 'coreCount' in part: try: cN = int(part.split('=')[-1]) except ValueError: e = sys.exc_info()[1] logging.error("Problems finding number of cores %s. Skipping",str(e)) continue if cN in cores: cores[cN] += 1 else: cores[cN] = 1 f.close() for corenum,jobs in cores.iteritems(): logging.info("%i job(s) use %i core(s)",jobs, corenum) corestr = 'ARC_JOBS_PROCESSING_' + str(corenum) + 'CORES' runGmetric(corestr, jobs, 'jobs', 'int32') def getFailedJobs(): ''' Look into the grid manager jobs log file to extract the quantity of failed jobs among last 100 finished and send to gmetric ''' if 'joblog' not in conf['grid-manager']: logging.warn('No grid manager jobs log defined in configuration') return gmjlog = conf['grid-manager']['joblog'][0] try: # Linux specific commands, but ganglia is only for *nix systems # Get last 400 lines from the log file, select only concerning finished jobs # and select failed in the finished p1 = subprocess.Popen(['tail', '-400', gmjlog], stdout = subprocess.PIPE) p2 = subprocess.Popen(['grep', '-i','finish'], stdin = p1.stdout, stdout = subprocess.PIPE) p1.stdout.close() p3 = subprocess.Popen(['tail', '-100'], stdin = p2.stdout, stdout = subprocess.PIPE) p2.stdout.close() p4 = subprocess.Popen(['grep', '-i', 'fail'], stdin = p3.stdout, stdout = subprocess.PIPE) p3.stdout.close() p5 = subprocess.Popen(['wc', '-l'], stdin = p4.stdout, stdout = subprocess.PIPE) p4.stdout.close() num_of_jobs = p5.stdout.readline() num_of_jobs = num_of_jobs.strip() logging.info('%s jobs failed among last 100', num_of_jobs) p5.stdout.close() except OSError: e = sys.exc_info()[1] logging.error("Error with running OS commands: %s", str(e)) return runGmetric('ARC_JOBS_FAILED_PER_100', num_of_jobs, 'jobs', 'int32') def handler(signum, frame): ''' shut down nicely ''' logging.info('*** gangliarc stopped ***') sys.exit(0) def run(conffile, pidfile, logfile): ''' Main program. It creates a daemon which loops indefinitely. In each loop several metrics are gathered and sent to gmetric. run() takes three arguments, the path to the ARC configuration file and the paths to the pid and log files for this process. ''' # path to arc.conf gangliarc_conf['conffile'] = conffile # set up logging logging.basicConfig(filename=logfile, level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s') # create daemon daemonize(pidfile) # add signal handler signal.signal(signal.SIGTERM, handler) logging.info('*** gangliarc started ***') # main loop - loop forever until interrupted while (True): try: # read arc conf file # TODO parse once, but enable reloading via /etc/init.d/gangliarc reload parseConf(conffile) # sanity check if 'grid-manager' not in conf: logging.critical("No [grid-manager] section found in configuration, exiting") break # check if some gangliarc defaults were overridden in configuration if 'gangliarc' in conf: for key in gangliarc_conf: if key in conf['gangliarc']: gangliarc_conf[key] = conf['gangliarc'][key][0] # metrics to measure metrics = gangliarc_conf['metrics'].split(',') if 'staging' in metrics or 'all' in metrics: # data staging info getDataStagingInfo() if 'jobstates' in metrics or 'all' in metrics: # jobs in different states getJobsStatesInfo() if 'heartbeat' in metrics or 'all' in metrics: # gm-heartbeat info getHeartBeatInfo() if 'cache' in metrics or 'all' in metrics: # cache free space getCacheFree() if 'session' in metrics or 'all' in metrics: # session dir free space getSessionFree() if 'processingjobs' in metrics or 'all' in metrics: # processing jobs getProcessingJobs() if 'getJobsINLRMS' in metrics or 'all' in metrics: # processing jobs getJobsINLRMS() if 'failedjobs' in metrics or 'all' in metrics: # number of failed jobs among last 100 getFailedJobs() time.sleep(float(gangliarc_conf['frequency'])) except SystemExit: # raised by signal handler break except: logging.critical("Unexpected exception, exiting gangliarc") logging.critical(traceback.format_exc()) logging.info('*** gangliarc stopped ***') break if __name__ == '__main__': run('/etc/arc.conf', '/tmp/gangliarc.pid', '/tmp/gangliarc.log') nordugrid-arc-gangliarc-1.0.2/README0000644000175000002070000000651012723554361017571 0ustar mockbuildmockbuildgangliarc provides a way to monitor an ARC Computing Element through an existing ganglia installation. Running gangliarc adds various ARC-related metrics to ganglia using gmetric which can then be viewed on the ganglia web page for the ARC CE host. The available metrics are configurable and explained below. gangliarc takes information (eg control directory, cache directories) from the standard ARC configuration file arc.conf. If it is not in the default location (/etc/arc.conf) then ARC_CONFIG must be set. Requirements: python >= 2.4.x ganglia >= 3.0.x ARC >= 0.8.x (Some metrics are only available with ARC >= 1.0) To install from sources: python setup.py install (as superuser) To start/stop/restart: /etc/init.d/gangliarc start/stop/restart (as superuser) Log messages are logged to /var/log/arc/gangliarc.log by default but this can be configured. To configure: In many cases no gangliarc configuration is necessary, however the following parameters may be specified in a [gangliarc] section in arc.conf. - frequency -- period of gathering the info, in seconds. Default is 20. - dmax -- expiration period of information, passed to gmetric, in seconds. 0 means infinity. Default is 180. - gmetric_exec -- path to gmetric executable. Default is /usr/bin/gmetric - logfile -- log file of the daemon. Default is /var/log/arc/gangliarc.log - pidfile -- pid file of the daemon. Default is /var/run/gangliarc.pid - python_bin_path -- path to python executable. Default is /usr/bin/python - metrics -- the metrics to be monitored. Default is all. metrics takes a comma-separated list of one or more of the following metrics: - staging -- number of tasks in different data staging states - cache -- free cache space - session -- free session directory space - heartbeat -- last modification time of A-REX heartbeat - processingjobs -- the number of jobs currently being processed by ARC (jobs between PREPARING and FINISHING states) - failedjobs -- the number of failed jobs per last 100 finished - jobstates -- number of jobs in different A-REX internal stages - all -- all of the above metrics Explanation of data staging states: Data staging states metrics all start with ARC_STAGING CACHE_WAIT -- Files waiting to obtain a lock in the cache, currently held by another request downloading the same file STAGE_PREPARE -- There is a limit (max_prepared in arc.conf) on files prepared (pinned) on SRM storage. Files in this state are waiting for a free slot to prepare their source or destination. STAGING_PREPARING_WAIT -- Files which have made a staging request to SRM and are waiting for a TURL to be returned TOTAL -- All files in the data staging system (corresponding to jobs in PREPARING and FINISHING) TRANSFERRING_hostname -- Files actively transferring data, with the transfer running on hostname TRANSFER_WAIT -- Files ready for transfer and waiting on a TRANSFERRING slot Example configuration: [gangliarc] python_bin_path="/usr/bin/python2.6" metrics="cache,heartbeat,failedjobs,processingjobs,staging" Authors: David Cameron (d.g.cameron@fys.uio.no) Dmytro Karpenko (dmytro.karpenko@fys.uio.no) More information: http://wiki.nordugrid.org/index.php/Gangliarc