Esempio n. 1
0
class Mimosa(Cmd):
  dbconn = None
  prompt="Mimosa> " 

  def get_db(self):
    try:
      if self.dbconn == None:
        self.dbconn = Connection()
        
      self.dbconn.server_info()
      return self.dbconn['mimosa']
    except Exception, e:
      if e.__module__ == "pymongo.errors":
        self.dbconn = None
        print(self.colorize("Database error. Is MongoDB running?", "red")),
        
      print self.colorize("Cannot continue.", "red")
      return None
Esempio n. 2
0
class PlumageSessionThread(MintDaemonThread):
    def __init__(self, app, server_host, server_port, cls):
        super(PlumageSessionThread, self).__init__(app)
        self.cls = cls
        
        self.server_host = server_host
        self.server_port = server_port

        try:
            self.connection = Connection(server_host, server_port)
        except AutoReconnect:
            self.connection = None
            log.info("%s could not connect to mongo server at %s:%s, "\
                     "autoreconnect is on" % (self.__class__.__name__, 
                                              server_host, 
                                              server_port))
        self.database = None
        self.collection = None

    def _init(self):
        if self.database is None:
            self.database = Database(self.connection, self.cls.database)

        if self.collection is None:
            self.collection = Collection(self.database, self.cls.collection)

    def _check_connection(self):
        # Loop waiting for the server if it's not there.  Autoreconnect
        # will hook us up...
        while not self.stop_requested:
            try:
                if self.connection is None:
                    self.connection = Connection(self.server_host, 
                                                 self.server_port)
                else:
                    self.connection.server_info()
                break
            except AutoReconnect, e:
                log.info("%s waiting for server, %s, sleeping..."\
                             % (self.__class__.__name__, str(e)))
                for i in range(10):
                    sleep(1)
                    if self.stop_requested:
                        break
Esempio n. 3
0
class Mimosa(Cmd):
    dbconn = None
    prompt = "Mimosa> "

    def get_db(self):
        try:
            if self.dbconn == None:
                self.dbconn = Connection()

            self.dbconn.server_info()
            return self.dbconn['mimosa']
        except Exception, e:
            if e.__module__ == "pymongo.errors":
                self.dbconn = None
                print(
                    self.colorize("Database error. Is MongoDB running?",
                                  "red")),

            print self.colorize("Cannot continue.", "red")
            return None
Esempio n. 4
0
def makeDBConnection(dbport):
    global _C
    if not _C:
        logging.info("establishing db connection at port %s ..." % dbport)
        import pymongo
        logging.info("using pymongo version %s" % pymongo.version)
        if pymongo.version_tuple[0] < 3:
            from pymongo import Connection
            _C = Connection(port=dbport)
        else:
            from pymongo.mongo_client import MongoClient
            _C = MongoClient(port=dbport)
        mongo_info = _C.server_info()
        logging.info("mongodb version: %s" % mongo_info["version"])
Esempio n. 5
0
def makeDBConnection(dbport):
    global _C
    if not _C:
        logging.info("establishing db connection at port %s ..." % dbport)
        import pymongo
        logging.info("using pymongo version %s" % pymongo.version)
        if pymongo.version_tuple[0] < 3:
            from pymongo import Connection
            _C = Connection(port=dbport)
        else:
            from pymongo.mongo_client import MongoClient
            _C = MongoClient(port=dbport)
        mongo_info = _C.server_info()
        logging.info("mongodb version: %s" % mongo_info["version"])
Esempio n. 6
0
def view(server_oid):
    server = g.db['mangoadmin']['servers'].find_one({
        '_id': ObjectId(server_oid)
    })
    if not server:
        flash('Server %s not found' % server_oid, 'error')
        return redirect('/servers')
    connection = Connection(host=server['address'], port=int(server['port']))
    server_info = connection.server_info()
    databases = {
        database: {
            collection : {
                'count': connection[database][collection].count(),
                'index_count': len(connection[database][collection].index_information().keys()),
            } for collection in connection[database].collection_names() if not collection == 'system.indexes'
        }
        for database in connection.database_names()
    }
    return render_template(
        'server_view.html',
        server=server,
        server_info=server_info,
        databases=databases
   )
Esempio n. 7
0
class Instance(object):
	def __init__(self, main_config, node, name, replSet=None, logger_level=logging.INFO):
		self.logger = logging.getLogger('instance-%s' % name)
		self.logger.setLevel(logger_level)

		self.main_config = main_config
		self.name = name

		self.node = node

		mongo_dbin = 	 node.config['mongo_dbin']
		mongo_dbpath =  "%s/%s/" %    (node.config['mongo_dbpath'], name) 
		mongo_logpath = "%s/%s.log" % (node.config['mongo_logpath'], name) 
		mongo_pidpath = "%s/%s.pid" % (node.config['mongo_pidpath'], name) 

		default_config = {
			'flags': None,
			'port': 27017,
			'mongo_dbin': mongo_dbin,
			'mongo_logpath': mongo_logpath,
			'mongo_pidpath': mongo_pidpath,
			'mongo_dbpath': mongo_dbpath,
			'managed': True,
			'replset': None
		}

		self.config = get_config(main_config, 'instance-%s' % name, default_config)

		#self.logger.debug('Config: %s' % self.config)

		# Set by replicaSet
		self.replSet = replSet

		self.logger.debug('Config replset: %s' % self.config['replset'])

		self.pid = None
		self.connected = False
		self.mclient = None
		self.minfo = None
		self.me = None
		self.isMaster = False
		self.isPrimary = False
		self.isSecondary = False

	def make_cmd(self):
		cmd = self.config['mongo_dbin']

		cmd += " --logpath %s" % self.config['mongo_logpath']
		cmd += " --dbpath %s" % self.config['mongo_dbpath']
		cmd += " --pidfilepath %s" % self.config['mongo_pidpath']
		cmd += " --port %s" % self.config['port']

		if self.replSet:
			cmd += " --replSet %s " % self.replSet.name

		if self.config['flags']:
			cmd += " %s " % self.config['flags']

		cmd += "--logappend --fork"


		self.logger.debug('Command line: %s' % cmd)

		return cmd

	def get_pid(self):
		#if self.pid:
		#	return self.pid

		if not self.node.file_exist(self.config['mongo_pidpath']):
			return None

		pid = self.node.exec_command("cat %s | tail -n 1" % self.config['mongo_pidpath'])
		self.logger.debug("Pid: %s" % pid)
		try:
			pid = int(pid)
			return pid
		except:
			return None

	def ping(self):
		return tcp_ping(self.node.config["host"], self.config["port"])

	def get_state(self):
		state = True
		self.states = {}

		self.pid = self.get_pid()

		self.states['pid'] = self.pid
		self.states['pid_run'] = False
		self.states['tcp_ping'] = self.ping()

		self.states['lock'] = False

		try:
			lock = self.node.exec_command("cat %s/mongod.lock | tail -n 1" % self.config['mongo_dbpath'])
			if lock and int(lock) == self.pid:
				self.states['lock'] = True
		except:
			pass

		self.states['running'] = self.check_running()

		if self.pid:
			self.states['pid_run'] = self.node.file_exist("/proc/%s/cmdline" % self.pid)

		if self.states['lock']:
			self.connect()

		self.states['replSet'] = False
		if self.minfo and self.replSet:
			self.states['replSet'] = self.minfo["isMaster"].get("setName", None) == self.replSet.name

		for key in self.states:
			state &= bool(self.states[key])

		self.state = state
		return state

	def check_running(self):
		self.pid = self.get_pid()

		state = self.ping()

		if state and not self.connected:
			state &= bool(self.connect())
			
		return state
		
	def start(self):
		print("Start " + str_blue(self.name) + " on " + str_blue(self.node.name) + ":")

		if not self.config['managed']:
			print(" + Not managed")
			return True

		self.node.exec_command("mkdir -p %s" % self.config['mongo_dbpath'])

		state = self.check_running()
		if state:
			print(" + Already started")
			return True

		if not self.node.file_exist(self.config['mongo_dbin']):
			str_state(False, nok=" + Impossible to find mongod binary")
			return False

		cmd = self.make_cmd()
		self.node.exec_command(cmd)

		for i in range(0, 10):
			state = self.check_running()
			if state:
				print(" + " + str_state(True, ok="Done"))
				return True

			time.sleep(1)

		print(" + " + str_state(False, nok="Fail"))
		print("See '%s' for more informations ..." % self.config['mongo_logpath'])
		return False

	def stop(self):
		print("Stop " + str_blue(self.name) + " on " + str_blue(self.node.name) + ":")

		if not self.config['managed']:
			print(" + Not managed")
			return True

		state = self.check_running()
		if not state:
			print(" + Already stoped")
			return True

		pid = self.get_pid()
		if pid:
			self.node.exec_command("kill %s" % pid)
		else:
			self.logger.warning("Invalid Pid")
			return

		for i in range(0, 10):
			state = self.check_running()
			if not state:
				print(" + " + str_state(True, ok="Done"))
				return True

			time.sleep(1)

		print(" + " + str_state(False, nok="Fail"))
		return False

	def reset(self, prompt=True):
		print("Reset " + str_blue(self.name) + " on " + str_blue(self.node.name) + ":")

		do = True

		if prompt:
			do = False
			try:
				choice = raw_input('Warning, this operation erase all your DB data, are you sure ? (yes/no): ')
			except:
				print('')
				sys.exit(1)

			if choice == "yes":
				do = True
		
		if not do:
			return

		self.node.exec_command("rm -Rf %s" % self.config['mongo_dbpath'])
		self.node.exec_command("rm %s" % self.config['mongo_pidpath'])
		self.node.exec_command("rm %s" % self.config['mongo_logpath'])
		self.node.exec_command("rm %s.*" % self.config['mongo_logpath'])

		print(" + " + str_state(True, ok="Done"))
		return True

	def connect(self):
		if not self.connected:
			try:
				self.mclient = Connection(self.node.config['host'], self.config['port'], slaveOk=True)
				self.minfo = self.mclient.server_info()
				self.connected = True

				self.minfo['isMaster'] = self.mclient["admin"].command("isMaster")

				self.logger.debug("info: %s" % self.minfo)
				self.logger.debug("isMaster: %s" % self.minfo['isMaster'])

				self.me = 		self.minfo['isMaster'].get("me", None)
				self.setName =	self.minfo['isMaster'].get("setName", None)
				self.isMaster = self.minfo['isMaster'].get("ismaster", False)
				self.isArbiter = self.me in self.minfo['isMaster'].get("arbiters", [])

				self.isPrimary = self.me == self.minfo['isMaster'].get("primary", 'noOne')

				self.isSecondary = self.minfo['isMaster'].get("secondary", False)

				return self.minfo

			except Exception as err:
				self.logger.error(err)
				return None

	def disconnect(self):
		if self.connected:
			self.mclient.disconnect()
			self.connected = False

	def replSet_addMember(self, member):
		print("Add member " + str_blue(member.name) + " on " + str_blue(self.replSet.name) )
		#rs.add("wpain-laptop:2002")
		#self.mclient.admin.command("rs.add('wpain-laptop:20000')")

	def status(self):
		state = self.get_state()

		print("State of " + str_blue(self.name) + " on " + str_blue(self.node.name) + ": " + str_state(state))
		cprint(" + Node:",			str_state(self.node.get_state()) )
		cprint(" + Managed:",		str_state(self.config['managed'], ok="Yes", nok="No") )
		cprint(" + Sarted:",		str_state(self.states['running'], ok="Yes", nok="No") )
		cprint(" + Port:",			self.config['port'] )
		cprint(" + TCP Ping:",		str_state(self.states['tcp_ping']) )
		cprint(" + Lock:",		    str_state(self.states['lock']) )
		
		if self.connected:
			cprint(" + replset:",		str_state(self.states['replSet'], ok="Yes", nok="No"))

			cprint(" + PID:",			str_state(self.pid, ok=self.pid) )
			cprint(" + Mongod:", "%s (%s bits, debug: %s)" % (self.minfo.get('version', False), self.minfo.get('bits', ''), self.minfo.get('debug', '')) )
			
			isMaster = self.minfo.get("isMaster", None)

			isreplicaset =	isMaster.get("isreplicaset", False)
			hosts =			isMaster.get("hosts", [])
			arbiters =		isMaster.get("arbiters", [])

			if self.setName:
				cprint(" + setName:",	str_state(self.setName==self.replSet.name, ok=self.setName, nok=self.setName))
				cprint(" + Me:",		self.me)
				cprint(" + Master:",	str_state(self.isMaster,	ok="Yes", nok="No"))
				cprint(" + Primary:",	str_state(self.isPrimary,	ok="Yes", nok="No"))
				cprint(" + Secondary:",	str_state(self.isSecondary,	ok="Yes", nok="No"))
				cprint(" + Arbiter:",	str_state(self.isArbiter,	ok="Yes", nok="No"))
				cprint(" + Arbiters:",	arbiters)
				cprint(" + Members:",	hosts)

			"""
			if not self.isPrimary and not self.isSecondary:
				return

			dbs = self.mclient.database_names()
			cprint(" + DBs:", len(dbs))

			for db in dbs:
				cprint("   - '%s':" % db, "%s Collections" % len(self.mclient[db].collection_names()) )
			"""

	def __del__(self):
		self.disconnect()
Esempio n. 8
0
    def check(self, agentConfig):
        """
        Returns a dictionary that looks a lot like what's sent back by db.serverStatus()
        """

        if 'mongodb_server' not in agentConfig or agentConfig['mongodb_server'] == '':
            return False

        try:
            from pymongo import Connection
            dbName = None
            try:
                from pymongo import uri_parser
                # Configuration a URL, mongodb://user:pass@server/db
                dbName = uri_parser.parse_uri(agentConfig['mongodb_server'])['database']

                # parse_uri gives a default database of None
                dbName = dbName or 'test'

            except ImportError:
                # uri_parser is pymongo 2.0+
                dbName = mongo_uri_re.match(agentConfig['mongodb_server']).group(1)

            if dbName is None:
                self.logger.error("Mongo: cannot extract db name from config %s" % agentConfig['mongodb_server'])
                return False

            conn = Connection(agentConfig['mongodb_server'])
            db = conn[dbName]

            status = db.command('serverStatus') # Shorthand for {'serverStatus': 1}
            status['stats'] = db.command('dbstats')

            results = {}

            # Handle replica data, if any
            # See http://www.mongodb.org/display/DOCS/Replica+Set+Commands#ReplicaSetCommands-replSetGetStatus
            try:
                data = {}

                replSet = conn['admin'].command('replSetGetStatus')
                serverVersion = conn.server_info()['version']
                if replSet:
                    primary = None
                    current = None

                    # find nodes: master and current node (ourself)
                    for member in replSet.get('members'):
                        if member.get('self'):
                            current = member
                        if int(member.get('state')) == 1:
                            primary = member

                    # If we have both we can compute a lag time
                    if current is not None and primary is not None:
                        lag = current['optimeDate'] - primary['optimeDate']
                        # Python 2.7 has this built in, python < 2.7 don't...
                        if hasattr(lag,'total_seconds'):
                            data['replicationLag'] = lag.total_seconds()
                        else:
                            data['replicationLag'] = (lag.microseconds + \
                (lag.seconds + lag.days * 24 * 3600) * 10**6) / 10.0**6

                    if current is not None:
                        data['health'] = current['health']

                    data['state'] = replSet['myState']
                    event = self.checkLastState(data['state'], agentConfig, serverVersion)
                    if event is not None:
                        results['events'] = {'Mongo': [event]}
                    status['replSet'] = data
            except:
                self.logger.exception("Cannot determine replication set status")

            # If these keys exist, remove them for now as they cannot be serialized
            try:
                status['backgroundFlushing'].pop('last_finished')
            except KeyError:
                pass
            try:
                status.pop('localTime')
            except KeyError:
                pass

            # Flatten the metrics first
            # Collect samples
            # Send a dictionary back

            for m in self.get_metric_names():
                # each metric is of the form: x.y.z with z optional
                # and can be found at status[x][y][z]
                value = status
                try:
                    for c in m.split("."):
                        value = value[c]
                except KeyError:
                    continue

                # value is now status[x][y][z]
                assert type(value) in (types.IntType, types.LongType, types.FloatType)

                self.save_sample(m, value)

                # opposite op: x.y.z -> results[x][y][zPS], yes, ...PS for counters
                try:
                    val = self.get_sample(m)
                    r = results
                    for c in m.split(".")[:-1]:
                        if c not in r:
                            r[c] = {}
                        r = r[c]
                    if self.is_counter(m):
                        suffix = m.split(".")[-1] + "PS"
                    else:
                        suffix = m.split(".")[-1]
                    r[suffix] = val

                except UnknownValue:
                    pass

            return results

        except ImportError:
            self.logger.exception('Unable to import pymongo library')
            return False

        except:
            self.logger.exception('Unable to get MongoDB status')
            return False
Esempio n. 9
0
class MongoMonitor(object):
    """
    MongoDB Monitor class. It sets daemon to store into MongoDB its
    own stat information and provide web functionality.
    """
    def __init__(self, dburi, dbname='mongodb', dbcoll='stats', 
                        size=10*1024*1024, interval=5):
        self.dburi = dburi
        self.conn  = Connection(dburi)
        if  dbname not in self.conn.database_names():
            dbptr  = self.conn[dbname]
            dbptr.create_collection(dbcoll, {'capped':True, 'size':size})
        self.coll  = self.conn[dbname][dbcoll]
        self.attr  = []
        for key, val in self.conn[dbname].command( { "serverStatus" : 1 } ).items():
            if  isinstance(val, dict):
                for akey, aval in val.items():
                    if  isinstance(aval, dict):
                        for kkk, vvv in aval.items():
                            if  not isinstance(vvv, dict):
                                self.attr.append('%s.%s.%s' % (key, akey, kkk))
                    else:
                        self.attr.append('%s.%s' % (key, akey))

        # start thread with db_updater
        thread.start_new_thread(db_updater, (dburi, dbname, dbcoll, interval))

        # setup js/css dirs
        self.jsdir  = '%s/%s' % (__file__.rsplit('/', 1)[0], 'js')
        if  os.environ.has_key('JSPATH'):
            self.jsdir = os.environ['JSPATH']
        if  not os.path.isdir(self.jsdir):
            raise Exception('JS path is not set')
        # To be filled at run time
        self.cssmap = {}
        self.jsmap  = {}

        # Update CherryPy configuration
        mime_types  = ['text/css']
        mime_types += ['application/javascript', 'text/javascript',
                       'application/x-javascript', 'text/x-javascript']
        cherryconf.update({'tools.encode.on': True, 
                           'tools.gzip.on': True,
                           'tools.gzip.mime_types': mime_types,
                           'request.show_tracebacks': False,
                           'server.environment':'production',
                           'server.socket_host':'0.0.0.0',
                          })
        self._cache = {}

    def server_info(self):
        """Get server info"""
        return self.conn.server_info()

    def db_info(self):
        """
        Get DB info
        """
        ddict = {}
        for database in self.conn.database_names():
            collections = self.conn[database].collection_names()
            coll = self.conn[database]
            info_dict = {}
            for cname in collections:
                info_dict[cname] = coll.command({'collStats': cname})
            ddict[database] = info_dict
        return ddict

    def get_stats(self, attr, datetime1, datetime2):
        """
        Get MongoDB statistics for provided time interval
        """
        spec = {'localTime' : {'$gte': datetime1, '$lte': datetime2}}
        alist = attr.split('.')
        if  len(alist) == 2:
            key, att = alist
            alast = None
        elif len(alist) == 3:
            key, att, alast = alist
        else:
            raise Exception('Too many attributes')
        for row in self.coll.find(spec):
            if  row.has_key(key) and row[key].has_key(att):
                value = row[key][att]
                if  alast:
                    value = value[alast]
                if  isinstance(value, datetime.datetime):
                    value = time.mktime(datetime.datetime.timetuple(value))
                if  alast:
                    rec = {key : {att: {alast: value}}}
                else:
                    rec = {key : {att: value}}
                yield rec

    def minmaxval(self, attr, datetime1, datetime2):
        """
        Get MongoDB statistics for provided time interval
        """
        spec   = {'localTime' : {'$gte': datetime1, '$lte': datetime2}}
        maxval = 0
        minval = 0
        alist  = attr.split('.')
        if  len(alist) == 2:
            key, att = alist
            alast = None
        elif len(alist) == 3:
            key, att, alast = alist
        else:
            raise Exception('Too many attributes')
        for row in self.coll.find(spec):
            value = row[key][att]
            if  alast:
                value = value[alast]
            if  isinstance(value, datetime.datetime):
                value = time.mktime(datetime.datetime.timetuple(value))
            if  not minval:
                minval = value
            if  value > maxval:
                maxval = value
            if  value < minval:
                minval = value
        return minval, maxval

    @expose
    def index(self):
        """Main page"""
        page  = template_server_info(self.server_info())
        page += template_db_info(self.db_info())
        page += template_plot_form(self.attr)
        return self.page('MongoDB', page)

    @expose
    def page(self, title, content):
        """Format HTML page"""
        return template_top(title, self.dburi) + content + template_bottom()

    @expose
    def stat(self, **kwds):
        """Plot given set of parameters"""
        time1 = kwds.get('t1')
        time2 = kwds.get('t2')
        if  not time1 and not time2: # default is 1 hour
            time1 = datetime.datetime.utcfromtimestamp(time.time()-3600)
            time2 = datetime.datetime.utcfromtimestamp(time.time())
        else:
            time1 = parse_timestamp(time1)
            time2 = parse_timestamp(time2)
        attr  = kwds.get('attr')
        if  attr not in self.attr:
            raise HTTPError(500, 'Unknown attribute %s, supported: %s' \
                        % (attr, self.attr))
        data  = [r for r in self.get_stats(attr, time1, time2)]
        minval, maxval = self.minmaxval(attr, time1, time2)
        units, xmin, xmax = delta(time1, time2)
        spec  = {'data':str(data).replace("u'", "'"), 'attr':attr,
                 'title':attr, 'ymax':maxval, 'ymin':minval,
                 'units': units, 'xmin': xmin, 'xmax': xmax,
                 'time1': convert_timestamp(time1),
                 'time2': convert_timestamp(time2)}
        content = template_plot(spec)
        page    = template_server_info(self.server_info())
        page   += template_db_info(self.db_info())
        page   += template_plot_form(self.attr, attr)
        page   += content
        return self.page('MongoDB', page)

    @exposejs
    @tools.gzip()
    def js(self, *args, **kwargs):
        """
        Serve protovis JS file.
        """
        args = ['/'.join(args)] # preserve YUI dir structure
        scripts = self.check_scripts(args, self.jsmap, self.jsdir)
        return self.serve_files(args, scripts, self.jsmap)

    def check_scripts(self, scripts, resource, path):
        """
        Check a script is known to the resource map 
        and that the script actually exists   
        """           
        for script in scripts:
            if  script not in resource.keys():
                spath = os.path.normpath(os.path.join(path, script))
                if  os.path.isfile(spath):
                    resource.update({script: spath})
        return scripts

    def serve_files(self, args, scripts, resource, datatype='', minimize=False):
        """
        Return asked set of files for JS, CSS.
        """
        idx = "-".join(scripts)
        if  idx not in self._cache.keys():
            data = ''
            if  datatype == 'css':
                data = '@CHARSET "UTF-8";'
            for script in args:
                path = os.path.join(sys.path[0], resource[script])
                path = os.path.normpath(path)
                ifile = open(path)
                data = "\n".join ([data, ifile.read().\
                    replace('@CHARSET "UTF-8";', '')])
                ifile.close()
            if  datatype == 'css':
                set_headers("text/css")
            if  minimize:
                self._cache[idx] = minify(data)
            else:
                self._cache[idx] = data
        return self._cache[idx] 
Esempio n. 10
0
class Main:
	pkt_sum = {}
	pkt_sum_agg = {}

	def __init__(self, config):
		self.config = config
		self.db_connect()
		self.lock = threading.Lock()
		self.local_ip = self.get_ip()
		self.networks = [
		  {'re':re.compile('192.168.\d+.\d+'), 'zone':'internal'},
		  {'re':re.compile('10.\d+.\d+.\d+'), 'zone':'internal'},
		  {'re':re.compile('172.16.\d+.\d+'), 'zone':'internal'},
		  {'re':re.compile('169.254.\d+.\d+'), 'zone':'autoconf'},
		]
		# setup log
		logging.basicConfig(filename=self.get_config('log'), level=logging.DEBUG, format='%(asctime)s %(message)s')


	def get_config(self, name, section='general', default=''):
		return self.config.get(section, name) if self.config.has_option(section, name) else default


	def find_zone(self, ip):
		for n in self.networks:
			if re.match(n['re'], ip):
				return n['zone']
		return 'default'


	# DB
	def db_connect(self):
		try:
			self.connection = Connection(self.get_config('server'), 27017)
			db = self.connection.network
			self.flows = db.flows
		except Exception as e:
			logging.error("Connection error [%s]" % str(e))

	def db_insert(self, doc):
		try:
			si = self.connection.server_info()
			#print "Server Info [%s]" % str(si)
		except:
			self.db_connect()
		try:
			self.flows.insert(doc)
		except Exception as e:
			logging.error("Insert error [%s]" % str(e))


	# Save aggragated data to DB
	def dump(self):
		if self.pkt_sum:
			self.lock.acquire()
			try:
				msg = {'ts':int(time.time()), 'data':self.pkt_sum}
				logging.debug(str(msg))
				tosave_docs = []
				for key, vals in self.pkt_sum.items():
					keys = key.split("-")
					doc = {'v': 0.2, 'ts':int(time.time()), 'src':keys[0], 'dst':keys[1], 'vals':vals, 'sum':self.pkt_sum_agg[key]}
					#print doc
					tosave_docs.append(doc)
				self.pkt_sum = {}
				self.pkt_sum_agg = {}
			except Exception as e:
				logging.error("Error in dump(): [%s]" % str(e))
			finally:
				self.lock.release()
			# Insert in DB after lock release
			try:
				for doc in tosave_docs:
					self.db_insert(doc)
			except Exception as e:
				logging.error("Error while saving data: [%s]" % str(e))
		t = threading.Timer(60.0, self.dump)
		t.daemon = True
		t.start()

	def get_ip(self):
		s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
		s.connect(('google.com', 0)) 
		return s.getsockname()[0]

	# Network listening
	def go(self):
		#self.dump()
		try:
			pc = pcap.pcap(name=self.get_config('iface'))
		except Exception as e:
			logging.error(str(e))
			logging.error(str(e))
			return False
		filters = []
		if self.get_config('mode')=="local":
			filters.append("(src %s or dst %s)" % (self.local_ip, self.local_ip))
		if self.get_config('mode')=="out":
			filters.append("src %s" % (self.local_ip))
		if self.get_config('filter')<>"":
			filters.append(self.get_config('filter'))
		filter_str = " and ".join(filters)
		print filter_str
		logging.info("Start listening with the following params:")
		logging.info("iface [%s]" % self.get_config('iface'))
		logging.info("filter [%s]" % filter_str)
		pc.setfilter(filter_str)
		for ts, pkt in pc:
			p = dpkt.ethernet.Ethernet(pkt)
			ip = p.data
			#print `ip`
			if p.type==dpkt.ethernet.ETH_TYPE_IP: # IP
				src = socket.inet_ntoa(ip.src)
				dst = socket.inet_ntoa(ip.dst)
				size = int(ip.len)
				proto_ip = str(ip.p)
				sport = "0"
				dport = "0"
				if ip.p==dpkt.ip.IP_PROTO_TCP:
					proto_ip = 'TCP'
					sport = str(ip.data.sport)
					dport = str(ip.data.dport)
				elif ip.p==dpkt.ip.IP_PROTO_UDP:
					proto_ip = 'UDP'
					sport = str(ip.data.sport)
					dport = str(ip.data.dport)
				elif ip.p==dpkt.ip.IP_PROTO_IP6:
					proto_ip = 'IPv6'
				src_zone = self.find_zone(src)
				dst_zone = self.find_zone(dst)
				#print "%d: %s(%s) => %s(%s) [%d] [ip:%s] [dport:%d]" % (int(ts), src, src_zone, dst, dst_zone, size, proto_ip, dport)
				print "Ethernet [%s]=>[%s] [%s] [%s]=>[%s:%s] [%d]" % (add_colons_to_mac(binascii.hexlify(p.src)), add_colons_to_mac(binascii.hexlify(p.dst)), proto_ip, src, dst, dport, size)

				key = (src_zone if src_zone=="default" else src) + "-" + (dst_zone if dst_zone=="default" else dst)
				
				self.lock.acquire()
				try:
					if key not in self.pkt_sum: self.pkt_sum[key] = {}
					if proto_ip not in self.pkt_sum[key]: self.pkt_sum[key][proto_ip] = {'dport':{}, 'sport':{}}
					if dport not in self.pkt_sum[key][proto_ip]['dport']: self.pkt_sum[key][proto_ip]['dport'][dport] = 0
					if sport not in self.pkt_sum[key][proto_ip]['sport']: self.pkt_sum[key][proto_ip]['sport'][sport] = 0
					self.pkt_sum[key][proto_ip]["dport"][dport] += size
					self.pkt_sum[key][proto_ip]["sport"][sport] += size
					#print self.pkt_sum

					if key not in self.pkt_sum_agg: self.pkt_sum_agg[key] = {}
					if proto_ip not in self.pkt_sum_agg[key]: self.pkt_sum_agg[key][proto_ip] = 0
					self.pkt_sum_agg[key][proto_ip] += size
				except Exception as e:
					print str(e)
					logging.error("Error in go(): [%s]" % str(e))
				finally:
					self.lock.release()
Esempio n. 11
0
    def check(self, agentConfig):
        """
        Returns a dictionary that looks a lot like what's sent back by db.serverStatus()
        """

        if 'mongodb_server' not in agentConfig or agentConfig[
                'mongodb_server'] == '':
            return False

        try:
            from pymongo import Connection
            dbName = None
            try:
                from pymongo import uri_parser
                # Configuration a URL, mongodb://user:pass@server/db
                dbName = uri_parser.parse_uri(
                    agentConfig['mongodb_server'])['database']

                # parse_uri gives a default database of None
                dbName = dbName or 'test'

            except ImportError:
                # uri_parser is pymongo 2.0+
                dbName = mongo_uri_re.match(
                    agentConfig['mongodb_server']).group(1)

            if dbName is None:
                self.logger.error(
                    "Mongo: cannot extract db name from config %s" %
                    agentConfig['mongodb_server'])
                return False

            conn = Connection(agentConfig['mongodb_server'])
            db = conn[dbName]

            status = db.command(
                'serverStatus')  # Shorthand for {'serverStatus': 1}
            status['stats'] = db.command('dbstats')

            results = {}

            # Handle replica data, if any
            # See http://www.mongodb.org/display/DOCS/Replica+Set+Commands#ReplicaSetCommands-replSetGetStatus
            try:
                data = {}

                replSet = conn['admin'].command('replSetGetStatus')
                serverVersion = conn.server_info()['version']
                if replSet:
                    primary = None
                    current = None

                    # find nodes: master and current node (ourself)
                    for member in replSet.get('members'):
                        if member.get('self'):
                            current = member
                        if int(member.get('state')) == 1:
                            primary = member

                    # If we have both we can compute a lag time
                    if current is not None and primary is not None:
                        lag = current['optimeDate'] - primary['optimeDate']
                        # Python 2.7 has this built in, python < 2.7 don't...
                        if hasattr(lag, 'total_seconds'):
                            data['replicationLag'] = lag.total_seconds()
                        else:
                            data['replicationLag'] = (lag.microseconds + \
                (lag.seconds + lag.days * 24 * 3600) * 10**6) / 10.0**6

                    if current is not None:
                        data['health'] = current['health']

                    data['state'] = replSet['myState']
                    event = self.checkLastState(data['state'], agentConfig,
                                                serverVersion)
                    if event is not None:
                        results['events'] = {'Mongo': [event]}
                    status['replSet'] = data
            except:
                self.logger.exception(
                    "Cannot determine replication set status")

            # If these keys exist, remove them for now as they cannot be serialized
            try:
                status['backgroundFlushing'].pop('last_finished')
            except KeyError:
                pass
            try:
                status.pop('localTime')
            except KeyError:
                pass

            # Flatten the metrics first
            # Collect samples
            # Send a dictionary back

            for m in self.get_metric_names():
                # each metric is of the form: x.y.z with z optional
                # and can be found at status[x][y][z]
                value = status
                try:
                    for c in m.split("."):
                        value = value[c]
                except KeyError:
                    continue

                # value is now status[x][y][z]
                assert type(value) in (types.IntType, types.LongType,
                                       types.FloatType)

                self.save_sample(m, value)

                # opposite op: x.y.z -> results[x][y][zPS], yes, ...PS for counters
                try:
                    val = self.get_sample(m)
                    r = results
                    for c in m.split(".")[:-1]:
                        if c not in r:
                            r[c] = {}
                        r = r[c]
                    if self.is_counter(m):
                        suffix = m.split(".")[-1] + "PS"
                    else:
                        suffix = m.split(".")[-1]
                    r[suffix] = val

                except UnknownValue:
                    pass

            return results

        except ImportError:
            self.logger.exception('Unable to import pymongo library')
            return False

        except:
            self.logger.exception('Unable to get MongoDB status')
            return False
Esempio n. 12
0
# getopt
try:
	opts, args = getopt.getopt(sys.argv[1:], 'h:p:u:w:')
except getopt.GetoptError, err:
	print str(err)
	usage()
	sys.exit(2)
for o, a in opts:
	if o == "-h":
		host = a
	elif o == "-p":
		port = int(a)
	elif o == "-u":
		username = a
	elif o == "-w":
		password = a

connection = Connection(host, port)
if not username is None:
	connection['admin'].authenticate(username, password)
	
db = connection['admin']
print connection.server_info()

dblocal = connection['local']
#dblocal.system.namespaces.find({'name': 'local.oplog.$main'})
a = dblocal['optlog.$main'].find()
for op in a:
	print a