import java.io.File; import java.io.FilenameFilter; import java.io.RandomAccessFile; import java.io.IOException; import java.io.InterruptedIOException; import java.util.TimerTask; import java.util.TimeZone; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.net.HttpURLConnection; import java.net.URL; import java.net.Socket; import java.net.SocketException; import java.net.InetAddress; import java.net.DatagramSocket; import ExtensionFilter; import hostinfo; import svcgrp; import sendmail; import shell; import status; import missed; //----------- // main engine called by timer - get time, cruise map dir tree and one at a time load host into hostinfo, // load his service profile and test each service if within host schedule by sniffing or running external // shell script. If failure create entry for status.xml and write new status when all hosts completed. //----------- public class em extends TimerTask { public String mapdir = "/opt/emsweb/emonster/maps"; // parent of the map dirs public String svcdir = "/opt/emsweb/emonster/services"; // location of sevice profiles public String statspath = "/opt/emsweb/emonster/tmp/status.xml"; // status file public String misspath = "/opt/emsweb/emonster/tmp/missed.xml"; // status file public String indexxml = "/opt/emsweb/emonster/index.xml"; // parent doc to touch after status update public String depchk = "scripts/ping.sh"; // script to use for dependency check public void run() { TimeZone tz = TimeZone.getTimeZone("PST"); // or EST, MID, etc ... Date now = new Date(); DateFormat df = new SimpleDateFormat("EEE"); DateFormat tf = new SimpleDateFormat("kk:mm"); DateFormat sf = new SimpleDateFormat("EEE kk:mm MM/dd/yy"); df.setTimeZone(tz); tf.setTimeZone(tz); sf.setTimeZone(tz); String dayofweek = df.format(now); String timeofday = tf.format(now); String logtimeofday = sf.format(now); System.out.println( "Dow: " + dayofweek + " Tod: " + timeofday + " LTD: " + logtimeofday ); File mapPath = new File( mapdir ); ExtensionFilter ef = new ExtensionFilter( "map" ); String[] mapDirs = mapPath.list( ef ); status systat = new status(); systat.load( statspath ); missed misses = new missed(); misses.load( misspath ); for ( int i = 0; i < mapDirs.length; i++ ) { File hostsPath = new File( mapdir + System.getProperty("file.separator") + mapDirs[ i ] ); ExtensionFilter xf = new ExtensionFilter( "xml" ); String[] hosts = hostsPath.list( xf ); for ( int j = 0; j < hosts.length; j++ ) { hostinfo hi = new hostinfo(); hi.getHostInfo( hostsPath + System.getProperty("file.separator") + hosts[ j ].trim() ); svcgrp sg = new svcgrp(); sg.getServiceInfo( svcdir + System.getProperty("file.separator") + hi.servicegroup + ".xml" ); int m = systat.exists( hi.mapname.trim(), hi.hostname.trim() ); if ( hi.pollenabled.equals( "yes" ) && hi.scheduledays.indexOf( dayofweek ) >= 0 && timeofday.compareTo( hi.schedulestart ) >= 0 && timeofday.compareTo( hi.scheduleend ) <= 0 ) { if ( checkDependency( depchk, systat, hi, logtimeofday )) continue; System.out.println( "Scanning " + hi.hostname + " using " + hi.servicegroup ); StringBuffer bad = new StringBuffer(); // list of downage for a host sent to notify for ( int k = 0; k < sg.servicenum; k++ ) { String sname = (String)sg.servicename.get( k ); String stype = (String)sg.servicetype.get( k ); String sport = (String)sg.serviceport.get( k ); String sprot = (String)sg.serviceprotocol.get( k ); String sextr = (String)sg.serviceexternal.get( k ); if ( sextr != null ) { shell sh = new shell(); int x = sh.shell( "scripts/" + sextr + " " + hi.hostname ); if ( x != 0 ) bad.append( " " ).append( sname ); } else if ( stype.equals( "tcp" )) { if ( sprot != null ) { if ( sprot.equals( "http" )) { if ( ! httping( sprot, hi.hostname, sport )) bad.append( " " ).append( sname ); } else { if ( ! tcpsniff( hi.hostname, sport )) bad.append( " " ).append( sname ); } } } else if ( stype.equals( "udp" )) { if ( ! udpsniff( hi.hostname, sport )) bad.append( " " ).append( sname ); } } //eo polling one hosts services if ( bad.length() > 0 ) // we down { misses.update( hi.mapname, hi.hostname ); // System.out.println( "Systat " + hi.mapname + "/" + hi.hostname + " exists: " + m ); String msg = new String( hi.hostname + " " + hi.label + " DOWN:" + bad.toString() + " @ " + logtimeofday ); System.out.println( "bad: " + bad.toString() + " - " + hi.notify ); if ( m >= 0 ) // it's in status file { if ( systat.getPage( m ).equals( "no" )&& notify( hi.notify, msg )) { systat.update( hi.mapname, hi.hostname, hi.label, bad.toString(), "DOWN", "yes" ); msglog.write( hi.mapname + " " + hi.hostname + " notification " + hi.notify + " sent: " + msg ); } } else // not found in status - first scan { systat.add( hi.mapname, hi.hostname, hi.label, bad.toString(), "DOWN", "no", logtimeofday ); msglog.write( hi.mapname + " " + hi.hostname + " DOWN - failed " + bad.toString() ); } } else // we's up { if ( m >= 0 ) // in status - was down previous scan { String msg = new String( hi.mapname + " " + hi.hostname + " " + hi.label + " back UP @ " + logtimeofday ); if ( systat.getPage( m ).equals( "yes" )) { // only if down msg sent notify( hi.notify, msg ); } systat.delete( hi.mapname, hi.hostname ); msglog.write( hi.mapname + " " + hi.hostname + " " + hi.label + " back UP " ); } } } // for each host else { if ( m >= 0 ) // was down and is now disabled { System.out.println( "Systat delete disabled " + hi.mapname + "/" + hi.hostname + " exists: " + m ); systat.delete( hi.mapname, hi.hostname ); } System.out.println( "Skipping " + hi.hostname ); } }// done all hosts } // done all maps System.out.println( "=================" ); systat.save( statspath ); misses.save( misspath ); try { RandomAccessFile xd = new RandomAccessFile( indexxml, "rw"); int z = xd.read(); xd.seek(0L); xd.write(z); xd.close(); } catch ( IOException e ) { System.err.println( "Error touching: " + indexxml + " " + e.getMessage() ); } } //----------- // sniff a udp port at a host named victim to see if he's listening //----------- static boolean udpsniff( String victim, String port ) { try { Integer p = new Integer( port ); DatagramSocket ds = new DatagramSocket(); ds.setSoTimeout( 30000 ); ds.connect( InetAddress.getByName( victim ), p.intValue() ); ds.close(); return true; } catch ( SocketException e ) { System.err.println( "UDPsniff-se " + port + ": " + e.getMessage() ); } catch ( IOException e ) { System.err.println( "UDPSniff-ioe " + port + ": " + e.getMessage() ); } return false; } //----------- // sniff a tcp port at a host named victim to see if she's listening //----------- static boolean tcpsniff( String victim, String port ) { try { Integer p = new Integer( port ); Socket so = new Socket( victim, p.intValue() ); so.close(); return true; } catch ( InterruptedIOException e ) { System.err.println( "TCPsniff-iioe " + port + ": " + e.getMessage() ); } catch ( IOException e ) { System.err.println( "TCPsniff-ioe " + port + ": " + e.getMessage() ); } return false; } //----------- // ping web server name with proto at port using URL //----------- static boolean httping( String proto, String name, String port ) { try { String url = proto + "://" + name + ":" + port; // System.out.println( "Checking URL: " + url ); HttpURLConnection.setFollowRedirects( true ); HttpURLConnection con = (HttpURLConnection)new URL( url ).openConnection(); con.setRequestMethod( "HEAD" ); if ( con.getResponseCode() == HttpURLConnection.HTTP_OK ) { return true; } } catch ( java.io.InterruptedIOException e ) { System.err.println( "Timed Out" ); } catch( IOException e ) { System.err.println( "Exception: " + e.getMessage() ); } return false; } //----------- // returns true on successful notification - script returned 0 //----------- static boolean notify( String notify, String msg ) { boolean retval = false; if ( notify != null ) { shell sh = new shell(); int x = sh.shell( "../notify/" + notify + " \"" + msg + "\"" ); System.out.println( "shell ran " + notify + " return: " + x ); if ( x == 0 ) retval = true; } return( retval ); } //----------- // returns true if dependency is down //----------- static boolean checkDependency( String script, status systat, hostinfo hinfo, String tod ) { boolean retval = true; String FailMsg = "Failed Dependency"; if ( script != null && ! hinfo.dependencyup.trim().equalsIgnoreCase( "none" )) { shell sh = new shell(); int x = sh.shell( script + " " + hinfo.dependencyup ); System.out.println( hinfo.hostname +" dependency " + script + " " + hinfo.dependencyup + " returned: " + x ); if ( x == 0 ) // success! retval = false; else { // failure int i = systat.exists( hinfo.mapname, hinfo.hostname ); if ( i > 0 ) // in there { if ( ! systat.getState( i ).equals( "OUT" )) // change down to out systat.update( hinfo.mapname, hinfo.hostname, hinfo.label, FailMsg, "OUT", "yes" ); } else // first timer { systat.add( hinfo.mapname, hinfo.hostname, hinfo.label, FailMsg, "OUT", "no", tod ); msglog.write( hinfo.mapname + " " + hinfo.hostname + " " + FailMsg + " " + script ); } } } else // no dep script null or none retval = false; return( retval ); } //----------- //----------- } // eoclass //-----------