Blog Archives

Configure unixODBC for use with PHP and MSSQL on Oracle Linux

This short article describes how to configure unixODBC 2.2.11-10.el5 in conjunction with PHP 5.3.3-26. Many forums out there contain articles that describe the absence of php_mssql drivers in the oracle yum repo. There various reason for that; non in which Oracle has a part. No matter what reason you like best, there is a decent alternative by using unixODBC.

To help all the people out that are just looking for a solution I wrote this article. I wont go into depths, ill just describe the major steps with some hints and tips. Happy reading 🙂

The OS version of my virtual box image:

Linux sandboxpinguin 2.6.18-194.0.0.0.3.el5xen #1 SMP Mon Mar 29 18:27:00 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
  1. Make sure you have the latest version of unixODBC installed. If Yum is configured correctly the following command should do the trick.
     yum update unixODBC
  2. Download the freeDTS driver, this is the driver unixODBC will use to connect to mssql. If wget is available on your production environment (remove it) after running the command:
     wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-stable.tgz

    . Make sure you are in an desired location like your home folder.

  3. Unpack the tar-Gzip ball by running the following command
    tar -xf  ./freetds-stable.tgz
  4. Browse into the unpacked folder and run the configure command
    ./configure --with-tdsver=7.2 --enable-msdblib
  5. If the configure ran without any issues you can link/compile the driver by running the command:
    make

    and then

    make install

    and then

    make clean

    Congratulations, you are now the pride owner of the freeDTS driver 🙂

The next part tend to get a bit fuzzy, feel free to ask questions in the comment and ill try to answer them to the best of my ability.

There are allot of articles available on how to configure the unixODBC DSN correctly. Be adviced: the config is specific for your setup and usually needs to be tweaked. In order to enable you to ill explain the concepts of unixODBC. Ill point out some documentation, commands and stuff. Afterward ill have a short tutorial of the steps i used to configure the odbc connection.

  1. unixODBC is configured properly by using the
    odbcinst

    command.

  2. unixODBC will write into:
    odbc.ini

    files and uses input files to do so;

  3. The connection can be tested with osql commands from bash, but! it will use the hidden .odbc.ini file in your profile instead of the /etc/odbc.ini. PHP and odbcinst use the one in /etc/odbc.ini. If the one in your profile works than make sure it is identical to the one located in /etc/ directory. Below how the osql output will look if configured correctly. (charset isnt relevant in this stage)
    screenshot
  4. Documentation on how to use FreeTDS in conjunction with unixODBC can be found here.
    http://www.freetds.org/userguide/odbcconnattr.htm
  5. Documentation on how to use ODBC can be found here
    http://www.unixodbc.org/odbcinst.html
    (ignore the freetds configuration here and use ad4 to figure the settings out for your setup)

Next ill describe my steps in order to make it work.

Configuring the FreeTDS driver

  1. Create the file /etc/odbcDriver.ini
  2. Insert the following in the file (check the paths)
    [FreeTDS]
    Description     = FreeTDS Driver with protocol v5.0
    Driver          = /usr/local/freetds/lib/libtdsodbc.so
    
  3. Create the file /etc/odbc.ini
  4. Insert the following and tweak this to match your environment
    [ExampleSource]
    Description     = FreeTDS Driver with protocol v5.0
    Driver          = /usr/local/freetds/lib/libtdsodbc.so
    Server          = [SERVERIP]
    Port            = [REMOTE_TSQL_PORT]
    ClientCharset   = UTF-8
    TDS_Version     = 7.1
    Database        = [DATABASENAME]
    Trusted_Connection = Yes      # Required with most MSSQL environments.
    
  5. Register the ODBC driver
     odbcinst -i -d -f /etc/odbcDriver.ini 
  6. Register the data source
     odbcinst -i -s -f /etc/odbc.ini

Finally test your config by using the php odbc functions.

<?php
$sql = "select 1 + 5 as outcome";

$conn = odbc_connect("ExampleSource" , "Username", "Password");
$result = odbc_exec($conn, $sql);
$row = odbc_fetch_array($result);
echo $row['outcome'];

Good luck querying 🙂

Fix (enable) GLPI 0.84.8 Inline knowledgebase images.

For some reason the in-line images keep getting blocked in GLPI. I think database cluttering is the main reason for this. I still think they should make it optional. But hey, who am i to tell INDEPNET whats right 🙂

Anywayz…

Enabling (Fixing) the images has become a bit more complex in comparison with my previous post. So, i cant be held responsible for any issues that might affect you after you followed this article. In my environment it works without any issues.

  1. Again, configure htmlAwed to accept data: in the src: schema.
    1. Open the htmlAwed lib with your favorite editor. The file is located at: GLPI_ROOT/lib/htmlawed/htmlawed.php
    2. Locate line 47.
    3. make the end of the line look like this:
      t; *:file, http, https; src: data';
      
  2. For some reason the ‘denied:’ part in ‘src=’denied:data:image/png;base64…’ is saved in the database. Because of this the ‘denied’ portion still turns up in the content (not because of htmlAwed). You can easily fix this by running the following SQL statement in your TEST database.
    update glpi_knowbaseitems set answer =REPLACE(answer, 'denied:', '');
    
    Query OK, 12 rows affected (0.29 sec)
    Rows matched: 284  Changed: 12  Warnings: 0
    

If all is well, the images should again be displayed in your knowledge base.

Tiny MCE will accept the inline images (inserted from the clpiboard with greenshot) and will display them correctly…

Got any remarks or tips, let me know 🙂

Check_VM for Oracle VM and Nagios.

Personal backup…

Refinements might be added if bugs or improvements are found. So keep an eye out for newer versions 😉

This script might also be compatible with other  Xen clones.


#!/usr/bin/perl
#
# Author : Chris Gralike
# Company: AMIS Services BV
#
# Simple but effective Oracle VM check command for use with nagios
# This command checks the state of any given VM machine using the XM command.
# It will try to match the friendly name as well as the system name.
# It will return OK - and usefull metadata on succes, NOK on failure.
# usage : check_xm vmname
# ########################

use strict;                     # Good practice
use warnings;                   # Good practice

my (@data, @values, @name, $vmname, $vmcheck, $i, $result);

# Get the command parameters
if( ($#ARGV + 1) == 1 ) {
$vmname = $ARGV['0'];
}else{
print "usage: ./check_xm vmname \n";
exit 1;
}

# Perform the actual test
open(XM, "xm list|");
$i = 0;
while(<XM>){
if($i > 0){
# Split the output in portions
@data = split(" ", $_);
# Get the human readable name
@name = split('_', $data['0']);
if(!$name['1']){
$name['1'] = 'dezeisnietingebruik!';
}
if(($vmname eq $name['1']) || ($vmname eq $data['0'])){
print "OK - $data['0'] is active with Id:$data['1'] $data['3']CPUs $data['2']M \n";
exit 0;
}
}
$i++;
}
close XM;

# If the loop was finished without result, then there is a problem!
print "NOK - $vmname is not running on this server\n";
exit 2;

Backup script for GLPI (http://www.glpi-project.org)

If you are using the great GLPI tool, you will notice that the market value of the data inside will increase rapidly. This usually also implicates that it is ‘wise’ to back this data up.

There are many ways to do so using nice plugins, even nicer gui`s and apps. I (headstrong that I am), wanted something very basic and functional, easy to configure, and that will work in an environment that has multiple GLPI installations. Answer to my question: build something for your own.

So i scripted something for Linux that will allow you to backup the entire GLPI tree (where the uploaded files reside), and the sql database.

Because we use a deduped backup storage (datadomain), i dont have to worry about duplicate data. If you need to, then add something to clean the backup store. This script doesn’t account for that 🙂

This is the script:


#!/bin/bash
# Wrote by Chris
# Goal is to easly backup glpi in a multi installation environment.

GLPI_DIR='/var/www/glpi_0805';
BACKUP_DIR='/backup/nfsloc';
LOGFILE='/var/log/backup.log';

############################################################################
#Dont change anything after this point, unless you know what you are doing #
#No guarantees, une this script at own risk                                #
############################################################################

# Do some generic stuff here
# Add checks if you like 🙂
#############################
MYSQLDUMP=`which mysqldump`;
AWK=`which awk`;
FIND=`which find`;
DATE=`date +%d.%m.%Y`;
LOGTIME=`date +"%d-%m-%Y %H:%m"`;
DBCONFIG=`find $GLPI_DIR -name "config_db.php"`;
DBNAME=`grep "dbdefault" $DBCONFIG | awk -F '=' '{ gsub(/\047/,""); gsub(/\;/,""); gsub(/ /,""); print $2;}'`;
GLPISIZE=`du -sh $GLPI_DIR`;

#
# Start working....
############################
echo -e "$LOGTIME \t## New backup started ##" >> $LOGFILE;
echo -e "$LOGTIME \tpacking: $GLPISIZE.. into $BACKUP_DIR/backup.$DATE.tar.bz2 ..." >> $LOGFILE;
tar -cjPf $BACKUP_DIR/backup.$DATE.tar.bz2 $GLPI_DIR >> $LOGFILE;
echo -e "$LOGTIME \tCreating mysqldump into $BACKUP_DIR/sqldump.$DATE.sql ..." >> $LOGFILE;
mysqldump $DBNAME > $BACKUP_DIR/sqldump.$DATE.sql;
# Go back to original working directory.
echo -e "$LOGTIME \tAll done..." >> $LOGFILE;
echo "all done! ";

exit 0;

If you want to install this script follow the following instructions:


#This is for Oracle Enterprise Linux / RedHat EL distro`s
#Your environment might be slightly different.
cd /opt
mkdir ./scripts
cd scripts
vi ./backup.sh
#insert the code above into the editor and save the lot using ':wq'
#alter the top of the script to match your environment.
chmod +x ./backup.sh
#next create a symbolic link to the cron.daily, this might be different in your linux distro (see manual pages on your distro using 'man cron').
ln -s /opt/scripts/backup.sh /etc/cron.daily/backup
#monitor the /var/log/backup.log for details

Happy backing up 🙂

(Dont forget to clean the backup dir on a regular basis if you dont have the luxury of an deduping storage)

Draw dots in images using PHP, XMLHttp, Mysql.

A family member asked me if it was possible to use html, php, mysql to mark spots in an image of the human skeleton during an medical anamnesis collection. He wanted this to easily mark the complaint spots of his patients. He also needed to be able to remove marks when they where faulty and wanted this all to be stored in a database for easy reference and backup.

Seeing the complexity of it, I accepted the challenge he laid out for me.

The most complex part of this was the ‘how to remove’ spots from an image without deleting the actual fixed image of the skeleton. The solution I came up with was using an Fixed background image in HTML and use a transparent overlay that I will be updating using PHP and XMLHttp request headers.

The result of this approach was the following.

All that needs to be done during reporting is merging both images together, which is fairly easy using php.

But because I though someone else might use this script as well, I thought sharing it here with the world was a nice option. The application is endless, from damage reporting to Location reporting, and in the finished from its fairly easy to understand and adjust to your needs.

I added the sourcecode for this script to this post. You need to have a mysql database, php with GD enabled, browser that supports XHTMLRequest (all modern browsers). Simply dump the files into the a php html enabled location and make sure you create the required SQL table (usign the .sql script inside the archive) and have a go with it (you might need to alter the mysql user/pass inside the PHP script)….

image_draw-rar.pdf

Use the “save as” option to grab the file from this site. Rename the file to something.zip, unpack and access the srcfiles inside the rar archive… use winrar to unpack.

Let me know what you think, or if you found it usefull 🙂

p.s. I wasnt able to verify the author of the used skeleton image. If you are/know him, let me know if this application is allowed, and how to publish the credits.

Check_iostat.pl version 0.9.7

Previous version and detaild information
https://sysengineers.wordpress.com/2010/02/05/check_iostat-for-nagios-version-0-9-5/

Application Goal:
Check disk IO using a simple perl script and possibly the counters allready available in the linux /proc/ directory. The program must be able to run under Nagios and should return a ‘Nagios’ correct syntax to the prompt. This way the plugin should be usable for Linux users to monitor their Disk IO within Nagios. The program should also report back performance information in the ‘Nagios’ compatible syntax so that graphing is available in the ‘Nagios’ / Cacti / Centreon add-ons.

Changes
Fixed lacking devision in validated summed results
Added sprintf functions rounding the validated numbers with 2 dimentions
Fixed some declaration problems
Added -debug switch to enable the debugging options
Coded arround the used math::Complex functions and removed the module
Improved the debugging output (readability)
Small fixes in de syntax

Installation
1. Copy the code below to your clipboard (ctr+c or the copy-button inside the code field)
2. Logon to the linuxbox with the nagios or nrpe client.
3. browse to the plugin-dir usually cd /usr/local/nagios/libexec/
4. Create a new file vi ./check_iostat.pl
5. Press insert and paste the code inside (when using putty paste is done with a rightmouse click)
6. save the file (esc > : > rq > enter, when using vi)
7. give the file execute rights using chmod +x ./check_iostat
8. make nagios the owner chown nagios:nagios ./check_iostat
9. Test it using updatedb& ./check_iostat -d sd -dbu -dbuw 70 -dbuc 88 -kbs -kbsw 10000 -kbsc 50000 -p

Next configure a nagios command or use nrpe and have fun 🙂

#!/usr/bin/perl
# Written by Chris Gralike @ AMIS.
# Perl based check command to fetch and report the
# TPS (transactions per second) and IO wait times.
# Plugin uses iostat for opperation.
# Verion 0.9.7
#
# Changes post 0.9.7 >> 28-05-2010
# Line 298...303 Prevent devision by zerro else exit because no data was collected  - Bug reported by Epiq.
# Line 380       Correction of a type that prevented pref data of r/s w/s from being printed. - Bug reported by Epiq.
# Line 40        Added dm as possible device input used by the linux LVM. - Suggested by Epiq.
# Line 269       Extended the device if/pragmatch validation to match more devices - Added by Jean Ventura.
#
###########################
use Switch;
use warnings;

my($numArgs,
   $debug,	# Print debugging information.
   $DevType,	# Used to match a certain devicetype from the resulting IOstat rows.
   $IOBIN,	# Is used to store a path to the iostat binairy for execution.
   $Samples,	# Used to store the initial Samples returned by iostat.
   @SampleRows, # Used to store the rows generated by the splitted samples.
   $firstseen,  # Used to keep track of the found devices (IOstat might return a set of devices i.e sda, sdb, sdc etc.)
   $Items,      # Used in the foreach to store the row being parsed.
   @cols,       # Used to store the columns in a row after an split.
   $dev,	# Used to create a symbolic link to dynamicly create a var.
   $rqm,
   $val,
   $devtypes,
   $rws, $rws_warn, $rws_crit,
   $kbs, $kbs_warn, $kbs_crit,
   $awt, $awt_warn, $awt_crit,
   $svc, $svc_warn, $svc_crit,
   $devices, $itd,$v1,$v2,$v3,
   $v4,$v5,$v6,$v7,$v8,$v9,$v10,$v11,
   $dbu, $dbu_warn, $dbu_crit
   );

# Preparing to collect the dangerious user input.
# Here is a list of known device types. Please add any device you would like to monitor..
$devtypes=";sd;hd;dm;";
$numArgs = $#ARGV + 1;
$critical_global = 0;
$warning_global = 0;

if($numArgs gt '0'){
	for($i=0;$i<$numArgs;$i++){
	# Process our command line arguments and do some basic testing.
	# Could be make human save in the future.
	switch ($ARGV[$i]) {
		# Enable debugging.
		case '-debug'{
				$debug = 1;
			     }
		# Handle device type
		case '-d'    {
				$val=$ARGV[$i+1];
		 		if( (index($devtypes, $val)) gt '-1'){
					$DevType=$val;
					$i++;
		  		}else{
					print "Ivalid Disktype found. Typo?\n"; exit 1;
		  		}
			     }
		# Do we need to check rqm?
		case '-rqm'  { $rqm='1'; }
		# What is the warning treshold?
		case '-rqmw' {
				$val=$ARGV[$i+1];
				# Is the value nummeric?
				if($val=~m/[0-9]*/){
					$rqm_warn= int $val;
					$i++;
				}else{
				# Possible type?
					print "Non Numeric value used in rqmw, typo? \n"; exit 1;
				}
			     }
		case '-rqmc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rqm_crit= int $val;
					$i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rqmc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check rws?
		case '-rws'  { $rws='1'; }
		case '-rwsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsw, typo? \n"; exit 1;
                                }
			     }
		case '-rwsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check kbs?
		case '-kbs'  { $kbs='1'; }
		case '-kbsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsw, typo? \n"; exit 1;
                                }
			     }
		case '-kbsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check awt?
		case '-awt'  { $awt='1'; }
		case '-awtw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtw, typo? \n"; exit 1;
                                }
			     }
		case '-awtc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check svc?
		case '-svc'  { $svc='1'; }
		case '-svcw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcw, typo? \n"; exit 1;
                                }
			     }
		case '-svcc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check dbu?
		case '-dbu'  { $dbu='1'; }
		case '-dbuw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuw, typo? \n"; exit 1;
                                }
			     }
		case '-dbuc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuc, typo? \n"; exit 1;
                                }
			     }
		# performance data. Might make the string human unreadable.. ow well, no loss there <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
		case '-p'    { $prf='1'; }
		# Print full messages per device overview.
		#case '-m'    { $fms='1'; }
		# Most used help switches.
		case '--help'{ USAGE(); }
		case '-h'    { USAGE(); }
	}
	}
	# Check if the basic requirements are met.
	if(!($DevType) ||  !(($rqm || $rws || $kbs || $awt || $svc || $dbu))){
		print "Minimal requiremens, device and checktype are not met\n";
		USAGE();
	}
}else{
	# No input was given. Show the Usage();
	USAGE();
}

# Locate the IOBin binairy needed to fetch the stats.
chomp($IOBIN=`which iostat`);

if( !(-f $IOBIN) || !(-x $IOBIN)){
	print "A working iostat command is needed for this script to work \n";
	print "Also make sure the sysstat service is running! /etc/init.d/sysstat \n";
	exit 1;
}

if($DevType){
	# IF IOStat is found, lets collect some data.
	chomp($Samples=`$IOBIN -d -x -k 1 5 | grep $DevType`);
}else{
	print "Please select a valid devicetype \n";
	exit 1;
}

# Break the samples up in lines so we can evaluate them.
# The first set of samples are avg. values counted from boot.
# We need to discard them and collect the remaining samples.
@SampleRows=split(/\n/, $Samples);

# Firstseen is used to track de device names and to skip the first itteration of iostat that contains
# avg stats counted from system boot time, stats we cant use here sadly <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
$firstseen='';
$CT=0;
$Devices=0;

# Print Debugging information
if($debug){
	    print "### Data collected ###\n";
	    print "dev|rrqm|wrqm|r/s|w/s|rKB/s|wKB/s|rq-sz|qu-sz|await|svctm|util%|\n";
}

foreach $Items (@SampleRows){
	 # Break the latter up in usable columns.
        @cols=split(/\s+/,$Items);
	 # We only want a certain device type. So lets match what we know.
	 # Disks usualy have a prefix for example (scsi = sd) its set using
	 # the DevType var.
         if($cols[0]=~m/$DevType-[0-9]$/ || $cols[0]=~m/$DevType[a-z]$/ || $cols[0]=~m/$DevType[a-z][0-9]$/){

		$dev=$cols[0];
		if((rindex $firstseen, $dev) gt '-1'){
			#Declare new $$
			#my @$dev;
			# Store the collected data in the correct (dynamic) vars.
			$$dev[1]+=$cols[1];	# rrqm/s   Read Requests Merged per Second.
			$$dev[2]+=$cols[2];	# wrqm/s   Write Requests Merged per Second.
			$$dev[3]+=$cols[3];	# r/s      Number of read requests issued per Second
			$$dev[4]+=$cols[4];	# w/s      Number of write requests issued per Second
			$$dev[5]+=$cols[5];	# rKB/s    Number of Kilobytes read per Second.
			$$dev[6]+=$cols[6];	# wKB/s    Number of Kilobytes written per Second.
			$$dev[7]+=$cols[7];	# Avgrq-sz Avarage size (in sectors) of the issued requests.
			$$dev[8]+=$cols[8];	# Avgqu-sz Avarage Queue length of the requests issued.
			$$dev[9]+=$cols[9];	# Await	  Avarage wait time in ms for IO requests to be served.
			$$dev[10]+=$cols[10];	# svctm    Avarage service time in ms for IO requests that where issued.
			$$dev[11]+=$cols[11];   # %util    Precentage of CPU time during IO requests (bandwidth util), saturation at 90~100%
			$CT++; # Add a new itteration to the count
			# Print some debugging vars if requested. to show the data is collected.
			if($debug){
				    print "$dev|$cols[1]|$cols[2]|$cols[3]|$cols[4]|$cols[5]|$cols[6]|$cols[7]|$cols[8]|$cols[9]|$cols[10]|$cols[11]|\n";
			}
		}else{
			$Devices++;
			$firstseen.="$dev;";
		}
	}
}

# Prevent $itd (itterations / disk) from becomming zerro and exit when no devices are found.
# on line 299.
if($Devices > 0){
	$itd = ($CT / $Devices);
}else{
	print "No performance data was captured. Please check if the device name is correct\n"; exit 1;
}

# Print debugging information
if($debug){
	print "###Devices Counted###\n";
	print "Number of devices : $Devices\n";
	print "Number of itterations per device : $itd\n";
	print "Total Number of Itterations : $CT\n";
}
# Lets collect the device information from the firstseen var
# and start processing it for some perf check/data
# Lets also recycle some previously used vars for this.
@cols=split(/;/,$firstseen);
foreach $Items (@cols){
	# Items now contains the devicenames needed to access the data again.
	# We now need to check them against some basic tresholds
	# Print a nice table with the calculated values when we are in debug.

  	# Print debugging information
	if($debug){
		   print "### Counted Values ###\n";
		   print "$Items|$$Items[1]|$$Items[2]|$$Items[3]|$$Items[4]|$$Items[5]|$$Items[6]|$$Items[7]|$$Items[8]|$$Items[9]|$$Items[10]|$$Items[11]|\n";
        }

	#What do we want to check against a treshold?
	#First check the selection if any.
	if($rqm || $rws || $kbs || $awt || $svc || $dbu){

		#Set the counts to zerro
		$critical_state='0';
		$warning_state='0';
		$ok_state='0';
		# Devide
		$round="%.2f";
		$v1 = sprintf($round, ($$Items[1] / $itd));
        $v2 = sprintf($round, ($$Items[2] / $itd));
		$v3 = sprintf($round, ($$Items[3] / $itd));
        $v4 = sprintf($round, ($$Items[4] / $itd));
		$v5 = sprintf($round, ($$Items[5] / $itd));
        $v6 = sprintf($round, ($$Items[6] / $itd));
		$v7 = sprintf($round, ($$Items[7] / $itd));
        $v8 = sprintf($round, ($$Items[8] / $itd));
		$v9 = sprintf($round, ($$Items[9] / $itd));
        $v10 = sprintf($round, ($$Items[10] / $itd));
        $v11 = sprintf($round, ($$Items[11] / $itd));

		# Requests Merged per second.
		if($rqm){
			# Critical
			if(($v1 >= $rqm_crit) || ($v2 >= $rqm_crit)){
				$critical_state+='1';
			# Warning?
			}elsif(($v1 >= $rqm_warn) || ($v2 >= $rqm_warn)){
				$warning_state+='1';
			# Ok
			}else{
				$ok_state+='1';
			}
			# Add the counters to the performance vars
			$perf.="$Items-rrqm/s=$v1; $Items-wrqm/s=$v2;";
		}
		# Reads / Writes per second.
		if($rws){
			if(($v3 >= $rws_crit) || ($v4 >= $rws_crit)){
	                    	$critical_state+='1';
             		# Warning?
               	 	}elsif(($v3 >= $rws_warn) || ($v4 >= $rws_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			# Add the counters to the performance var.
			$perf.="$Items-r/s=$v3; $Items-w/s=$v4; ";
		}
		# KB Read/Writes per second.
		if($kbs){
			if(($v5 >= $kbs_crit) || ($v6 >= $kbs_crit)){
	                        $critical_state+='1';
	                # Warning?
       	         	}elsif(($v5 >= $kbs_warn) || ($v6 >= $kbs_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                       	 	$ok_state+='1';
                	}
			$perf.="$Items-rKB/s=$v5; $Items-wKB/s=$v6; ";
		}
		# Avarage wait time
		if($awt){
			if(($v9 >= $awt_crit)){
                        	$critical_state+='1';
                	# Warning?
                	}elsif(($v9 >= $awt_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-await=$v9; ";
		}
		# Avarage service time issuing time
		if($svc){
			if($v10 >= $svc_crit){
       	                	$critical_state+='1';
                	# Warning?
                	}elsif($v10 >= $svc_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-svctm=$v10; "
		}
		# Disk bandwidth Utilization
		if($dbu){
			if($v11 >= $dbu_crit){
                	        $critical_state+='1';
              	  	# Warning?
               	 	}elsif($v11 >= $dbu_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-util=$v11%; ";
		}
	}else{
		print "At least select a value to measure..\n";
		exit 1;
	}
	# Print Debugging information about the validated values.
	if($debug){ print "### validated Devisions ###\n";
                    print "$Items|$v1|$v2|$v3|$v4|$v5|$v6|$v7|$v8|$v9|$v10|$v11|\n";
	}

	# Create a messages var.
	$mgs.="$Items=O:$ok_state,W:$warning_state,C:$critical_state; ";

	# Track the global state (1 crit 1 warn)
	if(($critical_state gt '0') || ( $critical_global gt '0')){
		$critical_global+='1';
	}
	if(($warning_state gt '0') || ( $warning_global gt '0')){
		$warning_global+='1';
	}
}

# Compose a nice nagios output.
if($critical_global >= '1'){
	print "CRITICAL:";
	$exit=2;
}elsif($warning_global >= '1'){
	print "WARNING:";
	$exit=1;
}else{
	print "OK:";
	$exit=0;
}
# Print the remainder, the most important data was processed.
print $mgs; if($prf){ print "|$perf"; } print "\n";
exit $exit;

###Subroutines
sub USAGE{
	print "
                Usage : $0 -d [Dev] [options]

		-p Print performance data about the measured samples.

		-d {grep string used on IOstat}
		examples;
                 sd     #All scsi devices.
                 hd     #All Cdrom devices.
		 sda	#Only device sda

                [Available Measurement Options]
                -rqm -rqmw val -rqmc val        # read/write merged             [#]
                -rws -rwsw val -rwsc val        # read/write per second.        [s]
                -kbs -kbsw val -kbsc val        # KBs read/written per second.  [s]
                -awt -awtw val -awtc val        # Avarage IO wait time.         [ms]
                -svc -svcw val -svcc val        # Avarage service IO wait time. [s]
                -dbu -dbuw val -dbuc val        # Disk utilization              [%]\n";
        exit 1;
}

check_iostat / check_io for nagios Version 0.9.5

Oke here is the first working version of check_iostat.pl

NEW Version available HERE

https://sysengineers.wordpress.com/2010/05/27/check_iostat-pl-version-0-9-7

Why this version?
Well to my big surprise I was not able to find any satisfying check plugin for diskio that didnt need all kinds of additional software or undocumented perl plugins. What i really wanted was a simple check plugin that would only require the default sysstat daemon allready present on allot of our systems (Oracle DB requirement).

Because no one seemed to have written such a plug-in I decided to write one myself. And here is the result.

How to get started?
Copy paste the source into a check_iostat.pl file within nagios/libexec.

The following needs to be on your Linux machine.
sysstat must be installed!
iostat must be available!
perl (base) should be installed!

What can you do?
1. Let us know on what distro you have tested this code! And or what changes you made to make it work.
2. Tell me if you spotted any improvements in the code.
3. Tell me if there are any bugs.

What more?
Questions? Different requirements? Improvements? Code cleanup?
Please let me know…

Tested with?
PERL
v5.8.8
v5.8.3

LINUX
Enterprise Linux Enterprise Linux Server release 5.3 (Carthage)
Enterprise Linux Enterprise Linux Server release 5.2 (Carthage)
SUSE LINUX Enterprise Server 9 (i586)

Note!
the code is still a bit messy but functional. Keep an eye out here for updates. I will be cleaning up this code further.

Rgrds,
Chris.

Code below…
Read the rest of this entry

Phase one, Check IOStat for Nagios.

Full Working version can be found here

/* CHECK OUT THE LINK AT THE TOP OF THIS POST 😉 */
/* OR CHECK THE SOURCE DIRECTLY HERE ;               
     http://technology.amis.nl/download/iostat/

    THIS SCRIPT REQUIRES THE SYSSTAT PACKAGE (IOSTAT)
*/

Thanks, Rgrds,

Simple php function to filter out unwanted text char types.

Just wrote a little function that will remove all char types from a string or text (if thats in the string) that are not given in the chars list. In my example I only wanted alpha chars and spaces. It also converts all to lower caps.

It walks through the given string using a substr function to locate the char to be evaluated. If the char is found in the given allowed string using a strstr function it will add it to the return string, else it will simply discard it. Before evaluation it also converts the val to a lowercap.

<?php

function cleanstr($s, $c, $l=true){
        $r='';
        $l=strlen($s);
        if($l){$s=strtolower($s);}
        for($i=0;$i<$l;$i++){
                $v=substr($s, $i, 1);
                if(strstr($c, $v)){ $r .=$v;}
        }
        return $r;
}

$string='abcdef $%%# Chris';
$chars=' abcdefhijklmnopqrstuvwxyz';
echo cleanstr($string, $chars);
?>

Prints out…

php ./test.php
abcdef  chris

NDO2DB startup script for RH (EL) / OEL

Below a script designed to use the RH . /etc/init.d/functions library. It will use 2 “find” commands to test if it can find the ndo2db binairy and config file. Next it will daemonize the ndo2db process following the Redhat standard init procedure.

This script was written for Redhat enterprise linux using Nagios, Centreon (auto generation of the config)

Edit the “searchdir” for a broader searchscope. In the current code the nagios tree is searched for both the config and the ndo2db binairy.

touch a file in the init.d like so.

touch /etc/init.d/ndodaemon

NExt edit the file and add the code below.

vi /etc/init.d/ndodaemon

Please note the fact that this script uses the /etc/init.d/functions file. Not all linux distro`s deliver this file. Do check its availability in your own distro!

#!/bin/sh
#
# "$Id: ndodaemon.sh,v 0.9 2010/01/19 Chris Exp $"
#
#   Startup/shutdown script for the NDO2DB daemon under centreon/nagios.
#
#   Linux chkconfig stuff:
#
#   chkconfig: 2345 56 10
#   description: Startup/shutdown script for NDO2DB Daemon \
#                using Centreon / Nagios.

# Source function library.
. /etc/init.d/functions

# Set various vars
#DAEMON=ndo2db;
prog=ndo2db;
SEARCHDIR="/usr/local/nagios"
NDODAEMON=`find $SEARCHDIR -name "ndo2db"`;
NDOCONFIG=`find $SEARCHDIR -name "ndo2db.cfg"`;

#Check if both the ndo daemon and config are found.
#echo -n $"Searching ndo config & binairies : "
if test -f $NDODAEMON
then
        if test -f $NDOCONFIG
        then
                RETVAL=0;
                #echo "Files found!";
        else
                echo "ERROR: Config file not found!";
                exit 1;
        fi
else
        echo "ERROR: ndo2db not found!";
        exit 1;
fi
        start () {
                if test -f "/var/lock/subsys/ndo2db"
                then
                        echo "ndo2db is allready running...";
                        return 1;
                fi

                echo -n $"Starting $prog: "
                # start daemon
                daemon $NDODAEMON -c $NDOCONFIG
                RETVAL=$?
                echo
                [ $RETVAL = 0 ] && touch /var/lock/subsys/ndo2db
                return $RETVAL
        }
        stop () {
                # stop daemon
                echo -n $"Stopping $prog: "
                killproc $NDODAEMON
                RETVAL=$?
                echo
                [ $RETVAL = 0 ] && rm -f /var/lock/subsys/ndo2db
        }

        restart() {
                stop
                start
        }

        case $1 in
                start)
                        start
                ;;
                stop)
                        stop
                ;;
                restart)
                        restart
                ;;
                condrestart)
                        [ -f /var/lock/subsys/ndo2db ] && restart || :
                ;;
                reload)
                        echo -n $"Reloading $prog: "
                        killproc $NDODAEMON -HUP
                        RETVAL=$?
                        echo
                ;;
                status)
                        status $NDODAEMON
                        RETVAL=$?
                ;;
                *)

                echo $"Usage: $prog {start|stop|restart|condrestart|reload|status}"
                exit 3
        esac
exit $RETVAL

Next if you have chkconfig available as package, you should be able to add the script to the linux init using the commands;

chkconfig --add ndodaemon
chkconfig --level 2345 ndodaemon on

start the ndodaemon manually using

/etc/init.d/ndodaemon start
#or
service ndodaemon start

For those not using Centreon (a shame 😛 ) here is an example (default) ndo2db configuration file.

###################################################################
# #
# GENERATED BY CENTREON #
# #
# Developped by : #
# – Julien Mathis #
# – Romain Le Merlus #
# #
# http://www.centreon.com #
# For information : contact@centreon.com #
###################################################################
# #
# Last modification January 19, 2010, 11:11 am #
# By AMIS Services #
# #
###################################################################

ndo2db_user=nagios
ndo2db_group=nagios
socket_type=tcp
socket_name=/var/run/ndo.sock
tcp_port=5668
db_servertype=mysql
db_host=localhost
db_name=centstatus
db_port=3306
db_prefix=nagios_
db_user=centreon
max_timedevents_age=1440
max_systemcommands_age=1440
max_servicechecks_age=1440
max_hostchecks_age=1440
max_eventhandlers_age=1440

Hope this helps!

-Regards,