serverdensity-heroku 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/checks.pyc ADDED
Binary file
data/bin/config.cfg ADDED
@@ -0,0 +1,56 @@
1
+ #
2
+ # Server Density Agent Config
3
+ # Docs: http://support.serverdensity.com/knowledgebase/articles/69360-agent-config-variables-linux-mac-freebsd
4
+ #
5
+
6
+ [Main]
7
+ sd_url: http://robelkin.serverdensity.com
8
+ agent_key: be935d3c673f3611097bdb711a685d1b
9
+
10
+ #
11
+ # Plugins
12
+ #
13
+ # Leave blank to ignore. See http://support.serverdensity.com/knowledgebase/articles/76018-writing-a-plugin-linux-mac-and-freebsd
14
+ #
15
+
16
+ plugin_directory:
17
+
18
+ #
19
+ # Optional status monitoring
20
+ #
21
+ # See http://support.serverdensity.com/knowledgebase/topics/10921-configuration
22
+ # Ignore these if you do not wish to monitor them
23
+ #
24
+
25
+ # Apache
26
+ # See http://support.serverdensity.com/knowledgebase/articles/71145-apache-monitoring-linux-mac-and-freebsd
27
+
28
+ apache_status_url: http://www.example.com/server-status/?auto
29
+ apache_status_user:
30
+ apache_status_pass:
31
+
32
+ # MongoDB
33
+ # See http://support.serverdensity.com/knowledgebase/articles/71151-mongodb-monitoring-linux-mac-and-freebsd
34
+
35
+ mongodb_server:
36
+ mongodb_dbstats: no
37
+ mongodb_replset: no
38
+
39
+ # MySQL
40
+ # See http://support.serverdensity.com/knowledgebase/articles/71166-mysql-monitoring-linux-mac-and-freebsd
41
+
42
+ mysql_server:
43
+ mysql_user:
44
+ mysql_pass:
45
+
46
+ # nginx
47
+ # See http://support.serverdensity.com/knowledgebase/articles/75885-nginx-monitoring-linux-mac-and-freebsd
48
+
49
+ nginx_status_url: http://www.example.com/nginx_status
50
+
51
+ # RabbitMQ
52
+ # See http://support.serverdensity.com/knowledgebase/articles/75888-rabbitmq-monitoring-linux-mac-and-freebsd
53
+
54
+ rabbitmq_status_url: http://www.example.com:55672/json
55
+ rabbitmq_user: guest
56
+ rabbitmq_pass: guest
data/bin/daemon.py ADDED
@@ -0,0 +1,174 @@
1
+ '''
2
+ ***
3
+ Modified generic daemon class
4
+ ***
5
+
6
+ Author: http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
7
+ www.boxedice.com
8
+
9
+ License: http://creativecommons.org/licenses/by-sa/3.0/
10
+
11
+ Changes: 23rd Jan 2009 (David Mytton <david@boxedice.com>)
12
+ - Replaced hard coded '/dev/null in __init__ with os.devnull
13
+ - Added OS check to conditionally remove code that doesn't work on OS X
14
+ - Added output to console on completion
15
+ - Tidied up formatting
16
+ 11th Mar 2009 (David Mytton <david@boxedice.com>)
17
+ - Fixed problem with daemon exiting on Python 2.4 (before SystemExit was part of the Exception base)
18
+ 13th Aug 2010 (David Mytton <david@boxedice.com>
19
+ - Fixed unhandled exception if PID file is empty
20
+ '''
21
+
22
+ # Core modules
23
+ import atexit
24
+ import os
25
+ import sys
26
+ import time
27
+
28
+ from signal import SIGTERM
29
+
30
+ class Daemon:
31
+ """
32
+ A generic daemon class.
33
+
34
+ Usage: subclass the Daemon class and override the run() method
35
+ """
36
+ def __init__(self, pidfile, stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
37
+ self.stdin = stdin
38
+ self.stdout = stdout
39
+ self.stderr = stderr
40
+ self.pidfile = pidfile
41
+
42
+ def daemonize(self):
43
+ """
44
+ Do the UNIX double-fork magic, see Stevens' "Advanced
45
+ Programming in the UNIX Environment" for details (ISBN 0201563177)
46
+ http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
47
+ """
48
+ try:
49
+ pid = os.fork()
50
+ if pid > 0:
51
+ # Exit first parent
52
+ sys.exit(0)
53
+ except OSError, e:
54
+ sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
55
+ sys.exit(1)
56
+
57
+ # Decouple from parent environment
58
+ os.chdir("/")
59
+ os.setsid()
60
+ os.umask(0)
61
+
62
+ # Do second fork
63
+ try:
64
+ pid = os.fork()
65
+ if pid > 0:
66
+ # Exit from second parent
67
+ sys.exit(0)
68
+ except OSError, e:
69
+ sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
70
+ sys.exit(1)
71
+
72
+ if sys.platform != 'darwin': # This block breaks on OS X
73
+ # Redirect standard file descriptors
74
+ sys.stdout.flush()
75
+ sys.stderr.flush()
76
+ si = file(self.stdin, 'r')
77
+ so = file(self.stdout, 'a+')
78
+ se = file(self.stderr, 'a+', 0)
79
+ os.dup2(si.fileno(), sys.stdin.fileno())
80
+ os.dup2(so.fileno(), sys.stdout.fileno())
81
+ os.dup2(se.fileno(), sys.stderr.fileno())
82
+
83
+ print "Started"
84
+
85
+ # Write pidfile
86
+ atexit.register(self.delpid) # Make sure pid file is removed if we quit
87
+ pid = str(os.getpid())
88
+ file(self.pidfile,'w+').write("%s\n" % pid)
89
+
90
+ def delpid(self):
91
+ os.remove(self.pidfile)
92
+
93
+ def start(self):
94
+ """
95
+ Start the daemon
96
+ """
97
+
98
+ print "Starting..."
99
+
100
+ # Check for a pidfile to see if the daemon already runs
101
+ try:
102
+ pf = file(self.pidfile,'r')
103
+ pid = int(pf.read().strip())
104
+ pf.close()
105
+ except IOError:
106
+ pid = None
107
+ except SystemExit:
108
+ pid = None
109
+
110
+ if pid:
111
+ message = "pidfile %s already exists. Is it already running?\n"
112
+ sys.stderr.write(message % self.pidfile)
113
+ sys.exit(1)
114
+
115
+ # Start the daemon
116
+ self.daemonize()
117
+ self.run()
118
+
119
+ def stop(self):
120
+ """
121
+ Stop the daemon
122
+ """
123
+
124
+ print "Stopping..."
125
+
126
+ # Get the pid from the pidfile
127
+ try:
128
+ pf = file(self.pidfile,'r')
129
+ pid = int(pf.read().strip())
130
+ pf.close()
131
+ except IOError:
132
+ pid = None
133
+ except ValueError:
134
+ pid = None
135
+
136
+ if not pid:
137
+ message = "pidfile %s does not exist. Not running?\n"
138
+ sys.stderr.write(message % self.pidfile)
139
+
140
+ # Just to be sure. A ValueError might occur if the PID file is empty but does actually exist
141
+ if os.path.exists(self.pidfile):
142
+ os.remove(self.pidfile)
143
+
144
+ return # Not an error in a restart
145
+
146
+ # Try killing the daemon process
147
+ try:
148
+ while 1:
149
+ os.kill(pid, SIGTERM)
150
+ time.sleep(0.1)
151
+ except OSError, err:
152
+ err = str(err)
153
+ if err.find("No such process") > 0:
154
+ if os.path.exists(self.pidfile):
155
+ os.remove(self.pidfile)
156
+ else:
157
+ print str(err)
158
+ sys.exit(1)
159
+
160
+ print "Stopped"
161
+
162
+ def restart(self):
163
+ """
164
+ Restart the daemon
165
+ """
166
+ self.stop()
167
+ self.start()
168
+
169
+ def run(self):
170
+ """
171
+ You should override this method when you subclass Daemon. It will be called after the process has been
172
+ daemonized by start() or restart().
173
+ """
174
+
data/bin/daemon.pyc ADDED
Binary file
data/bin/minjson.py ADDED
@@ -0,0 +1,280 @@
1
+ ##############################################################################
2
+ ##
3
+ ## minjson.py implements JSON reading and writing in python.
4
+ ## Copyright (c) 2005 Jim Washington and Contributors.
5
+ ##
6
+ ## This library is free software; you can redistribute it and/or
7
+ ## modify it under the terms of the GNU Lesser General Public
8
+ ## License as published by the Free Software Foundation; either
9
+ ## version 2.1 of the License, or (at your option) any later version.
10
+ ##
11
+ ## This library is distributed in the hope that it will be useful,
12
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ ## Lesser General Public License for more details.=
15
+ ##
16
+ ## You should have received a copy of the GNU Lesser General Public
17
+ ## License along with this library; if not, write to the Free Software
18
+ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ ##
20
+ ##############################################################################
21
+
22
+
23
+ # minjson.py
24
+ # use python's parser to read minimal javascript objects.
25
+ # str's objects and fixes the text to write javascript.
26
+
27
+ # Thanks to Patrick Logan for starting the json-py project and making so many
28
+ # good test cases.
29
+
30
+ # Jim Washington 7 Aug 2005.
31
+
32
+ from re import compile, sub, search, DOTALL
33
+
34
+ # set to true if transmission size is much more important than speed
35
+ # only affects writing, and makes a minimal difference in output size.
36
+ alwaysStripWhiteSpace = False
37
+
38
+ # add to this string if you wish to exclude additional math operators
39
+ # from reading.
40
+ badOperators = '*'
41
+
42
+ #################################
43
+ # read JSON object #
44
+ #################################
45
+
46
+ slashstarcomment = compile(r'/\*.*?\*/',DOTALL)
47
+ doubleslashcomment = compile(r'//.*\n')
48
+
49
+ def _Read(aString):
50
+ """Use eval in a 'safe' way to turn javascript expression into
51
+ a python expression. Allow only True, False, and None in global
52
+ __builtins__, and since those map as true, false, null in
53
+ javascript, pass those as locals
54
+ """
55
+ try:
56
+ result = eval(aString,
57
+ {"__builtins__":{'True':True,'False':False,'None':None}},
58
+ {'null':None,'true':True,'false':False})
59
+ except NameError:
60
+ raise ReadException, \
61
+ "Strings must be quoted. Could not read '%s'." % aString
62
+ except SyntaxError:
63
+ raise ReadException, \
64
+ "Syntax error. Could not read '%s'." % aString
65
+ return result
66
+
67
+ # badOperators is defined at the top of the module
68
+
69
+ # generate the regexes for math detection
70
+ regexes = {}
71
+ for operator in badOperators:
72
+ if operator in '+*':
73
+ # '+' and '*' need to be escaped with \ in re
74
+ regexes[operator,'numeric operation'] \
75
+ = compile(r"\d*\s*\%s|\%s\s*\d*" % (operator, operator))
76
+ else:
77
+ regexes[operator,'numeric operation'] \
78
+ = compile(r"\d*\s*%s|%s\s*\d*" % (operator, operator))
79
+
80
+ def _getStringState(aSequence):
81
+ """return the list of required quote closures if the end of aString needs them
82
+ to close quotes.
83
+ """
84
+ state = []
85
+ for k in aSequence:
86
+ if k in ['"',"'"]:
87
+ if state and k == state[-1]:
88
+ state.pop()
89
+ else:
90
+ state.append(k)
91
+ return state
92
+
93
+ def _sanityCheckMath(aString):
94
+ """just need to check that, if there is a math operator in the
95
+ client's JSON, it is inside a quoted string. This is mainly to
96
+ keep client from successfully sending 'D0S'*9**9**9**9...
97
+ Return True if OK, False otherwise
98
+ """
99
+ for operator in badOperators:
100
+ #first check, is it a possible math operation?
101
+ if regexes[(operator,'numeric operation')].search(aString) is not None:
102
+ # OK. possible math operation. get the operator's locations
103
+ getlocs = regexes[(operator,'numeric operation')].finditer(aString)
104
+ locs = [item.span() for item in getlocs]
105
+ halfStrLen = len(aString) / 2
106
+ #fortunately, this should be rare
107
+ for loc in locs:
108
+ exprStart = loc[0]
109
+ exprEnd = loc[1]
110
+ # We only need to know the char is within open quote
111
+ # status.
112
+ if exprStart <= halfStrLen:
113
+ teststr = aString[:exprStart]
114
+ else:
115
+ teststr = list(aString[exprEnd+1:])
116
+ teststr.reverse()
117
+ if not _getStringState(teststr):
118
+ return False
119
+ return True
120
+
121
+ def safeRead(aString):
122
+ """turn the js into happier python and check for bad operations
123
+ before sending it to the interpreter
124
+ """
125
+ # get rid of trailing null. Konqueror appends this, and the python
126
+ # interpreter balks when it is there.
127
+ CHR0 = chr(0)
128
+ while aString.endswith(CHR0):
129
+ aString = aString[:-1]
130
+ # strip leading and trailing whitespace
131
+ aString = aString.strip()
132
+ # zap /* ... */ comments
133
+ aString = slashstarcomment.sub('',aString)
134
+ # zap // comments
135
+ aString = doubleslashcomment.sub('',aString)
136
+ # here, we only check for the * operator as a DOS problem by default;
137
+ # additional operators may be excluded by editing badOperators
138
+ # at the top of the module
139
+ if _sanityCheckMath(aString):
140
+ return _Read(aString)
141
+ else:
142
+ raise ReadException, 'Unacceptable JSON expression: %s' % aString
143
+
144
+ read = safeRead
145
+
146
+ #################################
147
+ # write object as JSON #
148
+ #################################
149
+
150
+ #alwaysStripWhiteSpace is defined at the top of the module
151
+
152
+ tfnTuple = (('True','true'),('False','false'),('None','null'),)
153
+
154
+ def _replaceTrueFalseNone(aString):
155
+ """replace True, False, and None with javascript counterparts"""
156
+ for k in tfnTuple:
157
+ if k[0] in aString:
158
+ aString = aString.replace(k[0],k[1])
159
+ return aString
160
+
161
+ def _handleCode(subStr,stripWhiteSpace):
162
+ """replace True, False, and None with javascript counterparts if
163
+ appropriate, remove unicode u's, fix long L's, make tuples
164
+ lists, and strip white space if requested
165
+ """
166
+ if 'e' in subStr:
167
+ #True, False, and None have 'e' in them. :)
168
+ subStr = (_replaceTrueFalseNone(subStr))
169
+ if stripWhiteSpace:
170
+ # re.sub might do a better job, but takes longer.
171
+ # Spaces are the majority of the whitespace, anyway...
172
+ subStr = subStr.replace(' ','')
173
+ if subStr[-1] in "uU":
174
+ #remove unicode u's
175
+ subStr = subStr[:-1]
176
+ if "L" in subStr:
177
+ #remove Ls from long ints
178
+ subStr = subStr.replace("L",'')
179
+ #do tuples as lists
180
+ if "(" in subStr:
181
+ subStr = subStr.replace("(",'[')
182
+ if ")" in subStr:
183
+ subStr = subStr.replace(")",']')
184
+ return subStr
185
+
186
+ # re for a double-quoted string that has a single-quote in it
187
+ # but no double-quotes and python punctuation after:
188
+ redoublequotedstring = compile(r'"[^"]*\'[^"]*"[,\]\}:\)]')
189
+ escapedSingleQuote = r"\'"
190
+ escapedDoubleQuote = r'\"'
191
+
192
+ def doQuotesSwapping(aString):
193
+ """rewrite doublequoted strings with single quotes as singlequoted strings with
194
+ escaped single quotes"""
195
+ s = []
196
+ foundlocs = redoublequotedstring.finditer(aString)
197
+ prevend = 0
198
+ for loc in foundlocs:
199
+ start,end = loc.span()
200
+ s.append(aString[prevend:start])
201
+ tempstr = aString[start:end]
202
+ endchar = tempstr[-1]
203
+ ts1 = tempstr[1:-2]
204
+ ts1 = ts1.replace("'",escapedSingleQuote)
205
+ ts1 = "'%s'%s" % (ts1,endchar)
206
+ s.append(ts1)
207
+ prevend = end
208
+ s.append(aString[prevend:])
209
+ return ''.join(s)
210
+
211
+ def _pyexpr2jsexpr(aString, stripWhiteSpace):
212
+ """Take advantage of python's formatting of string representations of
213
+ objects. Python always uses "'" to delimit strings. Except it doesn't when
214
+ there is ' in the string. Fix that, then, if we split
215
+ on that delimiter, we have a list that alternates non-string text with
216
+ string text. Since string text is already properly escaped, we
217
+ only need to replace True, False, and None in non-string text and
218
+ remove any unicode 'u's preceding string values.
219
+
220
+ if stripWhiteSpace is True, remove spaces, etc from the non-string
221
+ text.
222
+ """
223
+ inSingleQuote = False
224
+ inDoubleQuote = False
225
+ #python will quote with " when there is a ' in the string,
226
+ #so fix that first
227
+ if redoublequotedstring.search(aString):
228
+ aString = doQuotesSwapping(aString)
229
+ marker = None
230
+ if escapedSingleQuote in aString:
231
+ #replace escaped single quotes with a marker
232
+ marker = markerBase = '|'
233
+ markerCount = 1
234
+ while marker in aString:
235
+ #if the marker is already there, make it different
236
+ markerCount += 1
237
+ marker = markerBase * markerCount
238
+ aString = aString.replace(escapedSingleQuote,marker)
239
+
240
+ #escape double-quotes
241
+ aString = aString.replace('"',escapedDoubleQuote)
242
+ #split the string on the real single-quotes
243
+ splitStr = aString.split("'")
244
+ outList = []
245
+ alt = True
246
+ for subStr in splitStr:
247
+ #if alt is True, non-string; do replacements
248
+ if alt:
249
+ subStr = _handleCode(subStr,stripWhiteSpace)
250
+ outList.append(subStr)
251
+ alt = not alt
252
+ result = '"'.join(outList)
253
+ if marker:
254
+ #put the escaped single-quotes back as "'"
255
+ result = result.replace(marker,"'")
256
+ return result
257
+
258
+ def write(obj, encoding="utf-8",stripWhiteSpace=alwaysStripWhiteSpace):
259
+ """Represent the object as a string. Do any necessary fix-ups
260
+ with pyexpr2jsexpr"""
261
+ try:
262
+ #not really sure encode does anything here
263
+ aString = str(obj).encode(encoding)
264
+ except UnicodeEncodeError:
265
+ aString = obj.encode(encoding)
266
+ if isinstance(obj,basestring):
267
+ if '"' in aString:
268
+ aString = aString.replace(escapedDoubleQuote,'"')
269
+ result = '"%s"' % aString.replace('"',escapedDoubleQuote)
270
+ else:
271
+ result = '"%s"' % aString
272
+ else:
273
+ result = _pyexpr2jsexpr(aString,stripWhiteSpace).encode(encoding)
274
+ return result
275
+
276
+ class ReadException(Exception):
277
+ pass
278
+
279
+ class WriteException(Exception):
280
+ pass