Execute a notificationCommand with multiple users

I understand that by design Icinga will execute one NotificationCommand per user listed into a notification instance.

But is it possible to ask Icinga to execute the notificationCommand only once per notification and get the related users with his custom attributes using runtime macros or similar?

I would appreciate any help, thanks.

Hi,

not that I know of. What’s the idea behind that question?

Cheers,
Michael

Thanks for your reply.

Well, there are some situations that I want to control:

  • Grant to the notificationCommand’s script the control logic to distribute the list of emails per user instead of the Icinga Notification system.
  • Sometimes I want to join all the users address and send them in just one mail. I know that is posible making a notification instance with just one user with multiple addresses. But in that case I’m losing the opportunity to describe each address’ origin and see them from Icingaweb in the host/service’s history.
  • In some other cases I need to perform some actions one time per notification before sending the mail, but in the actual scenario, if a notification instance has 3 users, then those actions will repeat 3 times making incidents difficult to control.

Hi,

ok, then you’d need a “dummy” notification, command and user which fires a script for implementing the logic.

The rest requires some advanced programming techniques inside the DSL, or you’ll manage the user details as custom attribute statically inside e.g. the notification, or dummy user object.

Static details

apply Notification "..." to Service {
  ...
  vars.involved_users = {
     "michi" = "michael@domain.com"
     "patricio" = "patricio@domain.com"
  }
}

Having a dictionary or an array will require you to dump that in a certain way, best would be JSON as string which your script then can read.

object NotificationCommand "..." {
  command = ...

  arguments = {
    "-u" = "$users$"
  }

  vars.users = {{ Json.encode(macro("$notification.vars.involved_users$")) }}
}

Keep specific user objects and collect them

The above NotificationCommand can be re-used for this.

object User "michi" {
  email = "michael@domain.com"
}
object User "patricio" {
  email = "patricio@domain.com"
}
apply Notification "..." to Service {
  ...
  vars.involved_users = {{
     var res = {}

     for (u in get_objects(User)) {
        if (match("*@domain.com", u.email)) {
          res[u.name] = u.email
        }
     }

    return res
  }}

The above may also be abstracted directly into the NotificationCommand object in the vars.users attribute.

Notifications just one

Set interval to 0 then.

References

https://icinga.com/docs/icinga2/latest/doc/18-library-reference/#get_objects
https://icinga.com/docs/icinga2/latest/doc/17-language-reference/#for-loops
https://icinga.com/docs/icinga2/latest/doc/18-library-reference/#match
https://icinga.com/docs/icinga2/latest/doc/18-library-reference/#jsonencode
https://icinga.com/docs/icinga2/latest/doc/17-language-reference/#abbreviated-lambda-syntax
https://icinga.com/docs/icinga2/latest/doc/03-monitoring-basics/#functions-as-custom-attributes

Cheers,
Michael

Hi,
Now, i can join all the users address and send them in just one mail. But, I found that four notifications would be sent when there were four recipients, although join all the users address.
In the above scenario, is there any way to send a notification only once?
I would appreciate any help, thanks.

Hi,

Since you’re new to this topic, how is that configured and how does it look like in the icinga2.log and likewise, the mail log?

Cheers,
Michael

apply Notification “smartcall-search” to Service {
users = service.vars.search_notification.first.smartcall.users
user_groups = service.vars.search_notification.first.smartcall.groups
vars.involved_users = {{
var res = []
if (service.vars.search_notification.first.smartcall.users){
for (name in service.vars.search_notification.first.smartcall.users){
for (u in get_objects(User)){
if (u.name == name){
var temp = {}
temp[u.name] = u.pager
res += [temp]
}
}
}
}
if (service.vars.search_notification.first.smartcall.groups){
for (group in service.vars.search_notification.first.smartcall.groups){
for (u in get_objects(User)){
if (group in u.groups){
var temp = {}
temp[u.name] = u.pager
res += [temp]
}
}
}
}
return res
}}
command = “smartcall-service-notification”
states = [ Critical ]
types = [ Problem ]
interval = service.vars.notification_interval.smartcall
period = “24x7”
assign where service.vars.search_notification.first.smartcall
}
object NotificationCommand “smartcall-service-notification” {
import “plugin-notification-command”
command = [ SysconfDir + “/icinga2/scripts/custom/smartcall-service-notification.py” ]
arguments = {
“-s” = “$smartcall_platform$”
“-u” = “$no$”
}
vars.no = {{ Json.encode(macro("$notification.vars.involved_users$")) }}
env = {
NOTIFICATIONTYPE = “$notification.type$”
SERVICESTATE = “$service.state$”
LONGDATETIME = “$icinga.long_date_time$”
SERVICEDISPLAYNAME = “$service.display_name$”
}
}
apply Service “dkh-search.blender.resp.ok.ratio” {
import “search-service”
vars.tsd_metric = “search.blender.resp.ok.ratio”
vars.tsd_method = “lt”
vars.tsd_aggregator = “min”
vars.tsd_warning = “0.98”
vars.tsd_breaktimes = “3”
vars.tsd_tags += [ “env=dkh”,“hostname=","cluster=” ]
vars.tsd_duration = “195”
vars.search_notification.first.smartcall.users += [ “liujianfei5”,“fanxunan1” ]
vars.tsd_downsample = “avg”
vars.tsd_downsample_window = “30”
vars.search_notification.second.begin = 2h

assign where host.name == “search-host”

}
the configured is above, and in the log, the notification command will be run two times because the number of smartcall users is two

Please format your config snippets with markdown, plain text is barely readable.

# notification
apply Notification "smartcall-search" to Service {
    users = service.vars.search_notification.first.smartcall.users
    user_groups = service.vars.search_notification.first.smartcall.groups
    vars.involved_users = {{
      var res = []
      if (service.vars.search_notification.first.smartcall.users){
        for (name in service.vars.search_notification.first.smartcall.users){
          for (u in get_objects(User)){
            if (u.name == name){
              var temp = {}
              temp[u.name] = u.pager
              res += [temp]
              }
          }
        }
      }
      if (service.vars.search_notification.first.smartcall.groups){
        for (group in service.vars.search_notification.first.smartcall.groups){
          for (u in get_objects(User)){
            if (group in u.groups){
              var temp = {}
              temp[u.name] = u.pager
              res += [temp]
            }
          }
        }
      }
      return res
    }}
    command = "smartcall-service-notification"
    states = [ Critical ]
    types = [ Problem ]
    interval = service.vars.notification_interval.smartcall
    period = "24x7"
    assign where service.vars.search_notification.first.smartcall
}
# command conf
object NotificationCommand “smartcall-service-notification” {
    import “plugin-notification-command”
    command = [ SysconfDir + “/icinga2/scripts/custom/smartcall-service-notification.py” ]
	arguments = {
    “-s” = “$smartcall_platform$”
    “-u” = “$no$”
    }
	vars.no = {{ Json.encode(macro("$notification.vars.involved_users$")) }}
	env = {
	    NOTIFICATIONTYPE = “$notification.type$”
		SERVICESTATE = “$service.state$”
		LONGDATETIME = “$icinga.long_date_time$”
		SERVICEDISPLAYNAME = “$service.display_name$”
		}
	}
# service conf
apply Service “dkh-search.blender.resp.ok.ratio” {
    import “search-service”
    vars.tsd_metric = “search.blender.resp.ok.ratio”
    vars.tsd_method = “lt”
    vars.tsd_aggregator = “min”
    vars.tsd_warning = “0.98”
    vars.tsd_breaktimes = “3”
	vars.tsd_tags += [ “env=dkh”,“hostname=","cluster=” ]
	vars.tsd_duration = “195”
	vars.search_notification.first.smartcall.users += [ “liujianfei5”,“fanxunan1” ]
	vars.tsd_downsample = “avg”
	vars.tsd_downsample_window = “30”
	vars.search_notification.second.begin = 2h
	assign where host.name == “search-host”
}

###QUESTIONS

  • Configuration as shown above,
  • In the log, we can see that the notification command will be run two times because there are two smartcall users. But i have joined all the users address and send them in just one time, so i hope the notification command is run olny one times. What should i can do?

Hi,

these lines still assign multiple users to the notification. Verify that with icinga2 object list --type Notification --name *smartcall-search*.

You’ll need one dummy user to surpass the validation and instead use the joined involved_users custom variable.

Cheers,
Michael

In this way, I can’t get email or phoneNum flexibly through User object.
I still want to use User object to manage users.
Any other suggestions?

Can we see such a user object and how it is used in other notifications?

how to configure “one dummy user” that you say , which can surpass the validation and can join all the users address and send them in just one notification?