The main role of this feature is to allow users to have in one "indicator" the aggregation of other states. This indicator can provide a unique view for users focused on different roles.
Typical roles:
Let's take a simple example of a service delivery role for an ERP application. It mainly consists of the following IT components:
These IT components (Hosts in this example) will be the basis for the ERP service.
With business rules, you can have an "indicator" representing the "aggregated service" state for the ERP service! Shinken already checks all of the IT components one by one including processing for root cause analysis from a host and service perspective.
A Cluster have the same notification logic than the hosts. This means you can have contacts that will receive only the relevant notifications based on their role.
Here is a configuration for the ERP rule:
(srv-oracle-1 | srv-oracle-2) & (srv-http-1 | srv-http-2) & (srv-loadbalancer-1 | srv-loadbalancer-2) |

In some cases, you know that in a cluster of N elements, you need at least X of them to run OK. This is easily defined, you just need to use the "X of:" operator.
Here is an example of the same ERP but with 3 http web servers, and you need at least 2 of them (to handle the load):
(srv-oracle-1 | srv-oracle-2) & (2 of: srv-http-1 & srv-http-2 & srv-http-3) & (srv-loadbalancer-1 | srv-loadbalancer-2) |
The X of: expression may be configured different values depending on the needs. The supported expressions are described below:
Example:
(srv-oracle-1 | srv-oracle-2) & (srv-loadbalancer-1 | srv-loadbalancer-2) & 95% of: g:frontend
=============
You can define a not state rule. It can be useful for active/passive setups for example. You just need to add a ! before your element name.
Example:
::
define service{
use generic-service
host_name servicedelivery
service_description Cluster_state
check_command bp_rule!(h1,database1 & !h2,database2)
}
Aggregated state will be ok if database1 is ok and database2 is warning or critical (stopped).
=======================
In the ``Xof:`` way the only case where you got a "warning" (="degraded but not dead") it's when all your elements are in warning. But you should want to be in warning if 1 or your 3 http server is critical: the service is still running, but in a degraded state.
For this you can use the extended operator *X,Y,Zof:*
X: number min of OK to get an overall OK state
Y: number min of WARNING to get an overall WARNING state
Z: number min of CRITICAL to get an overall CRITICAL state
State processing will be done the following order:
is Ok possible?
is critical possible?
is warning possible?
if none is possible, set OK.
Here are some example for business rules about 5 services A, B, C, D and E. Like 5,1,1of:A|B|C|D|E
Example 1
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Warn Ok Ok Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
4of: --> Ok
5,1,1of: --> Warning
5,2,1of: --> Ok
Example 2
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Warn Warn Ok Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
4of: --> Warning
3of: --> Ok
4,1,1of: --> Warning
Example 3
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Crit Crit Ok Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
4of: --> Critical
3of: --> Ok
4,1,1of: --> Critical
Example 4
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Warn Crit Ok Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
4of: --> Critical
4,1,1of: --> Critical
Example 5
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Warn Warn Crit Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
2of: --> Ok
4,1,1of: --> Critical
Example 6
----------
===== ===== ===== ===== =====
**A***B***C***D***E**
Warn Crit Crit Ok Ok
===== ===== ===== ===== =====
Rules and overall states:
2of: --> Ok
2,4,4of: --> Ok
4,1,1of: --> Critical
4,1,2of: --> Critical
4,1,3of: --> Warning
--------------
Let's look at some classic setups, for MAX elements.
ON/OFF setup: MAXof: <=> MAX,MAX,MAXof:
Warning as soon as problem, and critical if all criticals: MAX,1,MAXof:
Worse state: MAX,1,1
==============================
Sometimes, you do not want to specify explicitly the hosts/services contained in a business rule, but prefer use a grouping expression such as *hosts from the hostgroup xxx*, *services holding lablel yyyor *hosts which name matches regex zzz*.
To do so, it is possible to use a *grouping expressionwhich is expanded into hosts or services. The supported expressions use the following syntax:
::
flag:expression
The flag is a single character qualifying the expansion type. The supported types (and associated flags) are described in the table below.
-----------
===== ================================== =========== =========================
**F***Expansion***Example***Equivalent to**
g Content of the hostgroup g:webs web-srv1 & web-srv2 & ...
l Hosts which are holding label l:front web-srv1 & db-srv1 & ...
r Hosts which name matches regex r:^web web-srv1 & web-srv2 & ...
t Hosts which are holding tag t:http web-srv1 & web-srv2 & ...
===== ================================== =========== =========================
--------------
===== ============================================ ============= ===================================
**F***Expansion***Example***Equivalent to**
g Content of the servicegroup g:web web-srv1,HTTP & web-srv2,HTTP & ...
l Services which are holding label l:front web-srv1,HTTP & db-srv1,MySQL & ...
r Services which description matches regex r:^HTTPS? web-srv1,HTTP & db-srv2,HTTPS & ...
t Services which are holding tag t:http web-srv1,HTTP & db-srv2,HTTPS & ...
===== ============================================ ============= ===================================
**Labels*are arbitrary names which may be set on any host or service using the ``label`` directive.
**Tags*are the template names inherited by hosts or services, generally coming from packs.
It is possible to combine both **host*and **service*expansion expression to build complex business rules.
.. note:: A business rule expression always has to be made of a host expression (selector if you prefer)
AND a service expression (still selector) separated by a coma when looking at service status.
If not so, there is no mean to distinguish a host status from a service status in the expression.
In servicegroup flag case, as you do not want to apply any filter on the host (you want ALL services which are member of the XXX service group, whichever host they are bound to),
you may use the host selector expression. The correct expression syntax should be:
``bp_rule!*,g:my-servicegroup``
The same rule applies to other service selectors (l, r, t, and so on).
Examples of combined expansion expression
-----------------------------------------
You want to build a business rule including all web servers composing the application frontend.
::
l:front,r:HTTPS?
which is equivalent to:
web-srv1,HTTP & web-srv3,HTTPS
You may obviously combine expression expansion with standard expressions.
::
l:front,h:HTTPS? & db-srv1,MySQL
which is equivalent to:
(web-srv1,HTTP & web-srv3,HTTPS) & db-srv1,MySQL