// // checkFileAgeExec.java // nagios plugin to monitor for files returned from shell commands which are older than a given # of milliseconds // // Author: Sergei Haramundanis // Date: 24-Apr-2007 // Update: [1.1] 22-May-2007 by S. Haramundanis to report target_file_age_ms in human readable format // // usage: java checkFileAgeExec command_filename target_file_age_ms check_from_time check_to_time // // Description: // // This plugin will scan files returned from commands contained in the command file specified to determine if any of // the files have not been modified for longer than the specified target file age in milliseconds // // Lines beginning with # or blank lines in the command file are ignored. // // Example commands: // // Unix: // // find /clareonProd/sched -name 'encrypted*' // find /clareonProd/sched -name 'non-encrypted*' // // Windows: // // C:\cygwin\bin\find . -name 'encrypted*' // C:\cygwin\bin\find . -name 'non-encrypted*' // // Output: // // During any run of the plugin, if it finds any files older than the specified number of milliseconds // it will return a WARNING state with the last file found prefixed by the number of files that were found // to be older as in the following example: // // [WARNING] [5] "/ftp/inbound/filename.pdf" is older than 1800000 ms // // in this case the [5] indicates that it found five files older than 30 minutes (1800000 ms) and // filename.pdf is the last one it found // // if no files are found to be older in the directory list it will return an OK state with the message: // // [OK] no files found older than ms // // If the current time falls outside the specified check_from_time and check_to_time it will return on OK state with the message: // // [OK] current time outside of monitoring timeframe 1600 and 1800 // // import java.util.*; import java.io.*; import java.text.*; public class checkFileAgeExec { static String productVersion = "checkFileAgeExec 1.1"; // nagios return codes: static int STATE_OK = 0; static int STATE_WARNING = 1; static int STATE_CRITICAL = 2; static int STATE_UNKNOWN = 3; static int STATE_DEPENDENT = 4; static String str_command_filename = ""; static long l_target_file_age_ms = 0; static String str_check_from_time = ""; static String str_check_to_time = ""; static Vector v_commands = new Vector(); static String str_last_old_file_message = ""; public static void main(String[] args) { if ((args.length == 0) || (args[0].equals("--help"))) { System.out.println(productVersion); System.out.println(""); System.out.println("nagios plugin to monitor for files returned from shell commands which are older than a given # of milliseconds"); System.out.println(""); System.out.println("This nagios plugin comes with ABSOLUTELY NO WARRANTY."); System.out.println("You may redistribute copies of this plugin under the terms of the GNU General Public License"); System.out.println("as long as the original author, edit history and description information remain in place."); System.out.println(""); System.out.println("usage: java checkFileAgeExec command_filename target_file_age_ms check_from_time check_to_time"); System.out.println("usage: java checkFileAgeExec --help"); System.out.println("usage: java checkFileAgeExec --version"); System.exit(STATE_OK); } else if (args[0].equals("--version")) { System.out.println(productVersion); System.out.println("This nagios plugin comes with ABSOLUTELY NO WARRANTY."); System.out.println("You may redistribute copies of this plugin under the terms of the GNU General Public License"); System.out.println("as long as the original author, edit history and description information remain in place."); System.exit(STATE_OK); } else if (args.length != 4) { System.out.println("usage: java checkFileAgeExec command_filename target_file_age_ms check_from_time check_to_time"); System.exit(STATE_CRITICAL); } else { long startTime = System.currentTimeMillis(); str_command_filename = args[0].trim(); // determine if command file exists File file_command_file = new File(str_command_filename); if (!file_command_file.exists() || !file_command_file.isFile()) { System.out.println("command file \""+str_command_filename+"\" does not exist"); System.exit(STATE_CRITICAL); } // strip non-ascii characters String str_target_file_age_ms = ""; byte[] bytearray_target_file_age_ms = args[1].trim().getBytes(); for (int i=0; i < bytearray_target_file_age_ms.length; i++) { byte temp_byte = bytearray_target_file_age_ms[i]; if ( (temp_byte >= 48) && (temp_byte <= 57) ) { str_target_file_age_ms += new String(bytearray_target_file_age_ms, i, 1); } } //System.out.println("str_target_file_age_ms = \""+str_target_file_age_ms+"\""); // determine if target file age ms is a number if ((isNotANumber(str_target_file_age_ms)) || (str_target_file_age_ms.indexOf(".") >= 0) || (str_target_file_age_ms.indexOf("-") >= 0) || (str_target_file_age_ms.indexOf("+") >= 0)) { System.out.println("target file age ms \""+str_target_file_age_ms+"\" is not a valid long number"); System.exit(STATE_CRITICAL); } // set target file age ms l_target_file_age_ms = new Long(str_target_file_age_ms).longValue(); // determine if check_from_time is valid // strip non-ascii characters byte[] bytearray_check_from_time = args[2].trim().getBytes(); for (int i=0; i < bytearray_check_from_time.length; i++) { byte temp_byte = bytearray_check_from_time[i]; if ( (temp_byte >= 48) && (temp_byte <= 57) ) { str_check_from_time += new String(bytearray_check_from_time, i, 1); } } if ((isNotANumber(str_check_from_time)) || (str_check_from_time.length() != 4) || (str_check_from_time.indexOf(".") >= 0) || (str_check_from_time.indexOf("-") >= 0) || (str_check_from_time.indexOf("+") >= 0)) { System.out.println("check from time \""+str_check_from_time+"\" is not valid: must be in format ####"); System.exit(STATE_CRITICAL); } int int_check_from_time = Integer.parseInt(str_check_from_time); if ( (int_check_from_time < 0) || (int_check_from_time > 2359) ) { System.out.println("check from time \""+str_check_from_time+"\" is not valid: must be between 0000 and 2359"); System.exit(STATE_CRITICAL); } // determine if check_to_time is valid // strip non-ascii characters byte[] bytearray_check_to_time = args[3].trim().getBytes(); for (int i=0; i < bytearray_check_to_time.length; i++) { byte temp_byte = bytearray_check_to_time[i]; if ( (temp_byte >= 48) && (temp_byte <= 57) ) { str_check_to_time += new String(bytearray_check_to_time, i, 1); } } if ((isNotANumber(str_check_to_time)) || (str_check_to_time.length() != 4) || (str_check_to_time.indexOf(".") >= 0) || (str_check_to_time.indexOf("-") >= 0) || (str_check_to_time.indexOf("+") >= 0)) { System.out.println("check to time \""+str_check_to_time+"\" is not valid: must be in format ####"); System.exit(STATE_CRITICAL); } int int_check_to_time = Integer.parseInt(str_check_to_time); if ( (int_check_to_time < 0) || (int_check_to_time > 2359) ) { System.out.println("check to time \""+str_check_to_time+"\" is not valid: must be between 0000 and 2359"); System.exit(STATE_CRITICAL); } if (int_check_from_time >= int_check_to_time) { System.out.println("check_from_time \""+str_check_from_time+"\" must be less than check_to_time \""+str_check_to_time+"\""); System.exit(STATE_CRITICAL); } // load commands in command file // ignore comments and blank lines RandomAccessFile raf_command_file = null; try { raf_command_file = new RandomAccessFile(str_command_filename, "r"); } catch (java.io.FileNotFoundException exception) { System.out.println("java.io.FileNotFoundException encountered attempting to open command file \""+str_command_filename+"\" : "+exception); System.exit(STATE_CRITICAL); } catch (java.io.IOException exception) { System.out.println("java.io.IOException encountered attempting to open command file \""+str_command_filename+"\" : "+exception); System.exit(STATE_CRITICAL); } String str_record = ""; while (str_record != null) { try { str_record = raf_command_file.readLine(); } catch (java.io.IOException exception) { System.out.println("java.io.IOException encountered attempting to read command file \""+str_command_filename+"\" : "+exception); System.exit(STATE_CRITICAL); } if ((str_record != null) && (!str_record.trim().equals("")) && (!str_record.trim().startsWith("#"))) { v_commands.add(str_record.trim()); } } try { raf_command_file.close(); } catch (java.io.IOException exception) { System.out.println("java.io.IOException encountered attempting to close command file \""+str_command_filename+"\" : "+exception); System.exit(STATE_CRITICAL); } // check if current time is within check_from_time and check_to_time Calendar currentCalendar = Calendar.getInstance(); int int_current_hour = currentCalendar.get(Calendar.HOUR_OF_DAY); int int_current_minute = currentCalendar.get(Calendar.MINUTE); String str_current_hour = ""; String str_current_minute = ""; if (int_current_hour < 10) { str_current_hour = "0"+Integer.toString(int_current_hour); } else { str_current_hour = Integer.toString(int_current_hour); } if (int_current_minute < 10) { str_current_minute = "0"+Integer.toString(int_current_minute); } else { str_current_minute = Integer.toString(int_current_minute); } String str_current_time = str_current_hour+str_current_minute; int int_current_time = Integer.parseInt(str_current_time); if ( (int_current_time >= int_check_from_time) && (int_current_time <= int_check_to_time) ) { int return_val = execCommands(); if (return_val > 0) { long endTime = System.currentTimeMillis(); long elapsedTimeMillisecs = (endTime-startTime); System.out.println("[WARNING] "+str_last_old_file_message+" | elapsedTimeMillisecs="+(elapsedTimeMillisecs)); System.exit(STATE_WARNING); } else { long endTime = System.currentTimeMillis(); long elapsedTimeMillisecs = (endTime-startTime); System.out.println("[OK] no files found older than "+targetAgeHumanReadable()+" | elapsedTimeMillisecs="+(elapsedTimeMillisecs)); System.exit(STATE_OK); } } else { long endTime = System.currentTimeMillis(); long elapsedTimeMillisecs = (endTime-startTime); System.out.println("[OK] current time outside of monitoring timeframe "+str_check_from_time+" and "+str_check_to_time+" | elapsedTimeMillisecs="+(elapsedTimeMillisecs)); System.exit(STATE_OK); } } }// end public static void main(String[] args) public static int execCommands() { int int_old_files_found_count = 0; try { for (int i=0; i < v_commands.size(); i++) { String str_command = (String)v_commands.elementAt(i); /// Runtime currentRuntime = Runtime.getRuntime(); Process childProcess = currentRuntime.exec(str_command); // get all active streams of child process InputStream inputStream = childProcess.getInputStream(); InputStream errorStream = childProcess.getErrorStream(); OutputStream outputStream = childProcess.getOutputStream(); // get the result of the command from the child process String str_result_string = ""; int i_next_byte = 0; while (i_next_byte != -1) { i_next_byte = inputStream.read(); if (i_next_byte != -1) { char c=(char)i_next_byte; str_result_string += c; } } str_result_string = str_result_string.trim(); //System.out.println("str_result_string = \""+str_result_string+"\""); // get stderr String str_error_string = ""; i_next_byte = 0; while (i_next_byte != -1) { i_next_byte = errorStream.read(); if (i_next_byte != -1) { char c=(char)i_next_byte; str_error_string += c; } } str_error_string = str_error_string.trim(); //System.out.println("str_error_string = \""+str_error_string+"\""); //wait for the subprocess to complete //System.out.println("waiting for subprocess to complete"); try { childProcess.waitFor(); } catch (InterruptedException exception) { System.out.println("InterruptedException encountered in checkFileAgeExec.execCommands() waiting for subprocess completion: "+exception); System.exit(STATE_CRITICAL); } //System.out.println("subprocess complete...destroying"); childProcess.destroy(); // close all streams inputStream.close(); errorStream.close(); outputStream.close(); if (!str_error_string.equals("")) { // return error System.out.println("[CRITICAL] problem executing command \""+str_command+"\": \""+str_error_string+"\""); System.exit(STATE_CRITICAL); } else { // for each line in command result, determine if file exists // if not skip silently (i.e. not a file) // if so check age and add to old files found // if no old files found, go on to next command silently BufferedReader br_result_string = new BufferedReader(new StringReader(str_result_string)); String str_file = ""; while (str_file != null) { str_file = br_result_string.readLine(); if (str_file != null) { //System.out.println("str_file = \""+str_file+"\""); File file_file = new File(str_file); if (!file_file.isFile()) { // if this is not a file, skip silently } else { // if this file hasn't been modified for target_file_age_ms report it long long_current_time = System.currentTimeMillis(); if ((long_current_time - file_file.lastModified()) > l_target_file_age_ms) { int_old_files_found_count++; str_last_old_file_message = "["+int_old_files_found_count+"] \""+file_file+"\" is older than "+targetAgeHumanReadable(); } } } } } } } catch (Exception exception) { System.out.println("Exception encountered during checkFileAgeExec.execCommands(): "+exception); System.exit(STATE_CRITICAL); } return int_old_files_found_count; }// end public static int execCommands() public static boolean isNotANumber(String value) { // check if the string value is convertable to a number ParsePosition parsePosition = new ParsePosition(0); Object numberObject = NumberFormat.getInstance().parseObject(value, parsePosition); if ( (parsePosition.getIndex() != value.length()) || (numberObject == null) ) { // not a number! return true; } else { return false; } }// end public static boolean isNotANumber(String value) public static String targetAgeHumanReadable() { long l_target_age_ms = l_target_file_age_ms; String str_return_val = ""; // convert l_target_age_ms to format: weeks, days, hours, minutes, seconds, milliseconds // 1000 milliseconds per second // 60 seconds per minute // 3600 seconds per hour // 86400 seconds per day // 604800 seconds per week long weeks = 0; long days = 0; long hours = 0; long minutes = 0; long seconds = 0; long milliseconds = 0; while (l_target_age_ms/1000 >= 604800) { weeks++; l_target_age_ms = l_target_age_ms - (604800*1000); } while (l_target_age_ms/1000 >= 86400) { days++; l_target_age_ms = l_target_age_ms - (86400*1000); } while (l_target_age_ms/1000 >= 3600) { hours++; l_target_age_ms = l_target_age_ms - (3600*1000); } while (l_target_age_ms/1000 >= 60) { minutes++; l_target_age_ms = l_target_age_ms - (60*1000); } while (l_target_age_ms/1000 >= 1) { seconds++; l_target_age_ms = l_target_age_ms - (1*1000); } if (weeks > 0) { if (weeks == 1) { str_return_val += weeks+" week "; } else { str_return_val += weeks+" weeks "; } } if (days > 0) { if (days == 1) { str_return_val += days+" day "; } else { str_return_val += days+" days "; } } if (hours > 0) { if (hours == 1) { str_return_val += hours+" hour "; } else { str_return_val += hours+" hours "; } } if (minutes > 0) { if (minutes == 1) { str_return_val += minutes+" minute "; } else { str_return_val += minutes+" minutes "; } } if (seconds > 0) { if (seconds == 1) { str_return_val += seconds+" second "; } else { str_return_val += seconds+" seconds "; } } if (l_target_age_ms > 0) { if (l_target_age_ms == 1) { str_return_val += l_target_age_ms+" millisecond"; } else { str_return_val += l_target_age_ms+" milliseconds"; } } return str_return_val; }// end public static String targetAgeHumanReadable() }// end public class checkFileAgeExec