Merge branch 'develop'
This commit is contained in:
@@ -2,11 +2,9 @@
|
||||
Zabbix plugin allows to show different type of data from [Zabbix](http://www.zabbix.com/)
|
||||
monitoring system.
|
||||
|
||||

|
||||
|
||||
### Live Demo
|
||||
|
||||
Check out the [live demo](http://play.grafana-zabbix.org/)
|
||||
Check out the [live demo](http://play.grafana-zabbix.org/) with dashboard examples.
|
||||
|
||||
### Features
|
||||
|
||||
|
||||
569
src/dashboards/template_linux_server.json
Normal file
569
src/dashboards/template_linux_server.json
Normal file
@@ -0,0 +1,569 @@
|
||||
{
|
||||
"id": null,
|
||||
"title": "Template Linux Server",
|
||||
"originalTitle": "Template Linux Server",
|
||||
"tags": [
|
||||
"zabbix",
|
||||
"example"
|
||||
],
|
||||
"style": "dark",
|
||||
"timezone": "browser",
|
||||
"editable": true,
|
||||
"hideControls": false,
|
||||
"sharedCrosshair": false,
|
||||
"rows": [
|
||||
{
|
||||
"collapse": false,
|
||||
"editable": true,
|
||||
"height": "250px",
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {
|
||||
"CPU iowait time": "#B7DBAB",
|
||||
"CPU system time": "#BF1B00",
|
||||
"CPU user time": "#EAB839"
|
||||
},
|
||||
"bars": false,
|
||||
"datasource": null,
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 3,
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2": null,
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"id": 1,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"span": 6,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"application": {
|
||||
"filter": "CPU"
|
||||
},
|
||||
"functions": [],
|
||||
"group": {
|
||||
"filter": "$group"
|
||||
},
|
||||
"host": {
|
||||
"filter": "$host"
|
||||
},
|
||||
"item": {
|
||||
"filter": "/CPU/"
|
||||
},
|
||||
"mode": 0,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "CPU",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "percent",
|
||||
"logBase": 1,
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Processor load (1 min average per core)": "#1F78C1"
|
||||
},
|
||||
"bars": false,
|
||||
"datasource": null,
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2": null,
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"application": {
|
||||
"filter": "CPU"
|
||||
},
|
||||
"functions": [],
|
||||
"group": {
|
||||
"filter": "$group"
|
||||
},
|
||||
"host": {
|
||||
"filter": "$host"
|
||||
},
|
||||
"item": {
|
||||
"filter": "Processor load (15 min average per core)"
|
||||
},
|
||||
"mode": 0,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "System load",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"showTitle": true,
|
||||
"title": "CPU"
|
||||
},
|
||||
{
|
||||
"collapse": false,
|
||||
"editable": true,
|
||||
"height": "250px",
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"datasource": null,
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 3,
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2": null,
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"minSpan": 4,
|
||||
"nullPointMode": "connected",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": "netif",
|
||||
"scopedVars": {
|
||||
"netif": {
|
||||
"text": "eth0",
|
||||
"value": "eth0",
|
||||
"selected": false
|
||||
}
|
||||
},
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "/Incoming/",
|
||||
"transform": "negative-Y"
|
||||
}
|
||||
],
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"application": {
|
||||
"filter": ""
|
||||
},
|
||||
"functions": [],
|
||||
"group": {
|
||||
"filter": "$group"
|
||||
},
|
||||
"host": {
|
||||
"filter": "$host"
|
||||
},
|
||||
"item": {
|
||||
"filter": "/$netif/"
|
||||
},
|
||||
"mode": 0,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Network traffic on $netif",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bps",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"datasource": null,
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 3,
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2": null,
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"minSpan": 4,
|
||||
"nullPointMode": "connected",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"scopedVars": {
|
||||
"netif": {
|
||||
"text": "eth1",
|
||||
"value": "eth1",
|
||||
"selected": false
|
||||
}
|
||||
},
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "/Incoming/",
|
||||
"transform": "negative-Y"
|
||||
}
|
||||
],
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"application": {
|
||||
"filter": ""
|
||||
},
|
||||
"functions": [],
|
||||
"group": {
|
||||
"filter": "$group"
|
||||
},
|
||||
"host": {
|
||||
"filter": "$host"
|
||||
},
|
||||
"item": {
|
||||
"filter": "/$netif/"
|
||||
},
|
||||
"mode": 0,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Network traffic on $netif",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bps",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"repeatIteration": 1460635040618,
|
||||
"repeatPanelId": 3
|
||||
}
|
||||
],
|
||||
"showTitle": true,
|
||||
"title": "Network"
|
||||
}
|
||||
],
|
||||
"time": {
|
||||
"from": "now-3h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"now": true,
|
||||
"refresh_intervals": [
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"3h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allFormat": "regex values",
|
||||
"current": {
|
||||
"text": "Frontend",
|
||||
"value": "Frontend"
|
||||
},
|
||||
"datasource": null,
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Group",
|
||||
"multi": false,
|
||||
"multiFormat": "glob",
|
||||
"name": "group",
|
||||
"options": [
|
||||
{
|
||||
"text": "Backend",
|
||||
"value": "Backend",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "Database servers",
|
||||
"value": "Database servers",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "Frontend",
|
||||
"value": "Frontend",
|
||||
"selected": true
|
||||
},
|
||||
{
|
||||
"text": "Linux servers",
|
||||
"value": "Linux servers",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "Network",
|
||||
"value": "Network",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "Workstations",
|
||||
"value": "Workstations",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "Zabbix servers",
|
||||
"value": "Zabbix servers",
|
||||
"selected": false
|
||||
}
|
||||
],
|
||||
"query": "*",
|
||||
"refresh": 1,
|
||||
"refresh_on_load": false,
|
||||
"regex": "",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"allFormat": "glob",
|
||||
"current": {
|
||||
"text": "frontend01",
|
||||
"value": "frontend01"
|
||||
},
|
||||
"datasource": null,
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Host",
|
||||
"multi": false,
|
||||
"multiFormat": "glob",
|
||||
"name": "host",
|
||||
"options": [
|
||||
{
|
||||
"text": "frontend01",
|
||||
"value": "frontend01",
|
||||
"selected": true
|
||||
},
|
||||
{
|
||||
"text": "frontend02",
|
||||
"value": "frontend02",
|
||||
"selected": false
|
||||
}
|
||||
],
|
||||
"query": "$group.*",
|
||||
"refresh": 1,
|
||||
"refresh_on_load": false,
|
||||
"regex": "",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"allFormat": "regex values",
|
||||
"current": {
|
||||
"text": "All",
|
||||
"value": "$__all"
|
||||
},
|
||||
"datasource": null,
|
||||
"hide": 0,
|
||||
"hideLabel": false,
|
||||
"includeAll": true,
|
||||
"label": "Network interface",
|
||||
"multi": true,
|
||||
"multiFormat": "regex values",
|
||||
"name": "netif",
|
||||
"options": [
|
||||
{
|
||||
"text": "All",
|
||||
"value": "$__all",
|
||||
"selected": true
|
||||
},
|
||||
{
|
||||
"text": "eth0",
|
||||
"value": "eth0",
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"text": "eth1",
|
||||
"value": "eth1",
|
||||
"selected": false
|
||||
}
|
||||
],
|
||||
"query": "*.$host.Network interfaces.*",
|
||||
"refresh": 1,
|
||||
"refresh_on_load": false,
|
||||
"regex": "/(?:Incoming|Outgoing) network traffic on (.*)/",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"annotations": {
|
||||
"list": []
|
||||
},
|
||||
"schemaVersion": 12,
|
||||
"version": 8,
|
||||
"links": []
|
||||
}
|
||||
@@ -249,7 +249,20 @@
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "/user/",
|
||||
"color": "#1F78C1"
|
||||
},
|
||||
{
|
||||
"alias": "/system/",
|
||||
"color": "#BF1B00"
|
||||
},
|
||||
{
|
||||
"alias": "/iowait/",
|
||||
"color": "#E5AC0E"
|
||||
}
|
||||
],
|
||||
"span": 7,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
@@ -286,7 +299,7 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"format": "percent",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -324,7 +337,7 @@
|
||||
"scroll": true,
|
||||
"showHeader": true,
|
||||
"sort": {
|
||||
"col": 0,
|
||||
"col": 2,
|
||||
"desc": true
|
||||
},
|
||||
"span": 5,
|
||||
@@ -335,17 +348,20 @@
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"colorMode": null,
|
||||
"colorMode": "cell",
|
||||
"colors": [
|
||||
"rgba(245, 54, 54, 0.9)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(50, 172, 45, 0.97)"
|
||||
"rgb(41, 170, 106)",
|
||||
"rgba(239, 148, 21, 0.89)",
|
||||
"rgba(239, 10, 10, 0.9)"
|
||||
],
|
||||
"decimals": 2,
|
||||
"decimals": 1,
|
||||
"pattern": "/.*/",
|
||||
"thresholds": [],
|
||||
"thresholds": [
|
||||
"50",
|
||||
"80"
|
||||
],
|
||||
"type": "number",
|
||||
"unit": "short"
|
||||
"unit": "percent"
|
||||
}
|
||||
],
|
||||
"targets": [
|
||||
@@ -373,6 +389,207 @@
|
||||
}
|
||||
],
|
||||
"title": "Row"
|
||||
},
|
||||
{
|
||||
"title": "New row",
|
||||
"height": "380",
|
||||
"editable": true,
|
||||
"collapse": false,
|
||||
"panels": [
|
||||
{
|
||||
"title": "Zabbix busy processes",
|
||||
"error": false,
|
||||
"span": 7.069277691711851,
|
||||
"editable": true,
|
||||
"type": "graph",
|
||||
"isNew": true,
|
||||
"id": 6,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"mode": 0,
|
||||
"group": {
|
||||
"filter": "Zabbix servers"
|
||||
},
|
||||
"host": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"application": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"item": {
|
||||
"filter": "/Zabbix busy/"
|
||||
},
|
||||
"functions": []
|
||||
}
|
||||
],
|
||||
"datasource": null,
|
||||
"renderer": "flot",
|
||||
"yaxes": [
|
||||
{
|
||||
"label": null,
|
||||
"show": true,
|
||||
"logBase": 1,
|
||||
"min": null,
|
||||
"max": null,
|
||||
"format": "percent"
|
||||
},
|
||||
{
|
||||
"label": null,
|
||||
"show": true,
|
||||
"logBase": 1,
|
||||
"min": null,
|
||||
"max": null,
|
||||
"format": "short"
|
||||
}
|
||||
],
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold2": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"lines": true,
|
||||
"fill": 0,
|
||||
"linewidth": 2,
|
||||
"points": false,
|
||||
"pointradius": 5,
|
||||
"bars": false,
|
||||
"stack": false,
|
||||
"percentage": false,
|
||||
"legend": {
|
||||
"show": true,
|
||||
"values": false,
|
||||
"min": false,
|
||||
"max": false,
|
||||
"current": false,
|
||||
"total": false,
|
||||
"avg": false,
|
||||
"hideEmpty": true,
|
||||
"hideZero": true,
|
||||
"alignAsTable": true,
|
||||
"rightSide": true
|
||||
},
|
||||
"nullPointMode": "connected",
|
||||
"steppedLine": false,
|
||||
"tooltip": {
|
||||
"value_type": "cumulative",
|
||||
"shared": true,
|
||||
"msResolution": false
|
||||
},
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"aliasColors": {},
|
||||
"seriesOverrides": [],
|
||||
"links": []
|
||||
},
|
||||
{
|
||||
"title": "Zabbix Queue",
|
||||
"error": false,
|
||||
"span": 4.930722308288148,
|
||||
"editable": true,
|
||||
"type": "graph",
|
||||
"isNew": true,
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"mode": 0,
|
||||
"group": {
|
||||
"filter": "Zabbix servers"
|
||||
},
|
||||
"host": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"application": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"item": {
|
||||
"filter": "Zabbix queue"
|
||||
},
|
||||
"functions": []
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"mode": 0,
|
||||
"group": {
|
||||
"filter": "Zabbix servers"
|
||||
},
|
||||
"host": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"application": {
|
||||
"filter": "Zabbix server"
|
||||
},
|
||||
"item": {
|
||||
"filter": "/Values processed/"
|
||||
},
|
||||
"functions": []
|
||||
}
|
||||
],
|
||||
"datasource": null,
|
||||
"renderer": "flot",
|
||||
"yaxes": [
|
||||
{
|
||||
"label": null,
|
||||
"show": true,
|
||||
"logBase": 1,
|
||||
"min": null,
|
||||
"max": null,
|
||||
"format": "short"
|
||||
},
|
||||
{
|
||||
"label": null,
|
||||
"show": true,
|
||||
"logBase": 1,
|
||||
"min": null,
|
||||
"max": null,
|
||||
"format": "short"
|
||||
}
|
||||
],
|
||||
"xaxis": {
|
||||
"show": true
|
||||
},
|
||||
"grid": {
|
||||
"threshold1": null,
|
||||
"threshold2": null,
|
||||
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
||||
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
||||
},
|
||||
"lines": true,
|
||||
"fill": 0,
|
||||
"linewidth": 2,
|
||||
"points": false,
|
||||
"pointradius": 5,
|
||||
"bars": false,
|
||||
"stack": false,
|
||||
"percentage": false,
|
||||
"legend": {
|
||||
"show": true,
|
||||
"values": false,
|
||||
"min": false,
|
||||
"max": false,
|
||||
"current": false,
|
||||
"total": false,
|
||||
"avg": false
|
||||
},
|
||||
"nullPointMode": "connected",
|
||||
"steppedLine": false,
|
||||
"tooltip": {
|
||||
"value_type": "cumulative",
|
||||
"shared": true,
|
||||
"msResolution": false
|
||||
},
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"aliasColors": {},
|
||||
"seriesOverrides": [],
|
||||
"links": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"time": {
|
||||
@@ -411,6 +628,6 @@
|
||||
"list": []
|
||||
},
|
||||
"schemaVersion": 12,
|
||||
"version": 5,
|
||||
"version": 6,
|
||||
"links": []
|
||||
}
|
||||
|
||||
@@ -57,46 +57,6 @@ export class ZabbixAPIDatasource {
|
||||
// Datasource methods //
|
||||
////////////////////////
|
||||
|
||||
/**
|
||||
* Test connection to Zabbix API
|
||||
* @return {object} Connection status and Zabbix API version
|
||||
*/
|
||||
testDatasource() {
|
||||
var self = this;
|
||||
return this.zabbixAPI.getVersion().then(function (version) {
|
||||
return self.zabbixAPI.login().then(function (auth) {
|
||||
if (auth) {
|
||||
return {
|
||||
status: "success",
|
||||
title: "Success",
|
||||
message: "Zabbix API version: " + version
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: "error",
|
||||
title: "Invalid user name or password",
|
||||
message: "Zabbix API version: " + version
|
||||
};
|
||||
}
|
||||
}, function(error) {
|
||||
console.log(error);
|
||||
return {
|
||||
status: "error",
|
||||
title: "Connection failed",
|
||||
message: error
|
||||
};
|
||||
});
|
||||
},
|
||||
function(error) {
|
||||
console.log(error);
|
||||
return {
|
||||
status: "error",
|
||||
title: "Connection failed",
|
||||
message: "Could not connect to given url"
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query panel data. Calls for each panel in dashboard.
|
||||
* @param {Object} options Contains time range, targets and other info.
|
||||
@@ -106,12 +66,13 @@ export class ZabbixAPIDatasource {
|
||||
var self = this;
|
||||
|
||||
// get from & to in seconds
|
||||
var from = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
|
||||
var useTrends = (timeFrom < useTrendsFrom) && this.trends;
|
||||
|
||||
// Create request for each target
|
||||
var promises = _.map(options.targets, function(target) {
|
||||
var promises = _.map(options.targets, target => {
|
||||
|
||||
if (target.mode !== 1) {
|
||||
|
||||
@@ -119,8 +80,7 @@ export class ZabbixAPIDatasource {
|
||||
target = migrations.migrate(target);
|
||||
|
||||
// Don't request undefined and hidden targets
|
||||
if (target.hide || !target.group ||
|
||||
!target.host || !target.item) {
|
||||
if (target.hide || !target.group || !target.host || !target.item) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -132,7 +92,51 @@ export class ZabbixAPIDatasource {
|
||||
|
||||
// Query numeric data
|
||||
if (!target.mode || target.mode === 0) {
|
||||
return self.queryNumericData(target, groupFilter, hostFilter, appFilter, itemFilter,
|
||||
timeFrom, timeTo, useTrends, options, self);
|
||||
}
|
||||
|
||||
// Query text data
|
||||
else if (target.mode === 2) {
|
||||
return self.queryTextData(target, groupFilter, hostFilter, appFilter, itemFilter,
|
||||
timeFrom, timeTo, options, self);
|
||||
}
|
||||
}
|
||||
|
||||
// IT services mode
|
||||
else if (target.mode === 1) {
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice || !target.slaProperty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.zabbixAPI
|
||||
.getSLA(target.itservice.serviceid, timeFrom, timeTo)
|
||||
.then(slaObject => {
|
||||
return self.queryProcessor
|
||||
.handleSLAResponse(target.itservice, target.slaProperty, slaObject);
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
|
||||
// Data for panel (all targets)
|
||||
return this.q.all(_.flatten(promises))
|
||||
.then(_.flatten)
|
||||
.then(timeseries_data => {
|
||||
|
||||
// Series downsampling
|
||||
var data = _.map(timeseries_data, timeseries => {
|
||||
if (timeseries.datapoints.length > options.maxDataPoints) {
|
||||
timeseries.datapoints = DataProcessor
|
||||
.groupBy(options.interval, DataProcessor.AVERAGE, timeseries.datapoints);
|
||||
}
|
||||
return timeseries;
|
||||
});
|
||||
return { data: data };
|
||||
});
|
||||
}
|
||||
|
||||
queryNumericData(target, groupFilter, hostFilter, appFilter, itemFilter, timeFrom, timeTo, useTrends, options, self) {
|
||||
// Build query in asynchronous manner
|
||||
return self.queryProcessor
|
||||
.build(groupFilter, hostFilter, appFilter, itemFilter, 'num')
|
||||
@@ -142,28 +146,35 @@ export class ZabbixAPIDatasource {
|
||||
var getHistory;
|
||||
|
||||
// Use trends
|
||||
if ((from < useTrendsFrom) && self.trends) {
|
||||
if (useTrends) {
|
||||
|
||||
// Find trendValue() function and get specified trend value
|
||||
var trendFunctions = _.map(metricFunctions.getCategories()['Trends'], 'name');
|
||||
var trendValueFunc = _.find(target.functions, function(func) {
|
||||
var trendValueFunc = _.find(target.functions, func => {
|
||||
return _.contains(trendFunctions, func.def.name);
|
||||
});
|
||||
var valueType = trendValueFunc ? trendValueFunc.params[0] : "avg";
|
||||
|
||||
getHistory = self.zabbixAPI.getTrend(items, from, to).then(function(history) {
|
||||
getHistory = self.zabbixAPI
|
||||
.getTrend(items, timeFrom, timeTo)
|
||||
.then(history => {
|
||||
return self.queryProcessor.handleTrends(history, items, addHostName, valueType);
|
||||
});
|
||||
} else {
|
||||
}
|
||||
|
||||
// Use history
|
||||
getHistory = self.zabbixCache.getHistory(items, from, to).then(function(history) {
|
||||
else {
|
||||
getHistory = self.zabbixCache
|
||||
.getHistory(items, timeFrom, timeTo)
|
||||
.then(history => {
|
||||
return self.queryProcessor.handleHistory(history, items, addHostName);
|
||||
});
|
||||
}
|
||||
|
||||
return getHistory.then(function (timeseries_data) {
|
||||
timeseries_data = _.map(timeseries_data, function (timeseries) {
|
||||
return getHistory.then(timeseries_data => {
|
||||
|
||||
// Apply transformation functions
|
||||
timeseries_data = _.map(timeseries_data, timeseries => {
|
||||
|
||||
// Filter only transform functions
|
||||
var transformFunctions = bindFunctionDefs(target.functions, 'Transform', DataProcessor);
|
||||
@@ -178,21 +189,23 @@ export class ZabbixAPIDatasource {
|
||||
return timeseries;
|
||||
});
|
||||
|
||||
// Aggregations
|
||||
// Apply aggregations
|
||||
var aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate', DataProcessor);
|
||||
var dp = _.map(timeseries_data, 'datapoints');
|
||||
if (aggregationFunctions.length) {
|
||||
for (var i = 0; i < aggregationFunctions.length; i++) {
|
||||
dp = aggregationFunctions[i](dp);
|
||||
}
|
||||
var lastAgg = _.findLast(target.functions, function(func) {
|
||||
var lastAgg = _.findLast(target.functions, func => {
|
||||
return _.contains(
|
||||
_.map(metricFunctions.getCategories()['Aggregate'], 'name'), func.def.name);
|
||||
});
|
||||
timeseries_data = [{
|
||||
timeseries_data = [
|
||||
{
|
||||
target: lastAgg.text,
|
||||
datapoints: dp
|
||||
}];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// Apply alias functions
|
||||
@@ -206,8 +219,7 @@ export class ZabbixAPIDatasource {
|
||||
});
|
||||
}
|
||||
|
||||
// Query text data
|
||||
else if (target.mode === 2) {
|
||||
queryTextData(target, groupFilter, hostFilter, appFilter, itemFilter, timeFrom, timeTo, options, self) {
|
||||
return self.queryProcessor
|
||||
.build(groupFilter, hostFilter, appFilter, itemFilter, 'text')
|
||||
.then(items => {
|
||||
@@ -234,7 +246,7 @@ export class ZabbixAPIDatasource {
|
||||
}
|
||||
return {
|
||||
target: items[index].name,
|
||||
datapoints: [[extractedValue, to * 1000]]
|
||||
datapoints: [[extractedValue, timeTo * 1000]]
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -243,36 +255,44 @@ export class ZabbixAPIDatasource {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// IT services mode
|
||||
else if (target.mode === 1) {
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice || !target.slaProperty) {
|
||||
return [];
|
||||
/**
|
||||
* Test connection to Zabbix API
|
||||
* @return {object} Connection status and Zabbix API version
|
||||
*/
|
||||
testDatasource() {
|
||||
var self = this;
|
||||
return this.zabbixAPI.getVersion()
|
||||
.then(version => {
|
||||
return self.zabbixAPI.login()
|
||||
.then(auth => {
|
||||
if (auth) {
|
||||
return {
|
||||
status: "success",
|
||||
title: "Success",
|
||||
message: "Zabbix API version: " + version
|
||||
};
|
||||
} else {
|
||||
return this.zabbixAPI.getSLA(target.itservice.serviceid, from, to)
|
||||
.then(slaObject => {
|
||||
return self.queryProcessor.handleSLAResponse(target.itservice, target.slaProperty, slaObject);
|
||||
return {
|
||||
status: "error",
|
||||
title: "Invalid user name or password",
|
||||
message: "Zabbix API version: " + version
|
||||
};
|
||||
}
|
||||
}, error => {
|
||||
return {
|
||||
status: "error",
|
||||
title: error.message,
|
||||
message: error.data
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
|
||||
// Data for panel (all targets)
|
||||
return this.q.all(_.flatten(promises))
|
||||
.then(_.flatten)
|
||||
.then(function (timeseries_data) {
|
||||
|
||||
// Series downsampling
|
||||
var data = _.map(timeseries_data, function(timeseries) {
|
||||
if (timeseries.datapoints.length > options.maxDataPoints) {
|
||||
timeseries.datapoints =
|
||||
DataProcessor.groupBy(options.interval, DataProcessor.AVERAGE, timeseries.datapoints);
|
||||
}
|
||||
return timeseries;
|
||||
});
|
||||
return { data: data };
|
||||
}, error => {
|
||||
console.log(error);
|
||||
return {
|
||||
status: "error",
|
||||
title: "Connection failed",
|
||||
message: "Could not connect to given url"
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -309,28 +329,33 @@ export class ZabbixAPIDatasource {
|
||||
if (template.app === '/.*/') {
|
||||
template.app = '';
|
||||
}
|
||||
return this.queryProcessor.getItems(template.group, template.host, template.app)
|
||||
.then(function(items) {
|
||||
return this.queryProcessor
|
||||
.getItems(template.group, template.host, template.app)
|
||||
.then(items => {
|
||||
return _.map(items, formatMetric);
|
||||
});
|
||||
}
|
||||
// Get applications
|
||||
else if (parts.length === 3) {
|
||||
return this.queryProcessor.getApps(template.group, template.host)
|
||||
.then(function(apps) {
|
||||
return this.queryProcessor
|
||||
.getApps(template.group, template.host)
|
||||
.then(apps => {
|
||||
return _.map(apps, formatMetric);
|
||||
});
|
||||
}
|
||||
// Get hosts
|
||||
else if (parts.length === 2) {
|
||||
return this.queryProcessor.getHosts(template.group)
|
||||
.then(function(hosts) {
|
||||
return this.queryProcessor
|
||||
.getHosts(template.group)
|
||||
.then(hosts => {
|
||||
return _.map(hosts, formatMetric);
|
||||
});
|
||||
}
|
||||
// Get groups
|
||||
else if (parts.length === 1) {
|
||||
return this.zabbixCache.getGroups(template.group).then(function(groups) {
|
||||
return this.zabbixCache
|
||||
.getGroups(template.group)
|
||||
.then(groups => {
|
||||
return _.map(groups, formatMetric);
|
||||
});
|
||||
}
|
||||
@@ -348,66 +373,66 @@ export class ZabbixAPIDatasource {
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
|
||||
var annotation = options.annotation;
|
||||
var self = this;
|
||||
var showOkEvents = annotation.showOkEvents ? [0, 1] : 1;
|
||||
|
||||
// Show all triggers
|
||||
var showTriggers = [0, 1];
|
||||
|
||||
var buildQuery = self.queryProcessor.buildTriggerQuery(this.replaceTemplateVars(annotation.group, {}),
|
||||
var buildQuery = this.queryProcessor
|
||||
.buildTriggerQuery(this.replaceTemplateVars(annotation.group, {}),
|
||||
this.replaceTemplateVars(annotation.host, {}),
|
||||
this.replaceTemplateVars(annotation.application, {}));
|
||||
return buildQuery.then(function(query) {
|
||||
return self.zabbixAPI.getTriggers(query.groupids,
|
||||
query.hostids,
|
||||
query.applicationids,
|
||||
showTriggers,
|
||||
timeFrom, timeTo)
|
||||
.then(function(triggers) {
|
||||
var self = this;
|
||||
return buildQuery.then(query => {
|
||||
return self.zabbixAPI
|
||||
.getTriggers(query.groupids, query.hostids, query.applicationids,
|
||||
showTriggers, timeFrom, timeTo)
|
||||
.then(triggers => {
|
||||
|
||||
// Filter triggers by description
|
||||
if (utils.isRegex(annotation.trigger)) {
|
||||
triggers = _.filter(triggers, function(trigger) {
|
||||
triggers = _.filter(triggers, trigger => {
|
||||
return utils.buildRegex(annotation.trigger).test(trigger.description);
|
||||
});
|
||||
} else if (annotation.trigger) {
|
||||
triggers = _.filter(triggers, function(trigger) {
|
||||
triggers = _.filter(triggers, trigger => {
|
||||
return trigger.description === annotation.trigger;
|
||||
});
|
||||
}
|
||||
|
||||
// Remove events below the chose severity
|
||||
triggers = _.filter(triggers, function(trigger) {
|
||||
triggers = _.filter(triggers, trigger => {
|
||||
return Number(trigger.priority) >= Number(annotation.minseverity);
|
||||
});
|
||||
|
||||
var objectids = _.map(triggers, 'triggerid');
|
||||
return self.zabbixAPI.getEvents(objectids, timeFrom, timeTo, showOkEvents)
|
||||
.then(function (events) {
|
||||
return self.zabbixAPI
|
||||
.getEvents(objectids, timeFrom, timeTo, showOkEvents)
|
||||
.then(events => {
|
||||
var indexedTriggers = _.indexBy(triggers, 'triggerid');
|
||||
|
||||
// Hide acknowledged events if option enabled
|
||||
if (annotation.hideAcknowledged) {
|
||||
events = _.filter(events, function(event) {
|
||||
events = _.filter(events, event => {
|
||||
return !event.acknowledges.length;
|
||||
});
|
||||
}
|
||||
|
||||
return _.map(events, function(e) {
|
||||
return _.map(events, event => {
|
||||
var title ='';
|
||||
if (annotation.showHostname) {
|
||||
title += e.hosts[0].name + ': ';
|
||||
title += event.hosts[0].name + ': ';
|
||||
}
|
||||
|
||||
// Show event type (OK or Problem)
|
||||
title += Number(e.value) ? 'Problem' : 'OK';
|
||||
title += Number(event.value) ? 'Problem' : 'OK';
|
||||
|
||||
var formatted_acknowledges = utils.formatAcknowledges(e.acknowledges);
|
||||
var formatted_acknowledges = utils.formatAcknowledges(event.acknowledges);
|
||||
return {
|
||||
annotation: annotation,
|
||||
time: e.clock * 1000,
|
||||
time: event.clock * 1000,
|
||||
title: title,
|
||||
text: indexedTriggers[e.objectid].description + formatted_acknowledges
|
||||
text: indexedTriggers[event.objectid].description + formatted_acknowledges
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -89,7 +89,6 @@
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.group.filter"
|
||||
bs-typeahead="ctrl.getGroupNames"
|
||||
ng-change="ctrl.onTargetPartChange(ctrl.target.group)"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
@@ -106,7 +105,6 @@
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.host.filter"
|
||||
bs-typeahead="ctrl.getHostNames"
|
||||
ng-change="ctrl.onTargetPartChange(ctrl.target.host)"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
@@ -123,26 +121,7 @@
|
||||
change="ctrl.onTargetBlur()">
|
||||
</editor-checkbox>
|
||||
</li>
|
||||
|
||||
<!-- Downsampling function -->
|
||||
<!-- <li class="tight-form-item input-medium" ng-hide="ctrl.target.mode == 2">
|
||||
Downsampling
|
||||
</li>
|
||||
<li ng-hide="ctrl.target.mode == 2">
|
||||
<select class="tight-form-input input-small"
|
||||
ng-change="ctrl.targetBlur()"
|
||||
ng-model="ctrl.target.downsampleFunction"
|
||||
bs-tooltip="'Downsampling function'"
|
||||
ng-options="func.name for func in downsampleFunctionList track by func.name">
|
||||
</select>
|
||||
<a bs-tooltip="ctrl.target.errors.metric"
|
||||
style="color: rgb(229, 189, 28)"
|
||||
ng-show="ctrl.target.errors.metric">
|
||||
<i class="icon-warning-sign"></i>
|
||||
</a>
|
||||
</li> -->
|
||||
</ul>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
@@ -156,7 +135,6 @@
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.application.filter"
|
||||
bs-typeahead="ctrl.getApplicationNames"
|
||||
ng-change="ctrl.onTargetPartChange(ctrl.target.application)"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
@@ -173,7 +151,6 @@
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.item.filter"
|
||||
bs-typeahead="ctrl.getItemNames"
|
||||
ng-change="ctrl.onTargetPartChange(ctrl.target.item)"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
|
||||
@@ -178,26 +178,12 @@ export class ZabbixQueryController extends QueryCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
onTargetPartChange(targetPart) {
|
||||
/*var regexStyle = {'color': '#CCA300'};
|
||||
targetPart.isRegex = utils.isRegex(targetPart.filter);
|
||||
targetPart.style = targetPart.isRegex ? regexStyle : {};*/
|
||||
}
|
||||
|
||||
isRegex(str) {
|
||||
return utils.isRegex(str);
|
||||
}
|
||||
|
||||
isVariable(str) {
|
||||
var variablePattern = /^\$\w+/;
|
||||
if (variablePattern.test(str)) {
|
||||
var variables = _.map(this.templateSrv.variables, variable => {
|
||||
return '$' + variable.name;
|
||||
});
|
||||
return _.contains(variables, str);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return utils.isTemplateVariable(str, this.templateSrv.variables);
|
||||
}
|
||||
|
||||
onTargetBlur() {
|
||||
|
||||
@@ -29,6 +29,18 @@ export function isRegex(str) {
|
||||
return regexPattern.test(str);
|
||||
}
|
||||
|
||||
export function isTemplateVariable(str, templateVariables) {
|
||||
var variablePattern = /^\$\w+/;
|
||||
if (variablePattern.test(str)) {
|
||||
var variables = _.map(templateVariables, variable => {
|
||||
return '$' + variable.name;
|
||||
});
|
||||
return _.contains(variables, str);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function buildRegex(str) {
|
||||
var matches = str.match(regexPattern);
|
||||
var pattern = matches[1];
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
<input type="text"
|
||||
ng-model="editor.panel.triggers.group.filter"
|
||||
bs-typeahead="editor.getGroupNames"
|
||||
ng-change="editor.onTargetPartChange(editor.panel.triggers.group)"
|
||||
ng-blur="editor.parseTarget()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
class="input-large tight-form-input"
|
||||
ng-style="editor.panel.triggers.group.style">
|
||||
ng-class="{
|
||||
'zbx-variable': editor.isVariable(editor.panel.triggers.group.filter),
|
||||
'zbx-regex': editor.isRegex(editor.panel.triggers.group.filter)
|
||||
}">
|
||||
</li>
|
||||
<li class="tight-form-item" style="width: 50px">
|
||||
Host
|
||||
@@ -24,12 +26,14 @@
|
||||
<input type="text"
|
||||
ng-model="editor.panel.triggers.host.filter"
|
||||
bs-typeahead="editor.getHostNames"
|
||||
ng-change="editor.onTargetPartChange(editor.panel.triggers.host)"
|
||||
ng-blur="editor.parseTarget()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
class="input-large tight-form-input last"
|
||||
ng-style="editor.panel.triggers.host.style">
|
||||
ng-class="{
|
||||
'zbx-variable': editor.isVariable(editor.panel.triggers.host.filter),
|
||||
'zbx-regex': editor.isRegex(editor.panel.triggers.host.filter)
|
||||
}">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
@@ -43,12 +47,14 @@
|
||||
<input type="text"
|
||||
ng-model="editor.panel.triggers.application.filter"
|
||||
bs-typeahead="editor.getApplicationNames"
|
||||
ng-change="editor.onTargetPartChange(editor.panel.triggers.application)"
|
||||
ng-blur="editor.parseTarget()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
class="input-large tight-form-input"
|
||||
ng-style="editor.panel.triggers.application.style">
|
||||
ng-class="{
|
||||
'zbx-variable': editor.isVariable(editor.panel.triggers.application.filter),
|
||||
'zbx-regex': editor.isRegex(editor.panel.triggers.application.filter)
|
||||
}">
|
||||
</li>
|
||||
<li class="tight-form-item" style="width: 50px">
|
||||
Trigger
|
||||
@@ -56,7 +62,6 @@
|
||||
<li>
|
||||
<input type="text"
|
||||
ng-model="editor.panel.triggers.trigger.filter"
|
||||
ng-change="editor.onTargetPartChange(editor.panel.triggers.trigger)"
|
||||
ng-blur="editor.parseTarget()"
|
||||
placeholder="trigger name"
|
||||
class="input-large tight-form-input last"
|
||||
|
||||
@@ -12,25 +12,30 @@
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import * as utils from '../datasource-zabbix/utils';
|
||||
|
||||
class TriggerPanelEditorCtrl{
|
||||
import '../datasource-zabbix/css/query-editor.css!';
|
||||
|
||||
class TriggerPanelEditorCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $q, uiSegmentSrv, datasourceSrv, templateSrv, popoverSrv) {
|
||||
constructor($scope, $rootScope, $q, uiSegmentSrv, datasourceSrv, templateSrv, popoverSrv) {
|
||||
$scope.editor = this;
|
||||
this.panelCtrl = $scope.ctrl;
|
||||
this.panel = this.panelCtrl.panel;
|
||||
|
||||
this.$q = $q;
|
||||
this.datasourceSrv = datasourceSrv;
|
||||
this.templateSrv = templateSrv;
|
||||
this.popoverSrv = popoverSrv;
|
||||
|
||||
// Map functions for bs-typeahead
|
||||
this.getGroupNames = _.partial(getMetricNames, this, 'groupList');
|
||||
this.getHostNames = _.partial(getMetricNames, this, 'filteredHosts');
|
||||
this.getApplicationNames = _.partial(getMetricNames, this, 'filteredApplications');
|
||||
this.getItemNames = _.partial(getMetricNames, this, 'filteredItems');
|
||||
this.getHostNames = _.partial(getMetricNames, this, 'hostList');
|
||||
this.getApplicationNames = _.partial(getMetricNames, this, 'appList');
|
||||
|
||||
// Update metric suggestion when template variable was changed
|
||||
$rootScope.$on('template-variable-value-updated', () => this.onVariableChange());
|
||||
|
||||
this.ackFilters = [
|
||||
'all triggers',
|
||||
@@ -78,40 +83,75 @@ class TriggerPanelEditorCtrl{
|
||||
}
|
||||
|
||||
initFilters() {
|
||||
this.filterGroups();
|
||||
this.filterHosts();
|
||||
this.filterApplications();
|
||||
var self = this;
|
||||
return this.$q
|
||||
.when(this.suggestGroups())
|
||||
.then(() => {return self.suggestHosts();})
|
||||
.then(() => {return self.suggestApps();});
|
||||
}
|
||||
|
||||
filterGroups() {
|
||||
suggestGroups() {
|
||||
var self = this;
|
||||
this.datasource.queryProcessor.getGroups().then(function(groups) {
|
||||
return this.datasource.zabbixCache
|
||||
.getGroups()
|
||||
.then(groups => {
|
||||
self.metric.groupList = groups;
|
||||
return groups;
|
||||
});
|
||||
}
|
||||
|
||||
filterHosts() {
|
||||
suggestHosts() {
|
||||
var self = this;
|
||||
var groupFilter = this.templateSrv.replace(this.panel.triggers.group.filter);
|
||||
this.datasource.queryProcessor.getHosts(groupFilter).then(function(hosts) {
|
||||
self.metric.filteredHosts = hosts;
|
||||
var groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter);
|
||||
return this.datasource.queryProcessor
|
||||
.filterGroups(self.metric.groupList, groupFilter)
|
||||
.then(groups => {
|
||||
var groupids = _.map(groups, 'groupid');
|
||||
return self.datasource.zabbixAPI
|
||||
.getHosts(groupids)
|
||||
.then(hosts => {
|
||||
self.metric.hostList = hosts;
|
||||
return hosts;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
filterApplications() {
|
||||
suggestApps() {
|
||||
var self = this;
|
||||
var groupFilter = this.templateSrv.replace(this.panel.triggers.group.filter);
|
||||
var hostFilter = this.templateSrv.replace(this.panel.triggers.host.filter);
|
||||
this.datasource.queryProcessor.getApps(groupFilter, hostFilter)
|
||||
.then(function(apps) {
|
||||
self.metric.filteredApplications = apps;
|
||||
var hostFilter = this.datasource.replaceTemplateVars(this.panel.triggers.host.filter);
|
||||
return this.datasource.queryProcessor
|
||||
.filterHosts(self.metric.hostList, hostFilter)
|
||||
.then(hosts => {
|
||||
var hostids = _.map(hosts, 'hostid');
|
||||
return self.datasource.zabbixAPI
|
||||
.getApps(hostids)
|
||||
.then(apps => {
|
||||
return self.metric.appList = apps;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onTargetPartChange(targetPart) {
|
||||
var regexStyle = {'color': '#CCA300'};
|
||||
targetPart.isRegex = isRegex(targetPart.filter);
|
||||
targetPart.style = targetPart.isRegex ? regexStyle : {};
|
||||
onVariableChange() {
|
||||
if (this.isContainsVariables()) {
|
||||
this.targetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check query for template variables
|
||||
*/
|
||||
isContainsVariables() {
|
||||
var self = this;
|
||||
return _.some(self.templateSrv.variables, variable => {
|
||||
return _.some(['group', 'host', 'application'], field => {
|
||||
return self.templateSrv.containsVariable(self.panel.triggers[field].filter, variable.name);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
targetChanged() {
|
||||
this.initFilters();
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
|
||||
parseTarget() {
|
||||
@@ -140,36 +180,12 @@ class TriggerPanelEditorCtrl{
|
||||
this.refreshTriggerSeverity();
|
||||
}
|
||||
|
||||
openTriggerColorSelector(event) {
|
||||
var el = $(event.currentTarget);
|
||||
var index = getTriggerIndexForElement(el);
|
||||
var popoverScope = this.$new();
|
||||
popoverScope.trigger = this.panel.triggerSeverity[index];
|
||||
popoverScope.changeTriggerSeverityColor = this.changeTriggerSeverityColor;
|
||||
|
||||
this.popoverSrv.show({
|
||||
element: el,
|
||||
placement: 'top',
|
||||
templateUrl: 'public/plugins/alexanderzobnin-zabbix-app/panel-triggers/trigger.colorpicker.html',
|
||||
scope: popoverScope
|
||||
});
|
||||
isRegex(str) {
|
||||
return utils.isRegex(str);
|
||||
}
|
||||
|
||||
openOkEventColorSelector(event) {
|
||||
var el = $(event.currentTarget);
|
||||
var popoverScope = this.$new();
|
||||
popoverScope.trigger = {color: this.panel.okEventColor};
|
||||
popoverScope.changeTriggerSeverityColor = function(trigger, color) {
|
||||
this.panel.okEventColor = color;
|
||||
this.refreshTriggerSeverity();
|
||||
};
|
||||
|
||||
this.popoverSrv.show({
|
||||
element: el,
|
||||
placement: 'top',
|
||||
templateUrl: 'public/plugins/alexanderzobnin-zabbix-app/panel-triggers/trigger.colorpicker.html',
|
||||
scope: popoverScope
|
||||
});
|
||||
isVariable(str) {
|
||||
return utils.isTemplateVariable(str, this.templateSrv.variables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,16 +194,6 @@ function getMetricNames(scope, metricList) {
|
||||
return _.uniq(_.map(scope.metric[metricList], 'name'));
|
||||
}
|
||||
|
||||
function getTriggerIndexForElement(el) {
|
||||
return el.parents('[data-trigger-index]').data('trigger-index');
|
||||
}
|
||||
|
||||
function isRegex(str) {
|
||||
// Pattern for testing regex
|
||||
var regexPattern = /^\/(.*)\/([gmi]*)$/m;
|
||||
return regexPattern.test(str);
|
||||
}
|
||||
|
||||
export function triggerPanelEditor() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import * as utils from '../datasource-zabbix/utils';
|
||||
import {MetricsPanelCtrl} from 'app/plugins/sdk';
|
||||
import {triggerPanelEditor} from './editor';
|
||||
import './css/panel_triggers.css!';
|
||||
@@ -66,7 +67,9 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
|
||||
this.defaultTimeFormat = defaultTimeFormat;
|
||||
|
||||
// Load panel defaults
|
||||
_.defaults(this.panel, panelDefaults);
|
||||
// _.cloneDeep() need for prevent changing shared defaultSeverity.
|
||||
// Load object "by value" istead "by reference".
|
||||
_.defaults(this.panel, _.cloneDeep(panelDefaults));
|
||||
|
||||
this.triggerList = [];
|
||||
this.refreshData();
|
||||
@@ -88,15 +91,15 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
|
||||
// ignore fetching data if another panel is in fullscreen
|
||||
if (this.otherPanelInFullscreenMode()) { return; }
|
||||
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
refreshData() {
|
||||
// clear loading/error state
|
||||
delete this.error;
|
||||
this.loading = true;
|
||||
this.setTimeQueryStart();
|
||||
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
refreshData() {
|
||||
var self = this;
|
||||
|
||||
// Load datasource
|
||||
@@ -107,9 +110,9 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
|
||||
var triggerFilter = self.panel.triggers;
|
||||
|
||||
// Replace template variables
|
||||
var groupFilter = self.templateSrv.replace(triggerFilter.group.filter);
|
||||
var hostFilter = self.templateSrv.replace(triggerFilter.host.filter);
|
||||
var appFilter = self.templateSrv.replace(triggerFilter.application.filter);
|
||||
var groupFilter = datasource.replaceTemplateVars(triggerFilter.group.filter);
|
||||
var hostFilter = datasource.replaceTemplateVars(triggerFilter.host.filter);
|
||||
var appFilter = datasource.replaceTemplateVars(triggerFilter.application.filter);
|
||||
|
||||
var buildQuery = queryProcessor.buildTriggerQuery(groupFilter, hostFilter, appFilter);
|
||||
return buildQuery.then(query => {
|
||||
@@ -208,8 +211,9 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
|
||||
// Limit triggers number
|
||||
self.triggerList = _.first(triggerList, self.panel.limit);
|
||||
|
||||
this.setTimeQueryEnd();
|
||||
this.loading = false;
|
||||
// Notify panel that request is finished
|
||||
self.setTimeQueryEnd();
|
||||
self.loading = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -228,9 +232,9 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
|
||||
TriggerPanelCtrl.templateUrl = 'panel-triggers/module.html';
|
||||
|
||||
function filterTriggers(triggers, triggerFilter) {
|
||||
if (isRegex(triggerFilter)) {
|
||||
if (utils.isRegex(triggerFilter)) {
|
||||
return _.filter(triggers, function(trigger) {
|
||||
return buildRegex(triggerFilter).test(trigger.description);
|
||||
return utils.buildRegex(triggerFilter).test(trigger.description);
|
||||
});
|
||||
} else {
|
||||
return _.filter(triggers, function(trigger) {
|
||||
@@ -239,20 +243,6 @@ function filterTriggers(triggers, triggerFilter) {
|
||||
}
|
||||
}
|
||||
|
||||
function isRegex(str) {
|
||||
// Pattern for testing regex
|
||||
var regexPattern = /^\/(.*)\/([gmi]*)$/m;
|
||||
return regexPattern.test(str);
|
||||
}
|
||||
|
||||
function buildRegex(str) {
|
||||
var regexPattern = /^\/(.*)\/([gmi]*)$/m;
|
||||
var matches = str.match(regexPattern);
|
||||
var pattern = matches[1];
|
||||
var flags = matches[2] !== "" ? matches[2] : undefined;
|
||||
return new RegExp(pattern, flags);
|
||||
}
|
||||
|
||||
export {
|
||||
TriggerPanelCtrl,
|
||||
TriggerPanelCtrl as PanelCtrl
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<div class="graph-legend-popover">
|
||||
<a class="close"
|
||||
href=""
|
||||
ng-click="dismiss();">×</a>
|
||||
|
||||
<div class="editor-row">
|
||||
<i ng-repeat="color in colors" class="pointer"
|
||||
ng-class="{'fa fa-circle-o': color === trigger.color,'fa fa-circle': color !== trigger.color}"
|
||||
ng-style="{color:color}"
|
||||
ng-click="changeTriggerSeverityColor(trigger, color);dismiss();"> </i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,8 +24,15 @@
|
||||
{"name": "Docs", "url": "http://docs.grafana-zabbix.org"},
|
||||
{"name": "License", "url": "https://github.com/alexanderzobnin/grafana-zabbix/blob/master/LICENSE.md"}
|
||||
],
|
||||
"version": "3.0.0-beta6",
|
||||
"updated": "2016-04-13"
|
||||
"screenshots": [
|
||||
{"name": "Showcase", "path": "https://cloud.githubusercontent.com/assets/4932851/8269101/9e6ee67e-17a3-11e5-85de-fe9dcc2dd375.png"},
|
||||
{"name": "Dashboard", "path": "https://cloud.githubusercontent.com/assets/4932851/14539264/5ff70b58-0288-11e6-9de3-8aabe8c85e4c.png"},
|
||||
{"name": "Annotations", "path": "https://cloud.githubusercontent.com/assets/4932851/14539263/5fd8abd6-0288-11e6-9c87-b960c654ab29.png"},
|
||||
{"name": "Metric Editor", "path": "https://cloud.githubusercontent.com/assets/4932851/14539267/6004cb8a-0288-11e6-9b1f-78ec54409835.png"},
|
||||
{"name": "Triggers", "path": "https://cloud.githubusercontent.com/assets/4932851/14539266/600495fc-0288-11e6-8d15-308bbef16535.png"}
|
||||
],
|
||||
"version": "3.0.0-beta7",
|
||||
"updated": "2016-04-14"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
@@ -42,6 +49,12 @@
|
||||
"name": "Zabbix Server Dashboard",
|
||||
"path": "dashboards/zabbix_server_dashboard.json",
|
||||
"addToNav": true
|
||||
},
|
||||
{
|
||||
"type": "dashboard",
|
||||
"name": "Template Linux Server",
|
||||
"path": "dashboards/template_linux_server.json",
|
||||
"addToNav": true
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
Reference in New Issue
Block a user