/src/com/clavain/muninmxcd.java
Java | 407 lines | 296 code | 44 blank | 67 comment | 23 complexity | e408f10ba704f67154ae1d51188c7293 MD5 | raw file
- /*
- * MuninMX
- * Written by Enrico Kern, kern@clavain.com
- * www.clavain.com
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- *
- *
- *
- * special thanks to the unbelievable machine company GmbH
- * www.unbelievable-machine.com
- */
- package com.clavain;
- import com.clavain.alerts.Alert;
- import com.clavain.alerts.msg.PushOverMessage;
- import com.clavain.alerts.msg.ShortTextMessage;
- import com.clavain.alerts.msg.TTSMessage;
- import com.clavain.alerts.ratelimiter.PushOverLimiter;
- import com.clavain.alerts.ratelimiter.SMSLimiter;
- import com.clavain.alerts.ratelimiter.TTSLimiter;
- import com.clavain.checks.ReturnDebugTrace;
- import com.mongodb.BasicDBObject;
- import com.mongodb.DB;
- import com.mongodb.DBCollection;
- import com.mongodb.MongoClient;
- import com.mongodb.MongoClientOptions;
- import com.mongodb.ServerAddress;
- import com.mongodb.WriteConcern;
- import com.clavain.executors.MongoExecutor;
- import com.clavain.executors.MongoEssentialExecutor;
- import com.clavain.handlers.JettyLauncher;
- import com.clavain.json.ServiceCheck;
- import com.clavain.munin.MuninNode;
- import com.clavain.munin.MuninPlugin;
- import com.clavain.rca.Analyzer;
- import com.clavain.workers.PluginUpdater;
- import java.io.FileInputStream;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.util.ArrayList;
- import java.util.Properties;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.LinkedBlockingQueue;
- import org.apache.log4j.ConsoleAppender;
- import org.apache.log4j.FileAppender;
- import org.apache.log4j.Level;
- import org.apache.log4j.Logger;
- import org.apache.log4j.PatternLayout;
- import static com.clavain.utils.Database.*;
- import static com.clavain.utils.Quartz.*;
- import com.clavain.utils.SocketCheck;
- import com.clavain.workers.MongoWorker;
- import java.util.Collections;
- import java.util.concurrent.CopyOnWriteArrayList;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerFactory;
- import org.quartz.impl.StdSchedulerFactory;
- import static com.clavain.utils.Generic.getUnixtime;
- import com.clavain.workers.NewNodeWatcher;
- import static com.clavain.utils.Database.dbScheduleAllCustomJobs;
- import com.clavain.workers.DataRetentionWorker;
- import java.io.File;
- import java.io.ObjectInputStream;
- import com.clavain.checks.ReturnServiceCheck;
- import com.clavain.executors.MongoCheckExecutor;
- import com.clavain.workers.ErrorNotifyExecutor;
- import com.google.gson.Gson;
- import java.util.List;
- /**
- *
- * @author enricokern
- */
- public class muninmxcd {
- public static Logger logger = Logger.getRootLogger();
- public static Properties p = null;
- public static LinkedBlockingQueue<BasicDBObject> mongo_queue = new LinkedBlockingQueue<BasicDBObject>();
- public static LinkedBlockingQueue<BasicDBObject> mongo_essential_queue = new LinkedBlockingQueue<BasicDBObject>();
- public static LinkedBlockingQueue<BasicDBObject> mongo_check_queue = new LinkedBlockingQueue<BasicDBObject>();
- public static boolean logMore = false;
- public static MongoClient m;
- public static DB db;
- public static DBCollection col;
- public static String version = "1.0 <Codename: Regret>";
- public static Connection conn = null;
- public static CopyOnWriteArrayList<MuninNode> v_munin_nodes;
- public static CopyOnWriteArrayList<MuninPlugin> v_cinterval_plugins;
- public static Scheduler sched;
- public static Scheduler sched_custom;
- public static Scheduler sched_checks;
- public static CopyOnWriteArrayList<SocketCheck> v_sockets;
- // alerting
- public static LinkedBlockingQueue<PushOverMessage> notification_pushover_queue = new LinkedBlockingQueue<PushOverMessage>();
- public static LinkedBlockingQueue<ShortTextMessage> notification_sms_queue = new LinkedBlockingQueue<ShortTextMessage>();
- public static LinkedBlockingQueue<TTSMessage> notification_tts_queue = new LinkedBlockingQueue<TTSMessage>();
- public static LinkedBlockingQueue<ReturnServiceCheck> check_error_queue = new LinkedBlockingQueue<ReturnServiceCheck>();
- public static CopyOnWriteArrayList<Alert> v_alerts = new CopyOnWriteArrayList<>();
- // RCA
- public static CopyOnWriteArrayList<Analyzer> v_analyzer = new CopyOnWriteArrayList<>();
- public static int rcajobs_running = 0;
- public static int maxnodes = 100000;
- public static int maxchecks = 100000;
- public static int socketTimeout = 30000;
- // CHECKS
- public static CopyOnWriteArrayList<ServiceCheck> v_serviceChecks = new CopyOnWriteArrayList<>();;
- public static List<Integer> errorProcessing = new CopyOnWriteArrayList<Integer>();
- public static String[] initialArgs;
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) {
-
- if(args.length < 1)
- {
- System.err.println("Usage: java -jar MuninMXcd.jar <full path to config>");
- System.exit(1);
- }
-
- try
- {
-
- initialArgs = args;
- p = new Properties();
- FileInputStream propInFile = null;
- propInFile = new FileInputStream(args[0]);
- p.loadFromXML(propInFile);
- String logfile = p.getProperty("log.file");
- socketTimeout = Integer.parseInt(p.getProperty("socket.timeout"));
-
- PatternLayout layout = new PatternLayout("%d{ISO8601} %-5p %m%n");
- ConsoleAppender consoleAppender = new ConsoleAppender( layout );
- logger.addAppender( consoleAppender );
- FileAppender fileAppender = new FileAppender( layout, logfile, false );
- logger.addAppender( fileAppender );
- logger.info("MuninMX Collector Daemon - " + version + " starting up...");
- logger.info("Loading configuration from <"+args[0]+">" );
-
- String l_strLogLevel = p.getProperty("log.level");
- // ALL | DEBUG | INFO | WARN | ERROR | FATAL | OFF:
- if(l_strLogLevel.equals("ALL"))
- {
- logger.setLevel( Level.ALL );
- }
- else if (l_strLogLevel.equals("DEBUG"))
- {
- logger.setLevel( Level.DEBUG);
- }
- else if (l_strLogLevel.equals("INFO"))
- {
- logger.setLevel( Level.INFO);
- }
- else if (l_strLogLevel.equals("WARN"))
- {
- logger.setLevel( Level.WARN);
- }
- else if (l_strLogLevel.equals("ERROR"))
- {
- logger.setLevel( Level.ERROR);
- }
- else if (l_strLogLevel.equals("FATAL"))
- {
- logger.setLevel( Level.FATAL);
- }
- else
- {
- logger.setLevel( Level.OFF);
- }
-
- if(p.getProperty("log.more") != null)
- {
- if(p.getProperty("log.more").equals("true"))
- {
- logMore = true;
- }
- }
-
- } catch (Exception ex)
- {
- System.err.println("Failed to Init basic logging infastructure: " + ex.getLocalizedMessage());
- System.exit(1);
- }
-
-
- try
- {
- // connect to db
- logger.info("Connecting to TokuMX");
- MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
- builder.connectionsPerHost(400);
- builder.autoConnectRetry(true);
- builder.threadsAllowedToBlockForConnectionMultiplier(10);
-
- // speed up inserts, we dont care if we miss some if the shit hits the fan
- builder.writeConcern(WriteConcern.NONE);
- m = new MongoClient( new ServerAddress(p.getProperty("mongo.host")), builder.build());
-
-
- // connect to mysql
- connectToDatabase(p);
-
- // PreFilling Nodes, max 100 in concurrent
- logger.info("Loading initial MuninNode details. This can take a few minutes...");
- v_munin_nodes = new CopyOnWriteArrayList<>();
- v_cinterval_plugins = new CopyOnWriteArrayList<>();
- v_sockets = new CopyOnWriteArrayList<>();
-
- java.sql.Statement stmt = conn.createStatement();
- ResultSet rs = stmt.executeQuery("SELECT * FROM nodes");
- while(rs.next())
- {
- MuninNode mn = new MuninNode();
- mn.setHostname(rs.getString("hostname"));
- mn.setNodename(rs.getString("hostname"));
- mn.setNode_id(rs.getInt("id"));
- mn.setPort(rs.getInt("port"));
- mn.setUser_id(rs.getInt("user_id"));
- mn.setQueryInterval(rs.getInt("query_interval"));
- mn.setStr_via(rs.getString("via_host"));
- mn.setAuthpw(rs.getString("authpw"));
- mn.setGroup(rs.getString("groupname"));
- v_munin_nodes.add(mn);
- logger.info("* " + mn.getHostname() + " queued for pluginfetch");
- }
-
- // launching quartz scheduler
- logger.info("Launching Scheduler");
- SchedulerFactory sf = new StdSchedulerFactory("quartz.properties");
- sched = sf.getScheduler();
- sched.start();
-
- // launching quartz scheduler for custom interval
- logger.info("Launching Custom Interval Scheduler");
- SchedulerFactory sfc = new StdSchedulerFactory("customquartz.properties");
- sched_custom = sfc.getScheduler();
- sched_custom.start();
-
- // starting API server
- new Thread(new JettyLauncher()).start();
-
- int sleepTime = Integer.parseInt(p.getProperty("startup.sleeptime"));
- int startupIterations = Integer.parseInt(p.getProperty("startup.iterations"));
- // scheduling jobs
- int i = 0;
- for (MuninNode it_mn : v_munin_nodes) {
- if(i == startupIterations)
- {
- Thread.sleep(sleepTime);
- i = 0;
- logger.info("Waiting "+sleepTime+"ms for new scheduling slot");
- }
- scheduleJob(it_mn);
- i++;
- }
-
- // schedule custom interval jobs
- dbScheduleAllCustomJobs();
-
- // add all alerts
- dbAddAllAlerts();
-
- // Service Checks
- logger.info("Launching Service Check Scheduler");
- SchedulerFactory sfsc = new StdSchedulerFactory("checksquartz.properties");
- sched_checks = sfsc.getScheduler();
- sched_checks.start();
- // load service checks from database
- stmt = conn.createStatement();
- rs = stmt.executeQuery("SELECT * FROM service_checks");
- while(rs.next())
- {
- Gson gson = new Gson();
- ServiceCheck tc = gson.fromJson(rs.getString("json"), ServiceCheck.class);
- tc.setCid(rs.getInt("id"));
- tc.setUser_id(rs.getInt("user_id"));
- v_serviceChecks.add(tc);
- logger.info("* " + tc.getCheckname() + " Service Check added");
- }
- // queue service checks
- for (ServiceCheck it_sc : v_serviceChecks) {
- scheduleServiceCheck(it_sc);
- }
-
- // starting MongoExecutor
- new Thread(new MongoExecutor()).start();
-
- // starting MongoExecutor for Package Tracking and Essential Informations
- new Thread(new MongoEssentialExecutor()).start();
- // starting MongoExecutor for Service Checks
- new Thread(new MongoCheckExecutor()).start();
- // starting newnodewatcher
- new Thread(new NewNodeWatcher()).start();
-
- // start pushover sending message
- new Thread(new PushOverLimiter()).start();
-
- // SMS Limiter
- new Thread(new SMSLimiter()).start();
- // TTS Limiter
- new Thread(new TTSLimiter()).start();
-
- // start DataRetention Worker
- new Thread(new DataRetentionWorker()).start();
-
- // start Error Notify Inspector
- new Thread(new ErrorNotifyExecutor()).start();
-
- int curTime;
- int toTime;
- int mb = 1024*1024;
- while(true)
- {
- Thread.sleep(5000);
- System.out.println("Mongo Queue Size: " + mongo_queue.size());
- System.out.println("Mongo Check Queue Size: " + mongo_check_queue.size());
- System.out.println("Mongo Essential Queue Size: " + mongo_essential_queue.size());
- Runtime runtime = Runtime.getRuntime();
- //Print used memory
- System.out.println("Used Memory:"
- + (runtime.totalMemory() - runtime.freeMemory()) / mb);
- //Print free memory
- System.out.println("Free Memory:"
- + runtime.freeMemory() / mb);
- //Print total available memory
- System.out.println("Total Memory:" + runtime.totalMemory() / mb);
- //Print Maximum available memory
- System.out.println("Max Memory:" + runtime.maxMemory() / mb);
- System.out.println(" ");
-
- if(p.getProperty("kill.sockets").equals("true"))
- {
- System.out.println("Sockets: " + v_sockets.size());
- // check for sockets that we can kill
- curTime = getUnixtime();
- for(SocketCheck sc : v_sockets)
- {
- toTime = curTime - 120;
- if(sc.getSocketCreated() < toTime)
- {
- if(!sc.getSocket().isClosed())
- {
- logger.info("timing out socket... from: " + sc.getHostname());
- sc.closeSocket();
- v_sockets.remove(sc);
- }
- else
- {
- v_sockets.remove(sc);
- }
- }
- }
- }
-
- }
- } catch (Exception ex)
- {
- System.err.println("Something went wrong as fuck: " + ex.getLocalizedMessage());
- logger.fatal("Something went wrong as fuck. exiting: " + ex.getLocalizedMessage());
- ex.printStackTrace();
- System.exit(1);
- }
- }
-
-
- // Establish a connection to the database
- private static boolean connectToDatabase(Properties p)
- {
- try {
- logger.info("Connecting to MySQL");
- conn =
- DriverManager.getConnection("jdbc:mysql://"+p.getProperty("mysql.host")+":"+p.getProperty("mysql.port")+"/"+p.getProperty("mysql.db")+"?" +
- "user="+p.getProperty("mysql.user")+"&password="+p.getProperty("mysql.pass")+"&autoReconnect=true&failOverReadOnly=false&maxReconnects=10");
- return(true);
- } catch (Exception ex) {
- // handle any errors
- logger.fatal("Error connecting to database: " + ex.getMessage());
- return(false);
- }
- }
- }