Table of contents
Sageo (prononced Sah-gay-oh) is a rewriting of check_mk_ multisite web GUI.
The Sageo project started with the idea of having a monitoring web GUI that is:
- Able to browse many sites at a time
- Easy to maintain
- Builded with up to date technologies
- Lightweight
Sageo reimplements one of the most powerfull features of check_mk: the views customization feature.
Sageo offers these advantages over by check_mk multisite:
- Sageo doesn't use the deprecated apache module "mod_python".
- Sageo is MVC oriented, that means the content and the business logic is seperated from presentation.
Sageo is compatible with all monitoring plateforms providing a livestatus interoperability like Icinga, Nagios, Shinken, etc.
The main technologies used are:
- Flask web framework
- MK Livestatus
- Twitter Bootstrap
- LESS
- Babel
- SQL ALCHEMY
- WTFORMS-ALCHEMY
Views
- View editing
- Backend multi-columns sorting
- Frontend multi-columns sorting
- Multi-columns grouping
- Backend filters
- Frontend filters
- Columns order customizing by drag & drop
- Layout column number customization
- Columns linking
Views templates
- Table aspect
- Single dataset
Snapins
- Snapin development structure
- Snapin localizable
- Snapin presentation customized by drag & drop
- Tactical overview ported
Users
- Languages preferences
Global application
- Display easily external content with a framed mode.
- Localizable
- Easily web forms creation according to the DB model
- Content and logic separated from presentation
Views
- Views rights management
- Results pagination
- Commands execution on objects
Snapins
- Snapin preferences saving
Users
- User privileges
- Login configuration
Global application
- Tests
The view "all hosts"
The view "all services"
View editing
Available views list
$ sudo aptitude install python-virtualenv
Create you virtual environnement
$ virtualenv env
$ . env/bin/activate
Download the GIT repository
$ git clone https://github.com/smlacombe/sageo.git
$ cd sageo
$ pip install -r requirements.txt
Install python modules with pip
$ pip install -r requirements.txt
Create the database
$ python db_init.py
Add your broker adress
$ vim config.py
Look at the configuration example in the file config.py.sample.
Each time you change the sites, you must migrate the database because the site filter is an enum database field and will accept only the values it is aware of.
$ python db_migrate.py
You need first to install the LESS compiler (LESSC).
For Debian based distribution:
$ apt-get install node-less
Compiling stuff
$ cd app/static/css
$ lessc less/main.less main.css
$ python run.py
Open a browser et go to: http://127.0.0.1:5000
The default username and the default password is 'admin' and 'admin' respectively.
Go to the folder "column"
$ cd app/model/columns
You will see several classes named with the prefix "column_painter" and a "builtin.py" module. A column painter used to obtain a readable data to the user from the raw data from livestatus queries results. This object also stores various properties for a given column.
Look if there is already a "painter column" class that implements the type of column that you want to add. A "column painter" may be generic for multiple columns of the same type. For instance, host_state and service_state are both states and uses the same "column painter" ColumnPainterState. More "column painter" class is generic, there should be more of the parameters passed to the constructor of the class.
To implement a "painter column", look at the structure of the base class ColumnPainter. It specifies that it must be implemented in the concrete class, the (row) get_readable function. Row is the dictionary containing the raw livestatus columns that have been requested.
For columns that does not require conversion to be readable by the user like the host_name, use the "painter" ColumnPainterRaw.
Go to builtin.py
$ vi columns/builtin.py
In the file header, import the class "column painter" if it is not already done.
ex:
from .column_painter_raw import ColumnPainterRaw
Declare as a constant, the column name.
ex:
COL_HOST_NAME = 'host_name'
Store the "painter" in the "painters" dictionnary.
ex:
painters[COL_HOST_NAME] = ColumnPainterRaw(COL_HOST_NAME, _(u'Host name'), _(u'Host name'), ['hosts', 'services'])
Restart the server and the new columns will appears in the view related to it datasource.
The filters list is not complete yet. We invite you to sumbit some filters.
Go to the folder "filters".
$ cd app/model/filters
You will see several "filter" and a "builtin.py" module classes. A filter defines a "filter" function to return the text filter for livestatus matching the query filter. A filter also defines "get_col_def" function returning the column definition for the database.
Example of columns definition:
def get_col_def(self):
return [Column(self.name, Enum('1', '0', '-1'), default=self.default)]
Implement a filter class if these classes are not enough. You can specify a specific form field definition to override the default field definition from WTFORMS-ALCHEMY. It is usefull especially when you some want radio fields for an Enum DB field instead a SelectField. You can see the basic type conversion here:
To override a form field definition, you must set the attribute "form_def" in the init() function. The order of the elements in the list must be the same as the column definition list.
Example of a form field field definition override (we want here to force the usage of radio fields):
self.form_def = [RadioField(choices=[('1',_(u'Yes')),('0',_(u'No')),('-1',_(u'Ignore'))], default=default)]
When you get the filter class you want. Go to builtin.py.
$ vi filter/builtin.py
In the file head, import the filter class if it is not already done.
ex:
from app.model.filters.filter_text import FilterText
Declare as constant, the filter name.
FILTER_HOSTREGEX = 'host_regex'
Store the filter into the filters dictionnary.
ex:
filters[FILTER_HOSTREGEX] = FilterText(FILTER_HOSTREGEX, _("Hostname"), _("Search field allowing regular expressions and partial matches"), ["host_name"], OP_TILDE)
Be sure having the required display function for the filter type.
vim app/templates/views/filter_fields.html
Ensure that the templates can show filters correctly. Filters are generics, so it is the filters fields types that will determinate how filter will be displayed.
$ vim app/templates/lib/views.html
Migrating the database, that will add new filters field in the filters table. Go to the projet root directory
$ python db_migrate.py
Restart the server and the new filters will appears in the datasource related views.
A snapin consists of a folder with a python file with the same name inside. This file defines a class that inherits from the base class "SnapinBase." It defines a context method to do the processing and return an object to its use in the template of the snapin.
The template is within a "template" folder. There is an html file with the same prefix as the python file and styles.css file.
To have a multilingual snapin, it takes a translation folter within the snapin file folder. It is then the same structure as the Babel files. Howver, in snapin classn, you must define like in the SnapinAbout, a litle code to get the translation in the current language.
Restart the application, the new snapins will be automatically taken into account.
This is the common hiearchy of snapin:
- SnapinExample
- __init__.py
- SnapinExample.py
- template
- SnapinExample.html
- style.css (facultatif)
- translations
- ...
Sageo is multilanguages with the help of Babel and of FlaskBabelEx, a fork of FlaskBabel.
To contribute to translations, please look the Flask-Babel traduction documentation.
We suggest you the software Poedit to translate.