Skip to content

Commit c39ba76

Browse files
committed
Add: new 0.9-beta1 version, with:
* detectors * collectors * key value * time serie managment * check evaluators * docker managment
1 parent 20a5f63 commit c39ba76

207 files changed

Lines changed: 13660 additions & 5400 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ __pycache__/
55
.#*
66
*#*
77

8+
# emacs files
89
*~
10+
# pycharm
11+
.idea/
912

1013
# C extensions
1114
*.so

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.travis.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
language: python
2+
python:
3+
- "2.6"
4+
- "2.7"
5+
6+
# command to install dependencies
7+
# some are only used for travis/coveralls so we are installing them here only
8+
install:
9+
- "pip install -r dependencies"
10+
- "pip install coveralls"
11+
- "pip install nose-cov"
12+
- "pip install unittest2"
13+
# command to run tests
14+
# notice: the nose-cov is used because it is compatible with --processes, but produce a .coverage by process
15+
# so we must combine them in the end
16+
script:
17+
- cd test
18+
- nosetests -xv --process-restartworker --processes=1 --process-timeout=999999999 --with-cov --cov=kunai
19+
- coverage combine
20+
# specific call to launch coverage data into coveralls.io
21+
after_success:
22+
coveralls

README.md

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ Prereqs
1111

1212
You will need:
1313

14-
* python >= 2.6 (but not 3)
14+
* python >= 2.6 (but not 3 currently)
1515
* python-leveldb
1616
* python-requests
1717
* python-jinja2
1818
* python-cherrypy3
19-
* python-rsa
20-
* python-pyasn1
2119

2220

21+
On linux:
22+
23+
* sysstat
24+
25+
To monitor mongodb server:
26+
27+
* python-pymongo
28+
2329

2430

2531
Installation
@@ -42,15 +48,6 @@ You can also launch it in foreground:
4248
kunai agent start
4349

4450

45-
Terminology
46-
===========
47-
48-
This project reuse Consul terminology (node, service, etc) which is very different to Nagios/Shinken standard:
49-
* node: a server where you install the agent (similar to nagios/shinken host)
50-
* check: something that look for a specific state (OK/WARNING/CRITICAL/UNKNOWN), like CPU, memory or disk space. It's not exported to other hosts (similar to nagios/shinken services)
51-
* service: object that expose an important application state to the other nodes (like for example mysql state). It need a check to do the actual check. This data is shared with all others nodes. (no equivalent in nagios/shinken).
52-
53-
5451
How to get agent informations (pid, port, state, etc)
5552
=====================================================
5653

@@ -60,7 +57,7 @@ Just launch:
6057
kunai info
6158

6259

63-
Is there an UI available?
60+
Is there an UI avialable?
6461
=========================
6562

6663
Yes. There is a UI available in the /var/lib/kuani/ui/ directory. It's just flat files and so you can just export the directory with apache/nginx and play with it.
@@ -87,10 +84,18 @@ And you will see the new node on the UI if you enable it
8784

8885

8986

87+
How to see collected data? (metrology)
88+
======================================
89+
90+
The kunai agent is by default getting lot of metrology data from your OS and applications. It's done by "collctors" objets. You can easily list them and look at the colelcted data by launching:
91+
92+
kunai collectors show
93+
94+
9095
How to see docker performance informations?
9196
===========================================
9297

93-
If docker is launched on your server, Kunai will get data from it, images and performances.
98+
If docker is launched on your server, Kunai will get data from it, like colelctors, images and performances.
9499

95100
To list all of this just launch:
96101

@@ -105,15 +110,4 @@ Just launch:
105110
kunai agent stop
106111

107112

108-
Which checks packs/tags are available?
109-
======================================
110-
111-
Kunai is bundle with some packs, just add them as tag and checks and services will be enable
112-
113-
* linux
114-
* debian
115-
* redis
116-
* mongodb
117-
* mysql
118-
119113

bin/kunai

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,16 @@
77
import optparse
88
import sys
99
import os
10-
import re
11-
import tempfile
1210
import json
1311
import imp
1412
import signal
15-
import socket
16-
from StringIO import StringIO
17-
1813

1914
sys.path.append('.')
2015

2116
from kunai.log import cprint, logger
2217
from kunai import cli as cli_mod
2318
from kunai.version import VERSION
24-
19+
from kunai.defaultpaths import DEFAULT_LOG_DIR, DEFAULT_CFG_FILE
2520

2621
logger.setLevel('WARNING')
2722

@@ -40,29 +35,27 @@ banner = r'''
4035
'''
4136

4237

43-
4438
# Handle some signals
4539
def sig_handler(signalnum, handle):
4640
""" Handle some signals """
4741
sys.exit(0)
4842

43+
4944
signal.signal(signal.SIGTERM, sig_handler)
5045
signal.signal(signal.SIGINT, sig_handler)
5146

52-
5347
CONFIG = {}
5448

49+
5550
class Dummy():
5651
def __init__(self):
5752
pass
5853

5954

60-
if os.name != 'nt':
61-
DEFAULT_CFG = '/etc/kunai/local.json'
62-
else:
63-
DEFAULT_CFG = 'c:\\kunai\\etc\\local.json'
64-
65-
55+
# if os.name != 'nt':
56+
# DEFAULT_CFG = '/etc/kunai/local.json'
57+
# else:
58+
# DEFAULT_CFG = 'c:\\kunai\\etc\\local.json'
6659

6760

6861
# Commander is the main class for managing the CLI session and behavior
@@ -72,8 +65,7 @@ class CLICommander(object):
7265

7366
self.config = config
7467

75-
name = config.get('name', '%s' % socket.gethostname())
76-
log_dir = config.get('log', '/var/lib/kunai')
68+
log_dir = config.get('log', DEFAULT_LOG_DIR) # '/var/lib/kunai')
7769
log_level = config.get('log_level', 'INFO')
7870
# early set the logger part
7971
logger.load(log_dir, '(cli)')
@@ -91,7 +83,8 @@ class CLICommander(object):
9183
cli_mods_dir = os.path.dirname(os.path.abspath(cli_mod.__file__))
9284

9385
logger.debug("Loading the cli directory %s" % cli_mods_dir)
94-
cli_mods_dirs = [os.path.join(cli_mods_dir, d) for d in os.listdir(cli_mods_dir) if os.path.isdir(os.path.join(cli_mods_dir, d))]
86+
cli_mods_dirs = [os.path.join(cli_mods_dir, d) for d in os.listdir(cli_mods_dir) if
87+
os.path.isdir(os.path.join(cli_mods_dir, d))]
9588

9689
# Link the CONFIG objet into the common
9790
# cli mod
@@ -113,43 +106,42 @@ class CLICommander(object):
113106
if len(m_keywords) >= 2:
114107
k = m_keywords[1]
115108
sub_cmd = m_keywords[0]
116-
e = {'f': f,
117-
'args': v.get('args', []),
109+
e = {'f' : f,
110+
'args' : v.get('args', []),
118111
'description': v.get('description', ''),
119-
'came_from': sub_cmd}
112+
'came_from' : sub_cmd}
120113
if not sub_cmd in self.keywords:
121114
self.keywords[sub_cmd] = {}
122115
# Finally save it
123116
self.keywords[sub_cmd][k] = e
124117

125118
logger.debug('We load the keywords %s' % self.keywords)
126119

127-
120+
128121
# Execute a function based on the command line
129122
def one_loop(self, command_args):
130123
logger.debug("ARGS: %s" % command_args)
131124
sub_cmd = 'global'
132-
keyword = ''
133-
125+
134126
# cannot be void because if so won't be in this loop
135127
if len(command_args) == 1:
136128
keyword = command_args.pop(0)
137129
else:
138130
sub_cmd = command_args.pop(0)
139131
keyword = command_args.pop(0)
140-
132+
141133
d = self.keywords.get(sub_cmd, None)
142134
if d is None:
143135
logger.error('Unknown sub command %s' % sub_cmd)
144136
return
145-
137+
146138
mod = d.get(keyword, None)
147139
if mod is None:
148140
if sub_cmd == 'global':
149141
if keyword in self.keywords:
150142
# ok it's a known sub part, like collectors, just
151143
# print it's own sub commands
152-
self.print_list(keyword)
144+
self.print_list(keyword)
153145
else:
154146
logger.error("UNKNOWN command %s" % keyword)
155147
else:
@@ -179,7 +171,7 @@ class CLICommander(object):
179171
# download_only
180172
dest = dest.replace('-', '_')
181173
# add_option parameters, common ones
182-
d = {'action':'store_true', 'dest':dest, 'help':(description)}
174+
d = {'dest': dest, 'help': (description)}
183175
# If bool setup it
184176
if _type == 'bool':
185177
d['action'] = 'store_true'
@@ -190,13 +182,12 @@ class CLICommander(object):
190182

191183
cmd_opts, cmd_args = command_parser.parse_args(command_args)
192184
f = mod.get('f', None)
193-
logger.debug("CALLING" + str(f) + "WITH" + str(cmd_args) + "and" + str(cmd_opts) + str(type(cmd_opts)) + str(dir(cmd_opts)))
185+
logger.debug("CALLING " + str(f) + " WITH " + str(cmd_args) + " and " + str(cmd_opts))
194186
f(*cmd_args, **cmd_opts.__dict__)
195187

196188

197189
def print_list(self, keyword=''):
198190
print "Available commands:"
199-
all_from = {}
200191
sub_cmds = self.keywords.keys()
201192
sub_cmds.remove('global')
202193
sub_cmds.sort()
@@ -224,8 +215,7 @@ class CLICommander(object):
224215
cprint(': %s' % m['description'])
225216
return
226217

227-
228-
218+
229219
if __name__ == '__main__':
230220
parser = optparse.OptionParser(
231221
'',
@@ -237,8 +227,8 @@ if __name__ == '__main__':
237227
dest="do_list", help=("List available commands"))
238228
parser.add_option('-D', action='store_true',
239229
dest="do_debug", help=("Enable the debug mode"))
240-
parser.add_option('-c', '--config', dest="jsonconfig", default=DEFAULT_CFG,
241-
help=("Path to your local.json file. Default: %s" % DEFAULT_CFG))
230+
parser.add_option('-c', '--config', dest="jsonconfig", default=DEFAULT_CFG_FILE,
231+
help=("Path to your local.json file. Default: %s" % DEFAULT_CFG_FILE))
242232
parser.add_option('-v', action='store_true',
243233
dest="do_verbose", help=("Be more verbose"))
244234
parser.add_option('-h', '--help', action='store_true',
@@ -270,7 +260,7 @@ if __name__ == '__main__':
270260
try:
271261
with open(opts.jsonconfig, 'r') as f:
272262
CONFIG = json.load(f)
273-
logger.debug("Loaded configuration file %s : %s" %(opts.jsonconfig, CONFIG))
263+
logger.debug("Loaded configuration file %s : %s" % (opts.jsonconfig, CONFIG))
274264
except Exception, exp:
275265
logger.error('Cannot load configuration file %s: %s' % (opts.jsonconfig, exp))
276266
sys.exit(2)
@@ -279,10 +269,11 @@ if __name__ == '__main__':
279269

280270
# Reset levels if cli setup it
281271
if opts.do_verbose:
282-
logger.setLevel('INFO')
272+
logger.setLevel('INFO')
283273
if opts.do_debug:
284274
logger.setLevel('DEBUG')
285275

276+
286277
# We should look on the sys.argv if we find a valid keywords to
287278
# call in one loop or not.
288279
def hack_sys_argv():
@@ -310,6 +301,7 @@ if __name__ == '__main__':
310301
sys.argv = internal_values
311302
return command_values
312303

304+
313305
# We will remove specific commands from the sys.argv list and keep
314306
# them for parsing them after
315307
command_args = hack_sys_argv()

etc/generators/haproxy.cfg renamed to data/global-configuration/generators/haproxy.cfg

File renamed without changes.

etc/generators/haproxy.json renamed to data/global-configuration/generators/haproxy.json

File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
heheheh
2+
3+
blablabla
4+
5+
hihihi
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"generator": {
3+
"apply_on": "windows",
4+
"path": "c:\\authorized_keys.txt",
5+
"template": "ssh_keys.txt",
6+
"partial_start": "###### SSH Key deploy start",
7+
"partial_end": "###### SSH Key deploy end"
8+
}
9+
}

etc/default.json renamed to data/global-configuration/handlers/default.json

File renamed without changes.

0 commit comments

Comments
 (0)