zabbix_export:
  version: '7.0'
  template_groups:
    - uuid: 1d12408342854fd5a4436dd6d5d1bd4a
      name: Templates/Telephony
  templates:
    - uuid: 30cc187a4e994c39b07f53d86b5cc6bc
      template: 'Asterisk by HTTP'
      name: 'Asterisk by HTTP'
      description: |
        The template gets Asterisk metrics from AMI by HTTP agent.
        You should enable the mini-HTTP Server, add the option webenabled=yes in the general section of the manager.conf file and create Asterisk Manager user with system and command write permissions within your Asterisk instance.
        Disable the PJSIP driver if you do not use PJSIP or do not have PJSIP endpoints.
        Please, define AMI address in the {$AMI.URL} macro. Also, set the hostname or IP address of the AMI host in the {$AMI.HOST} macro for Zabbix to check Asterisk service status.
        Then you can define {$AMI.USERNAME} and {$AMI.SECRET} macros in the template for using on the host level.
        If there are errors, increase the logging to debug level and see the Zabbix server log.
        
        You can discuss this template or leave feedback on our forum https://www.zabbix.com/forum/zabbix-suggestions-and-feedback/410060-discussion-thread-for-official-zabbix-template-asterisk
        
        Generated by official Zabbix template tool "Templator"
      vendor:
        name: Zabbix
        version: 7.0-0
      groups:
        - name: Templates/Telephony
      items:
        - uuid: 72d074f6bb214ef9884d8cc4b1530ad3
          name: 'Active calls'
          type: DEPENDENT
          key: asterisk.active_calls
          description: 'The number of active calls at the moment.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.active_calls
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: calls
        - uuid: bb9ac1ac188b43239456477e13ae555f
          name: 'Active channels'
          type: DEPENDENT
          key: asterisk.active_channels
          description: 'The number of active channels at the moment.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.active_channels
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: channels
        - uuid: ccfc2a8a5880430196e2c874b66370ca
          name: 'Calls processed'
          type: DEPENDENT
          key: asterisk.calls_processed
          description: 'The number of calls processed after the last service restart.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.calls_processed
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: calls
        - uuid: 196af875a190438abd8de5a6803a550f
          name: 'Calls processed per second'
          type: DEPENDENT
          key: asterisk.calls_processed.rate
          value_type: FLOAT
          description: 'The number of calls processed per second.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.calls_processed
            - type: CHANGE_PER_SECOND
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: calls
        - uuid: 7db3e9cdae3d4bffa7429617e351fce1
          name: 'Get stats'
          type: HTTP_AGENT
          key: asterisk.get_stats
          history: '0'
          value_type: TEXT
          description: 'Asterisk system information in JSON format.'
          preprocessing:
            - type: JAVASCRIPT
              parameters:
                - |
                  var Ami = {
                  	params: {
                  		url: '{$AMI.URL}',
                  		trunk: '{$AMI.TRUNK_REGEXP}'
                  	},
                  	api_request: new HttpRequest(),
                  
                  	request: function (url, action) {
                  		url += action;
                  		Zabbix.log(4, '[ Asterisk ] Sending request: ' + url);
                  		try {
                  			response = Ami.api_request.get(url);
                  		} catch (error) {
                  			Zabbix.log(4, '[ Asterisk ] Get request returned error ' + error);
                  			throw 'Get request returned error ' + error + '. Check debug log for more information.';
                  		}
                  		Zabbix.log(4, '[ Asterisk ] Received response with status code ' +
                  			Ami.api_request.getStatus() + '\n' + response);
                  
                  		if (Ami.api_request.getStatus() !== 200) {
                  			var message = 'Request failed with status code ' + Ami.api_request.getStatus();
                  			if (response !== null) {
                  				if (typeof response.message === 'string') {
                  					message += ': ' + response.message;
                  				}
                  			}
                  
                  			throw message + ' Check debug log for more information.';
                  		}
                  
                  		var match = response.match('Response: (.+)');
                  		if (match !== null && match[1] !== 'Success' && match[1] !== 'Goodbye' && match[1] !== 'Follows') {
                  			var responseText = match[1],
                  				message = 'Request failed with message ' + match[1];
                  
                  			match = response.match('Message: (.+)');
                  			if (match !== null && match[1]) {
                  				var responseMessage = match[1];
                  				message += ': ' + match[1];
                  			}
                  			if (responseText !== 'Error' || responseMessage !== 'No endpoints found') {
                  				throw message + '. Check debug log for more information.';
                  			}
                  		}
                  
                  		return {
                  			status: Ami.api_request.getStatus(),
                  			body: response
                  		};
                  	}
                  };
                  
                  var asterisk = {
                  	version: '',
                  	uptime: 0,
                  	uptime_reload: 0,
                  	active_channels: 0,
                  	active_calls: 0,
                  	calls_processed: 0,
                  	sip: {
                  		trunks: [],
                  		monitored_online: 0,
                  		monitored_offline: 0,
                  		unmonitored_online: 0,
                  		unmonitored_offline: 0,
                  		active_channels: 0,
                  		total: 0
                  	},
                  	iax: {
                  		trunks: [],
                  		online: 0,
                  		offline: 0,
                  		unmonitored: 0,
                  		active_channels: 0,
                  		total: 0
                  	},
                  	pjsip: {
                  		trunks: [],
                  		available: 0,
                  		unavailable: 0,
                  		active_channels: 0,
                  		total: 0
                  	},
                  	queue: {
                  		queues: [],
                  		total: 0
                  	}
                  };
                  
                  function block2Object(text) {
                  	var parts = [],
                  		dict = {};
                  
                  	text = text.replace(/^Output: /gm, '');
                  
                  	text.split('\n').forEach(function (line) {
                  		parts = line.split(':');
                  		if (parts.length > 1) {
                  			dict[parts.shift().trim()] = parts.join(':').trim();
                  		}
                  	})
                  
                  	return dict;
                  }
                  
                  function text2Object(text) {
                  	var blocks = text.split('\r\n\r\n'),
                  		arr = [],
                  		i = 1,
                  		j = blocks.length - 2;
                  
                  	for (i; i < j; i++) {
                  		arr.push(block2Object(blocks[i]));
                  	}
                  
                  	return arr;
                  }
                  
                  function getSipPeers() {
                  	var response = Ami.request(url, 'SIPpeers'),
                  		elements = text2Object(response.body);
                  	asterisk.sip.total = elements.length;
                  	asterisk.sip.trunks = elements.filter(function (element) {
                  		return element.ObjectName.search(Ami.params.trunk) != -1;
                  	});
                  	elements.forEach(function (element) {
                  		if (element.IPaddress === '-none-') {
                  			switch (element.Status) {
                  				case 'Unmonitored':
                  					asterisk.sip.unmonitored_offline++;
                  					break;
                  
                  				case 'UNKNOWN':
                  					asterisk.sip.monitored_offline++;
                  					break;
                  			}
                  		}
                  		else {
                  			if (element.Status === 'Unmonitored') {
                  				asterisk.sip.unmonitored_online++;
                  			}
                  			else {
                  				asterisk.sip.monitored_online++;
                  				if (element.Status.search('^OK') != -1) {
                  					element.Status = element.Status.split(' ')[0];
                  				}
                  			}
                  		}
                  	});
                  	asterisk.sip.trunks.forEach(function (trunk) {
                  		var active_channels = channels.match(new RegExp('[^!J]SIP/' + escapeChars(trunk.ObjectName), 'g'));
                  		trunk.active_channels = (active_channels === null) ? 0 : active_channels.length;
                  		asterisk.sip.active_channels += trunk.active_channels;
                  	});
                  }
                  
                  function getIaxPeerList() {
                  	response = Ami.request(url, 'IAXpeerlist');
                  	elements = text2Object(response.body);
                  	asterisk.iax.total = elements.length;
                  	asterisk.iax.trunks = elements.filter(function (element) {
                  		return element.ObjectName.search(Ami.params.trunk) != -1;
                  	});
                  	elements.forEach(function (element) {
                  		if (element.Status.search('^OK') != -1) {
                  			element.Status = element.Status.split(' ')[0];
                  		}
                  		switch (element.Status) {
                  			case 'Unmonitored':
                  				asterisk.iax.unmonitored++;
                  				break;
                  
                  			case 'UNKNOWN':
                  				asterisk.iax.offline++;
                  				break;
                  		}
                  	});
                  	asterisk.iax.online = asterisk.iax.total - asterisk.iax.offline;
                  	asterisk.iax.trunks.forEach(function (trunk) {
                  		var active_channels = channels.match(new RegExp('[^!](IAX2/' + escapeChars(trunk.ObjectName) +
                  			'|IAX2/' + escapeChars(trunk.ObjectUsername) + ')', 'g'));
                  		trunk.active_channels = (active_channels === null) ? 0 : active_channels.length;
                  		asterisk.iax.active_channels += trunk.active_channels;
                  	});
                  }
                  
                  function getPjsipShowEndpoints() {
                  	response = Ami.request(url, 'PJSIPShowEndpoints');
                  	elements = text2Object(response.body);
                  	asterisk.pjsip.total = elements.length;
                  	asterisk.pjsip.trunks = elements.filter(function (element) {
                  		return element.ObjectName.search(Ami.params.trunk) != -1;
                  	});
                  
                  	elements.forEach(function (element) {
                  		if (element.DeviceState === 'Unavailable') {
                  			asterisk.pjsip.unavailable++;
                  		}
                  	});
                  	asterisk.pjsip.available = asterisk.pjsip.total - asterisk.pjsip.unavailable;
                  	asterisk.pjsip.trunks.forEach(function (trunk) {
                  		var active_channels = channels.match(new RegExp('[^!]PJSIP/' + escapeChars(trunk.ObjectName), 'g'));
                  		trunk.active_channels = (active_channels === null) ? 0 : active_channels.length;
                  		asterisk.pjsip.active_channels += trunk.active_channels;
                  	});
                  }
                  
                  function getQueueSummary() {
                  	response = Ami.request(url, 'QueueSummary');
                  	asterisk.queue.queues = text2Object(response.body);
                  	asterisk.queue.total = asterisk.queue.queues.length;
                  }
                  
                  function escapeChars(str) {
                  	return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
                  }
                  
                  function getUptimeSeconds(text) {
                  	var date = {
                  		years: 0,
                  		weeks: 0,
                  		days: 0,
                  		hours: 0,
                  		minutes: 0,
                  		seconds: 0
                  	};
                  
                  	var fields = {
                  		years: 'years?',
                  		weeks: 'weeks?',
                  		days: 'days?',
                  		hours: 'hours?',
                  		minutes: 'minutes?',
                  		seconds: 'seconds?'
                  	};
                  
                  	Object.keys(fields).forEach(function (field) {
                  		var match = text.match('(\\d+) ' + fields[field]);
                  		if (match !== null && typeof match[1] !== 'undefined') {
                  			date[field] = parseInt(match[1]);
                  		}
                  	});
                  	return date.years * 220752000 + date.weeks * 604800 + date.days * 86400 +
                  		date.hours * 3600 + date.minutes * 60 + date.seconds;
                  }
                  
                  var cookie = value.match(/mansession_id="([0-9A-z]+)"/);
                  if (cookie == null) {
                  	throw 'Cannot find mansession_id with cookie in response.';
                  }
                  
                  var url = Ami.params.url.split('?')[0] + '?action=';
                  
                  Ami.api_request.addHeader('Cookie: mansession_id="' + cookie[1] + '"');
                  
                  var response = Ami.request(url, 'CoreSettings');
                  var coreSettings = block2Object(response.body);
                  if (typeof coreSettings.AsteriskVersion !== 'undefined') {
                  	asterisk.version = coreSettings.AsteriskVersion;
                  }
                  
                  response = Ami.request(url, 'command&command=core%20show%20uptime');
                  var uptime = block2Object(response.body);
                  if (typeof uptime["System uptime"] !== 'undefined') {
                  	asterisk.uptime = getUptimeSeconds(uptime["System uptime"]);
                  }
                  if (typeof uptime["Last reload"] !== 'undefined') {
                  	asterisk.uptime_reload = getUptimeSeconds(uptime["Last reload"]);
                  }
                  
                  response = Ami.request(url, 'command&command=core%20show%20channels%20count');
                  channels = response.body;
                  var fields = {
                  	active_channels: 'active channels?',
                  	active_calls: 'active calls?',
                  	calls_processed: 'calls? processed'
                  };
                  
                  Object.keys(fields).forEach(function (field) {
                  	var match = channels.match('(\\d+) ' + fields[field]);
                  	if (match !== null && typeof match[1] !== 'undefined') {
                  		asterisk[field] = parseInt(match[1]);
                  	}
                  });
                  
                  response = Ami.request(url, 'command&command=core%20show%20channels%20concise');
                  channels = response.body;
                  
                  response = Ami.request(url, 'ListCommands');
                  var list = response.body;
                  if (list.includes('SIPpeers')) {
                  	getSipPeers();
                  }
                  if (list.includes('IAXpeerlist')) {
                  	getIaxPeerList();
                  }
                  if (list.includes('PJSIPShowEndpoints')) {
                  	getPjsipShowEndpoints();
                  }
                  if (list.includes('QueueSummary')) {
                  	getQueueSummary();
                  }
                  
                  try {
                  	response = Ami.request(url, 'Logoff');
                  }
                  catch (e) {}
                  
                  return JSON.stringify(asterisk);
          url: '{$AMI.URL}'
          query_fields:
            - name: action
              value: login
            - name: username
              value: '{$AMI.USERNAME}'
            - name: secret
              value: '{$AMI.SECRET}'
          retrieve_mode: HEADERS
          tags:
            - tag: component
              value: raw
        - uuid: d9900a1f096a4b89a2aa4af89f30b2cc
          name: 'IAX trunks active channels'
          type: DEPENDENT
          key: asterisk.iax.active_channels
          description: 'The total number of IAX trunks active channels.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.active_channels
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: channels
          triggers:
            - uuid: 0ae0a5b6123a42dd9722219e5e5839df
              expression: 'min(/Asterisk by HTTP/asterisk.iax.active_channels,10m)>={$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"IAX"}'
              name: 'Total number of active channels of IAX trunks is too high'
              event_name: 'Total number of active channels of IAX trunks is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"IAX"} for 10m)'
              priority: WARNING
              description: 'The IAX trunks may not be able to process new calls.'
              tags:
                - tag: scope
                  value: performance
        - uuid: 0798cf46d82041e6a7091698c7693ec5
          name: 'IAX offline peers'
          type: DEPENDENT
          key: asterisk.iax.offline
          description: 'The number of offline IAX peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.offline
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: bf741f5560734530be352341071c5984
          name: 'IAX online peers'
          type: DEPENDENT
          key: asterisk.iax.online
          description: 'The number of online IAX peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.online
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: ccb62e9b41da4f20b4ab19e4eecd598b
          name: 'IAX peers'
          type: DEPENDENT
          key: asterisk.iax.total
          description: 'The total number of IAX peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.total
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: cf5c07c1a09b4a10af21292b876fcb20
          name: 'IAX unmonitored peers'
          type: DEPENDENT
          key: asterisk.iax.unmonitored
          description: 'The number of unmonitored IAX peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.unmonitored
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 5ae6135a49764db7b496f5d2378ddd77
          name: 'PJSIP trunks active channels'
          type: DEPENDENT
          key: asterisk.pjsip.active_channels
          description: 'The total number of PJSIP trunks active channels.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.pjsip.active_channels
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: channels
          triggers:
            - uuid: 9b158fe0efb4416cb6ad5d53b38c3e38
              expression: 'min(/Asterisk by HTTP/asterisk.pjsip.active_channels,10m)>={$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"PJSIP"}'
              name: 'Total number of active channels of PJSIP trunks is too high'
              event_name: 'Total number of active channels of PJSIP trunks is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"PJSIP"} for 10m)'
              priority: WARNING
              description: 'The PJSIP trunks may not be able to process new calls.'
              tags:
                - tag: scope
                  value: performance
        - uuid: cc07f186104842aabec3d26dcd4322d2
          name: 'PJSIP available endpoints'
          type: DEPENDENT
          key: asterisk.pjsip.available
          description: 'The number of available PJSIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.pjsip.available
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: fdc888cb355a4b738be8a77354a7ce76
          name: 'PJSIP endpoints'
          type: DEPENDENT
          key: asterisk.pjsip.total
          description: 'The total number of PJSIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.pjsip.total
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 5c10fe1a4bfb4628be20137d0f1ec725
          name: 'PJSIP unavailable endpoints'
          type: DEPENDENT
          key: asterisk.pjsip.unavailable
          description: 'The number of unavailable PJSIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.pjsip.unavailable
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 2df0dca89a744e86b4f5a2cec673d427
          name: 'SIP trunks active channels'
          type: DEPENDENT
          key: asterisk.sip.active_channels
          description: 'The total number of SIP trunks active channels.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.active_channels
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: channels
          triggers:
            - uuid: d2fde5d26d284a129346a12ba0949b60
              expression: 'min(/Asterisk by HTTP/asterisk.sip.active_channels,10m)>={$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"SIP"}'
              name: 'Total number of active channels of SIP trunks is too high'
              event_name: 'Total number of active channels of SIP trunks is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"SIP"} for 10m)'
              priority: WARNING
              description: 'The SIP trunks may not be able to process new calls.'
              tags:
                - tag: scope
                  value: performance
        - uuid: fb08ec8d143a41a097f8652c8261bad8
          name: 'SIP monitored offline'
          type: DEPENDENT
          key: asterisk.sip.monitored_offline
          description: 'The number of monitored offline SIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.monitored_offline
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 23744b0a04b54637a7dbe1c7f8f5200f
          name: 'SIP monitored online'
          type: DEPENDENT
          key: asterisk.sip.monitored_online
          description: 'The number of monitored online SIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.monitored_online
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: fb78998a342942ac942a7e1632b98208
          name: 'SIP peers'
          type: DEPENDENT
          key: asterisk.sip.total
          description: 'The total number of SIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.total
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: ae21f8c13063402d9eece400a18c6167
          name: 'SIP unmonitored offline'
          type: DEPENDENT
          key: asterisk.sip.unmonitored_offline
          description: 'The number of unmonitored offline SIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.unmonitored_offline
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 1cd5fb5232ca4f4398f85d959ac11b2c
          name: 'SIP unmonitored online'
          type: DEPENDENT
          key: asterisk.sip.unmonitored_online
          description: 'The number of unmonitored online SIP peers.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.unmonitored_online
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: peers
        - uuid: 9c64cb54c2c541c1862558dcf8c6e3a3
          name: 'Total queues'
          type: DEPENDENT
          key: asterisk.total_queues
          description: 'The number of configured queues.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.queue.total
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: queues
        - uuid: 8395ab5b70a7433eb508c513995988bb
          name: Uptime
          type: DEPENDENT
          key: asterisk.uptime
          value_type: FLOAT
          units: uptime
          description: 'The system uptime expressed in the following format: "N days, hh:mm:ss".'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.uptime
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: system
          triggers:
            - uuid: 35ca01e504a548db9d4db8be1390d6b9
              expression: 'nodata(/Asterisk by HTTP/asterisk.uptime,30m)=1'
              name: 'Failed to fetch AMI page'
              event_name: 'Failed to fetch AMI page (or no data for 30m)'
              priority: WARNING
              description: 'Zabbix has not received any data for items for the last 30 minutes.'
              manual_close: 'YES'
              dependencies:
                - name: 'Service is down'
                  expression: 'last(/Asterisk by HTTP/net.tcp.service["tcp","{$AMI.HOST}","{$AMI.PORT}"])=0'
              tags:
                - tag: scope
                  value: availability
            - uuid: 100d38b62c1d4ce298a9fadfbab19e4c
              expression: 'last(/Asterisk by HTTP/asterisk.uptime)<10m'
              name: 'Host has been restarted'
              event_name: '{HOST.NAME} has been restarted (uptime < 10m)'
              priority: INFO
              description: 'Uptime is less than 10 minutes.'
              manual_close: 'YES'
              tags:
                - tag: scope
                  value: notice
        - uuid: 86e23b5b9fd64e6e840588d25921fcbf
          name: 'Uptime after reload'
          type: DEPENDENT
          key: asterisk.uptime_reload
          value_type: FLOAT
          units: uptime
          description: 'System uptime after a config reload in ''N days, hh:mm:ss'' format.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.uptime_reload
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: system
          triggers:
            - uuid: 4e99b65188264ba1aa80e24662f9b3cd
              expression: 'last(/Asterisk by HTTP/asterisk.uptime_reload)<10m'
              name: 'has been reloaded'
              event_name: 'has been reloaded (uptime < 10m)'
              priority: INFO
              description: 'Uptime is less than 10 minutes.'
              manual_close: 'YES'
              tags:
                - tag: scope
                  value: notice
        - uuid: 8ed124c5d61541c0ab1dcc3491fb05c6
          name: Version
          type: DEPENDENT
          key: asterisk.version
          value_type: CHAR
          description: 'Service version'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.version
          master_item:
            key: asterisk.get_stats
          tags:
            - tag: component
              value: application
          triggers:
            - uuid: f1a260626ae6446d89e1e725e14c1098
              expression: 'last(/Asterisk by HTTP/asterisk.version,#1)<>last(/Asterisk by HTTP/asterisk.version,#2) and length(last(/Asterisk by HTTP/asterisk.version))>0'
              name: 'Version has changed'
              event_name: 'Version has changed (new version: {ITEM.VALUE})'
              priority: INFO
              description: 'The Asterisk version has changed. Acknowledge to close the problem manually.'
              manual_close: 'YES'
              tags:
                - tag: scope
                  value: notice
        - uuid: 09102393dc6a4ac598f02d95801c6ca0
          name: 'Service response time'
          type: SIMPLE
          key: 'net.tcp.service.perf["tcp","{$AMI.HOST}","{$AMI.PORT}"]'
          value_type: FLOAT
          units: s
          description: 'Asterisk Manager API performance.'
          tags:
            - tag: component
              value: network
          triggers:
            - uuid: dbc74502be01498194003dc1a3d90014
              expression: 'min(/Asterisk by HTTP/net.tcp.service.perf["tcp","{$AMI.HOST}","{$AMI.PORT}"],5m)>{$AMI.RESPONSE_TIME.MAX.WARN}'
              name: 'Service response time is too high'
              event_name: 'Service response time is too high (over {$AMI.RESPONSE_TIME.MAX.WARN} for 5m)'
              priority: WARNING
              manual_close: 'YES'
              dependencies:
                - name: 'Service is down'
                  expression: 'last(/Asterisk by HTTP/net.tcp.service["tcp","{$AMI.HOST}","{$AMI.PORT}"])=0'
              tags:
                - tag: scope
                  value: performance
        - uuid: 58e18df6a5534395bf74d3babdb73170
          name: 'Service status'
          type: SIMPLE
          key: 'net.tcp.service["tcp","{$AMI.HOST}","{$AMI.PORT}"]'
          description: 'Asterisk Manager API port availability.'
          valuemap:
            name: 'Service state'
          preprocessing:
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 10m
          tags:
            - tag: component
              value: health
            - tag: component
              value: network
          triggers:
            - uuid: 1fa3370fa93f4d07a2c470f993096554
              expression: 'last(/Asterisk by HTTP/net.tcp.service["tcp","{$AMI.HOST}","{$AMI.PORT}"])=0'
              name: 'Service is down'
              priority: AVERAGE
              manual_close: 'YES'
              tags:
                - tag: scope
                  value: availability
      discovery_rules:
        - uuid: 3e7facc25a344cec8e384e8a9f8b372a
          name: 'IAX peers discovery'
          type: DEPENDENT
          key: asterisk.iax_peers.discovery
          item_prototypes:
            - uuid: 72d71ec4fa2b4e88a03d25e3bbe8771a
              name: 'IAX trunk "{#OBJECTNAME}": Active channels'
              type: DEPENDENT
              key: 'asterisk.iax.trunk.active_channels[{#OBJECTNAME}]'
              description: 'The total number of active IAX trunk channels.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.active_channels
              master_item:
                key: 'asterisk.iax.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: channels
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: e2a6c7a9b6234e2aae20c9aa480f9ef1
                  expression: 'min(/Asterisk by HTTP/asterisk.iax.trunk.active_channels[{#OBJECTNAME}],10m)>={$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"}'
                  name: 'IAX trunk "{#OBJECTNAME}": Number of the IAX trunk "{#OBJECTNAME}" active channels is too high'
                  event_name: 'IAX trunk "{#OBJECTNAME}": Number of the IAX trunk "{#OBJECTNAME}" active channels is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"} for 10m)'
                  priority: WARNING
                  description: 'The IAX trunk may not be able to process new calls.'
                  tags:
                    - tag: scope
                      value: performance
            - uuid: 9c6554be77234ed98cee4a49e23506b7
              name: 'IAX trunk "{#OBJECTNAME}": Get IAX trunk'
              type: DEPENDENT
              key: 'asterisk.iax.trunk.get[{#OBJECTNAME}]'
              history: '0'
              value_type: TEXT
              description: 'Raw data for an IAX trunk.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.iax.trunks[?(@.ObjectName==''{#OBJECTNAME}'')].first()'
              master_item:
                key: asterisk.get_stats
              tags:
                - tag: component
                  value: raw
                - tag: trunk
                  value: '{#OBJECTNAME}'
            - uuid: bbde7e898b4b4d34b27308d6ddaf86fc
              name: 'IAX trunk "{#OBJECTNAME}": Status'
              type: DEPENDENT
              key: 'asterisk.iax.trunk.status[{#OBJECTNAME}]'
              value_type: CHAR
              description: |
                IAX trunk status. Here are the possible states that a device state may have:
                Unmonitored
                UNKNOWN
                UNREACHABLE
                OK
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.Status
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 1h
              master_item:
                key: 'asterisk.iax.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: health
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: db595245acef4ec9b771c266c14100d2
                  expression: 'last(/Asterisk by HTTP/asterisk.iax.trunk.status[{#OBJECTNAME}])="UNKNOWN" or last(/Asterisk by HTTP/asterisk.iax.trunk.status[{#OBJECTNAME}])="UNREACHABLE"'
                  name: 'IAX trunk "{#OBJECTNAME}": IAX trunk {#OBJECTNAME} has a state {ITEM.VALUE}'
                  priority: AVERAGE
                  description: 'The IAX trunk is unable to establish a connection with a neighbor due to network issues or incorrect configuration.'
                  tags:
                    - tag: scope
                      value: availability
          master_item:
            key: asterisk.get_stats
          lld_macro_paths:
            - lld_macro: '{#OBJECTNAME}'
              path: $.ObjectName
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.iax.trunks
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 1h
        - uuid: 1a123ca04c7544bfa823a39b8a9fe84c
          name: 'PJSIP endpoints discovery'
          type: DEPENDENT
          key: asterisk.pjsip_endpoints.discovery
          item_prototypes:
            - uuid: ec8220a1aa814112908337a009f6fcac
              name: 'PJSIP trunk "{#OBJECTNAME}": Active channels'
              type: DEPENDENT
              key: 'asterisk.pjsip.trunk.active_channels[{#OBJECTNAME}]'
              description: 'The total number of active PJSIP trunk channels.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.active_channels
              master_item:
                key: 'asterisk.pjsip.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: channels
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: f192d555011c42c28c6a8f52c0388fe1
                  expression: 'min(/Asterisk by HTTP/asterisk.pjsip.trunk.active_channels[{#OBJECTNAME}],10m)>={$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"}'
                  name: 'PJSIP trunk "{#OBJECTNAME}": Number of the PJSIP trunk "{#OBJECTNAME}" active channels is too high'
                  event_name: 'PJSIP trunk "{#OBJECTNAME}": Number of the PJSIP trunk "{#OBJECTNAME}" active channels is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"} for 10m)'
                  priority: WARNING
                  description: 'The PJSIP trunk may not be able to process new calls.'
                  tags:
                    - tag: scope
                      value: performance
            - uuid: c364b2ac50344372b155cbb98d9a7afe
              name: 'PJSIP trunk "{#OBJECTNAME}": Device state'
              type: DEPENDENT
              key: 'asterisk.pjsip.trunk.devicestate[{#OBJECTNAME}]'
              value_type: CHAR
              description: |
                PJSIP trunk status. Here are the possible states that a device state may have:
                Unavailable
                Not in use
                In use
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.DeviceState
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 1h
              master_item:
                key: 'asterisk.pjsip.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: health
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: 6f31d886d6954b82874d38646b233689
                  expression: 'last(/Asterisk by HTTP/asterisk.pjsip.trunk.devicestate[{#OBJECTNAME}])="Unavailable"'
                  name: 'PJSIP trunk "{#OBJECTNAME}": PJSIP trunk {#OBJECTNAME} has a state Unavailable'
                  priority: AVERAGE
                  description: 'The PJSIP trunk is unable to establish a connection with a neighbor due to network issues or incorrect configuration.'
                  tags:
                    - tag: scope
                      value: availability
            - uuid: 0919612d88744ec7ad47b11ccfad1f4e
              name: 'PJSIP trunk "{#OBJECTNAME}": Get PJSIP trunk'
              type: DEPENDENT
              key: 'asterisk.pjsip.trunk.get[{#OBJECTNAME}]'
              history: '0'
              value_type: TEXT
              description: 'Raw data for a PJSIP trunk.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.pjsip.trunks[?(@.ObjectName==''{#OBJECTNAME}'')].first()'
              master_item:
                key: asterisk.get_stats
              tags:
                - tag: component
                  value: raw
                - tag: trunk
                  value: '{#OBJECTNAME}'
          master_item:
            key: asterisk.get_stats
          lld_macro_paths:
            - lld_macro: '{#OBJECTNAME}'
              path: $.ObjectName
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.pjsip.trunks
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 1h
        - uuid: 5a936a95d62f4b50a4f3db112a3e041f
          name: 'Queues discovery'
          type: DEPENDENT
          key: asterisk.queues.discovery
          item_prototypes:
            - uuid: c16d9df72ba749369726d4cfcc8b4f40
              name: '"{#QUEUE}": Available'
              type: DEPENDENT
              key: 'asterisk.queue.available[{#QUEUE}]'
              description: 'The number of available queue members.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.Available
              master_item:
                key: 'asterisk.queue.get[{#QUEUE}]'
              tags:
                - tag: component
                  value: members
                - tag: queue
                  value: '{#QUEUE}'
            - uuid: c271c7d76b2e49dea386bb08d60307d0
              name: '"{#QUEUE}": Callers'
              type: DEPENDENT
              key: 'asterisk.queue.callers[{#QUEUE}]'
              description: 'The number incoming calls in queue.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.Callers
              master_item:
                key: 'asterisk.queue.get[{#QUEUE}]'
              tags:
                - tag: component
                  value: calls
                - tag: queue
                  value: '{#QUEUE}'
              trigger_prototypes:
                - uuid: 4f72c6a755be465287f36b8b12d3175b
                  expression: 'min(/Asterisk by HTTP/asterisk.queue.callers[{#QUEUE}],10m)>{$AMI.QUEUE_CALLERS.MAX.WARN:"{#QUEUE}"}'
                  name: '"{#QUEUE}": Number of callers in the queue "{#QUEUE}" is too high'
                  event_name: '"{#QUEUE}": Number of callers in the queue "{#QUEUE}" is too high (over {$AMI.QUEUE_CALLERS.MAX.WARN:"{#QUEUE}"} for 10m)'
                  priority: WARNING
                  description: 'There is a large number of calls in the queue.'
                  tags:
                    - tag: scope
                      value: performance
            - uuid: 49bc8af136204b8bae9d7527d04b15bc
              name: '"{#QUEUE}": Get queue'
              type: DEPENDENT
              key: 'asterisk.queue.get[{#QUEUE}]'
              history: '0'
              value_type: TEXT
              description: 'Raw data for a queue.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.queue.queues[?(@.Queue==''{#QUEUE}'')].first()'
              master_item:
                key: asterisk.get_stats
              tags:
                - tag: component
                  value: raw
                - tag: queue
                  value: '{#QUEUE}'
            - uuid: 8319ec55cf6f4e8590f180f1a81f37ed
              name: '"{#QUEUE}": Logged in'
              type: DEPENDENT
              key: 'asterisk.queue.loggedin[{#QUEUE}]'
              description: 'The number of queue members.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.LoggedIn
              master_item:
                key: 'asterisk.queue.get[{#QUEUE}]'
              tags:
                - tag: component
                  value: members
                - tag: queue
                  value: '{#QUEUE}'
          master_item:
            key: asterisk.get_stats
          lld_macro_paths:
            - lld_macro: '{#QUEUE}'
              path: $.Queue
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.queue.queues
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 1h
        - uuid: 675fc5b11cb1482db0c539dfb9100e75
          name: 'SIP peers discovery'
          type: DEPENDENT
          key: asterisk.sip_peers.discovery
          item_prototypes:
            - uuid: 9043578864494b13b249ee7bdf13820d
              name: 'SIP trunk "{#OBJECTNAME}": Active channels'
              type: DEPENDENT
              key: 'asterisk.sip.trunk.active_channels[{#OBJECTNAME}]'
              description: 'The total number of active SIP trunk channels.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.active_channels
              master_item:
                key: 'asterisk.sip.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: channels
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: 51820b1326f84f51ba0e561946275133
                  expression: 'min(/Asterisk by HTTP/asterisk.sip.trunk.active_channels[{#OBJECTNAME}],10m)>={$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"}'
                  name: 'SIP trunk "{#OBJECTNAME}": Number of the SIP trunk "{#OBJECTNAME}" active channels is too high'
                  event_name: 'SIP trunk "{#OBJECTNAME}": Number of the SIP trunk "{#OBJECTNAME}" active channels is too high (over {$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN:"{#OBJECTNAME}"} for 10m)'
                  priority: WARNING
                  description: 'The SIP trunk may not be able to process new calls.'
                  tags:
                    - tag: scope
                      value: performance
            - uuid: a9532680f08445dd9a1bb37e2e2c44c5
              name: 'SIP trunk "{#OBJECTNAME}": Get SIP trunk'
              type: DEPENDENT
              key: 'asterisk.sip.trunk.get[{#OBJECTNAME}]'
              history: '0'
              value_type: TEXT
              description: 'Raw data for a SIP trunk.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.sip.trunks[?(@.ObjectName==''{#OBJECTNAME}'')].first()'
              master_item:
                key: asterisk.get_stats
              tags:
                - tag: component
                  value: raw
                - tag: trunk
                  value: '{#OBJECTNAME}'
            - uuid: df33da749e874f55be5f0c33cd201f62
              name: 'SIP trunk "{#OBJECTNAME}": Status'
              type: DEPENDENT
              key: 'asterisk.sip.trunk.status[{#OBJECTNAME}]'
              value_type: CHAR
              description: |
                SIP trunk status. Here are the possible states that a device state may have:
                Unmonitored
                UNKNOWN
                UNREACHABLE
                OK
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.Status
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 1h
              master_item:
                key: 'asterisk.sip.trunk.get[{#OBJECTNAME}]'
              tags:
                - tag: component
                  value: health
                - tag: trunk
                  value: '{#OBJECTNAME}'
              trigger_prototypes:
                - uuid: 39cac88e9263470da6e4b1a08f806c58
                  expression: 'last(/Asterisk by HTTP/asterisk.sip.trunk.status[{#OBJECTNAME}])="UNKNOWN" or last(/Asterisk by HTTP/asterisk.sip.trunk.status[{#OBJECTNAME}])="UNREACHABLE"'
                  name: 'SIP trunk "{#OBJECTNAME}": SIP trunk {#OBJECTNAME} has a state {ITEM.VALUE}'
                  priority: AVERAGE
                  description: 'The SIP trunk is unable to establish a connection with a neighbor due to network issues or incorrect configuration.'
                  tags:
                    - tag: scope
                      value: availability
          master_item:
            key: asterisk.get_stats
          lld_macro_paths:
            - lld_macro: '{#OBJECTNAME}'
              path: $.ObjectName
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.sip.trunks
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 1h
      tags:
        - tag: class
          value: voip
        - tag: target
          value: asterisk
      macros:
        - macro: '{$AMI.HOST}'
          value: '<SET AMI HOST>'
          description: 'The hostname or IP address of the Asterisk Manager API host.'
        - macro: '{$AMI.PORT}'
          value: '5038'
          description: 'AMI port number for checking service availability.'
        - macro: '{$AMI.QUEUE_CALLERS.MAX.WARN}'
          value: '10'
          description: 'The maximum number of callers in a queue for trigger expression.'
        - macro: '{$AMI.RESPONSE_TIME.MAX.WARN}'
          value: 10s
          description: 'The Asterisk Manager API page maximum response time in seconds for trigger expression.'
        - macro: '{$AMI.SECRET}'
          value: zabbix
          description: 'The Asterisk Manager secret.'
        - macro: '{$AMI.TRUNK_ACTIVE_CHANNELS.MAX.WARN}'
          value: '28'
          description: 'The maximum number of busy channels of a trunk for trigger expression.'
        - macro: '{$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"IAX"}'
          value: '28'
          description: 'The total maximum number of busy channels of IAX trunks for trigger expression.'
        - macro: '{$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"PJSIP"}'
          value: '28'
          description: 'The total maximum number of busy channels of PJSIP trunks for trigger expression.'
        - macro: '{$AMI.TRUNK_ACTIVE_CHANNELS_TOTAL.MAX.WARN:"SIP"}'
          value: '28'
          description: 'The total maximum number of busy channels of SIP trunks for trigger expression.'
        - macro: '{$AMI.TRUNK_REGEXP}'
          value: trunk
          description: 'The regexp for the identification of trunk peers.'
        - macro: '{$AMI.URL}'
          value: 'http://asterisk:8088/asterisk/rawman'
          description: 'The Asterisk Manager API URL in the format `<scheme>://<host>:<port>/<prefix>/rawman`.'
        - macro: '{$AMI.USERNAME}'
          value: zabbix
          description: 'The Asterisk Manager name.'
      valuemaps:
        - uuid: d6e38832f2d44ec0bf6761e36fd7668f
          name: 'Service state'
          mappings:
            - value: '0'
              newvalue: Down
            - value: '1'
              newvalue: Up
  graphs:
    - uuid: 92b561a0aee24da9a7d9875f2293316d
      name: 'Asterisk: Calls stats'
      graph_items:
        - color: 199C0D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.active_channels
        - sortorder: '1'
          color: F63100
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.active_calls
        - sortorder: '2'
          color: 00611C
          yaxisside: RIGHT
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.calls_processed.rate
    - uuid: 0e5d56155a1240108a4ffc2f3dc041be
      name: 'Asterisk: IAX peers'
      graph_items:
        - color: 199C0D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.iax.active_channels
        - sortorder: '1'
          color: F63100
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.iax.online
        - sortorder: '2'
          color: 00611C
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.iax.offline
        - sortorder: '3'
          color: F7941D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.iax.unmonitored
    - uuid: fd5b051daaf64df89856bec400bbc3a0
      name: 'Asterisk: PJSIP peers'
      graph_items:
        - color: 199C0D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.pjsip.active_channels
        - sortorder: '1'
          color: F63100
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.pjsip.available
        - sortorder: '2'
          color: 00611C
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.pjsip.unavailable
    - uuid: 2781590218fe4cc9ade68446e5d11aa2
      name: 'Asterisk: SIP peers'
      graph_items:
        - color: 199C0D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.sip.active_channels
        - sortorder: '1'
          color: F63100
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.sip.monitored_online
        - sortorder: '2'
          color: 00611C
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.sip.monitored_offline
        - sortorder: '3'
          color: F7941D
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.sip.unmonitored_online
        - sortorder: '4'
          color: FC6EA3
          item:
            host: 'Asterisk by HTTP'
            key: asterisk.sip.unmonitored_offline
