mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-05 16:49:45 +00:00
Removing unused mongo mms utils and configs.
This commit is contained in:
parent
30898df3e5
commit
5dba6549ef
34 changed files with 1 additions and 2111 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -41,7 +41,6 @@ media/css/circular
|
||||||
config/settings
|
config/settings
|
||||||
config/secrets
|
config/secrets
|
||||||
templates/maintenance_on.html
|
templates/maintenance_on.html
|
||||||
vendor/mms-agent/settings.py
|
|
||||||
apps/social/spam.py
|
apps/social/spam.py
|
||||||
venv*
|
venv*
|
||||||
backup
|
backup
|
||||||
|
|
|
@ -86,7 +86,7 @@ pyasn1==0.4.8
|
||||||
pycparser==2.20
|
pycparser==2.20
|
||||||
pyflakes==2.2.0
|
pyflakes==2.2.0
|
||||||
PyJWT==1.7.1
|
PyJWT==1.7.1
|
||||||
pymongo>=3,<3.9
|
pymongo>=3,<4
|
||||||
PyMySQL==0.10.1
|
PyMySQL==0.10.1
|
||||||
pynliner==0.8.0
|
pynliner==0.8.0
|
||||||
pyOpenSSL==20.0.1
|
pyOpenSSL==20.0.1
|
||||||
|
|
196
vendor/mms-agent/README
vendored
196
vendor/mms-agent/README
vendored
|
@ -1,196 +0,0 @@
|
||||||
(C) Copyright 2012, 10gen
|
|
||||||
|
|
||||||
10gen MongoDB Monitoring Service (MMS) - Agent
|
|
||||||
=============
|
|
||||||
|
|
||||||
For the complete MMS documentation, see: https://mms.10gen.com/help/
|
|
||||||
|
|
||||||
The MMS agent polls your MongoDB instance(s) once per minute and relays statistics to 10gen.
|
|
||||||
|
|
||||||
New hosts are added by entering them on this page (click the plus/+ button on the top of the page) - https://mms.10gen.com/host/list
|
|
||||||
|
|
||||||
If you have a replica set, you only need to enter one host and the agent will discover the rest of the nodes in the group/cluster.
|
|
||||||
|
|
||||||
If you have a shard cluster, you only need to enter one mongos host and the agent will discover the rest of the nodes in the cluster.
|
|
||||||
|
|
||||||
Only one MMS agent is active at a time, the others are simply hot-standys.
|
|
||||||
|
|
||||||
If you restart your agent or fail over to a secondary agent, there is a five minute timeout before data is sent to the central MMS servers.
|
|
||||||
|
|
||||||
The MMS agent only supports MongoDB 1.6.x+
|
|
||||||
|
|
||||||
The MMS agent currently does not support Python 3.x
|
|
||||||
|
|
||||||
Important
|
|
||||||
------------
|
|
||||||
|
|
||||||
If you have thousands of databases or collections, you should disable "DB Stats" on the "Settings" page before starting your agent.
|
|
||||||
|
|
||||||
Collecting db stats on thousands of databases or collections can adversely impact performance of your system.
|
|
||||||
|
|
||||||
* https://mms.10gen.com/settings
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
* Install Python (2.4+) and pymongo (1.9+) - http://api.mongodb.org/python/current/
|
|
||||||
|
|
||||||
* For most people (on Linux) this is as easy as running: sudo easy_install pymongo
|
|
||||||
|
|
||||||
* If you do not have easy_install, typically you can run: sudo yum install python-setuptools
|
|
||||||
|
|
||||||
* For more information, see: http://pypi.python.org/pypi/setuptools
|
|
||||||
|
|
||||||
* The hashlib package must be installed if running Python 2.4
|
|
||||||
|
|
||||||
* Try (as root): easy_install hashlib - if that does not work, use: http://pypi.python.org/pypi/hashlib/20081119
|
|
||||||
|
|
||||||
* Download and unzip and then run (requires root/sudo permission to install):
|
|
||||||
|
|
||||||
* python setup.py build
|
|
||||||
|
|
||||||
* python setup.py install
|
|
||||||
|
|
||||||
* The backported hmac package must be installed if running Python 2.4
|
|
||||||
|
|
||||||
* Do *not* use pip for installing this package. Pip is not pulling the correct files.
|
|
||||||
|
|
||||||
* Try (as root): easy_install hmac - if that does not work, use: http://pypi.python.org/pypi/hmac
|
|
||||||
|
|
||||||
* Download and unzip and then run (requires root/sudo permission to install):
|
|
||||||
|
|
||||||
* python setup.py build
|
|
||||||
|
|
||||||
* python setup.py install
|
|
||||||
|
|
||||||
* If you need to install any libraries then make sure you close your session/terminal after installing and open a new one, before starting the agent.
|
|
||||||
|
|
||||||
* The agent will securely update itself as new releases are published by 10gen. The agent directory must be writable by the user the agent is running under.
|
|
||||||
|
|
||||||
* Start the agent:
|
|
||||||
|
|
||||||
nohup python agent.py > /REPLACE_SOME_DIRECTORY/agent.log 2>&1 &
|
|
||||||
|
|
||||||
Note: If you are running Python 2.4, you should reduce the default stack size for the user account the MMS agent runs under. In Python 2.5+, the agent reduces the stack size programmatically.
|
|
||||||
|
|
||||||
Hardware Monitoring - Munin Setup
|
|
||||||
------------
|
|
||||||
|
|
||||||
MMS also supports hardware monitoring on database servers. To accomplish this, MMS collects data from the ubiquitous Munin Node daemon.
|
|
||||||
|
|
||||||
Note munin-node, and hardware monitoring is only available for MongoDB instances running on Linux hosts.
|
|
||||||
|
|
||||||
The following are a list of steps to install and configure the Munin Node daemon for MMS.
|
|
||||||
|
|
||||||
* Install the munin-node module
|
|
||||||
|
|
||||||
* On the majority of OSs, this can be accomplished by using apt-get or yum - e.g., sudo yum install munin-node)
|
|
||||||
|
|
||||||
* If you install from source you must also install the plugins (described in the links below under "Additional Documentation")
|
|
||||||
|
|
||||||
* MMS currently uses the cpu, iostat and iostat_ios plugins
|
|
||||||
|
|
||||||
* Configure munin-node.conf to allow connections from the server(s) running your MMS agent(s).
|
|
||||||
|
|
||||||
* Typically, this file is located in /etc/munin/munin-node.conf
|
|
||||||
|
|
||||||
* Modify the "allow" property - See the munin-node.conf documentation for more information: http://munin-monitoring.org/wiki/munin-node.conf
|
|
||||||
|
|
||||||
* If your disk devices are numbered (e.g., /dev/sda1) then you need to configure the munin iostat plugin to support numbered disks (disabled by default).
|
|
||||||
|
|
||||||
* For a typical installation, the configuration file is: /etc/munin/plugin-conf.d/munin-node
|
|
||||||
|
|
||||||
* If this file does not exist, create and add the following:
|
|
||||||
[iostat]
|
|
||||||
env.SHOW_NUMBERED 1
|
|
||||||
|
|
||||||
* Ensure your Munin Node process is registered to start on server boot
|
|
||||||
|
|
||||||
* E.g. sudo ln -s /etc/init.d/munin-node /etc/rc3.d/S99munin-node
|
|
||||||
|
|
||||||
* Restart your Munin Node process to update the configuration:
|
|
||||||
|
|
||||||
* sudo /etc/init.d/munin-node restart
|
|
||||||
|
|
||||||
* You can verify your munin-node setup by running the following from the agent(s) nodes:
|
|
||||||
|
|
||||||
* telnet HOSTNAME 4949 (the default and required port for munin-node)
|
|
||||||
|
|
||||||
* fetch iostat
|
|
||||||
|
|
||||||
* fetch iostat_ios
|
|
||||||
|
|
||||||
* fetch cpu
|
|
||||||
|
|
||||||
(each command should be on a separate line - i.e., hit return after fetch COMMAND - if the plugins are not installed you will see '# Unknown service')
|
|
||||||
|
|
||||||
* Additional Documentation
|
|
||||||
|
|
||||||
* http://munin-monitoring.org/wiki/munin-node
|
|
||||||
|
|
||||||
* http://munin-monitoring.org/wiki/LinuxInstallation
|
|
||||||
|
|
||||||
* http://munin-monitoring.org/wiki/SolarisInstallation
|
|
||||||
|
|
||||||
* http://munin-monitoring.org/wiki/HowToMonitorWindows
|
|
||||||
|
|
||||||
* http://munin-monitoring.org
|
|
||||||
|
|
||||||
Firewall
|
|
||||||
-------------
|
|
||||||
|
|
||||||
If your datacenter is secured by a firewall, please configure your firewall to allow outbound connections on port 443 (SSL) to mms.10gen.com
|
|
||||||
|
|
||||||
Proxy
|
|
||||||
-------------
|
|
||||||
|
|
||||||
If your datacenter requires outbound connections to route through a proxy, you can add the following environment variable:
|
|
||||||
|
|
||||||
export https_proxy='http://someProxyServer:port';
|
|
||||||
|
|
||||||
(on Windows use HTTPS_PROXY)
|
|
||||||
|
|
||||||
Note: This requires Python 2.6.1+
|
|
||||||
|
|
||||||
|
|
||||||
Data Collected
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Different commands are executed based on the host type. Below is an overall list of commands/queries executed.
|
|
||||||
|
|
||||||
* Default
|
|
||||||
* serverStatus
|
|
||||||
* buildinfo
|
|
||||||
* getCmdLineOpts
|
|
||||||
* connPoolStats
|
|
||||||
* _isSelf
|
|
||||||
* getParameter
|
|
||||||
* ismaster
|
|
||||||
* getShardVersion
|
|
||||||
* netstat
|
|
||||||
* replSetGetStatus
|
|
||||||
* shards.find
|
|
||||||
* mongos.find
|
|
||||||
* config.chunks.group
|
|
||||||
* oplog.find
|
|
||||||
* collstats - oplog.rs
|
|
||||||
* sources.find (slave)
|
|
||||||
* config.settings.find
|
|
||||||
* config.collections.find
|
|
||||||
* config.databases.find
|
|
||||||
* config.lockpings.find
|
|
||||||
* dbstats
|
|
||||||
* db.locks
|
|
||||||
|
|
||||||
* Enabled By User
|
|
||||||
* profiler.find
|
|
||||||
|
|
||||||
For more information see:
|
|
||||||
|
|
||||||
* https://groups.google.com/forum/#!forum/10gen-mms
|
|
||||||
|
|
||||||
To submit a support request:
|
|
||||||
|
|
||||||
* https://jira.mongodb.org/secure/CreateIssue.jspa?pid=10582&issuetype=6
|
|
||||||
|
|
||||||
|
|
57
vendor/mms-agent/WINDOWS.txt
vendored
57
vendor/mms-agent/WINDOWS.txt
vendored
|
@ -1,57 +0,0 @@
|
||||||
Contents
|
|
||||||
------------
|
|
||||||
* README.txt
|
|
||||||
* mongommsinstall.bat
|
|
||||||
* mongommstinstall.ps1
|
|
||||||
* srvany.exe
|
|
||||||
|
|
||||||
Prerequisites
|
|
||||||
------------
|
|
||||||
* Expects a MMS/PyMongo compatible python version to be installed
|
|
||||||
* Expects pymongo to be installed
|
|
||||||
* Powershell version 2.0 (for windows service installation)
|
|
||||||
* Powershell script execution to be turned on
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
* The following instructions are to run MMS as a windows service
|
|
||||||
* More information can be found at https://mms.10gen.com/help/install.html#installing-mms-on-windows
|
|
||||||
|
|
||||||
Install Prerequisites
|
|
||||||
---------------------
|
|
||||||
* Install python 2.7.x using the Windows Installer. 64 bit installer is preferred.
|
|
||||||
e.g. http://www.python.org/ftp/python/2.7.2/python-2.7.2.amd64.msi
|
|
||||||
* Install latest version of pymongo using the Windows Installer from pypi. Ensure
|
|
||||||
you pick the installer that corresponds to your python version and the type (32 bit or 64 bit).
|
|
||||||
http://pypi.python.org/pypi/pymongo/
|
|
||||||
|
|
||||||
Install Powershell 2.0
|
|
||||||
----------------------
|
|
||||||
* If you do not have powershell 2.0 installed you would need to install it from http://support.microsoft.com/kb/968929.
|
|
||||||
|
|
||||||
Enable Powershell Script Execution
|
|
||||||
----------------------------------
|
|
||||||
* Open the Windows Powershell by right-clicking its icon in the Start bar and selecting Run as Administrator
|
|
||||||
* Type `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned` and agree when prompted about changing the policy
|
|
||||||
|
|
||||||
Specifying a Proxy Server
|
|
||||||
-------------------------
|
|
||||||
If the MMS agent needs a proxy server to connect outside, specify it in the HTTPS_PROXY environment variable
|
|
||||||
as http://proxyservername:port
|
|
||||||
|
|
||||||
Sevice Installation
|
|
||||||
-------------------
|
|
||||||
* The script reads python path from windows registry if not specified on command line
|
|
||||||
* If multiple python installations are present edit the bat file to specify the path of the python install to work
|
|
||||||
* Run mongommsinstall.bat from an administrator command window
|
|
||||||
* This will install the windows service and start it
|
|
||||||
* If you stop the windows service, the agent will stop
|
|
||||||
|
|
||||||
Uninstall
|
|
||||||
---------
|
|
||||||
- Stop the "MongoDB MMS" windows service
|
|
||||||
- Run "sc delete mongomms"
|
|
||||||
|
|
||||||
More Information
|
|
||||||
----------------
|
|
||||||
- MMS Help https://mms.10gen.com/help/
|
|
336
vendor/mms-agent/agent.py
vendored
336
vendor/mms-agent/agent.py
vendored
|
@ -1,336 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
# App
|
|
||||||
import settings as _settings
|
|
||||||
import logConfig
|
|
||||||
|
|
||||||
# Python
|
|
||||||
import sys, socket, time, os, hmac, urllib.request, urllib.error, urllib.parse, threading, subprocess, traceback
|
|
||||||
|
|
||||||
try:
|
|
||||||
import hashlib
|
|
||||||
except ImportError:
|
|
||||||
sys.exit( 'ERROR - you must have hashlib installed - see README for more info' )
|
|
||||||
|
|
||||||
_logger = logConfig.initLogger()
|
|
||||||
|
|
||||||
socket.setdefaulttimeout( _settings.socket_timeout )
|
|
||||||
|
|
||||||
_pymongoVersion = None
|
|
||||||
|
|
||||||
_processPid = os.getpid()
|
|
||||||
|
|
||||||
# Try and reduce the stack size.
|
|
||||||
try:
|
|
||||||
threading.stack_size( 409600 )
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if _settings.mms_key == '@API_KEY@':
|
|
||||||
sys.exit( 'ERROR - you must set your @API_KEY@ - see https://mms.10gen.com/settings' )
|
|
||||||
|
|
||||||
if _settings.secret_key == '@SECRET_KEY@':
|
|
||||||
sys.exit( 'ERROR - you must set your @SECRET_KEY@ - see https://mms.10gen.com/settings' )
|
|
||||||
|
|
||||||
if sys.version_info < ( 2, 4 ):
|
|
||||||
sys.exit( 'ERROR - old Python - the MMS agent requires Python 2.4 or higher' )
|
|
||||||
|
|
||||||
# Make sure pymongo is installed
|
|
||||||
try:
|
|
||||||
import pymongo
|
|
||||||
import bson
|
|
||||||
except ImportError:
|
|
||||||
sys.exit( 'ERROR - pymongo not installed - see: http://api.mongodb.org/python/ - run: easy_install pymongo' )
|
|
||||||
|
|
||||||
# Check the version of pymongo.
|
|
||||||
pyv = pymongo.version
|
|
||||||
if "partition" in dir( pyv ):
|
|
||||||
pyv = pyv.partition( "+" )[0]
|
|
||||||
_pymongoVersion = pyv
|
|
||||||
if list(map( int, pyv.split('.') )) < [ 1, 9]:
|
|
||||||
sys.exit( 'ERROR - The MMS agent requires pymongo 1.9 or higher: easy_install -U pymongo' )
|
|
||||||
|
|
||||||
if _settings.useSslForAllConnections:
|
|
||||||
if list(map( int, pyv.split('.') )) < [ 2, 1, 1]:
|
|
||||||
sys.exit( 'ERROR - The MMS agent requires pymongo 2.1.1 or higher to use SSL: easy_install -U pymongo' )
|
|
||||||
|
|
||||||
_pymongoVersion = pymongo.version
|
|
||||||
|
|
||||||
class AgentProcessContainer( object ):
|
|
||||||
""" Store the handle and lock to the agent process. """
|
|
||||||
|
|
||||||
def __init__( self ):
|
|
||||||
""" Init the lock and init process to none """
|
|
||||||
self.lock = threading.Lock()
|
|
||||||
self.agent = None
|
|
||||||
|
|
||||||
def pingAgentProcess( self ):
|
|
||||||
""" Ping the agent process """
|
|
||||||
try:
|
|
||||||
self.lock.acquire()
|
|
||||||
|
|
||||||
if self.agent is None or self.agent.poll() is not None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.agent.stdin.write( 'hello\n' )
|
|
||||||
self.agent.stdin.flush()
|
|
||||||
finally:
|
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
def stopAgentProcess( self ):
|
|
||||||
""" Send the stop message to the agent process """
|
|
||||||
try:
|
|
||||||
self.lock.acquire()
|
|
||||||
|
|
||||||
if self.agent is None or self.agent.poll() is not None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.agent.stdin.write( 'seeya\n' )
|
|
||||||
self.agent.stdin.flush()
|
|
||||||
|
|
||||||
time.sleep( 1 )
|
|
||||||
self.agent = None
|
|
||||||
|
|
||||||
finally:
|
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
class AgentShutdownListenerThread( threading.Thread ):
|
|
||||||
""" Disabled by default. When enabled listens for shutdown messages. """
|
|
||||||
|
|
||||||
def __init__( self, loggerObj, settingsObj ):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.logger = loggerObj
|
|
||||||
self.settings = settingsObj
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Listen for the shutdown messages """
|
|
||||||
try:
|
|
||||||
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
|
|
||||||
sock.bind( ( self.settings.shutdownAgentBindAddr, self.settings.shutdownAgentBindPort ) )
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
self.logger.info( 'Shutdown listener bound to address %s on port %d' % ( self.settings.shutdownAgentBindAddr, self.settings.shutdownAgentBindPort ) )
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
time.sleep( 5 )
|
|
||||||
data, addr = sock.recvfrom( 1024 )
|
|
||||||
if data != self.settings.shutdownAgentBindChallenge:
|
|
||||||
self.logger.error( 'received bad shutdown message from: %s' % addr[0] )
|
|
||||||
else:
|
|
||||||
self.logger.info( 'received valid shutdown message from: %s - exiting' % addr[0] )
|
|
||||||
os._exit( 0 )
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class AgentProcessMonitorThread( threading.Thread ):
|
|
||||||
""" Make sure the agent process is running """
|
|
||||||
|
|
||||||
def __init__( self, logger, agentDir, processContainerObj ):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.logger = logger
|
|
||||||
self.agentDir = agentDir
|
|
||||||
self.processContainer = processContainerObj
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def _launchAgentProcess( self ):
|
|
||||||
""" Execute the agent process and keep a handle to it. """
|
|
||||||
return subprocess.Popen( [ sys.executable, os.path.join( sys.path[0], 'agentProcess.py' ), str( _processPid ) ], stdin=subprocess.PIPE, stdout=subprocess.PIPE )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" If the agent process is not alive, start the process """
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
time.sleep( 5 )
|
|
||||||
self._monitorProcess()
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
def _monitorProcess( self ):
|
|
||||||
""" Monitor the child process """
|
|
||||||
self.processContainer.lock.acquire()
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
if self.processContainer.agent is None or self.processContainer.agent.poll() is not None:
|
|
||||||
self.processContainer.agent = self._launchAgentProcess()
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
finally:
|
|
||||||
self.processContainer.lock.release()
|
|
||||||
|
|
||||||
class AgentUpdateThread( threading.Thread ):
|
|
||||||
""" Check to see if updates are available - if so download and restart agent process """
|
|
||||||
|
|
||||||
def __init__( self, logger, agentDir, settingsObj, processContainerObj ):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.logger = logger
|
|
||||||
self.agentDir = agentDir
|
|
||||||
self.settings = settingsObj
|
|
||||||
self.processContainer = processContainerObj
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Update the agent if possible """
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
time.sleep( 300 )
|
|
||||||
self._checkForUpdate()
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( 'Problem with upgrade check: ' + traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
def _checkForUpdate( self ):
|
|
||||||
""" Update the agent if possible """
|
|
||||||
|
|
||||||
res = urllib.request.urlopen( self.settings.version_url % { 'key' : self.settings.mms_key } )
|
|
||||||
|
|
||||||
resBson = None
|
|
||||||
try:
|
|
||||||
resBson = bson.decode_all( res.read() )
|
|
||||||
finally:
|
|
||||||
if res is not None:
|
|
||||||
res.close()
|
|
||||||
res = None
|
|
||||||
|
|
||||||
if len(resBson) != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
versionResponse = resBson[0]
|
|
||||||
|
|
||||||
if 'status' not in versionResponse or versionResponse['status'] != 'ok':
|
|
||||||
return
|
|
||||||
|
|
||||||
if 'agentVersion' not in versionResponse or 'authCode' not in versionResponse:
|
|
||||||
return
|
|
||||||
|
|
||||||
remoteAgentVersion = versionResponse['agentVersion']
|
|
||||||
authCode = versionResponse['authCode']
|
|
||||||
|
|
||||||
if authCode != hmac.new( self.settings.secret_key, remoteAgentVersion, digestmod=hashlib.sha1 ).hexdigest():
|
|
||||||
self.logger.error( 'Invalid auth code - please confirm your secret key (defined on Settings page) is correct and hmac is properly installed - http://mms.10gen.com/help/' )
|
|
||||||
return
|
|
||||||
|
|
||||||
if self._shouldUpgradeAgent( self.settings.settingsAgentVersion, remoteAgentVersion ):
|
|
||||||
self._upgradeAgent( remoteAgentVersion )
|
|
||||||
|
|
||||||
def _shouldUpgradeAgent( self, localVersion, remoteVersion ):
|
|
||||||
""" Returns true if the agent should upgrade itself. """
|
|
||||||
try:
|
|
||||||
for l, r in zip( localVersion.split('.'), remoteVersion.split('.') ):
|
|
||||||
if int( l ) < int( r ):
|
|
||||||
return True
|
|
||||||
if int( l ) > int( r ):
|
|
||||||
return False
|
|
||||||
except Exception:
|
|
||||||
self.logger.error( "Upgrade problem with versions - local: '%s' - remote: '%s'" % ( localVersion, remoteVersion ) )
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _upgradeAgent( self, newAgentVersion ):
|
|
||||||
""" Pull down the files, verify and then stop the current process """
|
|
||||||
|
|
||||||
res = urllib.request.urlopen( self.settings.upgrade_url % { 'key' : self.settings.mms_key } )
|
|
||||||
|
|
||||||
resBson = None
|
|
||||||
try:
|
|
||||||
resBson = bson.decode_all( res.read() )
|
|
||||||
finally:
|
|
||||||
if res is not None:
|
|
||||||
res.close()
|
|
||||||
res = None
|
|
||||||
|
|
||||||
if len(resBson) != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
upgradeResponse = resBson[0]
|
|
||||||
|
|
||||||
if 'status' not in upgradeResponse or upgradeResponse['status'] != 'ok' or 'files' not in upgradeResponse:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Verify the auth codes for all files and names first.
|
|
||||||
for fileInfo in upgradeResponse['files']:
|
|
||||||
if fileInfo['fileAuthCode'] != hmac.new( self.settings.secret_key, fileInfo['file'], digestmod=hashlib.sha1 ).hexdigest():
|
|
||||||
self.logger.error( 'Invalid file auth code for upgrade - cancelling' )
|
|
||||||
return
|
|
||||||
|
|
||||||
if fileInfo['fileNameAuthCode'] != hmac.new( self.settings.secret_key, fileInfo['fileName'], digestmod=hashlib.sha1 ).hexdigest():
|
|
||||||
self.logger.error( 'Invalid file name auth code for upgrade - cancelling' )
|
|
||||||
return
|
|
||||||
|
|
||||||
# Write the files.
|
|
||||||
for fileInfo in upgradeResponse['files']:
|
|
||||||
|
|
||||||
fileContent = fileInfo['file']
|
|
||||||
fileName = fileInfo['fileName']
|
|
||||||
|
|
||||||
# If the user has a global username/password defined, make sure it is set in the new settings.py file.
|
|
||||||
if fileName == 'settings.py' and getattr( self.settings, 'globalAuthUsername', None ) is not None and getattr( self.settings, 'globalAuthPassword', None ) is not None:
|
|
||||||
fileContent = fileContent.replace( 'globalAuthPassword = None', 'globalAuthPassword=%r' % self.settings.globalAuthPassword )
|
|
||||||
fileContent = fileContent.replace( 'globalAuthUsername = None', 'globalAuthUsername=%r' % self.settings.globalAuthUsername )
|
|
||||||
|
|
||||||
fileSystemName = os.path.join( self.agentDir, fileName )
|
|
||||||
newFile = open( fileSystemName, 'w' )
|
|
||||||
|
|
||||||
try:
|
|
||||||
newFile.write( fileContent )
|
|
||||||
finally:
|
|
||||||
if newFile is not None:
|
|
||||||
newFile.close()
|
|
||||||
|
|
||||||
# Stop the current agent process
|
|
||||||
try:
|
|
||||||
self.processContainer.stopAgentProcess()
|
|
||||||
self.settings.settingsAgentVersion = newAgentVersion
|
|
||||||
self.logger.info( 'Agent upgraded to version: ' + newAgentVersion + ' - there is up to a five minute timeout before data will be sent again' )
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( 'Problem restarting agent process: ' + traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
#
|
|
||||||
# Run the process monitor and update threads.
|
|
||||||
#
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
_logger.info( 'Starting agent parent process - version: %s' % ( _settings.settingsAgentVersion ) )
|
|
||||||
_logger.info( 'Note: If you have hundreds or thousands of databases, disable dbstats on the settings page before running the MMS agent.' )
|
|
||||||
|
|
||||||
processContainer = AgentProcessContainer()
|
|
||||||
|
|
||||||
# Star the agent monitor thread.
|
|
||||||
monitorThread = AgentProcessMonitorThread( _logger, sys.path[0], processContainer )
|
|
||||||
monitorThread.setName( 'AgentProcessMonitorThread' )
|
|
||||||
monitorThread.setDaemon( True )
|
|
||||||
monitorThread.start()
|
|
||||||
|
|
||||||
# If enabled, start the shutdown listener thread (disabled by default).
|
|
||||||
if _settings.shutdownAgentBindAddr is not None:
|
|
||||||
shutdownListenerThread = AgentShutdownListenerThread( _logger, _settings )
|
|
||||||
shutdownListenerThread.setName( 'AgentShutdownListenerThread' )
|
|
||||||
shutdownListenerThread.setDaemon( True )
|
|
||||||
shutdownListenerThread.start()
|
|
||||||
|
|
||||||
if _settings.autoUpdateEnabled:
|
|
||||||
updateThread = AgentUpdateThread( _logger, sys.path[0], _settings, processContainer )
|
|
||||||
updateThread.setName( 'AgentUpdateThread' )
|
|
||||||
updateThread.setDaemon( True )
|
|
||||||
updateThread.start()
|
|
||||||
|
|
||||||
_logger.info( 'Started agent parent process - version: %s' % ( _settings.settingsAgentVersion ) )
|
|
||||||
|
|
||||||
# The parent process will let the child process know it's alive.
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
time.sleep( 2 )
|
|
||||||
processContainer.pingAgentProcess()
|
|
||||||
except Exception as exc:
|
|
||||||
_logger.error( traceback.format_exc( exc ) )
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
processContainer.stopAgentProcess()
|
|
||||||
except Exception as ex:
|
|
||||||
_logger.error( traceback.format_exc( ex ) )
|
|
||||||
|
|
289
vendor/mms-agent/agentProcess.py
vendored
289
vendor/mms-agent/agentProcess.py
vendored
|
@ -1,289 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Mongo
|
|
||||||
import pymongo, bson
|
|
||||||
|
|
||||||
if '_closed' in dir( pymongo.connection ):
|
|
||||||
pymongo.connection._closed = lambda sock: False
|
|
||||||
|
|
||||||
# App
|
|
||||||
import settings as _settings
|
|
||||||
from mmsAgent import MmsAgent
|
|
||||||
from confPull import ConfPullThread
|
|
||||||
import logConfig
|
|
||||||
|
|
||||||
# Python
|
|
||||||
import os, sys, platform, time, threading, socket, traceback, random, hashlib, tempfile
|
|
||||||
|
|
||||||
socket.setdefaulttimeout( _settings.socket_timeout )
|
|
||||||
|
|
||||||
_agentVersion = "1.5.7"
|
|
||||||
|
|
||||||
_pymongoVersion = pymongo.version
|
|
||||||
|
|
||||||
_pymongoHasC = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
_pymongoHasC = pymongo.has_c()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Try and reduce the stack size.
|
|
||||||
try:
|
|
||||||
threading.stack_size(409600)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class AgentProcess( threading.Thread ):
|
|
||||||
""" The parent process - monitors agent process and checks for updates etc """
|
|
||||||
|
|
||||||
def __init__( self, loggerObj, agentDir, existingSessionKey ):
|
|
||||||
""" Construct the object """
|
|
||||||
self.logger = loggerObj
|
|
||||||
self.agentDir = agentDir
|
|
||||||
self.mmsAgent = MmsAgent( _settings, _agentVersion, platform.python_version(), _pymongoVersion, _pymongoHasC, platform.uname()[1], self.logger, existingSessionKey )
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def stop( self ):
|
|
||||||
""" Stop the agent process """
|
|
||||||
try:
|
|
||||||
self.mmsAgent.done = True
|
|
||||||
self.mmsAgent.stopAll()
|
|
||||||
|
|
||||||
except Exception as fe:
|
|
||||||
self.logger.error( traceback.format_exc( fe ) )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" The agent process """
|
|
||||||
try:
|
|
||||||
# Start the configuration request
|
|
||||||
confThread = ConfPullThread( _settings, self.mmsAgent )
|
|
||||||
confThread.setName( 'ConfPullThread' )
|
|
||||||
confThread.start()
|
|
||||||
|
|
||||||
hostStateMonitorThread = MonitorHostState( self.logger, self.mmsAgent )
|
|
||||||
hostStateMonitorThread.setName( 'MonitorHostState' )
|
|
||||||
hostStateMonitorThread.start()
|
|
||||||
|
|
||||||
# Loop through and send data back to the MMS servers.
|
|
||||||
while not self.mmsAgent.done:
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
self.mmsAgent.sendDataToMms()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
time.sleep( self.mmsAgent.collectionInterval )
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
class ParentProcessMonitor( threading.Thread ):
|
|
||||||
""" The parent process monitor - monitors to see if the parent process is sending heartbeats """
|
|
||||||
|
|
||||||
def __init__( self, agentProcessObj ):
|
|
||||||
""" Construct the object """
|
|
||||||
self.mmsAgent = agentProcessObj.mmsAgent
|
|
||||||
self.logger = self.mmsAgent.logger
|
|
||||||
self.agentProcess = agentProcessObj
|
|
||||||
self.lock = threading.Lock()
|
|
||||||
self.lastHeartbeat = time.time()
|
|
||||||
self.running = True
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Verify the parent process is sending pings """
|
|
||||||
while self.running:
|
|
||||||
time.sleep( 2 )
|
|
||||||
try:
|
|
||||||
self._check()
|
|
||||||
except Exception as ex:
|
|
||||||
self.logger.error( traceback.format_exc( ex ) )
|
|
||||||
raise
|
|
||||||
|
|
||||||
def _check( self ):
|
|
||||||
""" Verify the heartbeat """
|
|
||||||
try:
|
|
||||||
self.lock.acquire()
|
|
||||||
|
|
||||||
secsSinceHeartbeat = ( time.time() - self.lastHeartbeat )
|
|
||||||
|
|
||||||
if secsSinceHeartbeat > 10:
|
|
||||||
self.agentProcess.stop()
|
|
||||||
os._exit( 0 )
|
|
||||||
finally:
|
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
def stop( self ):
|
|
||||||
""" Stop the process """
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
def heartbeat( self ):
|
|
||||||
""" Update the last time a message was sent from the parent. """
|
|
||||||
try:
|
|
||||||
self.lock.acquire()
|
|
||||||
self.lastHeartbeat = time.time()
|
|
||||||
finally:
|
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
class ParentMsgReader( threading.Thread ):
|
|
||||||
""" The parent process message reader """
|
|
||||||
|
|
||||||
def __init__( self, loggerObj, agentProcessObj, parentMonitorObj ):
|
|
||||||
""" Construct the object """
|
|
||||||
self.logger = loggerObj
|
|
||||||
self.parentMonitor = parentMonitorObj
|
|
||||||
self.agentProcess = agentProcessObj
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Read the data from stdin and process """
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
time.sleep( 1 )
|
|
||||||
self._readParentMessage()
|
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
self.logger.error( traceback.format_exc( exc ) )
|
|
||||||
|
|
||||||
def _readParentMessage( self ):
|
|
||||||
""" Read the heartbeat or stop message from the parent process """
|
|
||||||
line = sys.stdin.readline()
|
|
||||||
|
|
||||||
if not line:
|
|
||||||
return
|
|
||||||
|
|
||||||
if line == 'hello\n':
|
|
||||||
self.parentMonitor.heartbeat()
|
|
||||||
return
|
|
||||||
|
|
||||||
if line == 'seeya\n':
|
|
||||||
try:
|
|
||||||
self.agentProcess.stop()
|
|
||||||
self.parentMonitor.stop()
|
|
||||||
finally:
|
|
||||||
os._exit( 0 )
|
|
||||||
|
|
||||||
class MonitorHostState( threading.Thread ):
|
|
||||||
""" Check to see if we're not getting updates to host state - if not, flush """
|
|
||||||
|
|
||||||
def __init__( self, loggerObj, mmsAgentObj ):
|
|
||||||
""" Construct the object """
|
|
||||||
self.logger = loggerObj
|
|
||||||
self.mmsAgent = mmsAgentObj
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Make sure the data is current, if not remove """
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
self.mmsAgent.cleanHostState()
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
time.sleep( 10 )
|
|
||||||
|
|
||||||
def generateSessionKey( *args ):
|
|
||||||
""" Generate a session key """
|
|
||||||
t = time.time() * 1000
|
|
||||||
r = random.random()*100000000000000000
|
|
||||||
try:
|
|
||||||
a = platform.uname()[1]
|
|
||||||
except:
|
|
||||||
a = random.random()*100000000000000000
|
|
||||||
|
|
||||||
return hashlib.md5( ( '%(time)s %(random)s %(host)s %(args)s' % {'time' : t, 'random': r, 'host' : a, 'args' : str( args ) } ).encode('utf-8') ).hexdigest()
|
|
||||||
|
|
||||||
def readTmpFile( processPid ):
|
|
||||||
""" Read the temp file """
|
|
||||||
fileName = os.path.join( tempfile.gettempdir(), 'mms-' + str( processPid ) )
|
|
||||||
|
|
||||||
if not os.path.isfile( fileName ):
|
|
||||||
return None
|
|
||||||
|
|
||||||
f = open( fileName )
|
|
||||||
|
|
||||||
try:
|
|
||||||
fileContent = f.read()
|
|
||||||
|
|
||||||
# Handle the legacy json files
|
|
||||||
if fileContent.startswith( '{' ):
|
|
||||||
os.remove( fileName )
|
|
||||||
return None
|
|
||||||
|
|
||||||
resBson = bson.decode_all( fileContent )
|
|
||||||
|
|
||||||
if len(resBson) != 1:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return resBson[0]
|
|
||||||
|
|
||||||
finally:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def writeTmpFile( processPid, content ):
|
|
||||||
""" Write the temp file """
|
|
||||||
fileName = os.path.join( tempfile.gettempdir(), 'mms-' + str( processPid ) )
|
|
||||||
|
|
||||||
f = open( fileName, 'wb', 0 )
|
|
||||||
|
|
||||||
try:
|
|
||||||
f.write( bson.BSON.encode( content) )
|
|
||||||
finally:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
logger = logConfig.initLogger()
|
|
||||||
|
|
||||||
logger.info( 'Starting agent process - version %s' % ( _agentVersion ) )
|
|
||||||
|
|
||||||
sessionKey = generateSessionKey()
|
|
||||||
|
|
||||||
parentPid = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
if len( sys.argv ) > 1:
|
|
||||||
parentPid = sys.argv[1]
|
|
||||||
currentState = readTmpFile( parentPid )
|
|
||||||
if currentState is not None:
|
|
||||||
if 'sessionKey' in currentState:
|
|
||||||
sessionKey = currentState['sessionKey']
|
|
||||||
else:
|
|
||||||
currentState['sessionKey'] = sessionKey
|
|
||||||
else:
|
|
||||||
currentState = { }
|
|
||||||
currentState['sessionKey'] = sessionKey
|
|
||||||
|
|
||||||
writeTmpFile( parentPid, currentState )
|
|
||||||
|
|
||||||
except Exception as ec:
|
|
||||||
logger.error( traceback.format_exc( ec ) )
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Star the agent monitor thread.
|
|
||||||
agentProcess = AgentProcess( logger, sys.path[0], sessionKey )
|
|
||||||
agentProcess.setName( 'AgentProcess' )
|
|
||||||
agentProcess.start()
|
|
||||||
|
|
||||||
parentMonitor = ParentProcessMonitor( agentProcess )
|
|
||||||
parentMonitor.setName( 'ParentProcessMonitor' )
|
|
||||||
parentMonitor.start()
|
|
||||||
|
|
||||||
msgReader = ParentMsgReader( logger, agentProcess, parentMonitor)
|
|
||||||
msgReader.setName( 'ParentMsgReader' )
|
|
||||||
msgReader.start()
|
|
||||||
|
|
||||||
logger.info( 'Started agent process - parent pid: %s - version: %s' % ( str( parentPid ), _agentVersion ) )
|
|
||||||
|
|
||||||
except Exception as ec:
|
|
||||||
logger.error( traceback.format_exc( ec ) )
|
|
||||||
|
|
304
vendor/mms-agent/blockingStats.py
vendored
304
vendor/mms-agent/blockingStats.py
vendored
|
@ -1,304 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
import threading, time, datetime, pymongo, traceback, socket, warnings
|
|
||||||
|
|
||||||
warnings.simplefilter( 'ignore', DeprecationWarning )
|
|
||||||
|
|
||||||
blockingStatsAgentVersion = "1.5.7"
|
|
||||||
|
|
||||||
class BlockingMongoStatsThread( threading.Thread ):
|
|
||||||
""" Pull the blocking data from the various hosts. """
|
|
||||||
|
|
||||||
def __init__( self, hostKey, mmsAgent):
|
|
||||||
""" Initialize the object """
|
|
||||||
|
|
||||||
self.hostKey = hostKey
|
|
||||||
self.mmsAgent = mmsAgent
|
|
||||||
self.logger = mmsAgent.logger
|
|
||||||
self.slowDbStats = False
|
|
||||||
self.lastDbStatsCheck = time.time()
|
|
||||||
self.running = True
|
|
||||||
self.host = mmsAgent.extractHostname( hostKey )
|
|
||||||
self.port = mmsAgent.extractPort( hostKey )
|
|
||||||
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def stopThread( self ):
|
|
||||||
""" Stop the thread """
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Pull the data from the various hosts. """
|
|
||||||
|
|
||||||
self.logger.info( 'starting blocking stats monitoring: ' + self.hostKey )
|
|
||||||
|
|
||||||
sleepTime = ( self.mmsAgent.collectionInterval / 2 ) - 1
|
|
||||||
|
|
||||||
if ( sleepTime < 1 ):
|
|
||||||
sleepTime = 1
|
|
||||||
|
|
||||||
monitorConn = None
|
|
||||||
|
|
||||||
passes = 0
|
|
||||||
|
|
||||||
while not self.mmsAgent.done and self.running:
|
|
||||||
try:
|
|
||||||
time.sleep( sleepTime )
|
|
||||||
passes = passes + 1
|
|
||||||
|
|
||||||
if passes % 60 == 0:
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
if not monitorConn:
|
|
||||||
monitorConn = self.mmsAgent.getDbConnection( self.hostKey )
|
|
||||||
|
|
||||||
if not self._collectBlockingStats( passes, monitorConn ):
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
self.logger.error( 'Problem collecting blocking data from: ' + self.hostKey + " - exception: " + traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
self.logger.info( 'stopping blocking stats monitoring: ' + self.hostKey )
|
|
||||||
self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
def _collectBlockingStats( self, passes, monitorConn ):
|
|
||||||
""" Collect the blocking stats from the hosts """
|
|
||||||
|
|
||||||
try:
|
|
||||||
if not self.mmsAgent.haveHostDef( self.hostKey ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Close the connection once per hour
|
|
||||||
# Verify the connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, monitorConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
stats = self._collectStats( passes, monitorConn )
|
|
||||||
|
|
||||||
try:
|
|
||||||
stats['hostIpAddr'] = socket.gethostbyname(self.hostKey[0 : self.hostKey.find( ':' )])
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'hostIpAddr', e )
|
|
||||||
|
|
||||||
stats['host'] = self.host
|
|
||||||
stats['port'] = self.port
|
|
||||||
|
|
||||||
# Make sure we ended up with the same connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, monitorConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.mmsAgent.setHostState( self.hostKey, 'mongoBlocking', stats )
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( 'Problem collecting blocking data from (check if it is up and DNS): ' + self.hostKey + " - exception: " + traceback.format_exc( e ) )
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _collectStats( self, passes, monitorConn ):
|
|
||||||
""" Make the call to mongo host and collect the blocking data """
|
|
||||||
root = {}
|
|
||||||
|
|
||||||
# Set the agent version and hostname.
|
|
||||||
root['agentVersion'] = self.mmsAgent.agentVersion
|
|
||||||
root['agentHostname'] = self.mmsAgent.agentHostname
|
|
||||||
|
|
||||||
isMaster = monitorConn.admin.command( 'ismaster' )
|
|
||||||
root['isMaster'] = isMaster
|
|
||||||
|
|
||||||
isMongos = ( 'msg' in isMaster and isMaster['msg'] == 'isdbgrid' )
|
|
||||||
|
|
||||||
# Check to see if this is a mongod host
|
|
||||||
try:
|
|
||||||
if isMaster['ismaster'] == True and isMongos:
|
|
||||||
# Look at the shards
|
|
||||||
root['shards'] = list( monitorConn.config.shards.find() )
|
|
||||||
|
|
||||||
# Pull from config.locks
|
|
||||||
try:
|
|
||||||
root['locks'] = list( monitorConn.config.locks.find( limit=200, sort=[ ( "$natural" , pymongo.DESCENDING ) ]) )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'config.locks.find', e )
|
|
||||||
|
|
||||||
# Pull from config.collections if enabled
|
|
||||||
try:
|
|
||||||
if self.mmsAgent.settings.configCollectionsEnabled:
|
|
||||||
root['configCollections'] = list( monitorConn.config.collections.find( limit=200, sort=[ ( "$natural" , pymongo.DESCENDING ) ] ) )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'config.collections.find', e )
|
|
||||||
|
|
||||||
# Pull from config.databases if enabled
|
|
||||||
try:
|
|
||||||
if self.mmsAgent.settings.configDatabasesEnabled:
|
|
||||||
root['configDatabases'] = list( monitorConn.config.databases.find( limit=200, sort=[ ( "$natural" , pymongo.DESCENDING ) ] ) )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'config.databases.find', e )
|
|
||||||
|
|
||||||
try:
|
|
||||||
root['configLockpings'] = list( monitorConn.config.lockpings.find( limit=200, sort=[ ( "$natural" , pymongo.DESCENDING ) ] ) )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'config.lockpings.find', e )
|
|
||||||
|
|
||||||
# Look at the mongos instances - only pull hosts that have a ping time
|
|
||||||
# updated in the last twenty minutes (and max 1k).
|
|
||||||
queryTime = datetime.datetime.utcnow() - datetime.timedelta( seconds=1200 )
|
|
||||||
root['mongoses'] = list( monitorConn.config.mongos.find( { 'ping' : { '$gte' : queryTime } } ).limit( 1000 ) )
|
|
||||||
|
|
||||||
# Get the shard chunk counts.
|
|
||||||
shardChunkCounts = []
|
|
||||||
positions = { }
|
|
||||||
counter = 0
|
|
||||||
|
|
||||||
if passes % 10 == 0:
|
|
||||||
for chunk in monitorConn.config.chunks.find():
|
|
||||||
key = chunk['ns'] + chunk['shard']
|
|
||||||
if key not in positions:
|
|
||||||
count = {}
|
|
||||||
positions[key] = counter
|
|
||||||
shardChunkCounts.append( count )
|
|
||||||
counter = counter + 1
|
|
||||||
count['count'] = 0
|
|
||||||
count['ns'] = chunk['ns']
|
|
||||||
count['shard'] = chunk['shard']
|
|
||||||
|
|
||||||
shardChunkCounts[positions[key]]['count'] = shardChunkCounts[positions[key]]['count'] + 1
|
|
||||||
|
|
||||||
root['shardChunkCounts'] = shardChunkCounts
|
|
||||||
except pymongo.errors.OperationFailure:
|
|
||||||
pass
|
|
||||||
|
|
||||||
root['serverStatus'] = monitorConn.admin.command( 'serverStatus' )
|
|
||||||
|
|
||||||
isReplSet = False
|
|
||||||
isArbiter = False
|
|
||||||
|
|
||||||
if 'repl' in root['serverStatus']:
|
|
||||||
# Check to see if this is a replica set
|
|
||||||
try:
|
|
||||||
root['replStatus'] = monitorConn.admin.command( 'replSetGetStatus' )
|
|
||||||
if root['replStatus']['myState'] == 7:
|
|
||||||
isArbiter = True
|
|
||||||
|
|
||||||
isReplSet = True
|
|
||||||
except pymongo.errors.OperationFailure:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if isReplSet:
|
|
||||||
oplog = "oplog.rs"
|
|
||||||
else:
|
|
||||||
oplog = "oplog.$main"
|
|
||||||
|
|
||||||
try:
|
|
||||||
root['localSystemReplSet'] = monitorConn.local.system.replset.find_one()
|
|
||||||
except pymongo.errors.OperationFailure as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'local.system.replset.findOne', e )
|
|
||||||
|
|
||||||
localConn = monitorConn.local
|
|
||||||
|
|
||||||
oplogStats = {}
|
|
||||||
|
|
||||||
# Get oplog status
|
|
||||||
if isArbiter:
|
|
||||||
# Do nothing for the time being
|
|
||||||
pass
|
|
||||||
elif isMaster['ismaster'] == True or isReplSet:
|
|
||||||
try:
|
|
||||||
oplogStats["start"] = localConn[oplog].find( limit=1, sort=[ ( "$natural" , pymongo.ASCENDING ) ], fields={ 'ts' : 1 } )[0]["ts"]
|
|
||||||
|
|
||||||
oplogStats["end"] = localConn[oplog].find( limit=1, sort=[ ( "$natural" , pymongo.DESCENDING ) ], fields={ 'ts' : 1} )[0]["ts"]
|
|
||||||
|
|
||||||
oplogStats['rsStats'] = localConn.command( {'collstats' : 'oplog.rs' } )
|
|
||||||
|
|
||||||
except pymongo.errors.OperationFailure as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'local.' + oplog + '.find', e )
|
|
||||||
else:
|
|
||||||
# Slave
|
|
||||||
try:
|
|
||||||
oplogStats["sources"] = {}
|
|
||||||
for s in localConn.sources.find():
|
|
||||||
oplogStats["sources"][s["host"]] = s
|
|
||||||
except pymongo.errors.OperationFailure as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'local.sources.find', e )
|
|
||||||
|
|
||||||
root["oplog"] = oplogStats
|
|
||||||
|
|
||||||
# Load the config.gettings collection (balancer info etc.)
|
|
||||||
if not isArbiter:
|
|
||||||
try:
|
|
||||||
root['configSettings'] = list( monitorConn.config.settings.find() )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'config.settings.find', e )
|
|
||||||
|
|
||||||
# per db info - mongos doesn't allow calls to local
|
|
||||||
root['databases'] = { }
|
|
||||||
root['dbProfiling'] = { }
|
|
||||||
root['dbProfileData'] = { }
|
|
||||||
|
|
||||||
profilerEnabled = self.mmsAgent.hostDefValue( self.hostKey, 'profiler' )
|
|
||||||
|
|
||||||
if ( passes % 20 == 0 or profilerEnabled ) and not isArbiter and not isMongos:
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
for x in monitorConn.database_names():
|
|
||||||
try:
|
|
||||||
if passes % 20 == 0:
|
|
||||||
if self.slowDbStats and ( ( time.time() - self.lastDbStatsCheck ) < 7200 ):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not self.mmsAgent.disableDbstats:
|
|
||||||
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
if count > 100:
|
|
||||||
break
|
|
||||||
|
|
||||||
startTime = time.time()
|
|
||||||
|
|
||||||
temp = monitorConn[x].command( 'dbstats' )
|
|
||||||
# work around Python 2.4 and older bug
|
|
||||||
for f in temp:
|
|
||||||
# this is super hacky b/c of Python 2.4
|
|
||||||
if isinstance( temp[f] , (int, float, complex)) and str(temp[f]) == "-inf":
|
|
||||||
temp[f] = 0
|
|
||||||
root['databases'][x] = temp
|
|
||||||
|
|
||||||
if ( time.time() - startTime ) > 6:
|
|
||||||
self.slowDbStats = True
|
|
||||||
else:
|
|
||||||
self.slowDbStats = False
|
|
||||||
|
|
||||||
self.lastDbStatsCheck = time.time()
|
|
||||||
|
|
||||||
# If the profiler is enabled in MMS, collect data
|
|
||||||
if profilerEnabled and not isArbiter and not self.mmsAgent.settings.disableProfileDataCollection:
|
|
||||||
try:
|
|
||||||
# Get the most recent entries.
|
|
||||||
profileData = list( monitorConn[x].system.profile.find( spec=None, fields=None, skip=0, limit=20, sort=[ ( "$natural", pymongo.DESCENDING ) ] ) )
|
|
||||||
|
|
||||||
if len( profileData ) > 0:
|
|
||||||
root['dbProfileData'][x] = profileData
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'system.profile.find-' + x, e )
|
|
||||||
|
|
||||||
# Check to see if the profiler is enabled
|
|
||||||
try:
|
|
||||||
profiling = monitorConn[x].command( { 'profile' : -1 } )
|
|
||||||
if profiling is not None and 'ok' in profiling:
|
|
||||||
del profiling['ok']
|
|
||||||
root['dbProfiling'][x] = profiling
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if 'serverStatus' in root:
|
|
||||||
del root['serverStatus']
|
|
||||||
|
|
||||||
return root
|
|
||||||
|
|
109
vendor/mms-agent/confPull.py
vendored
109
vendor/mms-agent/confPull.py
vendored
|
@ -1,109 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
import threading, time, urllib.request, urllib.error, urllib.parse, traceback
|
|
||||||
|
|
||||||
import bson
|
|
||||||
|
|
||||||
confPullAgentVersion = "1.5.7"
|
|
||||||
|
|
||||||
class ConfPullThread( threading.Thread ):
|
|
||||||
""" The remote configuration pull thread object """
|
|
||||||
|
|
||||||
def __init__( self, settings, mmsAgent):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.settings = settings
|
|
||||||
self.logger = mmsAgent.logger
|
|
||||||
self.mmsAgent = mmsAgent
|
|
||||||
|
|
||||||
self.confUrl = self.settings.config_url % {
|
|
||||||
'key' : self.settings.mms_key,
|
|
||||||
'hostname' : self.mmsAgent.agentHostname,
|
|
||||||
'sessionKey' : self.mmsAgent.sessionKey,
|
|
||||||
'agentVersion' : self.mmsAgent.agentVersion,
|
|
||||||
'srcVersion' : self.mmsAgent.srcVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Pull the configuration from the cloud (if enabled) """
|
|
||||||
|
|
||||||
while not self.mmsAgent.done:
|
|
||||||
self._pullRemoteConf()
|
|
||||||
time.sleep( self.mmsAgent.confInterval )
|
|
||||||
|
|
||||||
def _pullRemoteConf( self ):
|
|
||||||
""" Pull the remote configuration data """
|
|
||||||
|
|
||||||
uniqueHostnames = []
|
|
||||||
|
|
||||||
res = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
res = urllib.request.urlopen( self.confUrl )
|
|
||||||
|
|
||||||
resBson = None
|
|
||||||
try:
|
|
||||||
resBson = bson.decode_all( res.read() )
|
|
||||||
finally:
|
|
||||||
if res is not None:
|
|
||||||
res.close()
|
|
||||||
res = None
|
|
||||||
|
|
||||||
if len(resBson) != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
confResponse = resBson[0]
|
|
||||||
|
|
||||||
if 'hosts' not in confResponse:
|
|
||||||
self.mmsAgent.stopAll()
|
|
||||||
return
|
|
||||||
|
|
||||||
if 'disableDbstats' in confResponse:
|
|
||||||
self.mmsAgent.disableDbstats = confResponse['disableDbstats']
|
|
||||||
else:
|
|
||||||
self.mmsAgent.disableDbstats = False
|
|
||||||
|
|
||||||
hosts = confResponse['hosts']
|
|
||||||
|
|
||||||
self.mmsAgent.serverHostDefsLock.acquire()
|
|
||||||
try:
|
|
||||||
# Extract the host information
|
|
||||||
if hosts is not None:
|
|
||||||
for host in hosts:
|
|
||||||
|
|
||||||
hostDef, hostDefLast = self.mmsAgent.extractHostDef( host )
|
|
||||||
|
|
||||||
hostKey = hostDef['hostKey']
|
|
||||||
uniqueHostnames.append( hostKey )
|
|
||||||
|
|
||||||
if hostKey not in self.mmsAgent.serverHostDefs:
|
|
||||||
self.mmsAgent.startMonitoringThreads( hostDef )
|
|
||||||
else:
|
|
||||||
self.mmsAgent.checkChangedHostDef( hostDef, hostDefLast )
|
|
||||||
|
|
||||||
hostDef = None
|
|
||||||
hostDefLast = None
|
|
||||||
|
|
||||||
# Check to see if anything was removed
|
|
||||||
for hostDef in list(self.mmsAgent.serverHostDefs.values()):
|
|
||||||
if hostDef['hostKey'] not in uniqueHostnames:
|
|
||||||
self.mmsAgent.stopAndClearHost( hostDef['hostKey'] )
|
|
||||||
finally:
|
|
||||||
self.mmsAgent.serverHostDefsLock.release()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
if res is not None:
|
|
||||||
try:
|
|
||||||
res.close()
|
|
||||||
res = None
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.logger.warning( "Problem pulling configuration data from MMS (check firewall and network): " + traceback.format_exc( e ) )
|
|
||||||
|
|
130
vendor/mms-agent/getLogs.py
vendored
130
vendor/mms-agent/getLogs.py
vendored
|
@ -1,130 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2012, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
import threading, time, traceback, warnings, sets
|
|
||||||
|
|
||||||
warnings.simplefilter( 'ignore', DeprecationWarning )
|
|
||||||
|
|
||||||
getLogsAgentVersion = "1.5.7"
|
|
||||||
|
|
||||||
class GetLogsThread( threading.Thread ):
|
|
||||||
""" When enabled pull log data from hosts. """
|
|
||||||
|
|
||||||
def __init__( self, hostKey, mmsAgent):
|
|
||||||
""" Initialize the object """
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
self.hostKey = hostKey
|
|
||||||
self.mmsAgent = mmsAgent
|
|
||||||
self.logger = mmsAgent.logger
|
|
||||||
self.running = True
|
|
||||||
self.lastLogEntries = sets.Set()
|
|
||||||
|
|
||||||
def stopThread( self ):
|
|
||||||
""" Stop the thread """
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Pull the data from the various hosts. """
|
|
||||||
|
|
||||||
self.logger.info( 'starting log data collection: ' + self.hostKey )
|
|
||||||
|
|
||||||
sleepTime = self.mmsAgent.logCollectionInterval
|
|
||||||
|
|
||||||
if ( sleepTime < 1 ):
|
|
||||||
sleepTime = 5
|
|
||||||
|
|
||||||
logConn = None
|
|
||||||
passes = 0
|
|
||||||
|
|
||||||
while not self.mmsAgent.done and self.running:
|
|
||||||
try:
|
|
||||||
enabled = self.mmsAgent.hostDefValue( self.hostKey, 'getLogs' )
|
|
||||||
|
|
||||||
if not enabled:
|
|
||||||
return
|
|
||||||
|
|
||||||
passes = passes + 1
|
|
||||||
|
|
||||||
# Close the connection every so often.
|
|
||||||
if passes % 120 == 0:
|
|
||||||
logConn = self.mmsAgent.closeDbConnection( self.hostKey, logConn )
|
|
||||||
|
|
||||||
if not logConn:
|
|
||||||
logConn = self.mmsAgent.getDbConnection( self.hostKey )
|
|
||||||
|
|
||||||
time.sleep( sleepTime )
|
|
||||||
|
|
||||||
if not self._processLogs( logConn ):
|
|
||||||
logConn = self.mmsAgent.closeDbConnection( self.hostKey, logConn )
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logConn = self.mmsAgent.closeDbConnection( self.hostKey, logConn )
|
|
||||||
self.logger.error( 'Problem collecting log data from: ' + self.hostKey + " - exception: " + traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
self.logger.info( 'stopping log data collection: ' + self.hostKey )
|
|
||||||
self.mmsAgent.closeDbConnection( self.hostKey, logConn )
|
|
||||||
|
|
||||||
|
|
||||||
def _processLogs( self, logConn ):
|
|
||||||
""" Process the logs """
|
|
||||||
|
|
||||||
try:
|
|
||||||
if not self.mmsAgent.haveHostDef( self.hostKey ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Verify the connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, logConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not self.mmsAgent.hasCommand( 'getLog', self.hostKey, logConn ):
|
|
||||||
self.logger.error( 'This version of MongoDB does not support the getLog command' )
|
|
||||||
time.sleep( 60 )
|
|
||||||
return False
|
|
||||||
|
|
||||||
logs = self._collectLogs( logConn )
|
|
||||||
|
|
||||||
# Make sure we ended up with the same connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, logConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.mmsAgent.setHostState( self.hostKey, 'logs', logs )
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error( 'Problem collecting log data from: ' + self.hostKey + " - exception: " + traceback.format_exc( e ) )
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _collectLogs( self, logConn ):
|
|
||||||
""" Make the call to mongo host and pull the log data """
|
|
||||||
root = { }
|
|
||||||
|
|
||||||
logEntries = []
|
|
||||||
|
|
||||||
entries = logConn.admin.command( { 'getLog' : 'global' } )
|
|
||||||
|
|
||||||
if not entries or not entries.get('log'):
|
|
||||||
self.lastLogEntries.clear()
|
|
||||||
return root
|
|
||||||
|
|
||||||
for logEntry in entries['log']:
|
|
||||||
if logEntry in self.lastLogEntries:
|
|
||||||
continue
|
|
||||||
|
|
||||||
logEntries.append( logEntry )
|
|
||||||
|
|
||||||
if len ( logEntries ) == 0:
|
|
||||||
return root
|
|
||||||
|
|
||||||
self.lastLogEntries.clear()
|
|
||||||
|
|
||||||
for logEntry in entries['log']:
|
|
||||||
self.lastLogEntries.add( logEntry )
|
|
||||||
|
|
||||||
root['entries'] = logEntries
|
|
||||||
|
|
||||||
return root
|
|
||||||
|
|
125
vendor/mms-agent/logConfig.py
vendored
125
vendor/mms-agent/logConfig.py
vendored
|
@ -1,125 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
# App
|
|
||||||
import settings as _settings
|
|
||||||
|
|
||||||
# Mongo
|
|
||||||
import pymongo, bson
|
|
||||||
|
|
||||||
# Python
|
|
||||||
import logging, threading, time, logging.handlers, urllib.request, urllib.error, urllib.parse, platform, socket, queue
|
|
||||||
|
|
||||||
socket.setdefaulttimeout( _settings.socket_timeout )
|
|
||||||
|
|
||||||
class LogRelayThread( threading.Thread ):
|
|
||||||
""" The log relay thread - batch messages """
|
|
||||||
|
|
||||||
def __init__( self, recordQueue ):
|
|
||||||
""" Construct the object """
|
|
||||||
self.recordQueue = recordQueue
|
|
||||||
self.logUrl = _settings.logging_url % { 'key' : _settings.mms_key }
|
|
||||||
self.pythonVersion = platform.python_version()
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.hostname = platform.uname()[1]
|
|
||||||
except:
|
|
||||||
self.hostname = 'UNKNOWN'
|
|
||||||
|
|
||||||
self.pymongoVersion = pymongo.version
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" The agent process """
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
# Let the records batch for five seconds
|
|
||||||
time.sleep( 5 )
|
|
||||||
|
|
||||||
self._processRecords()
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _processRecords( self ):
|
|
||||||
""" Process the log records """
|
|
||||||
records = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
while not self.recordQueue.empty():
|
|
||||||
|
|
||||||
record = self.recordQueue.get( True, 1 )
|
|
||||||
|
|
||||||
if record is None:
|
|
||||||
break
|
|
||||||
|
|
||||||
data = { }
|
|
||||||
data['levelname'] = record.levelname
|
|
||||||
data['msg'] = record.msg
|
|
||||||
data['filename'] = record.filename
|
|
||||||
data['threadName'] = record.threadName
|
|
||||||
|
|
||||||
# This is to deal with older versions of python.
|
|
||||||
try:
|
|
||||||
data['funcName'] = record.funcName
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
data['process'] = record.process
|
|
||||||
data['lineno'] = record.lineno
|
|
||||||
data['pymongoVersion'] = self.pymongoVersion
|
|
||||||
data['pythonVersion'] = self.pythonVersion
|
|
||||||
data['hostname'] = self.hostname
|
|
||||||
|
|
||||||
records.append( data )
|
|
||||||
|
|
||||||
if len( records ) >= 10:
|
|
||||||
break
|
|
||||||
|
|
||||||
except queue.Empty:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if len( records ) == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Send the data back to mms.
|
|
||||||
res = None
|
|
||||||
try:
|
|
||||||
res = urllib.request.urlopen( self.logUrl, bson.BSON.encode( { 'records' : records }, check_keys=False ) )
|
|
||||||
res.read()
|
|
||||||
finally:
|
|
||||||
if res is not None:
|
|
||||||
res.close()
|
|
||||||
|
|
||||||
class MmsRemoteHandler( logging.Handler ):
|
|
||||||
""" The mms remote log handler """
|
|
||||||
def __init__( self ):
|
|
||||||
""" Construct a new object """
|
|
||||||
logging.Handler.__init__( self )
|
|
||||||
self.recordQueue = queue.Queue( 250 )
|
|
||||||
self.logRelay = LogRelayThread( self.recordQueue )
|
|
||||||
self.logRelay.setName( 'LogRelay' )
|
|
||||||
self.logRelay.start()
|
|
||||||
|
|
||||||
def emit( self, record ):
|
|
||||||
""" Send the record to the remote servers """
|
|
||||||
try:
|
|
||||||
if record is not None:
|
|
||||||
self.recordQueue.put_nowait( record )
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def initLogger( ):
|
|
||||||
""" Initialize the logger """
|
|
||||||
logger = logging.getLogger('MMS')
|
|
||||||
streamHandler = logging.StreamHandler()
|
|
||||||
streamHandler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s %(message)s') )
|
|
||||||
logger.addHandler( streamHandler )
|
|
||||||
logging.handlers.MmsRemoteHandler = MmsRemoteHandler
|
|
||||||
logger.addHandler( logging.handlers.MmsRemoteHandler() )
|
|
||||||
logger.setLevel( logging.INFO )
|
|
||||||
return logger
|
|
||||||
|
|
1
vendor/mms-agent/mongommsinstall.bat
vendored
1
vendor/mms-agent/mongommsinstall.bat
vendored
|
@ -1 +0,0 @@
|
||||||
powershell .\mongommsinstall.ps1
|
|
195
vendor/mms-agent/mongommsinstall.ps1
vendored
195
vendor/mms-agent/mongommsinstall.ps1
vendored
|
@ -1,195 +0,0 @@
|
||||||
$python64RegKey = "HKLM:\Software\Python\PythonCore\*"
|
|
||||||
$python32RegKey = "HKLM:\Software\Wow6432Node\Python\PythonCore\*"
|
|
||||||
$pythonExe = "python.exe"
|
|
||||||
$srvanyExe = "srvany.exe"
|
|
||||||
$scriptName = "agent.py"
|
|
||||||
$serviceName = "MongoMMS"
|
|
||||||
$serviceDisplayName = "MongoDB MMS"
|
|
||||||
$serviceDesc = "Service that runs the MongoDB Python MMS Script"
|
|
||||||
$serviceRegPath = Join-Path "HKLM:\SYSTEM\CurrentControlSet\Services\" $serviceName
|
|
||||||
$pyMongoTest = "pymongotest.py"
|
|
||||||
$pythonTest = "pythonversiontest.py"
|
|
||||||
|
|
||||||
function Test-PyMongo {
|
|
||||||
Param($pythonPath)
|
|
||||||
if ($pythonPath -eq $null) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
$res = (Start-Process -FilePath $pythonPath `
|
|
||||||
-ArgumentList $pyMongoTest -Wait -PassThru -NoNewWindow).ExitCode
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test-Python-Version {
|
|
||||||
Param($pythonPath)
|
|
||||||
if ($pythonPath -eq $null) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
$res = (Start-Process -FilePath $pythonPath `
|
|
||||||
-ArgumentList $pythonTest -Wait -PassThru -NoNewWindow).ExitCode
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test-ValidPython {
|
|
||||||
Param($pythonPath)
|
|
||||||
if ($pythonPath -eq $null) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
$res = Test-Python-Version($pythonPath)
|
|
||||||
if (!($res -eq 0)) {
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
$res = Test-PyMongo($pythonPath)
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function Get-PythonPath {
|
|
||||||
Param($location)
|
|
||||||
if ($location -eq $null) {
|
|
||||||
return Get-PythonRegistryPath
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$pythonExePath = $null
|
|
||||||
if (Test-Path -LiteralPath $location -PathType Leaf) {
|
|
||||||
$pythonExePath = $location
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (Test-Path -Path $location -PathType Container) {
|
|
||||||
$pythonExePath = Join-Path $location $pythonExe
|
|
||||||
if (!(Test-Path -Path $pythonExePath -PathType Leaf)) {
|
|
||||||
$pythonExePath = $null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Error "Error: Python installation cannot be found. Service not installed"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$res = Test-ValidPython($pythonExePath)
|
|
||||||
if ($res -eq 0) {
|
|
||||||
return $pythonExePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $null
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-PythonRegistryPath {
|
|
||||||
$pythonRegPath = Get-ActualPythonRegistryPath($python64RegKey)
|
|
||||||
if ($pythonRegPath -eq $null) {
|
|
||||||
$pythonRegPath = Get-ActualPythonRegistryPath($python32RegKey)
|
|
||||||
}
|
|
||||||
return $pythonRegPath
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-ActualPythonRegistryPath {
|
|
||||||
Param($registryBasePath)
|
|
||||||
if (Test-Path -Path $registryBasePath -PathType Container) {
|
|
||||||
$list = Get-Item $registryBasePath | select PSPath
|
|
||||||
foreach ($regPath in $list) {
|
|
||||||
$installPath = Join-Path $regPath.PSPath "InstallPath"
|
|
||||||
if (Test-Path -Path $installPath) {
|
|
||||||
$installPathValue = (Get-ItemProperty $installPath "(default)")."(default)"
|
|
||||||
$installPathValue = Join-Path $installPathValue $pythonExe
|
|
||||||
if (Test-Path -LiteralPath $installPathValue -PathType Leaf) {
|
|
||||||
$res = Test-ValidPython($installPathValue)
|
|
||||||
if ($res -eq 0) {
|
|
||||||
return $installPathValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-SrvanyPath {
|
|
||||||
$currentPath = Resolve-Path .
|
|
||||||
$exePath = Join-Path $currentPath $srvanyExe
|
|
||||||
|
|
||||||
if (Test-Path -LiteralPath $exePath -PathType Leaf) {
|
|
||||||
return $exePath
|
|
||||||
}
|
|
||||||
|
|
||||||
$progFilesPath = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)")
|
|
||||||
if ($progFilesPath -eq $null) {
|
|
||||||
$progFilesPath = [Environment]::GetEnvironmentVariable("ProgramFiles")
|
|
||||||
}
|
|
||||||
$exePath = Join-Path $progFilesPath (Join-Path "\Windows Resource Kits\Tools" $srvanyExe)
|
|
||||||
if (Test-Path -LiteralPath $exePath -PathType Leaf) {
|
|
||||||
return $exePath
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Error "Error: Windows Resource Toolkit srvany not found"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Create-MMSService {
|
|
||||||
Param($execName)
|
|
||||||
$svcList = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
|
|
||||||
if ($svcList -eq $null -or $svcList.Count -eq 0) {
|
|
||||||
New-Service -Name $serviceName -BinaryPathName $execName `
|
|
||||||
-Description $serviceDesc -DisplayName $serviceDisplayName `
|
|
||||||
-StartupType Automatic | Out-Null
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Error "Service already exists"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-MMSScriptPath {
|
|
||||||
$currentPath = Resolve-Path .
|
|
||||||
$scriptPath = Join-Path $currentPath $scriptName
|
|
||||||
if (Test-Path -LiteralPath $scriptPath -PathType Leaf) {
|
|
||||||
return $scriptPath
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Error "Error: MMS Script not found"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Modify-MMSService {
|
|
||||||
$appDir = Get-Item $mmsScriptPath | Split-Path -parent
|
|
||||||
$quotedAppDir = Quote-String($appDir)
|
|
||||||
$quotedPythonPath = Quote-String($pythonPath)
|
|
||||||
$quotedScriptPath = Quote-String($mmsScriptPath)
|
|
||||||
$application = $quotedPythonPath+" "+$quotedScriptPath
|
|
||||||
$parameterKey = Join-Path $serviceRegPath "Parameters"
|
|
||||||
New-Item -Path $parameterKey | Out-Null
|
|
||||||
New-ItemProperty -Path $parameterKey -Name "Application" -Value $application | Out-Null
|
|
||||||
New-ItemProperty -Path $parameterKey -Name "AppDir" -Value $quotedAppDir | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
function Start-MMSService {
|
|
||||||
Start-Service -Name $serviceName
|
|
||||||
}
|
|
||||||
|
|
||||||
function Quote-String {
|
|
||||||
Param($unquotedString)
|
|
||||||
return "`"" + $unquotedString + "`""
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($args.Length -gt 0) {
|
|
||||||
$pythonPath = Get-PythonPath($args[0])
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$pythonPath = Get-PythonPath
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pythonPath -eq $null) {
|
|
||||||
Write-Error -Message "Valid python install not found. Service not installed" `
|
|
||||||
-Category NotInstalled
|
|
||||||
Exit
|
|
||||||
}
|
|
||||||
|
|
||||||
$srvAnyPath = Get-SrvanyPath
|
|
||||||
$mmsScriptPath = Get-MMSScriptPath
|
|
||||||
|
|
||||||
Create-MMSService(Quote-String($srvAnyPath))
|
|
||||||
Modify-MMSService
|
|
||||||
Write-Host "Service succesfully created"
|
|
||||||
Start-MMSService
|
|
||||||
Write-Host "Service started"
|
|
170
vendor/mms-agent/munin.py
vendored
170
vendor/mms-agent/munin.py
vendored
|
@ -1,170 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Python
|
|
||||||
import socket, threading, time
|
|
||||||
|
|
||||||
muninAgentVersion = "1.5.7"
|
|
||||||
|
|
||||||
def containsStr( val, query ):
|
|
||||||
""" Returns true if the value is contained in the string """
|
|
||||||
return val.find( query ) > -1
|
|
||||||
|
|
||||||
class MuninThread( threading.Thread ):
|
|
||||||
""" Pull them munin data from the various hosts. """
|
|
||||||
|
|
||||||
def __init__( self, hostname, mmsAgent ):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.hostname = hostname
|
|
||||||
self.mmsAgent = mmsAgent
|
|
||||||
self.logger = mmsAgent.logger
|
|
||||||
self.muninNode = MuninNode( self.hostname )
|
|
||||||
self.running = True
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" Pull the munin data from the various hosts. """
|
|
||||||
|
|
||||||
self.logger.info( 'starting munin monitoring: ' + self.hostname + ':4949' )
|
|
||||||
|
|
||||||
sleepTime = ( self.mmsAgent.collectionInterval / 2 ) - 1
|
|
||||||
|
|
||||||
if ( sleepTime < 1 ):
|
|
||||||
sleepTime = 1
|
|
||||||
|
|
||||||
while not self.mmsAgent.done and self.mmsAgent.hasUniqueServer( self.hostname ) and self.running:
|
|
||||||
try:
|
|
||||||
time.sleep( sleepTime )
|
|
||||||
self._collectAndSetState()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.logger.info( 'stopping munin monitoring: ' + self.hostname + ':4949' )
|
|
||||||
|
|
||||||
def stopThread( self ):
|
|
||||||
""" Stop the thread. This sets a running flag to false """
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
def _collectAndSetState( self ):
|
|
||||||
""" Collect the data and set the state """
|
|
||||||
muninStats = self._collectStats()
|
|
||||||
|
|
||||||
if muninStats is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
muninStats['host'] = self.hostname
|
|
||||||
|
|
||||||
self.mmsAgent.setMuninHostState( self.hostname, muninStats )
|
|
||||||
|
|
||||||
def _collectStats( self ):
|
|
||||||
""" Collect the data from the munin host """
|
|
||||||
try:
|
|
||||||
return self.muninNode.fetchAndConfigMany( [ "cpu" , "iostat" , "iostat_ios" ] )
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|
||||||
class MuninNode( object ):
|
|
||||||
""" The Munin node collection object """
|
|
||||||
|
|
||||||
def __init__( self, host='127.0.0.1', port=4949 ):
|
|
||||||
""" Constructor """
|
|
||||||
self.host = host
|
|
||||||
self.port = port
|
|
||||||
|
|
||||||
def _send( self, cmd, sock ):
|
|
||||||
""" Send a command to Munin """
|
|
||||||
sock.send( cmd + "\r\n" )
|
|
||||||
|
|
||||||
def _readline( self, f ):
|
|
||||||
""" Read data from vendor.munin """
|
|
||||||
return f.readline().split("\n")[0]
|
|
||||||
|
|
||||||
def list( self, sock, f ):
|
|
||||||
""" Run a list operation """
|
|
||||||
self._send( 'list', sock )
|
|
||||||
s = self._readline( f )
|
|
||||||
return s.split( ' ' )
|
|
||||||
|
|
||||||
def config( self, cmd, sock, f ):
|
|
||||||
""" Run a config operation """
|
|
||||||
return self._data( 'config', cmd, sock, f )
|
|
||||||
|
|
||||||
def fetch( self, cmd, sock, f ):
|
|
||||||
""" Run a fetch operation """
|
|
||||||
return self._data( 'fetch', cmd, sock, f )
|
|
||||||
|
|
||||||
def _data( self, cmdType, cmd, sock, f ):
|
|
||||||
""" Collect data """
|
|
||||||
self._send( cmdType + ' ' + cmd, sock )
|
|
||||||
data = []
|
|
||||||
while True:
|
|
||||||
s = self._readline( f )
|
|
||||||
if s == ".":
|
|
||||||
break
|
|
||||||
|
|
||||||
if cmdType == 'config':
|
|
||||||
if containsStr( s, '.label' ) == False:
|
|
||||||
continue
|
|
||||||
|
|
||||||
data.append( s )
|
|
||||||
return data
|
|
||||||
|
|
||||||
def connect( self ):
|
|
||||||
""" Connect to the Munin node """
|
|
||||||
sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
|
||||||
sock.connect( ( self.host, self.port ) )
|
|
||||||
|
|
||||||
f = sock.makefile()
|
|
||||||
|
|
||||||
if not f:
|
|
||||||
try:
|
|
||||||
sock.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
raise Exception( 'Error reading data from socket' )
|
|
||||||
|
|
||||||
banner = f.readline() # banner
|
|
||||||
|
|
||||||
if len( banner ) == 0:
|
|
||||||
raise Exception( 'Unable to connect to Munin' )
|
|
||||||
|
|
||||||
return ( sock, f )
|
|
||||||
|
|
||||||
def disconnect( self, sock, f ):
|
|
||||||
""" Disconnect from vendor.munin """
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
self._send( 'quit', sock )
|
|
||||||
finally:
|
|
||||||
sock.close()
|
|
||||||
finally:
|
|
||||||
if f is not None:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def fetchAndConfigMany( self, cmdTypes ):
|
|
||||||
""" The fetch and config many cmds - opens and closes the connection """
|
|
||||||
sock = None
|
|
||||||
f = None
|
|
||||||
try:
|
|
||||||
sock, f = self.connect()
|
|
||||||
fetch = {}
|
|
||||||
config = {}
|
|
||||||
for t in cmdTypes:
|
|
||||||
fetch[t] = self.fetch( t, sock, f )
|
|
||||||
|
|
||||||
if ( t == 'cpu' ):
|
|
||||||
config[t] = { }
|
|
||||||
else:
|
|
||||||
config[t] = self.config( t, sock, f )
|
|
||||||
|
|
||||||
return { 'fetch' : fetch, 'config' : config }
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
self.disconnect( sock, f )
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
184
vendor/mms-agent/nonBlockingStats.py
vendored
184
vendor/mms-agent/nonBlockingStats.py
vendored
|
@ -1,184 +0,0 @@
|
||||||
"""
|
|
||||||
(C) Copyright 2011, 10gen
|
|
||||||
|
|
||||||
This is a label on a mattress. Do not modify this file!
|
|
||||||
"""
|
|
||||||
|
|
||||||
import threading, time, pymongo, traceback, warnings, datetime
|
|
||||||
|
|
||||||
warnings.simplefilter( 'ignore', DeprecationWarning )
|
|
||||||
|
|
||||||
nonBlockingStatsAgentVersion = "1.5.7"
|
|
||||||
|
|
||||||
class NonBlockingMongoStatsThread( threading.Thread ):
|
|
||||||
""" Pull the non-blocking data from the various hosts. """
|
|
||||||
|
|
||||||
def __init__( self, hostKey, mmsAgent ):
|
|
||||||
""" Initialize the object """
|
|
||||||
self.hostKey = hostKey
|
|
||||||
self.mmsAgent = mmsAgent
|
|
||||||
self.logger = mmsAgent.logger
|
|
||||||
self.running = True
|
|
||||||
self.host = mmsAgent.extractHostname( hostKey )
|
|
||||||
self.port = mmsAgent.extractPort( hostKey )
|
|
||||||
|
|
||||||
threading.Thread.__init__( self )
|
|
||||||
|
|
||||||
def stopThread( self ):
|
|
||||||
""" Stop the thread """
|
|
||||||
self.running = False
|
|
||||||
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
""" The thread to collect stats """
|
|
||||||
|
|
||||||
self.logger.info( 'starting non-blocking stats monitoring: ' + self.hostKey )
|
|
||||||
|
|
||||||
sleepTime = ( self.mmsAgent.collectionInterval / 2 ) - 1
|
|
||||||
|
|
||||||
if ( sleepTime < 1 ):
|
|
||||||
sleepTime = 1
|
|
||||||
|
|
||||||
monitorConn = None
|
|
||||||
|
|
||||||
passes = 0
|
|
||||||
|
|
||||||
while not self.mmsAgent.done and self.running:
|
|
||||||
try:
|
|
||||||
time.sleep( sleepTime )
|
|
||||||
passes = passes + 1
|
|
||||||
|
|
||||||
# Close the connection periodically
|
|
||||||
if passes % 60 == 0:
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
if not monitorConn:
|
|
||||||
monitorConn = self.mmsAgent.getDbConnection( self.hostKey )
|
|
||||||
|
|
||||||
if not self._collectNonBlockingStats( monitorConn ):
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
monitorConn = self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
self.logger.error( 'Problem collecting non-blocking data from: ' + self.hostKey + " - exception: " + traceback.format_exc( e ) )
|
|
||||||
|
|
||||||
self.logger.info( 'stopping non-blocking stats monitoring: ' + self.hostKey )
|
|
||||||
self.mmsAgent.closeDbConnection( self.hostKey, monitorConn )
|
|
||||||
|
|
||||||
def _collectNonBlockingStats( self, monitorConn ):
|
|
||||||
""" Collect the non-blocking stats """
|
|
||||||
try:
|
|
||||||
if not self.mmsAgent.haveHostDef( self.hostKey ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Verify the connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, monitorConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
stats = self._collectStats( monitorConn )
|
|
||||||
|
|
||||||
stats['host'] = self.host
|
|
||||||
stats['port'] = self.port
|
|
||||||
|
|
||||||
# Make sure we ended up with the same connection.
|
|
||||||
if not self.mmsAgent.isValidMonitorConn( self.hostKey, monitorConn ):
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.mmsAgent.setHostState( self.hostKey, 'mongoNonBlocking', stats )
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.warning( 'Problem collecting non-blocking data from (check if it is up and DNS): ' + self.hostKey + ' - ' + traceback.format_exc( e ) )
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _collectStats( self, monitorConn ):
|
|
||||||
""" Make the call to mongo host and collect the data """
|
|
||||||
root = {}
|
|
||||||
|
|
||||||
# Set the agent version and hostname.
|
|
||||||
root['agentVersion'] = self.mmsAgent.agentVersion
|
|
||||||
root['agentHostname'] = self.mmsAgent.agentHostname
|
|
||||||
root['agentSessionKey'] = self.mmsAgent.sessionKey
|
|
||||||
|
|
||||||
cmdStartTime = datetime.datetime.now()
|
|
||||||
root['serverStatus'] = monitorConn.admin.command( 'serverStatus' )
|
|
||||||
cmdExecTime = datetime.datetime.now() - cmdStartTime
|
|
||||||
root['serverStatusExecTimeMs'] = ( cmdExecTime.days * 24 * 60 * 60 + cmdExecTime.seconds ) * 1000 + cmdExecTime.microseconds / 1000.0
|
|
||||||
|
|
||||||
# The server build info
|
|
||||||
root['buildInfo'] = monitorConn.admin.command( 'buildinfo' )
|
|
||||||
|
|
||||||
# Try and get the command line operations
|
|
||||||
try:
|
|
||||||
root['cmdLineOpts'] = monitorConn.admin.command( 'getCmdLineOpts' )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'getCmdLineOpts', e )
|
|
||||||
|
|
||||||
# Get the connection pool stats.
|
|
||||||
try:
|
|
||||||
root['connPoolStats'] = monitorConn.admin.command( 'connPoolStats' )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'connPoolStats', e )
|
|
||||||
|
|
||||||
# Look for any startup warnings if this is a valid version of mongo.
|
|
||||||
if self.mmsAgent.hasCommand( 'getLog', self.hostKey, monitorConn ):
|
|
||||||
try:
|
|
||||||
root['startupWarnings'] = monitorConn.admin.command( { 'getLog' : 'startupWarnings' } )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'getLog.startupWarnings', e )
|
|
||||||
|
|
||||||
|
|
||||||
# See if we can get hostInfo.
|
|
||||||
if self.mmsAgent.hasCommand( 'hostInfo', self.hostKey, monitorConn ):
|
|
||||||
try:
|
|
||||||
root['hostInfo'] = monitorConn.admin.command( { 'hostInfo' : 1 } )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'hostInfo', e )
|
|
||||||
|
|
||||||
# Try and get the isSelf data
|
|
||||||
try:
|
|
||||||
root['isSelf'] = monitorConn.admin.command( '_isSelf' )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, '_isSelf', e )
|
|
||||||
|
|
||||||
# Get the params.
|
|
||||||
try:
|
|
||||||
root['getParameterAll'] = monitorConn.admin.command( { 'getParameter' : '*' } )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'getParameter.*', e )
|
|
||||||
|
|
||||||
# Check occasionally to see if we can discover nodes
|
|
||||||
isMaster = monitorConn.admin.command( 'ismaster' )
|
|
||||||
root['isMaster'] = isMaster
|
|
||||||
|
|
||||||
# Try and get the shard version
|
|
||||||
if isMaster['ismaster'] and 'msg' in isMaster:
|
|
||||||
if isMaster['msg'] != 'isdbgrid':
|
|
||||||
|
|
||||||
try:
|
|
||||||
root['shardVersion'] = monitorConn.admin.command( { 'getShardVersion' : 'mdbfoo.foo' } )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'getShardVersion.mdbfoo.foo', e )
|
|
||||||
|
|
||||||
elif isMaster['ismaster']:
|
|
||||||
try:
|
|
||||||
root['shardVersion'] = monitorConn.admin.command( { 'getShardVersion' : 'mdbfoo.foo' } )
|
|
||||||
except Exception as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'getShardVersion.mdbfoo.foo', e )
|
|
||||||
|
|
||||||
# Check to see if this is a mongod host
|
|
||||||
try:
|
|
||||||
if isMaster['ismaster'] and isMaster.get('msg', '') == 'isdbgrid':
|
|
||||||
root['netstat'] = monitorConn.admin.command( 'netstat' )
|
|
||||||
except pymongo.errors.OperationFailure as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'netstat', e )
|
|
||||||
|
|
||||||
if 'repl' in root['serverStatus']:
|
|
||||||
try:
|
|
||||||
root['replStatus'] = monitorConn.admin.command( 'replSetGetStatus' )
|
|
||||||
except pymongo.errors.OperationFailure as e:
|
|
||||||
self.mmsAgent.handleOperationFailure( self.hostKey, 'replSetGetStatus', e )
|
|
||||||
|
|
||||||
return root
|
|
||||||
|
|
7
vendor/mms-agent/pymongotest.py
vendored
7
vendor/mms-agent/pymongotest.py
vendored
|
@ -1,7 +0,0 @@
|
||||||
import sys
|
|
||||||
try:
|
|
||||||
import pymongo
|
|
||||||
sys.exit(0)
|
|
||||||
except Exception as exc:
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
6
vendor/mms-agent/pythonversiontest.py
vendored
6
vendor/mms-agent/pythonversiontest.py
vendored
|
@ -1,6 +0,0 @@
|
||||||
import sys
|
|
||||||
major_version=sys.version_info[0]
|
|
||||||
if major_version == 2:
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
sys.exit(-1)
|
|
BIN
vendor/mms-agent/srvany.exe
vendored
BIN
vendor/mms-agent/srvany.exe
vendored
Binary file not shown.
Loading…
Add table
Reference in a new issue