WebUI integration with Shinken

The WebUI is an external broker module. So it’s an external process launched by the broker that “eats” broks (broker messages) from the brokers. So it can get all broks if you place this broker in your top level realm.

The WebUI does not use a database to get data. Instead, it use a “regenerator” object that will eat each broks, and will “recreate” all Hosts/Services/Contacts objects as if the code was in the scheduler daemon. So basically, WebUI and pages always reflect the CURRENT state of hosts/services objects.

The WebUI http layer is managed by bottle.py. It’s a small but powerful framework.

How does the WebUI function globally ?

There a 2 Threads running:
  • the main thread is the bottle.py (http) listener. It will use the best backend it finds. We recommend using python-paste. If it does not find one, it will use the default swsgi. Paste is multi-thread, swsgi is mon-thread, so please use paste if you want to avoid locking problems.
  • the 2nd thread is the regenerator one. It only gets broks and gives them to the regenerator object.

There is a lock system between the threads. You can have N Http requests in progress without problem, but during this time the renererator one will wait. During execution of the regenerator, no requests are processed. This is not considered a problem, as the regenerator is very quick, and there is only a 1s lock for a 7k service conf loading, so it’s not a huge problem.

What is a WebUI User?

A WebUI user is a contact. A true contact object. You must match a contact name for your user.

To create a new page?

All pages are in the shinken/webui/plugins directory. Each “part” has it’s own directory. A part (like the eltdetail, element detail) can have more than one “page” (like /host or /service for eltdetail).

From here we will supose you want to create a “/contact” page.

You can copy the dummy example in the plugins directory into a contact directory.

You need to change the contact/dummy.py file into a contact/contact.py file, because the webui will search for a dir/dir.py file to “load”.


Templates are HTML with some Python code in it in the plugins/*/views direcotry for specific templates, and the “global layout” (menu and all common part) in the webui/views directory.

Your template must call the template layout (layout.tpl in the webui/views directory) wit ha “rebase” call.

If you put the rebase call at the beginning of your template, all there is below will be place “inside” the layout that will call the common javascripts and css, make the menu adn then call your html/python code.

The rebase call can take arguments. You MUST give it:
  • user: the user you give it in the return dict of your .py code
Then all is optional:
  • title: title of the page
  • top_right_banner_state: int, global state with clouds to put in your top right page. Look at the problem.tpl code for an example.
  • js and css list: list of YOUR specific javascript or css to call AFTER the common ones.
  • refresh: boolean, set the refresh to 60s or do not refresh at all
  • menu_part: will put the little “^” under this part of the menu.

Example of a call, taken from the problems view:

rebase layout title='All problems', top_right_banner_state=top_right_banner_state, js=['problems/js/accordion.js', 'problems/js/autocompleter.js', 'p\
roblems/js/autocompleter.Request.js', 'problems/js/autocompleterObserver.js'], css=['problems/css/accordion.css', 'problems/css/pagenavi.css', 'proble\
ms/css/autocompleter.css', 'problems/css/perfometer.css'], refresh=True, menu_part='/'+page, user=user

Call Python objects in your templates

Your templates are mainly HTML code. But of course you can call python code in it. The dict you returns in the plugin.py call will be available in this page.

For example, the my_host variable will be available in the page with the host object you find (or None if your give it a bad name of course). Then you can “call” python with for example here to show the host_name: <span>My host name is *my_host.host_name* </span> is a way in the templates to “call a variable or function” that will return a string, here the host_name.

If the function or property you call must return HTML code that SHOULD be output as it, without “protection”, you must put a ! before your call.

Let use an example where the output value of an host is in fact an html output. If you use the code my_host.output, bottle.py will “protect” the html generated by escaping the string, and change <> characters with escaped value. You can change this by calling my_host.output. Of course, it’s a security problem if the output is with a javascript code...

You can also “loop” or put “if” in your template. You just need to put your code with a % before. Like

%for i in xrange(1, 10):
  My valus is  {{i}}

You must put the %end here, the indentation will NOT be enougth, sorry.

For an if it’s also easy:

%if host.active_checks_enabled:
  The host got active checks enabled
  The host DO NOT have active check enabled

Which javascript lib are you using?

It’s mootools 1.3 with all options :)

What to do?

  • Finish the /mobile part
  • List of current alerts
  • Host info
  • Host status
  • Host interfaces
  • Hostgroup status
  • dashboard hierachique with states, and BP
  • Nagvis
  • add bp in nagvis auto-map
  • event sources
  • correlation
  • pre-filtering/enrichment
  • user profile
  • host/srv conf
Read the Docs v: documentation
On Read the Docs
Project Home

Free document hosting provided by Read the Docs.