# Cisco Meraki dashboard by HTTP ## Overview For Zabbix version: 6.0 and higher The template to monitor Cisco Meraki dashboard by Zabbix that works without any external scripts. Most of the metrics are collected in one go, thanks to Zabbix bulk data collection. This template was tested on: - Cisco Meraki API, version 1.24.0 ## Setup > See [Zabbix template operation](https://www.zabbix.com/documentation/6.0/manual/config/templates_out_of_the_box/http) for basic instructions. You must set {$MERAKI.TOKEN} and {$MERAKI.API.URL} macros. You have to create Meraki token in Meraki dashboard and use it in {$MERAKI.TOKEN} macro. Read detailed instructions how to create token in Meraki documentation [documentation](https://developer.cisco.com/meraki/api-latest/#!authorization/authorization) Set Meraki dashboard URl for {$MERAKI.API.URL}. e.g. api.meraki.com/api/v1 ## Zabbix configuration No specific Zabbix configuration is required. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$MERAKI.API.URL} |
Cisco Meraki Dashboard API URL. e.g api.meraki.com/api/v1
|`api.meraki.com/api/v1` | |{$MERAKI.DEVICE.NAME.MATCHES} |This macro is used in devices discovery. Can be overridden on the host or linked template level.
|`.+` | |{$MERAKI.DEVICE.NAME.NOT_MATCHES} |This macro is used in devices discovery. Can be overridden on the host or linked template level.
|`CHANGE_IF_NEEDED` | |{$MERAKI.HTTP_PROXY} |HTTP proxy for API requests. You can specify it using the format [protocol://][username[:password]@]proxy.example.com[:port]. See documentation at https://www.zabbix.com/documentation/6.0/manual/config/items/itemtypes/http
|`` | |{$MERAKI.ORGANIZATION.NAME.MATCHES} |This macro is used in organizations discovery. Can be overridden on the host or linked template level.
|`.+` | |{$MERAKI.ORGANIZATION.NAME.NOT_MATCHES} |This macro is used in organizations discovery. Can be overridden on the host or linked template level.
|`CHANGE_IF_NEEDED` | |{$MERAKI.TOKEN} |Cisco Meraki Dashboard API Token.
|`` | ## Template links There are no template links in this template. ## Discovery rules |Name|Description|Type|Key and additional info| |----|-----------|----|----| |Devices discovery |-
|DEPENDENT |meraki.devices.discovery**Preprocessing**:
- JSONPATH: `$.devices`
**Filter**:
- {#NAME} MATCHES_REGEX `{$MERAKI.DEVICE.NAME.MATCHES}`
- {#NAME} NOT_MATCHES_REGEX `{$MERAKI.DEVICE.NAME.NOT_MATCHES}`
| |Organizations discovery |-
|DEPENDENT |meraki.organization.discovery**Preprocessing**:
- JSONPATH: `$.organizations`
**Filter**:
- {#NAME} MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.MATCHES}`
- {#NAME} NOT_MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.NOT_MATCHES}`
| ## Items collected |Group|Name|Description|Type|Key and additional info| |-----|----|-----------|----|---------------------| |Zabbix raw items |Meraki: Get data |Item for gathering all the organizations and devices from Meraki API"
|SCRIPT |meraki.get.data**Expression**:
`The text is too long. Please see the template.` | |Zabbix raw items |Meraki: Data item errors |Item for gathering all the data item errors.
|DEPENDENT |meraki.get.data.errors**Preprocessing**:
- JSONPATH: `$.error`
- DISCARD_UNCHANGED_HEARTBEAT: `1h`
| ## Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----|----|----| |Meraki: There are errors in 'Get data' metric |-
|`length(last(/Cisco Meraki dashboard by HTTP/meraki.get.data.errors))>0` |WARNING | | ## Feedback Please report any issues with the template at https://support.zabbix.com You can also provide feedback, discuss the template or ask for help with it at [ZABBIX forums](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback/). # Cisco Meraki organization by HTTP ## Overview For Zabbix version: 6.0 and higher ## Setup Refer to the vendor documentation. ## Zabbix configuration No specific Zabbix configuration is required. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$MERAKI.API.URL} |Cisco Meraki Dashboard API URL. e.g api.meraki.com/api/v1
|`api.meraki.com/api/v1` | |{$MERAKI.CONFIG.CHANGE.TIMESPAN} |Timespan for gathering config change log. Used in metric config and in URL query.
|`1200` | |{$MERAKI.HTTP_PROXY} |HTTP proxy for API requests. You can specify it using the format [protocol://][username[:password]@]proxy.example.com[:port]. See documentation at https://www.zabbix.com/documentation/6.0/manual/config/items/itemtypes/http
|`` | |{$MERAKI.LICENSE.EXPIRE} |Time in seconds for license to expire.
|`86400` | |{$MERAKI.TOKEN} |Cisco Meraki Dashboard API Token.
|`` | ## Template links There are no template links in this template. ## Discovery rules |Name|Description|Type|Key and additional info| |----|-----------|----|----| |Uplinks discovery |-
|DEPENDENT |meraki.uplinks.discovery**Preprocessing**:
- JSONPATH: `$.uplinks`
| |VPN stats discovery |-
|DEPENDENT |meraki.vpn.stats.discovery**Preprocessing**:
- JSONPATH: `$.vpnStats`
| ## Items collected |Group|Name|Description|Type|Key and additional info| |-----|----|-----------|----|---------------------| |Meraki |Meraki: Groups |Meraki adaptive policy groups count.
|DEPENDENT |meraki.policies.groups**Preprocessing**:
- JSONPATH: `$.counts.groups`
| |Meraki |Meraki: Custom ACLs |Meraki adaptive policy custom ACLs count.
|DEPENDENT |meraki.policies.custom.acls**Preprocessing**:
- JSONPATH: `$.counts.customAcls`
| |Meraki |Meraki: Policies |Meraki adaptive policies count.
|DEPENDENT |meraki.policies**Preprocessing**:
- JSONPATH: `$.counts.policies`
| |Meraki |Meraki: Allow policies |Meraki adaptive allow policies count.
|DEPENDENT |meraki.policies.allow**Preprocessing**:
- JSONPATH: `$.counts.allowPolicies`
| |Meraki |Meraki: Deny policies |Meraki adaptive deny policies count.
|DEPENDENT |meraki.policies.deny**Preprocessing**:
- JSONPATH: `$.counts.denyPolicies`
| |Meraki |Meraki: License status |Meraki license status.
|DEPENDENT |meraki.license.status**Preprocessing**:
- JSONPATH: `$.status`
- JAVASCRIPT: `The text is too long. Please see the template.`
| |Meraki |Meraki: License expire |Meraki license expire time in seconds left.
|DEPENDENT |meraki.license.expire**Preprocessing**:
- JSONPATH: `$.expirationDate`
- JAVASCRIPT: `The text is too long. Please see the template.`
| |Meraki |Uplink [{#INTERFACE}]: [{#UPLINK.ROLE}]: [{#NETWORK.NAME}]: status |Network uplink status.
|DEPENDENT |meraki.uplink.status[{#NETWORK.NAME}, {#INTERFACE}, {#UPLINK.ROLE}]**Preprocessing**:
- JSONPATH: `$.uplinks[?(@.networkName== '{#NETWORK.NAME}' && @.interface== '{#INTERFACE}' && @.role== '{#UPLINK.ROLE}' )].status.first()`
- JAVASCRIPT: `The text is too long. Please see the template.`
| |Meraki |VPN [{#NETWORK.NAME}]=>[{#PEER.NETWORK.NAME}]: stats raw |VPN connection stats raw.
|DEPENDENT |meraki.vpn.stat.raw[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.vpnStats[?(@.networkId=='{#NETWORK.ID}' && @.senderUplink=='{#SENDER.UPLINK}' && @.peerNetworkId=='{#PEER.NETWORK.ID}' && @.receiverUplink=='{#RECEIVER.UPLINK}')].first()`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: latency avg |VPN connection avg latency.
|DEPENDENT |meraki.vpn.stat.latency.avg[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.avgLatencyMs`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: latency min |VPN connection min latency.
|DEPENDENT |meraki.vpn.stat.latency.min[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.minLatencyMs`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: latency max |VPN connection max latency.
|DEPENDENT |meraki.vpn.stat.latency.max[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.maxLatencyMs`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: loss avg, % |VPN connection loss avg.
|DEPENDENT |meraki.vpn.stat.loss.avg[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.avgLossPercentage`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: loss min, % |VPN connection loss min.
|DEPENDENT |meraki.vpn.stat.loss.min[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.minLossPercentage`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: loss max, % |VPN connection loss max.
|DEPENDENT |meraki.vpn.stat.loss.max[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.maxLossPercentage`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: jitter avg |VPN connection jitter avg.
|DEPENDENT |meraki.vpn.stat.jitter.avg[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.avgJitter`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: jitter min |VPN connection jitter min.
|DEPENDENT |meraki.vpn.stat.jitter.min[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.minJitter`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: jitter max |VPN connection jitter max.
|DEPENDENT |meraki.vpn.stat.jitter.max[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.maxJitter`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: mos avg |VPN connection mos avg.
|DEPENDENT |meraki.vpn.stat.mos.avg[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.avgMos`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: mos min |VPN connection mos min.
|DEPENDENT |meraki.vpn.stat.mos.min[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.minMos`
| |Meraki |VPN [{#NETWORK.NAME}][{#SENDER.UPLINK}]=>[{#PEER.NETWORK.NAME}][{#RECEIVER.UPLINK}]: mos max |VPN connection mos max.
|DEPENDENT |meraki.vpn.stat.mos.max[{#NETWORK.ID}, {#SENDER.UPLINK}, {#PEER.NETWORK.ID}, {#RECEIVER.UPLINK}]**Preprocessing**:
- JSONPATH: `$.maxMos`
| |Zabbix raw items |Meraki: Get list of the networks |Item for gathering all the networks of organization from Meraki API.
|SCRIPT |meraki.get.networks**Expression**:
`The text is too long. Please see the template.` | |Zabbix raw items |Meraki: Networks item errors |Item for gathering all the networks item errors.
|DEPENDENT |meraki.get.networks.errors**Preprocessing**:
- JSONPATH: `$.error`
- DISCARD_UNCHANGED_HEARTBEAT: `1h`
| |Zabbix raw items |Meraki: Get list of the vpn stats |Item for gathering all the vpn stats of the organization.
|SCRIPT |meraki.get.vpn.stats**Expression**:
`The text is too long. Please see the template.` | |Zabbix raw items |Meraki: VPN item errors |Item for gathering all the vpn item errors.
|DEPENDENT |meraki.get.vpn.stats.errors**Preprocessing**:
- JSONPATH: `$.error`
- DISCARD_UNCHANGED_HEARTBEAT: `1h`
| |Zabbix raw items |Meraki: Get list of configuration changes |Item for viewing the Change Log for your organization.\nGathering once per 20m by default.
|HTTP_AGENT |meraki.get.configuration.changes**Preprocessing**:
- DISCARD_UNCHANGED_HEARTBEAT: `2h`
| |Zabbix raw items |Meraki: Get list of adaptive policy aggregate statistics |Item for adaptive policy aggregate statistics for an organization.
|HTTP_AGENT |meraki.get.adaptive.policy | |Zabbix raw items |Meraki: Get licenses info |Return an overview of the license state for an organization.
|HTTP_AGENT |meraki.get.licenses | ## Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----|----|----| |Meraki: License status is not OK |-
|`last(/Cisco Meraki organization by HTTP/meraki.license.status)<>1` |WARNING | | |Meraki: License expires in less than {$MERAKI.LICENSE.EXPIRE} seconds |-
|`last(/Cisco Meraki organization by HTTP/meraki.license.expire)<{$MERAKI.LICENSE.EXPIRE} and last(/Cisco Meraki organization by HTTP/meraki.license.expire)>=0` |WARNING | | |Uplink [{#INTERFACE}]: [{#UPLINK.ROLE}]: [{#NETWORK.NAME}]: status is failed |-
|`last(/Cisco Meraki organization by HTTP/meraki.uplink.status[{#NETWORK.NAME}, {#INTERFACE}, {#UPLINK.ROLE}])=0` |WARNING | | |Meraki: There are errors in 'Get networks' metric |-
|`length(last(/Cisco Meraki organization by HTTP/meraki.get.networks.errors))>0` |WARNING | | |Meraki: There are errors in 'Get VPNs' metric |-
|`length(last(/Cisco Meraki organization by HTTP/meraki.get.vpn.stats.errors))>0` |WARNING | | |Meraki: Configuration has been changed |-
|`length(last(/Cisco Meraki organization by HTTP/meraki.get.configuration.changes))>3` |WARNING | | ## Feedback Please report any issues with the template at https://support.zabbix.com # Cisco Meraki device by HTTP ## Overview For Zabbix version: 6.0 and higher ## Setup Refer to the vendor documentation. ## Zabbix configuration No specific Zabbix configuration is required. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$MERAKI.API.URL} |Cisco Meraki Dashboard API URL. e.g api.meraki.com/api/v1
|`api.meraki.com/api/v1` | |{$MERAKI.DEVICE.LATENCY} |Devices uplink latency threshold in seconds.
|`0.15` | |{$MERAKI.DEVICE.LOSS} |Devices uplink loss threshold in percents.
|`15` | |{$MERAKI.HTTP_PROXY} |HTTP proxy for API requests. You can specify it using the format [protocol://][username[:password]@]proxy.example.com[:port]. See documentation at https://www.zabbix.com/documentation/6.0/manual/config/items/itemtypes/http
|`` | |{$MERAKI.TOKEN} |Cisco Meraki Dashboard API Token.
|`` | ## Template links There are no template links in this template. ## Discovery rules |Name|Description|Type|Key and additional info| |----|-----------|----|----| |Uplinks loss and quality discovery |-
|DEPENDENT |meraki.device.uplinks.discovery**Preprocessing**:
- JSONPATH: `$.uplinksLL`
| ## Items collected |Group|Name|Description|Type|Key and additional info| |-----|----|-----------|----|---------------------| |Meraki |Meraki: status |Device operational status
Network: {$NETWORK.ID}
MAC: {$MAC}
|DEPENDENT |meraki.device.status**Preprocessing**:
- JSONPATH: `$.device[0].status`
- JAVASCRIPT: `The text is too long. Please see the template.`
| |Meraki |Meraki: public ip |Device public ip
Network: {$NETWORK.ID}
MAC: {$MAC}
|DEPENDENT |meraki.device.public.ip**Preprocessing**:
- JSONPATH: `$.device[0].publicIp`
| |Meraki |Uplink [{#IP}]: [{#UPLINK}]: Loss, % |Loss percent of the device uplink.
Network: {#NETWORK.ID}.
Device serial: {$SERIAL}.
|DEPENDENT |meraki.device.loss.pct[{#IP},{#UPLINK}]**Preprocessing**:
- JSONPATH: `$.uplinksLL[?(@.ip == '{#IP}' && @.uplink== '{#UPLINK}')].timeSeries.[0].lossPercent.first()`
- JAVASCRIPT: `return value === "" ? -1 : value `
| |Meraki |Uplink [{#IP}]: [{#UPLINK}]: Latency |Latency of the device uplink.
Network: {#NETWORK.ID}.
Device serial: {$SERIAL}.
|DEPENDENT |meraki.device.latency[{#IP},{#UPLINK}]**Preprocessing**:
- JSONPATH: `$.uplinksLL[?(@.ip == '{#IP}' && @.uplink== '{#UPLINK}' && @.serial== '{#SERIAL}')].timeSeries.[0].latencyMs.first()`
- JAVASCRIPT: `return value === "" ? -1000 : value `
- MULTIPLIER: `0.001`
| |Zabbix raw items |Meraki: Get device data |Item for gathering device data from Meraki API.
|SCRIPT |meraki.get.device**Expression**:
`The text is too long. Please see the template.` | |Zabbix raw items |Meraki: Device data item errors |Item for gathering errors of the device item.
|DEPENDENT |meraki.get.device.errors**Preprocessing**:
- JSONPATH: `$.error`
- DISCARD_UNCHANGED_HEARTBEAT: `1h`
| ## Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----|----|----| |Meraki: Status is not online |-
|`last(/Cisco Meraki device by HTTP/meraki.device.status)<>1` |WARNING | | |Uplink [{#IP}]: [{#UPLINK}]: loss > {$MERAKI.DEVICE.LOSS}% |-
|`min(/Cisco Meraki device by HTTP/meraki.device.loss.pct[{#IP},{#UPLINK}],#3)>{$MERAKI.DEVICE.LOSS}` |WARNING | | |Uplink [{#IP}]: [{#UPLINK}]: latency > {$MERAKI.DEVICE.LATENCY} |-
|`min(/Cisco Meraki device by HTTP/meraki.device.latency[{#IP},{#UPLINK}],#3)>{$MERAKI.DEVICE.LATENCY}` |WARNING | | |Meraki: There are errors in 'Get Device data' metric |-
|`length(last(/Cisco Meraki device by HTTP/meraki.get.device.errors))>0` |WARNING | | ## Feedback Please report any issues with the template at https://support.zabbix.com