diff --git a/dist/datasource-zabbix/config.controller.js b/dist/datasource-zabbix/config.controller.js new file mode 100644 index 0000000..9b753aa --- /dev/null +++ b/dist/datasource-zabbix/config.controller.js @@ -0,0 +1,74 @@ +'use strict'; + +System.register(['lodash'], function (_export, _context) { + "use strict"; + + var _, _createClass, SUPPORTED_SQL_DS, defaultConfig, ZabbixDSConfigController; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + return { + setters: [function (_lodash) { + _ = _lodash.default; + }], + execute: function () { + _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + SUPPORTED_SQL_DS = ['mysql']; + defaultConfig = { + dbConnection: { + enable: false + } + }; + + _export('ZabbixDSConfigController', ZabbixDSConfigController = function () { + /** @ngInject */ + function ZabbixDSConfigController($scope, $injector, datasourceSrv) { + _classCallCheck(this, ZabbixDSConfigController); + + this.datasourceSrv = datasourceSrv; + + _.defaults(this.current.jsonData, defaultConfig); + this.sqlDataSources = this.getSupportedSQLDataSources(); + } + + _createClass(ZabbixDSConfigController, [{ + key: 'getSupportedSQLDataSources', + value: function getSupportedSQLDataSources() { + var datasources = this.datasourceSrv.getAll(); + return _.filter(datasources, function (ds) { + return _.includes(SUPPORTED_SQL_DS, ds.type); + }); + } + }]); + + return ZabbixDSConfigController; + }()); + + _export('ZabbixDSConfigController', ZabbixDSConfigController); + + ZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; + } + }; +}); +//# sourceMappingURL=config.controller.js.map diff --git a/dist/datasource-zabbix/config.controller.js.map b/dist/datasource-zabbix/config.controller.js.map new file mode 100644 index 0000000..afc3a6b --- /dev/null +++ b/dist/datasource-zabbix/config.controller.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../src/datasource-zabbix/config.controller.js"],"names":["_","SUPPORTED_SQL_DS","defaultConfig","dbConnection","enable","ZabbixDSConfigController","$scope","$injector","datasourceSrv","defaults","current","jsonData","sqlDataSources","getSupportedSQLDataSources","datasources","getAll","filter","includes","ds","type","templateUrl"],"mappings":";;;;;;;;;;;;;;;AAAOA,O;;;;;;;;;;;;;;;;;;;;;AAEDC,sB,GAAmB,CAAC,OAAD,C;AAEnBC,mB,GAAgB;AACpBC,sBAAc;AACZC,kBAAQ;AADI;AADM,O;;0CAMTC,wB;AACX;AACA,0CAAYC,MAAZ,EAAoBC,SAApB,EAA+BC,aAA/B,EAA8C;AAAA;;AAC5C,eAAKA,aAAL,GAAqBA,aAArB;;AAEAR,YAAES,QAAF,CAAW,KAAKC,OAAL,CAAaC,QAAxB,EAAkCT,aAAlC;AACA,eAAKU,cAAL,GAAsB,KAAKC,0BAAL,EAAtB;AACD;;;;uDAE4B;AAC3B,gBAAIC,cAAc,KAAKN,aAAL,CAAmBO,MAAnB,EAAlB;AACA,mBAAOf,EAAEgB,MAAF,CAASF,WAAT,EAAsB,cAAM;AACjC,qBAAOd,EAAEiB,QAAF,CAAWhB,gBAAX,EAA6BiB,GAAGC,IAAhC,CAAP;AACD,aAFM,CAAP;AAGD;;;;;;;;AAGHd,+BAAyBe,WAAzB,GAAuC,wCAAvC","file":"config.controller.js","sourcesContent":["import _ from 'lodash';\n\nconst SUPPORTED_SQL_DS = ['mysql'];\n\nconst defaultConfig = {\n dbConnection: {\n enable: false,\n }\n};\n\nexport class ZabbixDSConfigController {\n /** @ngInject */\n constructor($scope, $injector, datasourceSrv) {\n this.datasourceSrv = datasourceSrv;\n\n _.defaults(this.current.jsonData, defaultConfig);\n this.sqlDataSources = this.getSupportedSQLDataSources();\n }\n\n getSupportedSQLDataSources() {\n let datasources = this.datasourceSrv.getAll();\n return _.filter(datasources, ds => {\n return _.includes(SUPPORTED_SQL_DS, ds.type);\n });\n }\n}\n\nZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html';\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/datasource.js b/dist/datasource-zabbix/datasource.js index 505a619..bc8e398 100644 --- a/dist/datasource-zabbix/datasource.js +++ b/dist/datasource-zabbix/datasource.js @@ -23,10 +23,23 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations', }); } + function getConsolidateBy(target) { + var consolidateBy = 'avg'; + var funcDef = _.find(target.functions, function (func) { + return func.def.name === 'consolidateBy'; + }); + if (funcDef && funcDef.params && funcDef.params.length) { + consolidateBy = funcDef.params[0]; + } + return consolidateBy; + } + function downsampleSeries(timeseries_data, options) { + var defaultAgg = dataProcessor.aggregationFunctions['avg']; + var consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg; return _.map(timeseries_data, function (timeseries) { if (timeseries.datapoints.length > options.maxDataPoints) { - timeseries.datapoints = dataProcessor.groupBy(options.interval, dataProcessor.AVERAGE, timeseries.datapoints); + timeseries.datapoints = dataProcessor.groupBy(options.interval, consolidateByFunc, timeseries.datapoints); } return timeseries; }); @@ -191,6 +204,9 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations', this.dashboardSrv = dashboardSrv; this.zabbixAlertingSrv = zabbixAlertingSrv; + // Use custom format for template variables + this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv); + // General data source settings this.name = instanceSettings.name; this.url = instanceSettings.url; @@ -215,10 +231,21 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations', this.addThresholds = instanceSettings.jsonData.addThresholds; this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING; - this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL); + // Direct DB Connection options + this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable; + this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId; - // Use custom format for template variables - this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv); + var zabbixOptions = { + username: this.username, + password: this.password, + basicAuth: this.basicAuth, + withCredentials: this.withCredentials, + cacheTTL: this.cacheTTL, + enableDirectDBConnection: this.enableDirectDBConnection, + sqlDatasourceId: this.sqlDatasourceId + }; + + this.zabbix = new Zabbix(this.url, zabbixOptions); } //////////////////////// @@ -324,26 +351,38 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations', }; return this.zabbix.getItemsFromTarget(target, getItemOptions).then(function (items) { var getHistoryPromise = void 0; + options.consolidateBy = getConsolidateBy(target); if (useTrends) { - var valueType = _this2.getTrendValueType(target); - getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) { - return responseHandler.handleTrends(history, items, valueType); - }).then(function (timeseries) { - // Sort trend data, issue #202 - _.forEach(timeseries, function (series) { - series.datapoints = _.sortBy(series.datapoints, function (point) { - return point[c.DATAPOINT_TS]; - }); + if (_this2.enableDirectDBConnection) { + getHistoryPromise = _this2.zabbix.getTrendsDB(items, timeFrom, timeTo, options).then(function (history) { + return _this2.zabbix.dbConnector.handleGrafanaTSResponse(history, items); }); - - return timeseries; - }); + } else { + var valueType = _this2.getTrendValueType(target); + getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) { + return responseHandler.handleTrends(history, items, valueType); + }).then(function (timeseries) { + // Sort trend data, issue #202 + _.forEach(timeseries, function (series) { + series.datapoints = _.sortBy(series.datapoints, function (point) { + return point[c.DATAPOINT_TS]; + }); + }); + return timeseries; + }); + } } else { // Use history - getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) { - return responseHandler.handleHistory(history, items); - }); + if (_this2.enableDirectDBConnection) { + getHistoryPromise = _this2.zabbix.getHistoryDB(items, timeFrom, timeTo, options).then(function (history) { + return _this2.zabbix.dbConnector.handleGrafanaTSResponse(history, items); + }); + } else { + getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) { + return responseHandler.handleHistory(history, items); + }); + } } return getHistoryPromise; diff --git a/dist/datasource-zabbix/datasource.js.map b/dist/datasource-zabbix/datasource.js.map index 6d4e9c2..338081b 100644 --- a/dist/datasource-zabbix/datasource.js.map +++ b/dist/datasource-zabbix/datasource.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/datasource-zabbix/datasource.js"],"names":["bindFunctionDefs","functionDefs","category","aggregationFunctions","_","map","metricFunctions","getCategories","aggFuncDefs","filter","func","includes","def","name","funcInstance","createFuncInstance","params","bindFunction","dataProcessor","downsampleSeries","timeseries_data","options","timeseries","datapoints","length","maxDataPoints","groupBy","interval","AVERAGE","formatMetric","metricObj","text","expandable","zabbixTemplateFormat","value","utils","escapeRegex","escapedValues","join","replaceTemplateVars","templateSrv","target","scopedVars","replacedTarget","replace","isRegex","sequence","funcsArray","result","i","call","filterEnabledTargets","targets","hide","group","host","item","getTriggerThreshold","expression","thresholdPattern","finded_thresholds","match","threshold","Number","dateMath","migrations","c","responseHandler","ZabbixAPIError","ZabbixAPIDatasource","instanceSettings","alertSrv","dashboardSrv","zabbixAlertingSrv","Zabbix","url","basicAuth","withCredentials","username","jsonData","password","trends","trendsFrom","trendsRange","ttl","cacheTTL","parseInterval","alertingEnabled","alerting","addThresholds","alertingMinSeverity","SEV_WARNING","zabbix","partial","alertQuery","then","setPanelAlertState","panelId","alert","state","removeZabbixThreshold","forEach","thresholds","setPanelThreshold","promises","timeFrom","Math","ceil","parse","range","from","timeTo","to","cloneDeep","t","replaceTargetVariables","timeFunctions","functions","time_from","time_to","timeRange","useTrends","isUseTrends","mode","MODE_ITSERVICE","migrate","MODE_METRICS","queryNumericData","MODE_TEXT","queryTextData","itservice","slaProperty","getSLA","serviceid","handleSLAResponse","slaObject","Promise","all","flatten","data","getItemOptions","itemtype","getItemsFromTarget","getHistoryPromise","valueType","getTrendValueType","getTrend","items","handleTrends","history","series","sortBy","point","DATAPOINT_TS","getHistory","handleHistory","applyDataProcessingFunctions","catch","console","log","error","trendFunctions","trendValueFunc","find","transformFunctions","filterFunctions","aliasFunctions","dp","aggFuncNames","lastAgg","findLast","applyTimeShiftFunction","timeShiftFunc","shift","unShiftTimeSeries","handleText","resolve","zabbixVersion","getVersion","version","login","status","title","message","query","parts","each","splitTemplateQuery","part","push","template","zipObject","app","getItems","getApps","getHosts","getGroups","metrics","rangeRaw","annotation","showOkEvents","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","triggersOptions","showTriggers","SHOW_ALL_TRIGGERS","hideHostsInMaintenance","getTriggers","application","triggerName","trigger","triggers","buildRegex","test","description","priority","minseverity","objectids","getEvents","indexedTriggers","keyBy","hideAcknowledged","events","event","acknowledges","tags","showHostname","hosts","formatted_acknowledges","formatAcknowledges","time","clock","objectid","enabled_targets","getPanelItems","results","itemids","getAlerts","firedTriggers","p","textFilter","param","toString","useTrendsFrom","useTrendsRange","contains","indexBy"],"mappings":"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","file":"datasource.js","sourcesContent":["import _ from 'lodash';\nimport * as dateMath from 'app/core/utils/datemath';\nimport * as utils from './utils';\nimport * as migrations from './migrations';\nimport * as metricFunctions from './metricFunctions';\nimport * as c from './constants';\nimport dataProcessor from './dataProcessor';\nimport responseHandler from './responseHandler';\nimport './zabbix.js';\nimport './zabbixAlerting.service.js';\nimport {ZabbixAPIError} from './zabbixAPICore.service.js';\n\nclass ZabbixAPIDatasource {\n\n /** @ngInject */\n constructor(instanceSettings, templateSrv, alertSrv, dashboardSrv, zabbixAlertingSrv, Zabbix) {\n this.templateSrv = templateSrv;\n this.alertSrv = alertSrv;\n this.dashboardSrv = dashboardSrv;\n this.zabbixAlertingSrv = zabbixAlertingSrv;\n\n // General data source settings\n this.name = instanceSettings.name;\n this.url = instanceSettings.url;\n this.basicAuth = instanceSettings.basicAuth;\n this.withCredentials = instanceSettings.withCredentials;\n\n // Zabbix API credentials\n this.username = instanceSettings.jsonData.username;\n this.password = instanceSettings.jsonData.password;\n\n // Use trends instead history since specified time\n this.trends = instanceSettings.jsonData.trends;\n this.trendsFrom = instanceSettings.jsonData.trendsFrom || '7d';\n this.trendsRange = instanceSettings.jsonData.trendsRange || '4d';\n\n // Set cache update interval\n var ttl = instanceSettings.jsonData.cacheTTL || '1h';\n this.cacheTTL = utils.parseInterval(ttl);\n\n // Alerting options\n this.alertingEnabled = instanceSettings.jsonData.alerting;\n this.addThresholds = instanceSettings.jsonData.addThresholds;\n this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING;\n\n this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL);\n\n // Use custom format for template variables\n this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv);\n }\n\n ////////////////////////\n // Datasource methods //\n ////////////////////////\n\n /**\n * Query panel data. Calls for each panel in dashboard.\n * @param {Object} options Contains time range, targets and other info.\n * @return {Object} Grafana metrics object with timeseries data for each target.\n */\n query(options) {\n // Get alerts for current panel\n if (this.alertingEnabled) {\n this.alertQuery(options).then(alert => {\n this.zabbixAlertingSrv.setPanelAlertState(options.panelId, alert.state);\n\n this.zabbixAlertingSrv.removeZabbixThreshold(options.panelId);\n if (this.addThresholds) {\n _.forEach(alert.thresholds, threshold => {\n this.zabbixAlertingSrv.setPanelThreshold(options.panelId, threshold);\n });\n }\n });\n }\n\n // Create request for each target\n let promises = _.map(options.targets, t => {\n let timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);\n let timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);\n\n // Prevent changes of original object\n let target = _.cloneDeep(t);\n this.replaceTargetVariables(target, options);\n\n // Apply Time-related functions (timeShift(), etc)\n let timeFunctions = bindFunctionDefs(target.functions, 'Time');\n if (timeFunctions.length) {\n const [time_from, time_to] = sequence(timeFunctions)([timeFrom, timeTo]);\n timeFrom = time_from;\n timeTo = time_to;\n }\n let timeRange = [timeFrom, timeTo];\n\n let useTrends = this.isUseTrends(timeRange);\n\n // Metrics or Text query mode\n if (target.mode !== c.MODE_ITSERVICE) {\n // Migrate old targets\n target = migrations.migrate(target);\n\n // Don't request undefined and hidden targets\n if (target.hide || !target.group || !target.host || !target.item) {\n return [];\n }\n\n if (!target.mode || target.mode === c.MODE_METRICS) {\n return this.queryNumericData(target, timeRange, useTrends, options);\n } else if (target.mode === c.MODE_TEXT) {\n return this.queryTextData(target, timeRange);\n }\n }\n\n // IT services mode\n else if (target.mode === c.MODE_ITSERVICE) {\n // Don't show undefined and hidden targets\n if (target.hide || !target.itservice || !target.slaProperty) {\n return [];\n }\n\n return this.zabbix.getSLA(target.itservice.serviceid, timeRange)\n .then(slaObject => {\n return responseHandler.handleSLAResponse(target.itservice, target.slaProperty, slaObject);\n });\n }\n });\n\n // Data for panel (all targets)\n return Promise.all(_.flatten(promises))\n .then(_.flatten)\n .then(data => {\n return { data: data };\n });\n }\n\n queryNumericData(target, timeRange, useTrends, options) {\n let [timeFrom, timeTo] = timeRange;\n let getItemOptions = {\n itemtype: 'num'\n };\n return this.zabbix.getItemsFromTarget(target, getItemOptions)\n .then(items => {\n let getHistoryPromise;\n\n if (useTrends) {\n let valueType = this.getTrendValueType(target);\n getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo)\n .then(history => {\n return responseHandler.handleTrends(history, items, valueType);\n })\n .then(timeseries => {\n // Sort trend data, issue #202\n _.forEach(timeseries, series => {\n series.datapoints = _.sortBy(series.datapoints, point => point[c.DATAPOINT_TS]);\n });\n\n return timeseries;\n });\n } else {\n // Use history\n getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo)\n .then(history => {\n return responseHandler.handleHistory(history, items);\n });\n }\n\n return getHistoryPromise;\n })\n .then(timeseries => this.applyDataProcessingFunctions(timeseries, target))\n .then(timeseries => downsampleSeries(timeseries, options))\n .catch(error => {\n console.log(error);\n return [];\n });\n }\n\n getTrendValueType(target) {\n // Find trendValue() function and get specified trend value\n var trendFunctions = _.map(metricFunctions.getCategories()['Trends'], 'name');\n var trendValueFunc = _.find(target.functions, func => {\n return _.includes(trendFunctions, func.def.name);\n });\n return trendValueFunc ? trendValueFunc.params[0] : \"avg\";\n }\n\n applyDataProcessingFunctions(timeseries_data, target) {\n let transformFunctions = bindFunctionDefs(target.functions, 'Transform');\n let aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate');\n let filterFunctions = bindFunctionDefs(target.functions, 'Filter');\n let aliasFunctions = bindFunctionDefs(target.functions, 'Alias');\n\n // Apply transformation functions\n timeseries_data = _.map(timeseries_data, timeseries => {\n timeseries.datapoints = sequence(transformFunctions)(timeseries.datapoints);\n return timeseries;\n });\n\n // Apply filter functions\n if (filterFunctions.length) {\n timeseries_data = sequence(filterFunctions)(timeseries_data);\n }\n\n // Apply aggregations\n if (aggregationFunctions.length) {\n let dp = _.map(timeseries_data, 'datapoints');\n dp = sequence(aggregationFunctions)(dp);\n\n let aggFuncNames = _.map(metricFunctions.getCategories()['Aggregate'], 'name');\n let lastAgg = _.findLast(target.functions, func => {\n return _.includes(aggFuncNames, func.def.name);\n });\n\n timeseries_data = [{\n target: lastAgg.text,\n datapoints: dp\n }];\n }\n\n // Apply alias functions\n _.forEach(timeseries_data, sequence(aliasFunctions));\n\n // Apply Time-related functions (timeShift(), etc)\n // Find timeShift() function and get specified trend value\n this.applyTimeShiftFunction(timeseries_data, target);\n\n return timeseries_data;\n }\n\n applyTimeShiftFunction(timeseries_data, target) {\n // Find timeShift() function and get specified interval\n let timeShiftFunc = _.find(target.functions, (func) => {\n return func.def.name === 'timeShift';\n });\n if (timeShiftFunc) {\n let shift = timeShiftFunc.params[0];\n _.forEach(timeseries_data, (series) => {\n series.datapoints = dataProcessor.unShiftTimeSeries(shift, series.datapoints);\n });\n }\n }\n\n queryTextData(target, timeRange) {\n let [timeFrom, timeTo] = timeRange;\n let options = {\n itemtype: 'text'\n };\n return this.zabbix.getItemsFromTarget(target, options)\n .then(items => {\n if (items.length) {\n return this.zabbix.getHistory(items, timeFrom, timeTo)\n .then(history => {\n return responseHandler.handleText(history, items, target);\n });\n } else {\n return Promise.resolve([]);\n }\n });\n }\n\n /**\n * Test connection to Zabbix API\n * @return {object} Connection status and Zabbix API version\n */\n testDatasource() {\n let zabbixVersion;\n return this.zabbix.getVersion()\n .then(version => {\n zabbixVersion = version;\n return this.zabbix.login();\n })\n .then(() => {\n return {\n status: \"success\",\n title: \"Success\",\n message: \"Zabbix API version: \" + zabbixVersion\n };\n })\n .catch(error => {\n if (error instanceof ZabbixAPIError) {\n return {\n status: \"error\",\n title: error.message,\n message: error.data\n };\n } else {\n return {\n status: \"error\",\n title: \"Connection failed\",\n message: \"Could not connect to given url\"\n };\n }\n });\n }\n\n ////////////////\n // Templating //\n ////////////////\n\n /**\n * Find metrics from templated request.\n *\n * @param {string} query Query from Templating\n * @return {string} Metric name - group, host, app or item or list\n * of metrics in \"{metric1,metcic2,...,metricN}\" format.\n */\n metricFindQuery(query) {\n let result;\n let parts = [];\n\n // Split query. Query structure: group.host.app.item\n _.each(utils.splitTemplateQuery(query), part => {\n part = this.replaceTemplateVars(part, {});\n\n // Replace wildcard to regex\n if (part === '*') {\n part = '/.*/';\n }\n parts.push(part);\n });\n let template = _.zipObject(['group', 'host', 'app', 'item'], parts);\n\n // Get items\n if (parts.length === 4) {\n // Search for all items, even it's not belong to any application\n if (template.app === '/.*/') {\n template.app = '';\n }\n result = this.zabbix.getItems(template.group, template.host, template.app, template.item);\n } else if (parts.length === 3) {\n // Get applications\n result = this.zabbix.getApps(template.group, template.host, template.app);\n } else if (parts.length === 2) {\n // Get hosts\n result = this.zabbix.getHosts(template.group, template.host);\n } else if (parts.length === 1) {\n // Get groups\n result = this.zabbix.getGroups(template.group);\n } else {\n result = Promise.resolve([]);\n }\n\n return result.then(metrics => {\n return _.map(metrics, formatMetric);\n });\n }\n\n /////////////////\n // Annotations //\n /////////////////\n\n annotationQuery(options) {\n var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);\n var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);\n var annotation = options.annotation;\n var showOkEvents = annotation.showOkEvents ? c.SHOW_ALL_EVENTS : c.SHOW_OK_EVENTS;\n\n // Show all triggers\n let triggersOptions = {\n showTriggers: c.SHOW_ALL_TRIGGERS,\n hideHostsInMaintenance: false\n };\n\n var getTriggers = this.zabbix.getTriggers(this.replaceTemplateVars(annotation.group, {}),\n this.replaceTemplateVars(annotation.host, {}),\n this.replaceTemplateVars(annotation.application, {}),\n triggersOptions);\n\n return getTriggers.then(triggers => {\n\n // Filter triggers by description\n let triggerName = this.replaceTemplateVars(annotation.trigger, {});\n if (utils.isRegex(triggerName)) {\n triggers = _.filter(triggers, trigger => {\n return utils.buildRegex(triggerName).test(trigger.description);\n });\n } else if (triggerName) {\n triggers = _.filter(triggers, trigger => {\n return trigger.description === triggerName;\n });\n }\n\n // Remove events below the chose severity\n triggers = _.filter(triggers, trigger => {\n return Number(trigger.priority) >= Number(annotation.minseverity);\n });\n\n var objectids = _.map(triggers, 'triggerid');\n return this.zabbix\n .getEvents(objectids, timeFrom, timeTo, showOkEvents)\n .then(events => {\n var indexedTriggers = _.keyBy(triggers, 'triggerid');\n\n // Hide acknowledged events if option enabled\n if (annotation.hideAcknowledged) {\n events = _.filter(events, event => {\n return !event.acknowledges.length;\n });\n }\n\n return _.map(events, event => {\n let tags;\n if (annotation.showHostname) {\n tags = _.map(event.hosts, 'name');\n }\n\n // Show event type (OK or Problem)\n let title = Number(event.value) ? 'Problem' : 'OK';\n\n let formatted_acknowledges = utils.formatAcknowledges(event.acknowledges);\n return {\n annotation: annotation,\n time: event.clock * 1000,\n title: title,\n tags: tags,\n text: indexedTriggers[event.objectid].description + formatted_acknowledges\n };\n });\n });\n });\n }\n\n /**\n * Get triggers and its details for panel's targets\n * Returns alert state ('ok' if no fired triggers, or 'alerting' if at least 1 trigger is fired)\n * or empty object if no related triggers are finded.\n */\n alertQuery(options) {\n let enabled_targets = filterEnabledTargets(options.targets);\n let getPanelItems = _.map(enabled_targets, t => {\n let target = _.cloneDeep(t);\n this.replaceTargetVariables(target, options);\n return this.zabbix.getItemsFromTarget(target, {itemtype: 'num'});\n });\n\n return Promise.all(getPanelItems)\n .then(results => {\n let items = _.flatten(results);\n let itemids = _.map(items, 'itemid');\n\n return this.zabbix.getAlerts(itemids);\n })\n .then(triggers => {\n triggers = _.filter(triggers, trigger => {\n return trigger.priority >= this.alertingMinSeverity;\n });\n\n if (!triggers || triggers.length === 0) {\n return {};\n }\n\n let state = 'ok';\n\n let firedTriggers = _.filter(triggers, {value: '1'});\n if (firedTriggers.length) {\n state = 'alerting';\n }\n\n let thresholds = _.map(triggers, trigger => {\n return getTriggerThreshold(trigger.expression);\n });\n\n return {\n panelId: options.panelId,\n state: state,\n thresholds: thresholds\n };\n });\n }\n\n // Replace template variables\n replaceTargetVariables(target, options) {\n let parts = ['group', 'host', 'application', 'item'];\n _.forEach(parts, p => {\n if (target[p] && target[p].filter) {\n target[p].filter = this.replaceTemplateVars(target[p].filter, options.scopedVars);\n }\n });\n target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);\n\n _.forEach(target.functions, func => {\n func.params = _.map(func.params, param => {\n if (typeof param === 'number') {\n return +this.templateSrv.replace(param.toString(), options.scopedVars);\n } else {\n return this.templateSrv.replace(param, options.scopedVars);\n }\n });\n });\n }\n\n isUseTrends(timeRange) {\n let [timeFrom, timeTo] = timeRange;\n let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);\n let useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000);\n let useTrends = this.trends && (\n (timeFrom <= useTrendsFrom) ||\n (timeTo - timeFrom >= useTrendsRange)\n );\n return useTrends;\n }\n}\n\nfunction bindFunctionDefs(functionDefs, category) {\n var aggregationFunctions = _.map(metricFunctions.getCategories()[category], 'name');\n var aggFuncDefs = _.filter(functionDefs, function(func) {\n return _.includes(aggregationFunctions, func.def.name);\n });\n\n return _.map(aggFuncDefs, function(func) {\n var funcInstance = metricFunctions.createFuncInstance(func.def, func.params);\n return funcInstance.bindFunction(dataProcessor.metricFunctions);\n });\n}\n\nfunction downsampleSeries(timeseries_data, options) {\n return _.map(timeseries_data, timeseries => {\n if (timeseries.datapoints.length > options.maxDataPoints) {\n timeseries.datapoints = dataProcessor\n .groupBy(options.interval, dataProcessor.AVERAGE, timeseries.datapoints);\n }\n return timeseries;\n });\n}\n\nfunction formatMetric(metricObj) {\n return {\n text: metricObj.name,\n expandable: false\n };\n}\n\n/**\n * Custom formatter for template variables.\n * Default Grafana \"regex\" formatter returns\n * value1|value2\n * This formatter returns\n * (value1|value2)\n * This format needed for using in complex regex with\n * template variables, for example\n * /CPU $cpu_item.*time/ where $cpu_item is system,user,iowait\n */\nfunction zabbixTemplateFormat(value) {\n if (typeof value === 'string') {\n return utils.escapeRegex(value);\n }\n\n var escapedValues = _.map(value, utils.escapeRegex);\n return '(' + escapedValues.join('|') + ')';\n}\n\n/**\n * If template variables are used in request, replace it using regex format\n * and wrap with '/' for proper multi-value work. Example:\n * $variable selected as a, b, c\n * We use filter $variable\n * $variable -> a|b|c -> /a|b|c/\n * /$variable/ -> /a|b|c/ -> /a|b|c/\n */\nfunction replaceTemplateVars(templateSrv, target, scopedVars) {\n var replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat);\n if (target !== replacedTarget && !utils.isRegex(replacedTarget)) {\n replacedTarget = '/^' + replacedTarget + '$/';\n }\n return replacedTarget;\n}\n\n// Apply function one by one:\n// sequence([a(), b(), c()]) = c(b(a()));\nfunction sequence(funcsArray) {\n return function(result) {\n for (var i = 0; i < funcsArray.length; i++) {\n result = funcsArray[i].call(this, result);\n }\n return result;\n };\n}\n\nfunction filterEnabledTargets(targets) {\n return _.filter(targets, target => {\n return !(target.hide || !target.group || !target.host || !target.item);\n });\n}\n\nfunction getTriggerThreshold(expression) {\n let thresholdPattern = /.*[<>]([\\d\\.]+)/;\n let finded_thresholds = expression.match(thresholdPattern);\n if (finded_thresholds && finded_thresholds.length >= 2) {\n let threshold = finded_thresholds[1];\n threshold = Number(threshold);\n return threshold;\n } else {\n return null;\n }\n}\n\nexport {ZabbixAPIDatasource, zabbixTemplateFormat};\n\n// Fix for backward compatibility with lodash 2.4\nif (!_.includes) {_.includes = _.contains;}\nif (!_.keyBy) {_.keyBy = _.indexBy;}\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/datasource-zabbix/datasource.js"],"names":["bindFunctionDefs","functionDefs","category","aggregationFunctions","_","map","metricFunctions","getCategories","aggFuncDefs","filter","func","includes","def","name","funcInstance","createFuncInstance","params","bindFunction","dataProcessor","getConsolidateBy","target","consolidateBy","funcDef","find","functions","length","downsampleSeries","timeseries_data","options","defaultAgg","consolidateByFunc","timeseries","datapoints","maxDataPoints","groupBy","interval","formatMetric","metricObj","text","expandable","zabbixTemplateFormat","value","utils","escapeRegex","escapedValues","join","replaceTemplateVars","templateSrv","scopedVars","replacedTarget","replace","isRegex","sequence","funcsArray","result","i","call","filterEnabledTargets","targets","hide","group","host","item","getTriggerThreshold","expression","thresholdPattern","finded_thresholds","match","threshold","Number","dateMath","migrations","c","responseHandler","ZabbixAPIError","ZabbixAPIDatasource","instanceSettings","alertSrv","dashboardSrv","zabbixAlertingSrv","Zabbix","partial","url","basicAuth","withCredentials","username","jsonData","password","trends","trendsFrom","trendsRange","ttl","cacheTTL","parseInterval","alertingEnabled","alerting","addThresholds","alertingMinSeverity","SEV_WARNING","enableDirectDBConnection","dbConnection","enable","sqlDatasourceId","datasourceId","zabbixOptions","zabbix","alertQuery","then","setPanelAlertState","panelId","alert","state","removeZabbixThreshold","forEach","thresholds","setPanelThreshold","promises","timeFrom","Math","ceil","parse","range","from","timeTo","to","cloneDeep","t","replaceTargetVariables","timeFunctions","time_from","time_to","timeRange","useTrends","isUseTrends","mode","MODE_ITSERVICE","migrate","MODE_METRICS","queryNumericData","MODE_TEXT","queryTextData","itservice","slaProperty","getSLA","serviceid","handleSLAResponse","slaObject","Promise","all","flatten","data","getItemOptions","itemtype","getItemsFromTarget","getHistoryPromise","getTrendsDB","items","dbConnector","handleGrafanaTSResponse","history","valueType","getTrendValueType","getTrend","handleTrends","series","sortBy","point","DATAPOINT_TS","getHistoryDB","getHistory","handleHistory","applyDataProcessingFunctions","catch","console","log","error","trendFunctions","trendValueFunc","transformFunctions","filterFunctions","aliasFunctions","dp","aggFuncNames","lastAgg","findLast","applyTimeShiftFunction","timeShiftFunc","shift","unShiftTimeSeries","handleText","resolve","zabbixVersion","getVersion","version","login","status","title","message","query","parts","each","splitTemplateQuery","part","push","template","zipObject","app","getItems","getApps","getHosts","getGroups","metrics","rangeRaw","annotation","showOkEvents","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","triggersOptions","showTriggers","SHOW_ALL_TRIGGERS","hideHostsInMaintenance","getTriggers","application","triggerName","trigger","triggers","buildRegex","test","description","priority","minseverity","objectids","getEvents","indexedTriggers","keyBy","hideAcknowledged","events","event","acknowledges","tags","showHostname","hosts","formatted_acknowledges","formatAcknowledges","time","clock","objectid","enabled_targets","getPanelItems","results","itemids","getAlerts","firedTriggers","p","textFilter","param","toString","useTrendsFrom","useTrendsRange","contains","indexBy"],"mappings":";;;;;;;;;;;;;AAygBA,WAASA,gBAAT,CAA0BC,YAA1B,EAAwCC,QAAxC,EAAkD;AAChD,QAAIC,uBAAuBC,EAAEC,GAAF,CAAMC,gBAAgBC,aAAhB,GAAgCL,QAAhC,CAAN,EAAiD,MAAjD,CAA3B;AACA,QAAIM,cAAcJ,EAAEK,MAAF,CAASR,YAAT,EAAuB,UAASS,IAAT,EAAe;AACtD,aAAON,EAAEO,QAAF,CAAWR,oBAAX,EAAiCO,KAAKE,GAAL,CAASC,IAA1C,CAAP;AACD,KAFiB,CAAlB;;AAIA,WAAOT,EAAEC,GAAF,CAAMG,WAAN,EAAmB,UAASE,IAAT,EAAe;AACvC,UAAII,eAAeR,gBAAgBS,kBAAhB,CAAmCL,KAAKE,GAAxC,EAA6CF,KAAKM,MAAlD,CAAnB;AACA,aAAOF,aAAaG,YAAb,CAA0BC,cAAcZ,eAAxC,CAAP;AACD,KAHM,CAAP;AAID;;AAED,WAASa,gBAAT,CAA0BC,MAA1B,EAAkC;AAChC,QAAIC,gBAAgB,KAApB;AACA,QAAIC,UAAUlB,EAAEmB,IAAF,CAAOH,OAAOI,SAAd,EAAyB,gBAAQ;AAC7C,aAAOd,KAAKE,GAAL,CAASC,IAAT,KAAkB,eAAzB;AACD,KAFa,CAAd;AAGA,QAAIS,WAAWA,QAAQN,MAAnB,IAA6BM,QAAQN,MAAR,CAAeS,MAAhD,EAAwD;AACtDJ,sBAAgBC,QAAQN,MAAR,CAAe,CAAf,CAAhB;AACD;AACD,WAAOK,aAAP;AACD;;AAED,WAASK,gBAAT,CAA0BC,eAA1B,EAA2CC,OAA3C,EAAoD;AAClD,QAAIC,aAAaX,cAAcf,oBAAd,CAAmC,KAAnC,CAAjB;AACA,QAAI2B,oBAAoBZ,cAAcf,oBAAd,CAAmCyB,QAAQP,aAA3C,KAA6DQ,UAArF;AACA,WAAOzB,EAAEC,GAAF,CAAMsB,eAAN,EAAuB,sBAAc;AAC1C,UAAII,WAAWC,UAAX,CAAsBP,MAAtB,GAA+BG,QAAQK,aAA3C,EAA0D;AACxDF,mBAAWC,UAAX,GAAwBd,cACrBgB,OADqB,CACbN,QAAQO,QADK,EACKL,iBADL,EACwBC,WAAWC,UADnC,CAAxB;AAED;AACD,aAAOD,UAAP;AACD,KANM,CAAP;AAOD;;AAED,WAASK,YAAT,CAAsBC,SAAtB,EAAiC;AAC/B,WAAO;AACLC,YAAMD,UAAUxB,IADX;AAEL0B,kBAAY;AAFP,KAAP;AAID;;AAED;;;;;;;;;;AAUA,WAASC,oBAAT,CAA8BC,KAA9B,EAAqC;AACnC,QAAI,OAAOA,KAAP,KAAiB,QAArB,EAA+B;AAC7B,aAAOC,MAAMC,WAAN,CAAkBF,KAAlB,CAAP;AACD;;AAED,QAAIG,gBAAgBxC,EAAEC,GAAF,CAAMoC,KAAN,EAAaC,MAAMC,WAAnB,CAApB;AACA,WAAO,MAAMC,cAAcC,IAAd,CAAmB,GAAnB,CAAN,GAAgC,GAAvC;AACD;;AAED;;;;;;;;AAQA,WAASC,mBAAT,CAA6BC,WAA7B,EAA0C3B,MAA1C,EAAkD4B,UAAlD,EAA8D;AAC5D,QAAIC,iBAAiBF,YAAYG,OAAZ,CAAoB9B,MAApB,EAA4B4B,UAA5B,EAAwCR,oBAAxC,CAArB;AACA,QAAIpB,WAAW6B,cAAX,IAA6B,CAACP,MAAMS,OAAN,CAAcF,cAAd,CAAlC,EAAiE;AAC/DA,uBAAiB,OAAOA,cAAP,GAAwB,IAAzC;AACD;AACD,WAAOA,cAAP;AACD;;AAED;AACA;AACA,WAASG,QAAT,CAAkBC,UAAlB,EAA8B;AAC5B,WAAO,UAASC,MAAT,EAAiB;AACtB,WAAK,IAAIC,IAAI,CAAb,EAAgBA,IAAIF,WAAW5B,MAA/B,EAAuC8B,GAAvC,EAA4C;AAC1CD,iBAASD,WAAWE,CAAX,EAAcC,IAAd,CAAmB,IAAnB,EAAyBF,MAAzB,CAAT;AACD;AACD,aAAOA,MAAP;AACD,KALD;AAMD;;AAED,WAASG,oBAAT,CAA8BC,OAA9B,EAAuC;AACrC,WAAOtD,EAAEK,MAAF,CAASiD,OAAT,EAAkB,kBAAU;AACjC,aAAO,EAAEtC,OAAOuC,IAAP,IAAe,CAACvC,OAAOwC,KAAvB,IAAgC,CAACxC,OAAOyC,IAAxC,IAAgD,CAACzC,OAAO0C,IAA1D,CAAP;AACD,KAFM,CAAP;AAGD;;AAED,WAASC,mBAAT,CAA6BC,UAA7B,EAAyC;AACvC,QAAIC,mBAAmB,iBAAvB;AACA,QAAIC,oBAAoBF,WAAWG,KAAX,CAAiBF,gBAAjB,CAAxB;AACA,QAAIC,qBAAqBA,kBAAkBzC,MAAlB,IAA4B,CAArD,EAAwD;AACtD,UAAI2C,YAAYF,kBAAkB,CAAlB,CAAhB;AACAE,kBAAYC,OAAOD,SAAP,CAAZ;AACA,aAAOA,SAAP;AACD,KAJD,MAIO;AACL,aAAO,IAAP;AACD;AACF;;;;AAjnBMhE,O;;AACKkE,c;;AACA5B,W;;AACA6B,gB;;AACAjE,qB;;AACAkE,O;;AACLtD,mB;;AACAuD,qB;;AAGCC,oB,2BAAAA,c;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAEFC,mB;;AAEJ;AACA,qCAAYC,gBAAZ,EAA8B7B,WAA9B,EAA2C8B,QAA3C,EAAqDC,YAArD,EAAmEC,iBAAnE,EAAsFC,MAAtF,EAA8F;AAAA;;AAC5F,eAAKjC,WAAL,GAAmBA,WAAnB;AACA,eAAK8B,QAAL,GAAgBA,QAAhB;AACA,eAAKC,YAAL,GAAoBA,YAApB;AACA,eAAKC,iBAAL,GAAyBA,iBAAzB;;AAEA;AACA,eAAKjC,mBAAL,GAA2B1C,EAAE6E,OAAF,CAAUnC,mBAAV,EAA+B,KAAKC,WAApC,CAA3B;;AAEA;AACA,eAAKlC,IAAL,GAAwB+D,iBAAiB/D,IAAzC;AACA,eAAKqE,GAAL,GAAwBN,iBAAiBM,GAAzC;AACA,eAAKC,SAAL,GAAwBP,iBAAiBO,SAAzC;AACA,eAAKC,eAAL,GAAwBR,iBAAiBQ,eAAzC;;AAEA;AACA,eAAKC,QAAL,GAAwBT,iBAAiBU,QAAjB,CAA0BD,QAAlD;AACA,eAAKE,QAAL,GAAwBX,iBAAiBU,QAAjB,CAA0BC,QAAlD;;AAEA;AACA,eAAKC,MAAL,GAAwBZ,iBAAiBU,QAAjB,CAA0BE,MAAlD;AACA,eAAKC,UAAL,GAAwBb,iBAAiBU,QAAjB,CAA0BG,UAA1B,IAAwC,IAAhE;AACA,eAAKC,WAAL,GAAwBd,iBAAiBU,QAAjB,CAA0BI,WAA1B,IAAyC,IAAjE;;AAEA;AACA,cAAIC,MAAMf,iBAAiBU,QAAjB,CAA0BM,QAA1B,IAAsC,IAAhD;AACA,eAAKA,QAAL,GAAgBlD,MAAMmD,aAAN,CAAoBF,GAApB,CAAhB;;AAEA;AACA,eAAKG,eAAL,GAAuBlB,iBAAiBU,QAAjB,CAA0BS,QAAjD;AACA,eAAKC,aAAL,GAAqBpB,iBAAiBU,QAAjB,CAA0BU,aAA/C;AACA,eAAKC,mBAAL,GAA2BrB,iBAAiBU,QAAjB,CAA0BW,mBAA1B,IAAiDzB,EAAE0B,WAA9E;;AAEA;AACA,eAAKC,wBAAL,GAAgCvB,iBAAiBU,QAAjB,CAA0Bc,YAA1B,CAAuCC,MAAvE;AACA,eAAKC,eAAL,GAAuB1B,iBAAiBU,QAAjB,CAA0Bc,YAA1B,CAAuCG,YAA9D;;AAEA,cAAIC,gBAAgB;AAClBnB,sBAAU,KAAKA,QADG;AAElBE,sBAAU,KAAKA,QAFG;AAGlBJ,uBAAW,KAAKA,SAHE;AAIlBC,6BAAiB,KAAKA,eAJJ;AAKlBQ,sBAAU,KAAKA,QALG;AAMlBO,sCAA0B,KAAKA,wBANb;AAOlBG,6BAAiB,KAAKA;AAPJ,WAApB;;AAUA,eAAKG,MAAL,GAAc,IAAIzB,MAAJ,CAAW,KAAKE,GAAhB,EAAqBsB,aAArB,CAAd;AACD;;AAED;AACA;AACA;;AAEA;;;;;;;;;gCAKM5E,O,EAAS;AAAA;;AACb;AACA,gBAAI,KAAKkE,eAAT,EAA0B;AACxB,mBAAKY,UAAL,CAAgB9E,OAAhB,EAAyB+E,IAAzB,CAA8B,iBAAS;AACrC,sBAAK5B,iBAAL,CAAuB6B,kBAAvB,CAA0ChF,QAAQiF,OAAlD,EAA2DC,MAAMC,KAAjE;;AAEA,sBAAKhC,iBAAL,CAAuBiC,qBAAvB,CAA6CpF,QAAQiF,OAArD;AACA,oBAAI,MAAKb,aAAT,EAAwB;AACtB5F,oBAAE6G,OAAF,CAAUH,MAAMI,UAAhB,EAA4B,qBAAa;AACvC,0BAAKnC,iBAAL,CAAuBoC,iBAAvB,CAAyCvF,QAAQiF,OAAjD,EAA0DzC,SAA1D;AACD,mBAFD;AAGD;AACF,eATD;AAUD;;AAED;AACA,gBAAIgD,WAAWhH,EAAEC,GAAF,CAAMuB,QAAQ8B,OAAd,EAAuB,aAAK;AACzC,kBAAI2D,WAAWC,KAAKC,IAAL,CAAUjD,SAASkD,KAAT,CAAe5F,QAAQ6F,KAAR,CAAcC,IAA7B,IAAqC,IAA/C,CAAf;AACA,kBAAIC,SAASL,KAAKC,IAAL,CAAUjD,SAASkD,KAAT,CAAe5F,QAAQ6F,KAAR,CAAcG,EAA7B,IAAmC,IAA7C,CAAb;;AAEA;AACA,kBAAIxG,SAAShB,EAAEyH,SAAF,CAAYC,CAAZ,CAAb;AACA,oBAAKC,sBAAL,CAA4B3G,MAA5B,EAAoCQ,OAApC;;AAEA;AACA,kBAAIoG,gBAAgBhI,iBAAiBoB,OAAOI,SAAxB,EAAmC,MAAnC,CAApB;AACA,kBAAIwG,cAAcvG,MAAlB,EAA0B;AAAA,gCACK2B,SAAS4E,aAAT,EAAwB,CAACX,QAAD,EAAWM,MAAX,CAAxB,CADL;AAAA;AAAA,oBACjBM,SADiB;AAAA,oBACNC,OADM;;AAExBb,2BAAWY,SAAX;AACAN,yBAASO,OAAT;AACD;AACD,kBAAIC,YAAY,CAACd,QAAD,EAAWM,MAAX,CAAhB;;AAEA,kBAAIS,YAAY,MAAKC,WAAL,CAAiBF,SAAjB,CAAhB;;AAEA;AACA,kBAAI/G,OAAOkH,IAAP,KAAgB9D,EAAE+D,cAAtB,EAAsC;AACpC;AACAnH,yBAASmD,WAAWiE,OAAX,CAAmBpH,MAAnB,CAAT;;AAEA;AACA,oBAAIA,OAAOuC,IAAP,IAAe,CAACvC,OAAOwC,KAAvB,IAAgC,CAACxC,OAAOyC,IAAxC,IAAgD,CAACzC,OAAO0C,IAA5D,EAAkE;AAChE,yBAAO,EAAP;AACD;;AAED,oBAAI,CAAC1C,OAAOkH,IAAR,IAAgBlH,OAAOkH,IAAP,KAAgB9D,EAAEiE,YAAtC,EAAoD;AAClD,yBAAO,MAAKC,gBAAL,CAAsBtH,MAAtB,EAA8B+G,SAA9B,EAAyCC,SAAzC,EAAoDxG,OAApD,CAAP;AACD,iBAFD,MAEO,IAAIR,OAAOkH,IAAP,KAAgB9D,EAAEmE,SAAtB,EAAiC;AACtC,yBAAO,MAAKC,aAAL,CAAmBxH,MAAnB,EAA2B+G,SAA3B,CAAP;AACD;AACF;;AAED;AAhBA,mBAiBK,IAAI/G,OAAOkH,IAAP,KAAgB9D,EAAE+D,cAAtB,EAAsC;AACzC;AACA,sBAAInH,OAAOuC,IAAP,IAAe,CAACvC,OAAOyH,SAAvB,IAAoC,CAACzH,OAAO0H,WAAhD,EAA6D;AAC3D,2BAAO,EAAP;AACD;;AAED,yBAAO,MAAKrC,MAAL,CAAYsC,MAAZ,CAAmB3H,OAAOyH,SAAP,CAAiBG,SAApC,EAA+Cb,SAA/C,EACNxB,IADM,CACD,qBAAa;AACjB,2BAAOlC,gBAAgBwE,iBAAhB,CAAkC7H,OAAOyH,SAAzC,EAAoDzH,OAAO0H,WAA3D,EAAwEI,SAAxE,CAAP;AACD,mBAHM,CAAP;AAID;AACF,aAhDc,CAAf;;AAkDA;AACA,mBAAOC,QAAQC,GAAR,CAAYhJ,EAAEiJ,OAAF,CAAUjC,QAAV,CAAZ,EACJT,IADI,CACCvG,EAAEiJ,OADH,EAEJ1C,IAFI,CAEC,gBAAQ;AACZ,qBAAO,EAAE2C,MAAMA,IAAR,EAAP;AACD,aAJI,CAAP;AAKD;;;2CAEgBlI,M,EAAQ+G,S,EAAWC,S,EAAWxG,O,EAAS;AAAA;;AAAA,4CAC7BuG,SAD6B;AAAA,gBACjDd,QADiD;AAAA,gBACvCM,MADuC;;AAEtD,gBAAI4B,iBAAiB;AACnBC,wBAAU;AADS,aAArB;AAGA,mBAAO,KAAK/C,MAAL,CAAYgD,kBAAZ,CAA+BrI,MAA/B,EAAuCmI,cAAvC,EACN5C,IADM,CACD,iBAAS;AACb,kBAAI+C,0BAAJ;AACA9H,sBAAQP,aAAR,GAAwBF,iBAAiBC,MAAjB,CAAxB;;AAEA,kBAAIgH,SAAJ,EAAe;AACb,oBAAI,OAAKjC,wBAAT,EAAmC;AACjCuD,sCAAoB,OAAKjD,MAAL,CAAYkD,WAAZ,CAAwBC,KAAxB,EAA+BvC,QAA/B,EAAyCM,MAAzC,EAAiD/F,OAAjD,EACnB+E,IADmB,CACd;AAAA,2BAAW,OAAKF,MAAL,CAAYoD,WAAZ,CAAwBC,uBAAxB,CAAgDC,OAAhD,EAAyDH,KAAzD,CAAX;AAAA,mBADc,CAApB;AAED,iBAHD,MAGO;AACL,sBAAII,YAAY,OAAKC,iBAAL,CAAuB7I,MAAvB,CAAhB;AACAsI,sCAAoB,OAAKjD,MAAL,CAAYyD,QAAZ,CAAqBN,KAArB,EAA4BvC,QAA5B,EAAsCM,MAAtC,EACnBhB,IADmB,CACd;AAAA,2BAAWlC,gBAAgB0F,YAAhB,CAA6BJ,OAA7B,EAAsCH,KAAtC,EAA6CI,SAA7C,CAAX;AAAA,mBADc,EAEnBrD,IAFmB,CAEd,sBAAc;AAClB;AACAvG,sBAAE6G,OAAF,CAAUlF,UAAV,EAAsB,kBAAU;AAC9BqI,6BAAOpI,UAAP,GAAoB5B,EAAEiK,MAAF,CAASD,OAAOpI,UAAhB,EAA4B;AAAA,+BAASsI,MAAM9F,EAAE+F,YAAR,CAAT;AAAA,uBAA5B,CAApB;AACD,qBAFD;AAGA,2BAAOxI,UAAP;AACD,mBARmB,CAApB;AASD;AACF,eAhBD,MAgBO;AACL;AACA,oBAAI,OAAKoE,wBAAT,EAAmC;AACjCuD,sCAAoB,OAAKjD,MAAL,CAAY+D,YAAZ,CAAyBZ,KAAzB,EAAgCvC,QAAhC,EAA0CM,MAA1C,EAAkD/F,OAAlD,EACnB+E,IADmB,CACd;AAAA,2BAAW,OAAKF,MAAL,CAAYoD,WAAZ,CAAwBC,uBAAxB,CAAgDC,OAAhD,EAAyDH,KAAzD,CAAX;AAAA,mBADc,CAApB;AAED,iBAHD,MAGO;AACLF,sCAAoB,OAAKjD,MAAL,CAAYgE,UAAZ,CAAuBb,KAAvB,EAA8BvC,QAA9B,EAAwCM,MAAxC,EACnBhB,IADmB,CACd;AAAA,2BAAWlC,gBAAgBiG,aAAhB,CAA8BX,OAA9B,EAAuCH,KAAvC,CAAX;AAAA,mBADc,CAApB;AAED;AACF;;AAED,qBAAOF,iBAAP;AACD,aAjCM,EAkCN/C,IAlCM,CAkCD;AAAA,qBAAc,OAAKgE,4BAAL,CAAkC5I,UAAlC,EAA8CX,MAA9C,CAAd;AAAA,aAlCC,EAmCNuF,IAnCM,CAmCD;AAAA,qBAAcjF,iBAAiBK,UAAjB,EAA6BH,OAA7B,CAAd;AAAA,aAnCC,EAoCNgJ,KApCM,CAoCA,iBAAS;AACdC,sBAAQC,GAAR,CAAYC,KAAZ;AACA,qBAAO,EAAP;AACD,aAvCM,CAAP;AAwCD;;;4CAEiB3J,M,EAAQ;AACxB;AACA,gBAAI4J,iBAAiB5K,EAAEC,GAAF,CAAMC,gBAAgBC,aAAhB,GAAgC,QAAhC,CAAN,EAAiD,MAAjD,CAArB;AACA,gBAAI0K,iBAAiB7K,EAAEmB,IAAF,CAAOH,OAAOI,SAAd,EAAyB,gBAAQ;AACpD,qBAAOpB,EAAEO,QAAF,CAAWqK,cAAX,EAA2BtK,KAAKE,GAAL,CAASC,IAApC,CAAP;AACD,aAFoB,CAArB;AAGA,mBAAOoK,iBAAiBA,eAAejK,MAAf,CAAsB,CAAtB,CAAjB,GAA4C,KAAnD;AACD;;;uDAE4BW,e,EAAiBP,M,EAAQ;AACpD,gBAAI8J,qBAAuBlL,iBAAiBoB,OAAOI,SAAxB,EAAmC,WAAnC,CAA3B;AACA,gBAAIrB,uBAAuBH,iBAAiBoB,OAAOI,SAAxB,EAAmC,WAAnC,CAA3B;AACA,gBAAI2J,kBAAuBnL,iBAAiBoB,OAAOI,SAAxB,EAAmC,QAAnC,CAA3B;AACA,gBAAI4J,iBAAuBpL,iBAAiBoB,OAAOI,SAAxB,EAAmC,OAAnC,CAA3B;;AAEA;AACAG,8BAAkBvB,EAAEC,GAAF,CAAMsB,eAAN,EAAuB,sBAAc;AACrDI,yBAAWC,UAAX,GAAwBoB,SAAS8H,kBAAT,EAA6BnJ,WAAWC,UAAxC,CAAxB;AACA,qBAAOD,UAAP;AACD,aAHiB,CAAlB;;AAKA;AACA,gBAAIoJ,gBAAgB1J,MAApB,EAA4B;AAC1BE,gCAAkByB,SAAS+H,eAAT,EAA0BxJ,eAA1B,CAAlB;AACD;;AAED;AACA,gBAAIxB,qBAAqBsB,MAAzB,EAAiC;AAC/B,kBAAI4J,KAAKjL,EAAEC,GAAF,CAAMsB,eAAN,EAAuB,YAAvB,CAAT;AACA0J,mBAAKjI,SAASjD,oBAAT,EAA+BkL,EAA/B,CAAL;;AAEA,kBAAIC,eAAelL,EAAEC,GAAF,CAAMC,gBAAgBC,aAAhB,GAAgC,WAAhC,CAAN,EAAoD,MAApD,CAAnB;AACA,kBAAIgL,UAAUnL,EAAEoL,QAAF,CAAWpK,OAAOI,SAAlB,EAA6B,gBAAQ;AACjD,uBAAOpB,EAAEO,QAAF,CAAW2K,YAAX,EAAyB5K,KAAKE,GAAL,CAASC,IAAlC,CAAP;AACD,eAFa,CAAd;;AAIAc,gCAAkB,CAAC;AACjBP,wBAAQmK,QAAQjJ,IADC;AAEjBN,4BAAYqJ;AAFK,eAAD,CAAlB;AAID;;AAED;AACAjL,cAAE6G,OAAF,CAAUtF,eAAV,EAA2ByB,SAASgI,cAAT,CAA3B;;AAEA;AACA;AACA,iBAAKK,sBAAL,CAA4B9J,eAA5B,EAA6CP,MAA7C;;AAEA,mBAAOO,eAAP;AACD;;;iDAEsBA,e,EAAiBP,M,EAAQ;AAC9C;AACA,gBAAIsK,gBAAgBtL,EAAEmB,IAAF,CAAOH,OAAOI,SAAd,EAAyB,UAACd,IAAD,EAAU;AACrD,qBAAOA,KAAKE,GAAL,CAASC,IAAT,KAAkB,WAAzB;AACD,aAFmB,CAApB;AAGA,gBAAI6K,aAAJ,EAAmB;AACjB,kBAAIC,QAAQD,cAAc1K,MAAd,CAAqB,CAArB,CAAZ;AACAZ,gBAAE6G,OAAF,CAAUtF,eAAV,EAA2B,UAACyI,MAAD,EAAY;AACrCA,uBAAOpI,UAAP,GAAoBd,cAAc0K,iBAAd,CAAgCD,KAAhC,EAAuCvB,OAAOpI,UAA9C,CAApB;AACD,eAFD;AAGD;AACF;;;wCAEaZ,M,EAAQ+G,S,EAAW;AAAA;;AAAA,6CACNA,SADM;AAAA,gBAC1Bd,QAD0B;AAAA,gBAChBM,MADgB;;AAE/B,gBAAI/F,UAAU;AACZ4H,wBAAU;AADE,aAAd;AAGA,mBAAO,KAAK/C,MAAL,CAAYgD,kBAAZ,CAA+BrI,MAA/B,EAAuCQ,OAAvC,EACJ+E,IADI,CACC,iBAAS;AACb,kBAAIiD,MAAMnI,MAAV,EAAkB;AAChB,uBAAO,OAAKgF,MAAL,CAAYgE,UAAZ,CAAuBb,KAAvB,EAA8BvC,QAA9B,EAAwCM,MAAxC,EACNhB,IADM,CACD,mBAAW;AACf,yBAAOlC,gBAAgBoH,UAAhB,CAA2B9B,OAA3B,EAAoCH,KAApC,EAA2CxI,MAA3C,CAAP;AACD,iBAHM,CAAP;AAID,eALD,MAKO;AACL,uBAAO+H,QAAQ2C,OAAR,CAAgB,EAAhB,CAAP;AACD;AACF,aAVI,CAAP;AAWD;;;2CAMgB;AAAA;;AACf,gBAAIC,sBAAJ;AACA,mBAAO,KAAKtF,MAAL,CAAYuF,UAAZ,GACNrF,IADM,CACD,mBAAW;AACfoF,8BAAgBE,OAAhB;AACA,qBAAO,OAAKxF,MAAL,CAAYyF,KAAZ,EAAP;AACD,aAJM,EAKNvF,IALM,CAKD,YAAM;AACV,qBAAO;AACLwF,wBAAQ,SADH;AAELC,uBAAO,SAFF;AAGLC,yBAAS,yBAAyBN;AAH7B,eAAP;AAKD,aAXM,EAYNnB,KAZM,CAYA,iBAAS;AACd,kBAAIG,iBAAiBrG,cAArB,EAAqC;AACnC,uBAAO;AACLyH,0BAAQ,OADH;AAELC,yBAAOrB,MAAMsB,OAFR;AAGLA,2BAAStB,MAAMzB;AAHV,iBAAP;AAKD,eAND,MAMO;AACL,uBAAO;AACL6C,0BAAQ,OADH;AAELC,yBAAO,mBAFF;AAGLC,2BAAS;AAHJ,iBAAP;AAKD;AACF,aA1BM,CAAP;AA2BD;;;0CAaeC,K,EAAO;AAAA;;AACrB,gBAAIhJ,eAAJ;AACA,gBAAIiJ,QAAQ,EAAZ;;AAEA;AACAnM,cAAEoM,IAAF,CAAO9J,MAAM+J,kBAAN,CAAyBH,KAAzB,CAAP,EAAwC,gBAAQ;AAC9CI,qBAAO,OAAK5J,mBAAL,CAAyB4J,IAAzB,EAA+B,EAA/B,CAAP;;AAEA;AACA,kBAAIA,SAAS,GAAb,EAAkB;AAChBA,uBAAO,MAAP;AACD;AACDH,oBAAMI,IAAN,CAAWD,IAAX;AACD,aARD;AASA,gBAAIE,WAAWxM,EAAEyM,SAAF,CAAY,CAAC,OAAD,EAAU,MAAV,EAAkB,KAAlB,EAAyB,MAAzB,CAAZ,EAA8CN,KAA9C,CAAf;;AAEA;AACA,gBAAIA,MAAM9K,MAAN,KAAiB,CAArB,EAAwB;AACtB;AACA,kBAAImL,SAASE,GAAT,KAAiB,MAArB,EAA6B;AAC3BF,yBAASE,GAAT,GAAe,EAAf;AACD;AACDxJ,uBAAS,KAAKmD,MAAL,CAAYsG,QAAZ,CAAqBH,SAAShJ,KAA9B,EAAqCgJ,SAAS/I,IAA9C,EAAoD+I,SAASE,GAA7D,EAAkEF,SAAS9I,IAA3E,CAAT;AACD,aAND,MAMO,IAAIyI,MAAM9K,MAAN,KAAiB,CAArB,EAAwB;AAC7B;AACA6B,uBAAS,KAAKmD,MAAL,CAAYuG,OAAZ,CAAoBJ,SAAShJ,KAA7B,EAAoCgJ,SAAS/I,IAA7C,EAAmD+I,SAASE,GAA5D,CAAT;AACD,aAHM,MAGA,IAAIP,MAAM9K,MAAN,KAAiB,CAArB,EAAwB;AAC7B;AACA6B,uBAAS,KAAKmD,MAAL,CAAYwG,QAAZ,CAAqBL,SAAShJ,KAA9B,EAAqCgJ,SAAS/I,IAA9C,CAAT;AACD,aAHM,MAGA,IAAI0I,MAAM9K,MAAN,KAAiB,CAArB,EAAwB;AAC7B;AACA6B,uBAAS,KAAKmD,MAAL,CAAYyG,SAAZ,CAAsBN,SAAShJ,KAA/B,CAAT;AACD,aAHM,MAGA;AACLN,uBAAS6F,QAAQ2C,OAAR,CAAgB,EAAhB,CAAT;AACD;;AAED,mBAAOxI,OAAOqD,IAAP,CAAY,mBAAW;AAC5B,qBAAOvG,EAAEC,GAAF,CAAM8M,OAAN,EAAe/K,YAAf,CAAP;AACD,aAFM,CAAP;AAGD;;;0CAMeR,O,EAAS;AAAA;;AACvB,gBAAIyF,WAAWC,KAAKC,IAAL,CAAUjD,SAASkD,KAAT,CAAe5F,QAAQwL,QAAR,CAAiB1F,IAAhC,IAAwC,IAAlD,CAAf;AACA,gBAAIC,SAASL,KAAKC,IAAL,CAAUjD,SAASkD,KAAT,CAAe5F,QAAQwL,QAAR,CAAiBxF,EAAhC,IAAsC,IAAhD,CAAb;AACA,gBAAIyF,aAAazL,QAAQyL,UAAzB;AACA,gBAAIC,eAAeD,WAAWC,YAAX,GAA0B9I,EAAE+I,eAA5B,GAA8C/I,EAAEgJ,cAAnE;;AAEA;AACA,gBAAIC,kBAAkB;AACpBC,4BAAclJ,EAAEmJ,iBADI;AAEpBC,sCAAwB;AAFJ,aAAtB;;AAKA,gBAAIC,cAAc,KAAKpH,MAAL,CAAYoH,WAAZ,CAAwB,KAAK/K,mBAAL,CAAyBuK,WAAWzJ,KAApC,EAA2C,EAA3C,CAAxB,EACwB,KAAKd,mBAAL,CAAyBuK,WAAWxJ,IAApC,EAA0C,EAA1C,CADxB,EAEwB,KAAKf,mBAAL,CAAyBuK,WAAWS,WAApC,EAAiD,EAAjD,CAFxB,EAGwBL,eAHxB,CAAlB;;AAKA,mBAAOI,YAAYlH,IAAZ,CAAiB,oBAAY;;AAElC;AACA,kBAAIoH,cAAc,OAAKjL,mBAAL,CAAyBuK,WAAWW,OAApC,EAA6C,EAA7C,CAAlB;AACA,kBAAItL,MAAMS,OAAN,CAAc4K,WAAd,CAAJ,EAAgC;AAC9BE,2BAAW7N,EAAEK,MAAF,CAASwN,QAAT,EAAmB,mBAAW;AACvC,yBAAOvL,MAAMwL,UAAN,CAAiBH,WAAjB,EAA8BI,IAA9B,CAAmCH,QAAQI,WAA3C,CAAP;AACD,iBAFU,CAAX;AAGD,eAJD,MAIO,IAAIL,WAAJ,EAAiB;AACtBE,2BAAW7N,EAAEK,MAAF,CAASwN,QAAT,EAAmB,mBAAW;AACvC,yBAAOD,QAAQI,WAAR,KAAwBL,WAA/B;AACD,iBAFU,CAAX;AAGD;;AAED;AACAE,yBAAW7N,EAAEK,MAAF,CAASwN,QAAT,EAAmB,mBAAW;AACvC,uBAAO5J,OAAO2J,QAAQK,QAAf,KAA4BhK,OAAOgJ,WAAWiB,WAAlB,CAAnC;AACD,eAFU,CAAX;;AAIA,kBAAIC,YAAYnO,EAAEC,GAAF,CAAM4N,QAAN,EAAgB,WAAhB,CAAhB;AACA,qBAAO,OAAKxH,MAAL,CACJ+H,SADI,CACMD,SADN,EACiBlH,QADjB,EAC2BM,MAD3B,EACmC2F,YADnC,EAEJ3G,IAFI,CAEC,kBAAU;AACd,oBAAI8H,kBAAkBrO,EAAEsO,KAAF,CAAQT,QAAR,EAAkB,WAAlB,CAAtB;;AAEA;AACA,oBAAIZ,WAAWsB,gBAAf,EAAiC;AAC/BC,2BAASxO,EAAEK,MAAF,CAASmO,MAAT,EAAiB,iBAAS;AACjC,2BAAO,CAACC,MAAMC,YAAN,CAAmBrN,MAA3B;AACD,mBAFQ,CAAT;AAGD;;AAED,uBAAOrB,EAAEC,GAAF,CAAMuO,MAAN,EAAc,iBAAS;AAC5B,sBAAIG,aAAJ;AACA,sBAAI1B,WAAW2B,YAAf,EAA6B;AAC3BD,2BAAO3O,EAAEC,GAAF,CAAMwO,MAAMI,KAAZ,EAAmB,MAAnB,CAAP;AACD;;AAED;AACA,sBAAI7C,QAAQ/H,OAAOwK,MAAMpM,KAAb,IAAsB,SAAtB,GAAkC,IAA9C;;AAEA,sBAAIyM,yBAAyBxM,MAAMyM,kBAAN,CAAyBN,MAAMC,YAA/B,CAA7B;AACA,yBAAO;AACLzB,gCAAYA,UADP;AAEL+B,0BAAMP,MAAMQ,KAAN,GAAc,IAFf;AAGLjD,2BAAOA,KAHF;AAIL2C,0BAAMA,IAJD;AAKLzM,0BAAMmM,gBAAgBI,MAAMS,QAAtB,EAAgClB,WAAhC,GAA8Cc;AAL/C,mBAAP;AAOD,iBAjBM,CAAP;AAkBD,eA9BI,CAAP;AA+BD,aAnDM,CAAP;AAoDD;;;qCAOUtN,O,EAAS;AAAA;;AAClB,gBAAI2N,kBAAkB9L,qBAAqB7B,QAAQ8B,OAA7B,CAAtB;AACA,gBAAI8L,gBAAgBpP,EAAEC,GAAF,CAAMkP,eAAN,EAAuB,aAAK;AAC9C,kBAAInO,SAAShB,EAAEyH,SAAF,CAAYC,CAAZ,CAAb;AACA,qBAAKC,sBAAL,CAA4B3G,MAA5B,EAAoCQ,OAApC;AACA,qBAAO,OAAK6E,MAAL,CAAYgD,kBAAZ,CAA+BrI,MAA/B,EAAuC,EAACoI,UAAU,KAAX,EAAvC,CAAP;AACD,aAJmB,CAApB;;AAMA,mBAAOL,QAAQC,GAAR,CAAYoG,aAAZ,EACN7I,IADM,CACD,mBAAW;AACf,kBAAIiD,QAAQxJ,EAAEiJ,OAAF,CAAUoG,OAAV,CAAZ;AACA,kBAAIC,UAAUtP,EAAEC,GAAF,CAAMuJ,KAAN,EAAa,QAAb,CAAd;;AAEA,qBAAO,OAAKnD,MAAL,CAAYkJ,SAAZ,CAAsBD,OAAtB,CAAP;AACD,aANM,EAON/I,IAPM,CAOD,oBAAY;AAChBsH,yBAAW7N,EAAEK,MAAF,CAASwN,QAAT,EAAmB,mBAAW;AACvC,uBAAOD,QAAQK,QAAR,IAAoB,OAAKpI,mBAAhC;AACD,eAFU,CAAX;;AAIA,kBAAI,CAACgI,QAAD,IAAaA,SAASxM,MAAT,KAAoB,CAArC,EAAwC;AACtC,uBAAO,EAAP;AACD;;AAED,kBAAIsF,QAAQ,IAAZ;;AAEA,kBAAI6I,gBAAgBxP,EAAEK,MAAF,CAASwN,QAAT,EAAmB,EAACxL,OAAO,GAAR,EAAnB,CAApB;AACA,kBAAImN,cAAcnO,MAAlB,EAA0B;AACxBsF,wBAAQ,UAAR;AACD;;AAED,kBAAIG,aAAa9G,EAAEC,GAAF,CAAM4N,QAAN,EAAgB,mBAAW;AAC1C,uBAAOlK,oBAAoBiK,QAAQhK,UAA5B,CAAP;AACD,eAFgB,CAAjB;;AAIA,qBAAO;AACL6C,yBAASjF,QAAQiF,OADZ;AAELE,uBAAOA,KAFF;AAGLG,4BAAYA;AAHP,eAAP;AAKD,aAhCM,CAAP;AAiCD;;;iDAGsB9F,M,EAAQQ,O,EAAS;AAAA;;AACtC,gBAAI2K,QAAQ,CAAC,OAAD,EAAU,MAAV,EAAkB,aAAlB,EAAiC,MAAjC,CAAZ;AACAnM,cAAE6G,OAAF,CAAUsF,KAAV,EAAiB,aAAK;AACpB,kBAAInL,OAAOyO,CAAP,KAAazO,OAAOyO,CAAP,EAAUpP,MAA3B,EAAmC;AACjCW,uBAAOyO,CAAP,EAAUpP,MAAV,GAAmB,OAAKqC,mBAAL,CAAyB1B,OAAOyO,CAAP,EAAUpP,MAAnC,EAA2CmB,QAAQoB,UAAnD,CAAnB;AACD;AACF,aAJD;AAKA5B,mBAAO0O,UAAP,GAAoB,KAAKhN,mBAAL,CAAyB1B,OAAO0O,UAAhC,EAA4ClO,QAAQoB,UAApD,CAApB;;AAEA5C,cAAE6G,OAAF,CAAU7F,OAAOI,SAAjB,EAA4B,gBAAQ;AAClCd,mBAAKM,MAAL,GAAcZ,EAAEC,GAAF,CAAMK,KAAKM,MAAX,EAAmB,iBAAS;AACxC,oBAAI,OAAO+O,KAAP,KAAiB,QAArB,EAA+B;AAC7B,yBAAO,CAAC,OAAKhN,WAAL,CAAiBG,OAAjB,CAAyB6M,MAAMC,QAAN,EAAzB,EAA2CpO,QAAQoB,UAAnD,CAAR;AACD,iBAFD,MAEO;AACL,yBAAO,OAAKD,WAAL,CAAiBG,OAAjB,CAAyB6M,KAAzB,EAAgCnO,QAAQoB,UAAxC,CAAP;AACD;AACF,eANa,CAAd;AAOD,aARD;AASD;;;sCAEWmF,S,EAAW;AAAA,6CACIA,SADJ;AAAA,gBAChBd,QADgB;AAAA,gBACNM,MADM;;AAErB,gBAAIsI,gBAAgB3I,KAAKC,IAAL,CAAUjD,SAASkD,KAAT,CAAe,SAAS,KAAK/B,UAA7B,IAA2C,IAArD,CAApB;AACA,gBAAIyK,iBAAiB5I,KAAKC,IAAL,CAAU7E,MAAMmD,aAAN,CAAoB,KAAKH,WAAzB,IAAwC,IAAlD,CAArB;AACA,gBAAI0C,YAAY,KAAK5C,MAAL,KACb6B,YAAY4I,aAAb,IACCtI,SAASN,QAAT,IAAqB6I,cAFR,CAAhB;AAIA,mBAAO9H,SAAP;AACD;;;;;;qCA6GKzD,mB;;sCAAqBnC,oB;;AAE7B;AACA,UAAI,CAACpC,EAAEO,QAAP,EAAiB;AAACP,UAAEO,QAAF,GAAaP,EAAE+P,QAAf;AAAyB;AAC3C,UAAI,CAAC/P,EAAEsO,KAAP,EAAc;AAACtO,UAAEsO,KAAF,GAAUtO,EAAEgQ,OAAZ;AAAqB","file":"datasource.js","sourcesContent":["import _ from 'lodash';\nimport * as dateMath from 'app/core/utils/datemath';\nimport * as utils from './utils';\nimport * as migrations from './migrations';\nimport * as metricFunctions from './metricFunctions';\nimport * as c from './constants';\nimport dataProcessor from './dataProcessor';\nimport responseHandler from './responseHandler';\nimport './zabbix.js';\nimport './zabbixAlerting.service.js';\nimport {ZabbixAPIError} from './zabbixAPICore.service.js';\n\nclass ZabbixAPIDatasource {\n\n /** @ngInject */\n constructor(instanceSettings, templateSrv, alertSrv, dashboardSrv, zabbixAlertingSrv, Zabbix) {\n this.templateSrv = templateSrv;\n this.alertSrv = alertSrv;\n this.dashboardSrv = dashboardSrv;\n this.zabbixAlertingSrv = zabbixAlertingSrv;\n\n // Use custom format for template variables\n this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv);\n\n // General data source settings\n this.name = instanceSettings.name;\n this.url = instanceSettings.url;\n this.basicAuth = instanceSettings.basicAuth;\n this.withCredentials = instanceSettings.withCredentials;\n\n // Zabbix API credentials\n this.username = instanceSettings.jsonData.username;\n this.password = instanceSettings.jsonData.password;\n\n // Use trends instead history since specified time\n this.trends = instanceSettings.jsonData.trends;\n this.trendsFrom = instanceSettings.jsonData.trendsFrom || '7d';\n this.trendsRange = instanceSettings.jsonData.trendsRange || '4d';\n\n // Set cache update interval\n var ttl = instanceSettings.jsonData.cacheTTL || '1h';\n this.cacheTTL = utils.parseInterval(ttl);\n\n // Alerting options\n this.alertingEnabled = instanceSettings.jsonData.alerting;\n this.addThresholds = instanceSettings.jsonData.addThresholds;\n this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING;\n\n // Direct DB Connection options\n this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable;\n this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId;\n\n let zabbixOptions = {\n username: this.username,\n password: this.password,\n basicAuth: this.basicAuth,\n withCredentials: this.withCredentials,\n cacheTTL: this.cacheTTL,\n enableDirectDBConnection: this.enableDirectDBConnection,\n sqlDatasourceId: this.sqlDatasourceId\n };\n\n this.zabbix = new Zabbix(this.url, zabbixOptions);\n }\n\n ////////////////////////\n // Datasource methods //\n ////////////////////////\n\n /**\n * Query panel data. Calls for each panel in dashboard.\n * @param {Object} options Contains time range, targets and other info.\n * @return {Object} Grafana metrics object with timeseries data for each target.\n */\n query(options) {\n // Get alerts for current panel\n if (this.alertingEnabled) {\n this.alertQuery(options).then(alert => {\n this.zabbixAlertingSrv.setPanelAlertState(options.panelId, alert.state);\n\n this.zabbixAlertingSrv.removeZabbixThreshold(options.panelId);\n if (this.addThresholds) {\n _.forEach(alert.thresholds, threshold => {\n this.zabbixAlertingSrv.setPanelThreshold(options.panelId, threshold);\n });\n }\n });\n }\n\n // Create request for each target\n let promises = _.map(options.targets, t => {\n let timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);\n let timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);\n\n // Prevent changes of original object\n let target = _.cloneDeep(t);\n this.replaceTargetVariables(target, options);\n\n // Apply Time-related functions (timeShift(), etc)\n let timeFunctions = bindFunctionDefs(target.functions, 'Time');\n if (timeFunctions.length) {\n const [time_from, time_to] = sequence(timeFunctions)([timeFrom, timeTo]);\n timeFrom = time_from;\n timeTo = time_to;\n }\n let timeRange = [timeFrom, timeTo];\n\n let useTrends = this.isUseTrends(timeRange);\n\n // Metrics or Text query mode\n if (target.mode !== c.MODE_ITSERVICE) {\n // Migrate old targets\n target = migrations.migrate(target);\n\n // Don't request undefined and hidden targets\n if (target.hide || !target.group || !target.host || !target.item) {\n return [];\n }\n\n if (!target.mode || target.mode === c.MODE_METRICS) {\n return this.queryNumericData(target, timeRange, useTrends, options);\n } else if (target.mode === c.MODE_TEXT) {\n return this.queryTextData(target, timeRange);\n }\n }\n\n // IT services mode\n else if (target.mode === c.MODE_ITSERVICE) {\n // Don't show undefined and hidden targets\n if (target.hide || !target.itservice || !target.slaProperty) {\n return [];\n }\n\n return this.zabbix.getSLA(target.itservice.serviceid, timeRange)\n .then(slaObject => {\n return responseHandler.handleSLAResponse(target.itservice, target.slaProperty, slaObject);\n });\n }\n });\n\n // Data for panel (all targets)\n return Promise.all(_.flatten(promises))\n .then(_.flatten)\n .then(data => {\n return { data: data };\n });\n }\n\n queryNumericData(target, timeRange, useTrends, options) {\n let [timeFrom, timeTo] = timeRange;\n let getItemOptions = {\n itemtype: 'num'\n };\n return this.zabbix.getItemsFromTarget(target, getItemOptions)\n .then(items => {\n let getHistoryPromise;\n options.consolidateBy = getConsolidateBy(target);\n\n if (useTrends) {\n if (this.enableDirectDBConnection) {\n getHistoryPromise = this.zabbix.getTrendsDB(items, timeFrom, timeTo, options)\n .then(history => this.zabbix.dbConnector.handleGrafanaTSResponse(history, items));\n } else {\n let valueType = this.getTrendValueType(target);\n getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo)\n .then(history => responseHandler.handleTrends(history, items, valueType))\n .then(timeseries => {\n // Sort trend data, issue #202\n _.forEach(timeseries, series => {\n series.datapoints = _.sortBy(series.datapoints, point => point[c.DATAPOINT_TS]);\n });\n return timeseries;\n });\n }\n } else {\n // Use history\n if (this.enableDirectDBConnection) {\n getHistoryPromise = this.zabbix.getHistoryDB(items, timeFrom, timeTo, options)\n .then(history => this.zabbix.dbConnector.handleGrafanaTSResponse(history, items));\n } else {\n getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo)\n .then(history => responseHandler.handleHistory(history, items));\n }\n }\n\n return getHistoryPromise;\n })\n .then(timeseries => this.applyDataProcessingFunctions(timeseries, target))\n .then(timeseries => downsampleSeries(timeseries, options))\n .catch(error => {\n console.log(error);\n return [];\n });\n }\n\n getTrendValueType(target) {\n // Find trendValue() function and get specified trend value\n var trendFunctions = _.map(metricFunctions.getCategories()['Trends'], 'name');\n var trendValueFunc = _.find(target.functions, func => {\n return _.includes(trendFunctions, func.def.name);\n });\n return trendValueFunc ? trendValueFunc.params[0] : \"avg\";\n }\n\n applyDataProcessingFunctions(timeseries_data, target) {\n let transformFunctions = bindFunctionDefs(target.functions, 'Transform');\n let aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate');\n let filterFunctions = bindFunctionDefs(target.functions, 'Filter');\n let aliasFunctions = bindFunctionDefs(target.functions, 'Alias');\n\n // Apply transformation functions\n timeseries_data = _.map(timeseries_data, timeseries => {\n timeseries.datapoints = sequence(transformFunctions)(timeseries.datapoints);\n return timeseries;\n });\n\n // Apply filter functions\n if (filterFunctions.length) {\n timeseries_data = sequence(filterFunctions)(timeseries_data);\n }\n\n // Apply aggregations\n if (aggregationFunctions.length) {\n let dp = _.map(timeseries_data, 'datapoints');\n dp = sequence(aggregationFunctions)(dp);\n\n let aggFuncNames = _.map(metricFunctions.getCategories()['Aggregate'], 'name');\n let lastAgg = _.findLast(target.functions, func => {\n return _.includes(aggFuncNames, func.def.name);\n });\n\n timeseries_data = [{\n target: lastAgg.text,\n datapoints: dp\n }];\n }\n\n // Apply alias functions\n _.forEach(timeseries_data, sequence(aliasFunctions));\n\n // Apply Time-related functions (timeShift(), etc)\n // Find timeShift() function and get specified trend value\n this.applyTimeShiftFunction(timeseries_data, target);\n\n return timeseries_data;\n }\n\n applyTimeShiftFunction(timeseries_data, target) {\n // Find timeShift() function and get specified interval\n let timeShiftFunc = _.find(target.functions, (func) => {\n return func.def.name === 'timeShift';\n });\n if (timeShiftFunc) {\n let shift = timeShiftFunc.params[0];\n _.forEach(timeseries_data, (series) => {\n series.datapoints = dataProcessor.unShiftTimeSeries(shift, series.datapoints);\n });\n }\n }\n\n queryTextData(target, timeRange) {\n let [timeFrom, timeTo] = timeRange;\n let options = {\n itemtype: 'text'\n };\n return this.zabbix.getItemsFromTarget(target, options)\n .then(items => {\n if (items.length) {\n return this.zabbix.getHistory(items, timeFrom, timeTo)\n .then(history => {\n return responseHandler.handleText(history, items, target);\n });\n } else {\n return Promise.resolve([]);\n }\n });\n }\n\n /**\n * Test connection to Zabbix API\n * @return {object} Connection status and Zabbix API version\n */\n testDatasource() {\n let zabbixVersion;\n return this.zabbix.getVersion()\n .then(version => {\n zabbixVersion = version;\n return this.zabbix.login();\n })\n .then(() => {\n return {\n status: \"success\",\n title: \"Success\",\n message: \"Zabbix API version: \" + zabbixVersion\n };\n })\n .catch(error => {\n if (error instanceof ZabbixAPIError) {\n return {\n status: \"error\",\n title: error.message,\n message: error.data\n };\n } else {\n return {\n status: \"error\",\n title: \"Connection failed\",\n message: \"Could not connect to given url\"\n };\n }\n });\n }\n\n ////////////////\n // Templating //\n ////////////////\n\n /**\n * Find metrics from templated request.\n *\n * @param {string} query Query from Templating\n * @return {string} Metric name - group, host, app or item or list\n * of metrics in \"{metric1,metcic2,...,metricN}\" format.\n */\n metricFindQuery(query) {\n let result;\n let parts = [];\n\n // Split query. Query structure: group.host.app.item\n _.each(utils.splitTemplateQuery(query), part => {\n part = this.replaceTemplateVars(part, {});\n\n // Replace wildcard to regex\n if (part === '*') {\n part = '/.*/';\n }\n parts.push(part);\n });\n let template = _.zipObject(['group', 'host', 'app', 'item'], parts);\n\n // Get items\n if (parts.length === 4) {\n // Search for all items, even it's not belong to any application\n if (template.app === '/.*/') {\n template.app = '';\n }\n result = this.zabbix.getItems(template.group, template.host, template.app, template.item);\n } else if (parts.length === 3) {\n // Get applications\n result = this.zabbix.getApps(template.group, template.host, template.app);\n } else if (parts.length === 2) {\n // Get hosts\n result = this.zabbix.getHosts(template.group, template.host);\n } else if (parts.length === 1) {\n // Get groups\n result = this.zabbix.getGroups(template.group);\n } else {\n result = Promise.resolve([]);\n }\n\n return result.then(metrics => {\n return _.map(metrics, formatMetric);\n });\n }\n\n /////////////////\n // Annotations //\n /////////////////\n\n annotationQuery(options) {\n var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);\n var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);\n var annotation = options.annotation;\n var showOkEvents = annotation.showOkEvents ? c.SHOW_ALL_EVENTS : c.SHOW_OK_EVENTS;\n\n // Show all triggers\n let triggersOptions = {\n showTriggers: c.SHOW_ALL_TRIGGERS,\n hideHostsInMaintenance: false\n };\n\n var getTriggers = this.zabbix.getTriggers(this.replaceTemplateVars(annotation.group, {}),\n this.replaceTemplateVars(annotation.host, {}),\n this.replaceTemplateVars(annotation.application, {}),\n triggersOptions);\n\n return getTriggers.then(triggers => {\n\n // Filter triggers by description\n let triggerName = this.replaceTemplateVars(annotation.trigger, {});\n if (utils.isRegex(triggerName)) {\n triggers = _.filter(triggers, trigger => {\n return utils.buildRegex(triggerName).test(trigger.description);\n });\n } else if (triggerName) {\n triggers = _.filter(triggers, trigger => {\n return trigger.description === triggerName;\n });\n }\n\n // Remove events below the chose severity\n triggers = _.filter(triggers, trigger => {\n return Number(trigger.priority) >= Number(annotation.minseverity);\n });\n\n var objectids = _.map(triggers, 'triggerid');\n return this.zabbix\n .getEvents(objectids, timeFrom, timeTo, showOkEvents)\n .then(events => {\n var indexedTriggers = _.keyBy(triggers, 'triggerid');\n\n // Hide acknowledged events if option enabled\n if (annotation.hideAcknowledged) {\n events = _.filter(events, event => {\n return !event.acknowledges.length;\n });\n }\n\n return _.map(events, event => {\n let tags;\n if (annotation.showHostname) {\n tags = _.map(event.hosts, 'name');\n }\n\n // Show event type (OK or Problem)\n let title = Number(event.value) ? 'Problem' : 'OK';\n\n let formatted_acknowledges = utils.formatAcknowledges(event.acknowledges);\n return {\n annotation: annotation,\n time: event.clock * 1000,\n title: title,\n tags: tags,\n text: indexedTriggers[event.objectid].description + formatted_acknowledges\n };\n });\n });\n });\n }\n\n /**\n * Get triggers and its details for panel's targets\n * Returns alert state ('ok' if no fired triggers, or 'alerting' if at least 1 trigger is fired)\n * or empty object if no related triggers are finded.\n */\n alertQuery(options) {\n let enabled_targets = filterEnabledTargets(options.targets);\n let getPanelItems = _.map(enabled_targets, t => {\n let target = _.cloneDeep(t);\n this.replaceTargetVariables(target, options);\n return this.zabbix.getItemsFromTarget(target, {itemtype: 'num'});\n });\n\n return Promise.all(getPanelItems)\n .then(results => {\n let items = _.flatten(results);\n let itemids = _.map(items, 'itemid');\n\n return this.zabbix.getAlerts(itemids);\n })\n .then(triggers => {\n triggers = _.filter(triggers, trigger => {\n return trigger.priority >= this.alertingMinSeverity;\n });\n\n if (!triggers || triggers.length === 0) {\n return {};\n }\n\n let state = 'ok';\n\n let firedTriggers = _.filter(triggers, {value: '1'});\n if (firedTriggers.length) {\n state = 'alerting';\n }\n\n let thresholds = _.map(triggers, trigger => {\n return getTriggerThreshold(trigger.expression);\n });\n\n return {\n panelId: options.panelId,\n state: state,\n thresholds: thresholds\n };\n });\n }\n\n // Replace template variables\n replaceTargetVariables(target, options) {\n let parts = ['group', 'host', 'application', 'item'];\n _.forEach(parts, p => {\n if (target[p] && target[p].filter) {\n target[p].filter = this.replaceTemplateVars(target[p].filter, options.scopedVars);\n }\n });\n target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);\n\n _.forEach(target.functions, func => {\n func.params = _.map(func.params, param => {\n if (typeof param === 'number') {\n return +this.templateSrv.replace(param.toString(), options.scopedVars);\n } else {\n return this.templateSrv.replace(param, options.scopedVars);\n }\n });\n });\n }\n\n isUseTrends(timeRange) {\n let [timeFrom, timeTo] = timeRange;\n let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);\n let useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000);\n let useTrends = this.trends && (\n (timeFrom <= useTrendsFrom) ||\n (timeTo - timeFrom >= useTrendsRange)\n );\n return useTrends;\n }\n}\n\nfunction bindFunctionDefs(functionDefs, category) {\n var aggregationFunctions = _.map(metricFunctions.getCategories()[category], 'name');\n var aggFuncDefs = _.filter(functionDefs, function(func) {\n return _.includes(aggregationFunctions, func.def.name);\n });\n\n return _.map(aggFuncDefs, function(func) {\n var funcInstance = metricFunctions.createFuncInstance(func.def, func.params);\n return funcInstance.bindFunction(dataProcessor.metricFunctions);\n });\n}\n\nfunction getConsolidateBy(target) {\n let consolidateBy = 'avg';\n let funcDef = _.find(target.functions, func => {\n return func.def.name === 'consolidateBy';\n });\n if (funcDef && funcDef.params && funcDef.params.length) {\n consolidateBy = funcDef.params[0];\n }\n return consolidateBy;\n}\n\nfunction downsampleSeries(timeseries_data, options) {\n let defaultAgg = dataProcessor.aggregationFunctions['avg'];\n let consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg;\n return _.map(timeseries_data, timeseries => {\n if (timeseries.datapoints.length > options.maxDataPoints) {\n timeseries.datapoints = dataProcessor\n .groupBy(options.interval, consolidateByFunc, timeseries.datapoints);\n }\n return timeseries;\n });\n}\n\nfunction formatMetric(metricObj) {\n return {\n text: metricObj.name,\n expandable: false\n };\n}\n\n/**\n * Custom formatter for template variables.\n * Default Grafana \"regex\" formatter returns\n * value1|value2\n * This formatter returns\n * (value1|value2)\n * This format needed for using in complex regex with\n * template variables, for example\n * /CPU $cpu_item.*time/ where $cpu_item is system,user,iowait\n */\nfunction zabbixTemplateFormat(value) {\n if (typeof value === 'string') {\n return utils.escapeRegex(value);\n }\n\n var escapedValues = _.map(value, utils.escapeRegex);\n return '(' + escapedValues.join('|') + ')';\n}\n\n/**\n * If template variables are used in request, replace it using regex format\n * and wrap with '/' for proper multi-value work. Example:\n * $variable selected as a, b, c\n * We use filter $variable\n * $variable -> a|b|c -> /a|b|c/\n * /$variable/ -> /a|b|c/ -> /a|b|c/\n */\nfunction replaceTemplateVars(templateSrv, target, scopedVars) {\n var replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat);\n if (target !== replacedTarget && !utils.isRegex(replacedTarget)) {\n replacedTarget = '/^' + replacedTarget + '$/';\n }\n return replacedTarget;\n}\n\n// Apply function one by one:\n// sequence([a(), b(), c()]) = c(b(a()));\nfunction sequence(funcsArray) {\n return function(result) {\n for (var i = 0; i < funcsArray.length; i++) {\n result = funcsArray[i].call(this, result);\n }\n return result;\n };\n}\n\nfunction filterEnabledTargets(targets) {\n return _.filter(targets, target => {\n return !(target.hide || !target.group || !target.host || !target.item);\n });\n}\n\nfunction getTriggerThreshold(expression) {\n let thresholdPattern = /.*[<>]([\\d\\.]+)/;\n let finded_thresholds = expression.match(thresholdPattern);\n if (finded_thresholds && finded_thresholds.length >= 2) {\n let threshold = finded_thresholds[1];\n threshold = Number(threshold);\n return threshold;\n } else {\n return null;\n }\n}\n\nexport {ZabbixAPIDatasource, zabbixTemplateFormat};\n\n// Fix for backward compatibility with lodash 2.4\nif (!_.includes) {_.includes = _.contains;}\nif (!_.keyBy) {_.keyBy = _.indexBy;}\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/metricFunctions.js b/dist/datasource-zabbix/metricFunctions.js index 9016453..d9f8158 100644 --- a/dist/datasource-zabbix/metricFunctions.js +++ b/dist/datasource-zabbix/metricFunctions.js @@ -80,7 +80,8 @@ System.register(['lodash', 'jquery'], function (_export, _context) { Filter: [], Trends: [], Time: [], - Alias: [] + Alias: [], + Special: [] }; addFuncDef({ name: 'groupBy', @@ -225,6 +226,14 @@ System.register(['lodash', 'jquery'], function (_export, _context) { defaultParams: ['/(.*)/', '$1'] }); + // Special + addFuncDef({ + name: 'consolidateBy', + category: 'Special', + params: [{ name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] }], + defaultParams: ['avg'] + }); + _.each(categories, function (funcList, catName) { categories[catName] = _.sortBy(funcList, 'name'); }); diff --git a/dist/datasource-zabbix/metricFunctions.js.map b/dist/datasource-zabbix/metricFunctions.js.map index e80e9fc..8e9375d 100644 --- a/dist/datasource-zabbix/metricFunctions.js.map +++ b/dist/datasource-zabbix/metricFunctions.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/datasource-zabbix/metricFunctions.js"],"names":["addFuncDef","funcDef","params","defaultParams","category","categories","push","index","name","shortName","createFuncInstance","_","isString","message","FuncInstance","getFuncDef","getCategories","$","Transform","Aggregate","Filter","Trends","Time","Alias","type","options","each","funcList","catName","sortBy","def","slice","updateText","metricFunctions","func","bindedFunc","param","i","length","Number","partial","metricExp","str","parameters","map","value","paramType","isNumeric","unshift","join","strValue","indexOf","optional","_hasMultipleParamsInString","split","partVal","idx","updateParam","trim","splice","text"],"mappings":"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","file":"metricFunctions.js","sourcesContent":["import _ from 'lodash';\nimport $ from 'jquery';\n\nvar index = [];\nvar categories = {\n Transform: [],\n Aggregate: [],\n Filter: [],\n Trends: [],\n Time: [],\n Alias: []\n};\n\nfunction addFuncDef(funcDef) {\n funcDef.params = funcDef.params || [];\n funcDef.defaultParams = funcDef.defaultParams || [];\n\n if (funcDef.category) {\n categories[funcDef.category].push(funcDef);\n }\n index[funcDef.name] = funcDef;\n index[funcDef.shortName || funcDef.name] = funcDef;\n}\n\n// Transform\n\naddFuncDef({\n name: 'groupBy',\n category: 'Transform',\n params: [\n { name: 'interval', type: 'string'},\n { name: 'function', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: ['1m', 'avg'],\n});\n\naddFuncDef({\n name: 'scale',\n category: 'Transform',\n params: [\n { name: 'factor', type: 'float', options: [100, 0.01, 10, -1]}\n ],\n defaultParams: [100],\n});\n\naddFuncDef({\n name: 'delta',\n category: 'Transform',\n params: [],\n defaultParams: [],\n});\n\naddFuncDef({\n name: 'rate',\n category: 'Transform',\n params: [],\n defaultParams: [],\n});\n\n// Aggregate\n\naddFuncDef({\n name: 'sumSeries',\n category: 'Aggregate',\n params: [],\n defaultParams: [],\n});\n\naddFuncDef({\n name: 'median',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string'}\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'average',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'min',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'max',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'sum',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'count',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'aggregateBy',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' },\n { name: 'function', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: ['1m', 'avg'],\n});\n\n// Filter\n\naddFuncDef({\n name: 'top',\n category: 'Filter',\n params: [\n { name: 'number', type: 'int' },\n { name: 'value', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: [5, 'avg'],\n});\n\naddFuncDef({\n name: 'bottom',\n category: 'Filter',\n params: [\n { name: 'number', type: 'int' },\n { name: 'value', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: [5, 'avg'],\n});\n\n// Trends\n\naddFuncDef({\n name: 'trendValue',\n category: 'Trends',\n params: [\n { name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] }\n ],\n defaultParams: ['avg'],\n});\n\n// Time\n\naddFuncDef({\n name: 'timeShift',\n category: 'Time',\n params: [\n { name: 'interval', type: 'string', options: ['24h', '7d', '1M', '+24h', '-24h']}\n ],\n defaultParams: ['24h'],\n});\n\n//Alias\n\naddFuncDef({\n name: 'setAlias',\n category: 'Alias',\n params: [\n { name: 'alias', type: 'string' }\n ],\n defaultParams: []\n});\n\naddFuncDef({\n name: 'setAliasByRegex',\n category: 'Alias',\n params: [\n { name: 'aliasByRegex', type: 'string' }\n ],\n defaultParams: []\n});\n\naddFuncDef({\n name: 'replaceAlias',\n category: 'Alias',\n params: [\n { name: 'regexp', type: 'string' },\n { name: 'newAlias', type: 'string' }\n ],\n defaultParams: ['/(.*)/', '$1']\n});\n\n_.each(categories, function(funcList, catName) {\n categories[catName] = _.sortBy(funcList, 'name');\n});\n\nclass FuncInstance {\n constructor(funcDef, params) {\n this.def = funcDef;\n\n if (params) {\n this.params = params;\n } else {\n // Create with default params\n this.params = [];\n this.params = funcDef.defaultParams.slice(0);\n }\n\n this.updateText();\n }\n\n bindFunction(metricFunctions) {\n var func = metricFunctions[this.def.name];\n if (func) {\n\n // Bind function arguments\n var bindedFunc = func;\n var param;\n for (var i = 0; i < this.params.length; i++) {\n param = this.params[i];\n\n // Convert numeric params\n if (this.def.params[i].type === 'int' ||\n this.def.params[i].type === 'float') {\n param = Number(param);\n }\n bindedFunc = _.partial(bindedFunc, param);\n }\n return bindedFunc;\n } else {\n throw { message: 'Method not found ' + this.def.name };\n }\n }\n\n render(metricExp) {\n var str = this.def.name + '(';\n var parameters = _.map(this.params, function(value, index) {\n\n var paramType = this.def.params[index].type;\n if (paramType === 'int' ||\n paramType === 'float' ||\n paramType === 'value_or_series' ||\n paramType === 'boolean') {\n return value;\n }\n else if (paramType === 'int_or_interval' && $.isNumeric(value)) {\n return value;\n }\n\n return \"'\" + value + \"'\";\n\n }, this);\n\n if (metricExp) {\n parameters.unshift(metricExp);\n }\n\n return str + parameters.join(', ') + ')';\n }\n\n _hasMultipleParamsInString(strValue, index) {\n if (strValue.indexOf(',') === -1) {\n return false;\n }\n\n return this.def.params[index + 1] && this.def.params[index + 1].optional;\n }\n\n updateParam(strValue, index) {\n // handle optional parameters\n // if string contains ',' and next param is optional, split and update both\n if (this._hasMultipleParamsInString(strValue, index)) {\n _.each(strValue.split(','), function(partVal, idx) {\n this.updateParam(partVal.trim(), idx);\n }, this);\n return;\n }\n\n if (strValue === '' && this.def.params[index].optional) {\n this.params.splice(index, 1);\n }\n else {\n this.params[index] = strValue;\n }\n\n this.updateText();\n }\n\n updateText() {\n if (this.params.length === 0) {\n this.text = this.def.name + '()';\n return;\n }\n\n var text = this.def.name + '(';\n text += this.params.join(', ');\n text += ')';\n this.text = text;\n }\n}\n\nexport function createFuncInstance(funcDef, params) {\n if (_.isString(funcDef)) {\n if (!index[funcDef]) {\n throw { message: 'Method not found ' + name };\n }\n funcDef = index[funcDef];\n }\n return new FuncInstance(funcDef, params);\n}\n\nexport function getFuncDef(name) {\n return index[name];\n}\n\nexport function getCategories() {\n return categories;\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/datasource-zabbix/metricFunctions.js"],"names":["addFuncDef","funcDef","params","defaultParams","category","categories","push","index","name","shortName","createFuncInstance","_","isString","message","FuncInstance","getFuncDef","getCategories","$","Transform","Aggregate","Filter","Trends","Time","Alias","Special","type","options","each","funcList","catName","sortBy","def","slice","updateText","metricFunctions","func","bindedFunc","param","i","length","Number","partial","metricExp","str","parameters","map","value","paramType","isNumeric","unshift","join","strValue","indexOf","optional","_hasMultipleParamsInString","split","partVal","idx","updateParam","trim","splice","text"],"mappings":"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","file":"metricFunctions.js","sourcesContent":["import _ from 'lodash';\nimport $ from 'jquery';\n\nvar index = [];\nvar categories = {\n Transform: [],\n Aggregate: [],\n Filter: [],\n Trends: [],\n Time: [],\n Alias: [],\n Special: []\n};\n\nfunction addFuncDef(funcDef) {\n funcDef.params = funcDef.params || [];\n funcDef.defaultParams = funcDef.defaultParams || [];\n\n if (funcDef.category) {\n categories[funcDef.category].push(funcDef);\n }\n index[funcDef.name] = funcDef;\n index[funcDef.shortName || funcDef.name] = funcDef;\n}\n\n// Transform\n\naddFuncDef({\n name: 'groupBy',\n category: 'Transform',\n params: [\n { name: 'interval', type: 'string'},\n { name: 'function', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: ['1m', 'avg'],\n});\n\naddFuncDef({\n name: 'scale',\n category: 'Transform',\n params: [\n { name: 'factor', type: 'float', options: [100, 0.01, 10, -1]}\n ],\n defaultParams: [100],\n});\n\naddFuncDef({\n name: 'delta',\n category: 'Transform',\n params: [],\n defaultParams: [],\n});\n\naddFuncDef({\n name: 'rate',\n category: 'Transform',\n params: [],\n defaultParams: [],\n});\n\n// Aggregate\n\naddFuncDef({\n name: 'sumSeries',\n category: 'Aggregate',\n params: [],\n defaultParams: [],\n});\n\naddFuncDef({\n name: 'median',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string'}\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'average',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'min',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'max',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'sum',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'count',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' }\n ],\n defaultParams: ['1m'],\n});\n\naddFuncDef({\n name: 'aggregateBy',\n category: 'Aggregate',\n params: [\n { name: 'interval', type: 'string' },\n { name: 'function', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: ['1m', 'avg'],\n});\n\n// Filter\n\naddFuncDef({\n name: 'top',\n category: 'Filter',\n params: [\n { name: 'number', type: 'int' },\n { name: 'value', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: [5, 'avg'],\n});\n\naddFuncDef({\n name: 'bottom',\n category: 'Filter',\n params: [\n { name: 'number', type: 'int' },\n { name: 'value', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count', 'median'] }\n ],\n defaultParams: [5, 'avg'],\n});\n\n// Trends\n\naddFuncDef({\n name: 'trendValue',\n category: 'Trends',\n params: [\n { name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] }\n ],\n defaultParams: ['avg'],\n});\n\n// Time\n\naddFuncDef({\n name: 'timeShift',\n category: 'Time',\n params: [\n { name: 'interval', type: 'string', options: ['24h', '7d', '1M', '+24h', '-24h']}\n ],\n defaultParams: ['24h'],\n});\n\n//Alias\n\naddFuncDef({\n name: 'setAlias',\n category: 'Alias',\n params: [\n { name: 'alias', type: 'string' }\n ],\n defaultParams: []\n});\n\naddFuncDef({\n name: 'setAliasByRegex',\n category: 'Alias',\n params: [\n { name: 'aliasByRegex', type: 'string' }\n ],\n defaultParams: []\n});\n\naddFuncDef({\n name: 'replaceAlias',\n category: 'Alias',\n params: [\n { name: 'regexp', type: 'string' },\n { name: 'newAlias', type: 'string' }\n ],\n defaultParams: ['/(.*)/', '$1']\n});\n\n// Special\naddFuncDef({\n name: 'consolidateBy',\n category: 'Special',\n params: [\n { name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] }\n ],\n defaultParams: ['avg'],\n});\n\n_.each(categories, function(funcList, catName) {\n categories[catName] = _.sortBy(funcList, 'name');\n});\n\nclass FuncInstance {\n constructor(funcDef, params) {\n this.def = funcDef;\n\n if (params) {\n this.params = params;\n } else {\n // Create with default params\n this.params = [];\n this.params = funcDef.defaultParams.slice(0);\n }\n\n this.updateText();\n }\n\n bindFunction(metricFunctions) {\n var func = metricFunctions[this.def.name];\n if (func) {\n\n // Bind function arguments\n var bindedFunc = func;\n var param;\n for (var i = 0; i < this.params.length; i++) {\n param = this.params[i];\n\n // Convert numeric params\n if (this.def.params[i].type === 'int' ||\n this.def.params[i].type === 'float') {\n param = Number(param);\n }\n bindedFunc = _.partial(bindedFunc, param);\n }\n return bindedFunc;\n } else {\n throw { message: 'Method not found ' + this.def.name };\n }\n }\n\n render(metricExp) {\n var str = this.def.name + '(';\n var parameters = _.map(this.params, function(value, index) {\n\n var paramType = this.def.params[index].type;\n if (paramType === 'int' ||\n paramType === 'float' ||\n paramType === 'value_or_series' ||\n paramType === 'boolean') {\n return value;\n }\n else if (paramType === 'int_or_interval' && $.isNumeric(value)) {\n return value;\n }\n\n return \"'\" + value + \"'\";\n\n }, this);\n\n if (metricExp) {\n parameters.unshift(metricExp);\n }\n\n return str + parameters.join(', ') + ')';\n }\n\n _hasMultipleParamsInString(strValue, index) {\n if (strValue.indexOf(',') === -1) {\n return false;\n }\n\n return this.def.params[index + 1] && this.def.params[index + 1].optional;\n }\n\n updateParam(strValue, index) {\n // handle optional parameters\n // if string contains ',' and next param is optional, split and update both\n if (this._hasMultipleParamsInString(strValue, index)) {\n _.each(strValue.split(','), function(partVal, idx) {\n this.updateParam(partVal.trim(), idx);\n }, this);\n return;\n }\n\n if (strValue === '' && this.def.params[index].optional) {\n this.params.splice(index, 1);\n }\n else {\n this.params[index] = strValue;\n }\n\n this.updateText();\n }\n\n updateText() {\n if (this.params.length === 0) {\n this.text = this.def.name + '()';\n return;\n }\n\n var text = this.def.name + '(';\n text += this.params.join(', ');\n text += ')';\n this.text = text;\n }\n}\n\nexport function createFuncInstance(funcDef, params) {\n if (_.isString(funcDef)) {\n if (!index[funcDef]) {\n throw { message: 'Method not found ' + name };\n }\n funcDef = index[funcDef];\n }\n return new FuncInstance(funcDef, params);\n}\n\nexport function getFuncDef(name) {\n return index[name];\n}\n\nexport function getCategories() {\n return categories;\n}\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/module.js b/dist/datasource-zabbix/module.js index 2b772d3..32693a5 100644 --- a/dist/datasource-zabbix/module.js +++ b/dist/datasource-zabbix/module.js @@ -1,9 +1,9 @@ 'use strict'; -System.register(['./datasource', './query.controller'], function (_export, _context) { +System.register(['./datasource', './query.controller', './config.controller'], function (_export, _context) { "use strict"; - var ZabbixAPIDatasource, ZabbixQueryController, ZabbixConfigController, ZabbixQueryOptionsController, ZabbixAnnotationsQueryController; + var ZabbixAPIDatasource, ZabbixQueryController, ZabbixDSConfigController, ZabbixQueryOptionsController, ZabbixAnnotationsQueryController; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -16,14 +16,10 @@ System.register(['./datasource', './query.controller'], function (_export, _cont ZabbixAPIDatasource = _datasource.ZabbixAPIDatasource; }, function (_queryController) { ZabbixQueryController = _queryController.ZabbixQueryController; + }, function (_configController) { + ZabbixDSConfigController = _configController.ZabbixDSConfigController; }], execute: function () { - _export('ConfigCtrl', ZabbixConfigController = function ZabbixConfigController() { - _classCallCheck(this, ZabbixConfigController); - }); - - ZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; - _export('QueryOptionsCtrl', ZabbixQueryOptionsController = function ZabbixQueryOptionsController() { _classCallCheck(this, ZabbixQueryOptionsController); }); @@ -38,7 +34,7 @@ System.register(['./datasource', './query.controller'], function (_export, _cont _export('Datasource', ZabbixAPIDatasource); - _export('ConfigCtrl', ZabbixConfigController); + _export('ConfigCtrl', ZabbixDSConfigController); _export('QueryCtrl', ZabbixQueryController); diff --git a/dist/datasource-zabbix/module.js.map b/dist/datasource-zabbix/module.js.map index 776f7e4..bf4adfe 100644 --- a/dist/datasource-zabbix/module.js.map +++ b/dist/datasource-zabbix/module.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/datasource-zabbix/module.js"],"names":["ZabbixAPIDatasource","ZabbixQueryController","ZabbixConfigController","templateUrl","ZabbixQueryOptionsController","ZabbixAnnotationsQueryController"],"mappings":";;;;;;;;;;;;;;;AAAQA,yB,eAAAA,mB;;AACAC,2B,oBAAAA,qB;;;4BAEFC,sB;;;;AACNA,6BAAuBC,WAAvB,GAAqC,wCAArC;;kCAEMC,4B;;;;AACNA,mCAA6BD,WAA7B,GAA2C,+CAA3C;;sCAEME,gC;;;;AACNA,uCAAiCF,WAAjC,GAA+C,oDAA/C;;4BAGEH,mB;;4BACAE,sB;;2BACAD,qB;;kCACAG,4B;;sCACAC,gC","file":"module.js","sourcesContent":["import {ZabbixAPIDatasource} from './datasource';\nimport {ZabbixQueryController} from './query.controller';\n\nclass ZabbixConfigController {}\nZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html';\n\nclass ZabbixQueryOptionsController {}\nZabbixQueryOptionsController.templateUrl = 'datasource-zabbix/partials/query.options.html';\n\nclass ZabbixAnnotationsQueryController {}\nZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html';\n\nexport {\n ZabbixAPIDatasource as Datasource,\n ZabbixConfigController as ConfigCtrl,\n ZabbixQueryController as QueryCtrl,\n ZabbixQueryOptionsController as QueryOptionsCtrl,\n ZabbixAnnotationsQueryController as AnnotationsQueryCtrl\n};\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/datasource-zabbix/module.js"],"names":["ZabbixAPIDatasource","ZabbixQueryController","ZabbixDSConfigController","ZabbixQueryOptionsController","templateUrl","ZabbixAnnotationsQueryController"],"mappings":";;;;;;;;;;;;;;;AAAQA,yB,eAAAA,mB;;AACAC,2B,oBAAAA,qB;;AACAC,8B,qBAAAA,wB;;;kCAEFC,4B;;;;AACNA,mCAA6BC,WAA7B,GAA2C,+CAA3C;;sCAEMC,gC;;;;AACNA,uCAAiCD,WAAjC,GAA+C,oDAA/C;;4BAGEJ,mB;;4BACAE,wB;;2BACAD,qB;;kCACAE,4B;;sCACAE,gC","file":"module.js","sourcesContent":["import {ZabbixAPIDatasource} from './datasource';\nimport {ZabbixQueryController} from './query.controller';\nimport {ZabbixDSConfigController} from './config.controller';\n\nclass ZabbixQueryOptionsController {}\nZabbixQueryOptionsController.templateUrl = 'datasource-zabbix/partials/query.options.html';\n\nclass ZabbixAnnotationsQueryController {}\nZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html';\n\nexport {\n ZabbixAPIDatasource as Datasource,\n ZabbixDSConfigController as ConfigCtrl,\n ZabbixQueryController as QueryCtrl,\n ZabbixQueryOptionsController as QueryOptionsCtrl,\n ZabbixAnnotationsQueryController as AnnotationsQueryCtrl\n};\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/partials/config.html b/dist/datasource-zabbix/partials/config.html index 49e18b8..7f626c2 100644 --- a/dist/datasource-zabbix/partials/config.html +++ b/dist/datasource-zabbix/partials/config.html @@ -76,24 +76,53 @@
-

Alerting

- +

Direct DB Connection

+ - - -
- Min severity +
+
+ + SQL Data Source + + Select SQL Data Source for Zabbix database. + In order to use this feature you should create and + configure it first. Zabbix plugin uses this data source for querying history data directly from database. + This way usually faster than pulling data from Zabbix API, especially on the wide time ranges, and reduces + amount of data transfered. + +
-
+
+
+ +
+

Alerting

+ + +
+ + +
+ Min severity +
+ +
+
+
diff --git a/dist/datasource-zabbix/specs/datasource_specs.js b/dist/datasource-zabbix/specs/datasource_specs.js index 295f4fd..dec10a2 100644 --- a/dist/datasource-zabbix/specs/datasource_specs.js +++ b/dist/datasource-zabbix/specs/datasource_specs.js @@ -15,7 +15,10 @@ describe('ZabbixDatasource', () => { password: 'zabbix', trends: true, trendsFrom: '14d', - trendsRange: '7d' + trendsRange: '7d', + dbConnection: { + enabled: false + } } }; ctx.templateSrv = {}; diff --git a/dist/datasource-zabbix/zabbix.js b/dist/datasource-zabbix/zabbix.js index 51e6fd5..b24c18f 100644 --- a/dist/datasource-zabbix/zabbix.js +++ b/dist/datasource-zabbix/zabbix.js @@ -1,6 +1,6 @@ 'use strict'; -System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js'], function (_export, _context) { +System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js', './zabbixDBConnector'], function (_export, _context) { "use strict"; var angular, _, utils, _createClass; @@ -27,26 +27,44 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za // Each Zabbix data source instance should initialize its own API instance. /** @ngInject */ - function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) { + function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) { var Zabbix = function () { - function Zabbix(url, username, password, basicAuth, withCredentials, cacheTTL) { + function Zabbix(url, options) { _classCallCheck(this, Zabbix); + var username = options.username, + password = options.password, + basicAuth = options.basicAuth, + withCredentials = options.withCredentials, + cacheTTL = options.cacheTTL, + enableDirectDBConnection = options.enableDirectDBConnection, + sqlDatasourceId = options.sqlDatasourceId; + + // Initialize Zabbix API var ZabbixAPI = zabbixAPIService; this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials); + if (enableDirectDBConnection) { + this.dbConnector = new ZabbixDBConnector(sqlDatasourceId); + } + // Initialize caching proxy for requests var cacheOptions = { enabled: true, ttl: cacheTTL }; - this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions); + this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions); // Proxy methods this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy); this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy); + if (enableDirectDBConnection) { + this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy); + this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy); + } + this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); @@ -274,7 +292,7 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za _ = _lodash.default; }, function (_utils) { utils = _utils; - }, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}], + }, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}, function (_zabbixDBConnector) {}], execute: function () { _createClass = function () { function defineProperties(target, props) { diff --git a/dist/datasource-zabbix/zabbix.js.map b/dist/datasource-zabbix/zabbix.js.map index da87230..240c05b 100644 --- a/dist/datasource-zabbix/zabbix.js.map +++ b/dist/datasource-zabbix/zabbix.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/datasource-zabbix/zabbix.js"],"names":["ZabbixFactory","zabbixAPIService","ZabbixCachingProxy","Zabbix","url","username","password","basicAuth","withCredentials","cacheTTL","ZabbixAPI","zabbixAPI","cacheOptions","enabled","ttl","cachingProxy","getHistory","bind","getMacros","getTrend","getEvents","getAlerts","getAcknowledges","getITService","getSLA","getVersion","login","target","options","parts","filters","_","map","p","filter","getItems","getGroups","groupFilter","getAllGroups","then","findByFilter","groups","groupids","getHosts","hostFilter","getAllHosts","hosts","hostids","getApps","appFilter","filterByQuery","apps","appFilterEmpty","undefined","itemtype","appids","showDisabledItems","items","expandUserMacro","getHostIds","forEach","utils","containsMacro","item","name","replaceMacro","macros","itemFilter","getAllItems","promises","Promise","all","filteredGroups","results","filteredHosts","filteredApps","query","applicationids","flatten","getTriggers","findByName","list","finded","find","filterByName","filterByRegex","regex","filterPattern","buildRegex","zbx_obj","test","isRegex","hostIds","uniq","angular","module","factory"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAMA;AACA;;AAEA;AACA,WAASA,aAAT,CAAuBC,gBAAvB,EAAyCC,kBAAzC,EAA6D;AAAA,QAErDC,MAFqD;AAGzD,sBAAYC,GAAZ,EAAiBC,QAAjB,EAA2BC,QAA3B,EAAqCC,SAArC,EAAgDC,eAAhD,EAAiEC,QAAjE,EAA2E;AAAA;;AAEzE;AACA,YAAIC,YAAYT,gBAAhB;AACA,aAAKU,SAAL,GAAiB,IAAID,SAAJ,CAAcN,GAAd,EAAmBC,QAAnB,EAA6BC,QAA7B,EAAuCC,SAAvC,EAAkDC,eAAlD,CAAjB;;AAEA;AACA,YAAII,eAAe;AACjBC,mBAAS,IADQ;AAEjBC,eAAKL;AAFY,SAAnB;AAIA,aAAKM,YAAL,GAAoB,IAAIb,kBAAJ,CAAuB,KAAKS,SAA5B,EAAuCC,YAAvC,CAApB;;AAEA;AACA,aAAKI,UAAL,GAAkB,KAAKD,YAAL,CAAkBC,UAAlB,CAA6BC,IAA7B,CAAkC,KAAKF,YAAvC,CAAlB;AACA,aAAKG,SAAL,GAAiB,KAAKH,YAAL,CAAkBG,SAAlB,CAA4BD,IAA5B,CAAiC,KAAKF,YAAtC,CAAjB;;AAEA,aAAKI,QAAL,GAAgB,KAAKR,SAAL,CAAeQ,QAAf,CAAwBF,IAAxB,CAA6B,KAAKN,SAAlC,CAAhB;AACA,aAAKS,SAAL,GAAiB,KAAKT,SAAL,CAAeS,SAAf,CAAyBH,IAAzB,CAA8B,KAAKN,SAAnC,CAAjB;AACA,aAAKU,SAAL,GAAiB,KAAKV,SAAL,CAAeU,SAAf,CAAyBJ,IAAzB,CAA8B,KAAKN,SAAnC,CAAjB;AACA,aAAKW,eAAL,GAAuB,KAAKX,SAAL,CAAeW,eAAf,CAA+BL,IAA/B,CAAoC,KAAKN,SAAzC,CAAvB;AACA,aAAKY,YAAL,GAAoB,KAAKZ,SAAL,CAAeY,YAAf,CAA4BN,IAA5B,CAAiC,KAAKN,SAAtC,CAApB;AACA,aAAKa,MAAL,GAAc,KAAKb,SAAL,CAAea,MAAf,CAAsBP,IAAtB,CAA2B,KAAKN,SAAhC,CAAd;AACA,aAAKc,UAAL,GAAkB,KAAKd,SAAL,CAAec,UAAf,CAA0BR,IAA1B,CAA+B,KAAKN,SAApC,CAAlB;AACA,aAAKe,KAAL,GAAa,KAAKf,SAAL,CAAee,KAAf,CAAqBT,IAArB,CAA0B,KAAKN,SAA/B,CAAb;AACD;;AA5BwD;AAAA;AAAA,2CA8BtCgB,MA9BsC,EA8B9BC,OA9B8B,EA8BrB;AAClC,cAAIC,QAAQ,CAAC,OAAD,EAAU,MAAV,EAAkB,aAAlB,EAAiC,MAAjC,CAAZ;AACA,cAAIC,UAAUC,EAAEC,GAAF,CAAMH,KAAN,EAAa;AAAA,mBAAKF,OAAOM,CAAP,EAAUC,MAAf;AAAA,WAAb,CAAd;AACA,iBAAO,KAAKC,QAAL,gCAAiBL,OAAjB,UAA0BF,OAA1B,GAAP;AACD;AAlCwD;AAAA;AAAA,uCAoC1C;AACb,iBAAO,KAAKb,YAAL,CAAkBqB,SAAlB,EAAP;AACD;AAtCwD;AAAA;AAAA,kCAwC/CC,WAxC+C,EAwClC;AACrB,iBAAO,KAAKC,YAAL,GACNC,IADM,CACD;AAAA,mBAAUC,aAAaC,MAAb,EAAqBJ,WAArB,CAAV;AAAA,WADC,CAAP;AAED;AA3CwD;AAAA;AAAA,oCAgD7CA,WAhD6C,EAgDhC;AAAA;;AACvB,iBAAO,KAAKD,SAAL,CAAeC,WAAf,EACNE,IADM,CACD,kBAAU;AACd,gBAAIG,WAAWX,EAAEC,GAAF,CAAMS,MAAN,EAAc,SAAd,CAAf;AACA,mBAAO,MAAK1B,YAAL,CAAkB4B,QAAlB,CAA2BD,QAA3B,CAAP;AACD,WAJM,CAAP;AAKD;AAtDwD;AAAA;AAAA,iCAwDhDL,WAxDgD,EAwDnCO,UAxDmC,EAwDvB;AAChC,iBAAO,KAAKC,WAAL,CAAiBR,WAAjB,EACNE,IADM,CACD;AAAA,mBAASC,aAAaM,KAAb,EAAoBF,UAApB,CAAT;AAAA,WADC,CAAP;AAED;AA3DwD;AAAA;AAAA,mCAgE9CP,WAhE8C,EAgEjCO,UAhEiC,EAgErB;AAAA;;AAClC,iBAAO,KAAKD,QAAL,CAAcN,WAAd,EAA2BO,UAA3B,EACNL,IADM,CACD,iBAAS;AACb,gBAAIQ,UAAUhB,EAAEC,GAAF,CAAMc,KAAN,EAAa,QAAb,CAAd;AACA,mBAAO,OAAK/B,YAAL,CAAkBiC,OAAlB,CAA0BD,OAA1B,CAAP;AACD,WAJM,CAAP;AAKD;AAtEwD;AAAA;AAAA,gCAwEjDV,WAxEiD,EAwEpCO,UAxEoC,EAwExBK,SAxEwB,EAwEb;AAAA;;AAC1C,iBAAO,KAAKN,QAAL,CAAcN,WAAd,EAA2BO,UAA3B,EACNL,IADM,CACD,iBAAS;AACb,gBAAIQ,UAAUhB,EAAEC,GAAF,CAAMc,KAAN,EAAa,QAAb,CAAd;AACA,gBAAIG,SAAJ,EAAe;AACb,qBAAO,OAAKlC,YAAL,CAAkBiC,OAAlB,CAA0BD,OAA1B,EACNR,IADM,CACD;AAAA,uBAAQW,cAAcC,IAAd,EAAoBF,SAApB,CAAR;AAAA,eADC,CAAP;AAED,aAHD,MAGO;AACL,qBAAO;AACLG,gCAAgB,IADX;AAELL,yBAASA;AAFJ,eAAP;AAID;AACF,WAZM,CAAP;AAaD;AAtFwD;AAAA;AAAA,oCAwF7CV,WAxF6C,EAwFhCO,UAxFgC,EAwFpBK,SAxFoB,EAwFK;AAAA;;AAAA,cAAdrB,OAAc,uEAAJ,EAAI;;AAC5D,iBAAO,KAAKoB,OAAL,CAAaX,WAAb,EAA0BO,UAA1B,EAAsCK,SAAtC,EACNV,IADM,CACD,gBAAQ;AACZ,gBAAIY,KAAKC,cAAT,EAAyB;AACvB,qBAAO,OAAKrC,YAAL,CAAkBoB,QAAlB,CAA2BgB,KAAKJ,OAAhC,EAAyCM,SAAzC,EAAoDzB,QAAQ0B,QAA5D,CAAP;AACD,aAFD,MAEO;AACL,kBAAIC,SAASxB,EAAEC,GAAF,CAAMmB,IAAN,EAAY,eAAZ,CAAb;AACA,qBAAO,OAAKpC,YAAL,CAAkBoB,QAAlB,CAA2BkB,SAA3B,EAAsCE,MAAtC,EAA8C3B,QAAQ0B,QAAtD,CAAP;AACD;AACF,WARM,EASNf,IATM,CASD,iBAAS;AACb,gBAAI,CAACX,QAAQ4B,iBAAb,EAAgC;AAC9BC,sBAAQ1B,EAAEG,MAAF,CAASuB,KAAT,EAAgB,EAAC,UAAU,GAAX,EAAhB,CAAR;AACD;;AAED,mBAAOA,KAAP;AACD,WAfM,EAgBNlB,IAhBM,CAgBD,KAAKmB,eAAL,CAAqBzC,IAArB,CAA0B,IAA1B,CAhBC,CAAP;AAiBD;AA1GwD;AAAA;AAAA,wCA4GzCwC,KA5GyC,EA4GlC;AACrB,cAAIV,UAAUY,WAAWF,KAAX,CAAd;AACA,iBAAO,KAAKvC,SAAL,CAAe6B,OAAf,EACNR,IADM,CACD,kBAAU;AACdR,cAAE6B,OAAF,CAAUH,KAAV,EAAiB,gBAAQ;AACvB,kBAAII,MAAMC,aAAN,CAAoBC,KAAKC,IAAzB,CAAJ,EAAoC;AAClCD,qBAAKC,IAAL,GAAYH,MAAMI,YAAN,CAAmBF,IAAnB,EAAyBG,MAAzB,CAAZ;AACD;AACF,aAJD;AAKA,mBAAOT,KAAP;AACD,WARM,CAAP;AASD;AAvHwD;AAAA;AAAA,iCAyHhDpB,WAzHgD,EAyHnCO,UAzHmC,EAyHvBK,SAzHuB,EAyHZkB,UAzHY,EAyHc;AAAA,cAAdvC,OAAc,uEAAJ,EAAI;;AACrE,iBAAO,KAAKwC,WAAL,CAAiB/B,WAAjB,EAA8BO,UAA9B,EAA0CK,SAA1C,EAAqDrB,OAArD,EACNW,IADM,CACD;AAAA,mBAASW,cAAcO,KAAd,EAAqBU,UAArB,CAAT;AAAA,WADC,CAAP;AAED;AA5HwD;AAAA;AAAA,oCAiI7C9B,WAjI6C,EAiIhCO,UAjIgC,EAiIpBK,SAjIoB,EAiITrB,OAjIS,EAiIA;AAAA;;AACvD,cAAIyC,WAAW,CACb,KAAKjC,SAAL,CAAeC,WAAf,CADa,EAEb,KAAKM,QAAL,CAAcN,WAAd,EAA2BO,UAA3B,CAFa,EAGb,KAAKI,OAAL,CAAaX,WAAb,EAA0BO,UAA1B,EAAsCK,SAAtC,CAHa,CAAf;;AAMA,iBAAOqB,QAAQC,GAAR,CAAYF,QAAZ,EACN9B,IADM,CACD,mBAAW;AACf,gBAAIiC,iBAAiBC,QAAQ,CAAR,CAArB;AACA,gBAAIC,gBAAgBD,QAAQ,CAAR,CAApB;AACA,gBAAIE,eAAeF,QAAQ,CAAR,CAAnB;AACA,gBAAIG,QAAQ,EAAZ;;AAEA,gBAAI3B,SAAJ,EAAe;AACb2B,oBAAMC,cAAN,GAAuB9C,EAAE+C,OAAF,CAAU/C,EAAEC,GAAF,CAAM2C,YAAN,EAAoB,eAApB,CAAV,CAAvB;AACD;AACD,gBAAI/B,UAAJ,EAAgB;AACdgC,oBAAM7B,OAAN,GAAgBhB,EAAEC,GAAF,CAAM0C,aAAN,EAAqB,QAArB,CAAhB;AACD;AACD,gBAAIrC,WAAJ,EAAiB;AACfuC,oBAAMlC,QAAN,GAAiBX,EAAEC,GAAF,CAAMwC,cAAN,EAAsB,SAAtB,CAAjB;AACD;;AAED,mBAAOI,KAAP;AACD,WAlBM,EAkBJrC,IAlBI,CAkBC,iBAAS;AACf,mBAAO,OAAK5B,SAAL,CAAeoE,WAAf,CAA2BH,MAAMlC,QAAjC,EAA2CkC,MAAM7B,OAAjD,EAA0D6B,MAAMC,cAAhE,EAAgFjD,OAAhF,CAAP;AACD,WApBM,CAAP;AAqBD;AA7JwD;;AAAA;AAAA;;AAgK3D,WAAOzB,MAAP;AACD;;AAMD;;AAEA;;;;;;AAMA,WAAS6E,UAAT,CAAoBC,IAApB,EAA0BjB,IAA1B,EAAgC;AAC9B,QAAIkB,SAASnD,EAAEoD,IAAF,CAAOF,IAAP,EAAa,EAAC,QAAQjB,IAAT,EAAb,CAAb;AACA,QAAIkB,MAAJ,EAAY;AACV,aAAO,CAACA,MAAD,CAAP;AACD,KAFD,MAEO;AACL,aAAO,EAAP;AACD;AACF;;AAED;;;;;;;;AAQA,WAASE,YAAT,CAAsBH,IAAtB,EAA4BjB,IAA5B,EAAkC;AAChC,QAAIkB,SAASnD,EAAEG,MAAF,CAAS+C,IAAT,EAAe,EAAC,QAAQjB,IAAT,EAAf,CAAb;AACA,QAAIkB,MAAJ,EAAY;AACV,aAAOA,MAAP;AACD,KAFD,MAEO;AACL,aAAO,EAAP;AACD;AACF;;AAED,WAASG,aAAT,CAAuBJ,IAAvB,EAA6BK,KAA7B,EAAoC;AAClC,QAAIC,gBAAgB1B,MAAM2B,UAAN,CAAiBF,KAAjB,CAApB;AACA,WAAOvD,EAAEG,MAAF,CAAS+C,IAAT,EAAe,UAAUQ,OAAV,EAAmB;AACvC,aAAOF,cAAcG,IAAd,CAAmBD,QAAQzB,IAA3B,CAAP;AACD,KAFM,CAAP;AAGD;;AAED,WAASxB,YAAT,CAAsByC,IAAtB,EAA4B/C,MAA5B,EAAoC;AAClC,QAAI2B,MAAM8B,OAAN,CAAczD,MAAd,CAAJ,EAA2B;AACzB,aAAOmD,cAAcJ,IAAd,EAAoB/C,MAApB,CAAP;AACD,KAFD,MAEO;AACL,aAAO8C,WAAWC,IAAX,EAAiB/C,MAAjB,CAAP;AACD;AACF;;AAED,WAASgB,aAAT,CAAuB+B,IAAvB,EAA6B/C,MAA7B,EAAqC;AACnC,QAAI2B,MAAM8B,OAAN,CAAczD,MAAd,CAAJ,EAA2B;AACzB,aAAOmD,cAAcJ,IAAd,EAAoB/C,MAApB,CAAP;AACD,KAFD,MAEO;AACL,aAAOkD,aAAaH,IAAb,EAAmB/C,MAAnB,CAAP;AACD;AACF;;AAED,WAASyB,UAAT,CAAoBF,KAApB,EAA2B;AACzB,QAAImC,UAAU7D,EAAEC,GAAF,CAAMyB,KAAN,EAAa,gBAAQ;AACjC,aAAO1B,EAAEC,GAAF,CAAM+B,KAAKjB,KAAX,EAAkB,QAAlB,CAAP;AACD,KAFa,CAAd;AAGA,WAAOf,EAAE8D,IAAF,CAAO9D,EAAE+C,OAAF,CAAUc,OAAV,CAAP,CAAP;AACD;;;AA/OME,a;;AACA/D,O;;AACK8B,W;;;;;;;;;;;;;;;;;;;;;AA2KZiC,cACGC,MADH,CACU,kBADV,EAEGC,OAFH,CAEW,QAFX,EAEqBhG,aAFrB","file":"zabbix.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\nimport * as utils from './utils';\nimport './zabbixAPI.service.js';\nimport './zabbixCachingProxy.service.js';\n\n// Use factory() instead service() for multiple data sources support.\n// Each Zabbix data source instance should initialize its own API instance.\n\n/** @ngInject */\nfunction ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) {\n\n class Zabbix {\n constructor(url, username, password, basicAuth, withCredentials, cacheTTL) {\n\n // Initialize Zabbix API\n var ZabbixAPI = zabbixAPIService;\n this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials);\n\n // Initialize caching proxy for requests\n let cacheOptions = {\n enabled: true,\n ttl: cacheTTL\n };\n this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions);\n\n // Proxy methods\n this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy);\n this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy);\n\n this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);\n this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);\n this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);\n this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);\n this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);\n this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);\n this.getVersion = this.zabbixAPI.getVersion.bind(this.zabbixAPI);\n this.login = this.zabbixAPI.login.bind(this.zabbixAPI);\n }\n\n getItemsFromTarget(target, options) {\n let parts = ['group', 'host', 'application', 'item'];\n let filters = _.map(parts, p => target[p].filter);\n return this.getItems(...filters, options);\n }\n\n getAllGroups() {\n return this.cachingProxy.getGroups();\n }\n\n getGroups(groupFilter) {\n return this.getAllGroups()\n .then(groups => findByFilter(groups, groupFilter));\n }\n\n /**\n * Get list of host belonging to given groups.\n */\n getAllHosts(groupFilter) {\n return this.getGroups(groupFilter)\n .then(groups => {\n let groupids = _.map(groups, 'groupid');\n return this.cachingProxy.getHosts(groupids);\n });\n }\n\n getHosts(groupFilter, hostFilter) {\n return this.getAllHosts(groupFilter)\n .then(hosts => findByFilter(hosts, hostFilter));\n }\n\n /**\n * Get list of applications belonging to given groups and hosts.\n */\n getAllApps(groupFilter, hostFilter) {\n return this.getHosts(groupFilter, hostFilter)\n .then(hosts => {\n let hostids = _.map(hosts, 'hostid');\n return this.cachingProxy.getApps(hostids);\n });\n }\n\n getApps(groupFilter, hostFilter, appFilter) {\n return this.getHosts(groupFilter, hostFilter)\n .then(hosts => {\n let hostids = _.map(hosts, 'hostid');\n if (appFilter) {\n return this.cachingProxy.getApps(hostids)\n .then(apps => filterByQuery(apps, appFilter));\n } else {\n return {\n appFilterEmpty: true,\n hostids: hostids\n };\n }\n });\n }\n\n getAllItems(groupFilter, hostFilter, appFilter, options = {}) {\n return this.getApps(groupFilter, hostFilter, appFilter)\n .then(apps => {\n if (apps.appFilterEmpty) {\n return this.cachingProxy.getItems(apps.hostids, undefined, options.itemtype);\n } else {\n let appids = _.map(apps, 'applicationid');\n return this.cachingProxy.getItems(undefined, appids, options.itemtype);\n }\n })\n .then(items => {\n if (!options.showDisabledItems) {\n items = _.filter(items, {'status': '0'});\n }\n\n return items;\n })\n .then(this.expandUserMacro.bind(this));\n }\n\n expandUserMacro(items) {\n let hostids = getHostIds(items);\n return this.getMacros(hostids)\n .then(macros => {\n _.forEach(items, item => {\n if (utils.containsMacro(item.name)) {\n item.name = utils.replaceMacro(item, macros);\n }\n });\n return items;\n });\n }\n\n getItems(groupFilter, hostFilter, appFilter, itemFilter, options = {}) {\n return this.getAllItems(groupFilter, hostFilter, appFilter, options)\n .then(items => filterByQuery(items, itemFilter));\n }\n\n /**\n * Build query - convert target filters to array of Zabbix items\n */\n getTriggers(groupFilter, hostFilter, appFilter, options) {\n let promises = [\n this.getGroups(groupFilter),\n this.getHosts(groupFilter, hostFilter),\n this.getApps(groupFilter, hostFilter, appFilter)\n ];\n\n return Promise.all(promises)\n .then(results => {\n let filteredGroups = results[0];\n let filteredHosts = results[1];\n let filteredApps = results[2];\n let query = {};\n\n if (appFilter) {\n query.applicationids = _.flatten(_.map(filteredApps, 'applicationid'));\n }\n if (hostFilter) {\n query.hostids = _.map(filteredHosts, 'hostid');\n }\n if (groupFilter) {\n query.groupids = _.map(filteredGroups, 'groupid');\n }\n\n return query;\n }).then(query => {\n return this.zabbixAPI.getTriggers(query.groupids, query.hostids, query.applicationids, options);\n });\n }\n }\n\n return Zabbix;\n}\n\nangular\n .module('grafana.services')\n .factory('Zabbix', ZabbixFactory);\n\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * Find group, host, app or item by given name.\n * @param list list of groups, apps or other\n * @param name visible name\n * @return array with finded element or empty array\n */\nfunction findByName(list, name) {\n var finded = _.find(list, {'name': name});\n if (finded) {\n return [finded];\n } else {\n return [];\n }\n}\n\n/**\n * Different hosts can contains applications and items with same name.\n * For this reason use _.filter, which return all elements instead _.find,\n * which return only first finded.\n * @param {[type]} list list of elements\n * @param {[type]} name app name\n * @return {[type]} array with finded element or empty array\n */\nfunction filterByName(list, name) {\n var finded = _.filter(list, {'name': name});\n if (finded) {\n return finded;\n } else {\n return [];\n }\n}\n\nfunction filterByRegex(list, regex) {\n var filterPattern = utils.buildRegex(regex);\n return _.filter(list, function (zbx_obj) {\n return filterPattern.test(zbx_obj.name);\n });\n}\n\nfunction findByFilter(list, filter) {\n if (utils.isRegex(filter)) {\n return filterByRegex(list, filter);\n } else {\n return findByName(list, filter);\n }\n}\n\nfunction filterByQuery(list, filter) {\n if (utils.isRegex(filter)) {\n return filterByRegex(list, filter);\n } else {\n return filterByName(list, filter);\n }\n}\n\nfunction getHostIds(items) {\n let hostIds = _.map(items, item => {\n return _.map(item.hosts, 'hostid');\n });\n return _.uniq(_.flatten(hostIds));\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/datasource-zabbix/zabbix.js"],"names":["ZabbixFactory","zabbixAPIService","ZabbixCachingProxy","ZabbixDBConnector","Zabbix","url","options","username","password","basicAuth","withCredentials","cacheTTL","enableDirectDBConnection","sqlDatasourceId","ZabbixAPI","zabbixAPI","dbConnector","cacheOptions","enabled","ttl","cachingProxy","getHistory","bind","getMacros","getHistoryDB","getTrendsDB","getTrend","getEvents","getAlerts","getAcknowledges","getITService","getSLA","getVersion","login","target","parts","filters","_","map","p","filter","getItems","getGroups","groupFilter","getAllGroups","then","findByFilter","groups","groupids","getHosts","hostFilter","getAllHosts","hosts","hostids","getApps","appFilter","filterByQuery","apps","appFilterEmpty","undefined","itemtype","appids","showDisabledItems","items","expandUserMacro","getHostIds","forEach","utils","containsMacro","item","name","replaceMacro","macros","itemFilter","getAllItems","promises","Promise","all","filteredGroups","results","filteredHosts","filteredApps","query","applicationids","flatten","getTriggers","findByName","list","finded","find","filterByName","filterByRegex","regex","filterPattern","buildRegex","zbx_obj","test","isRegex","hostIds","uniq","angular","module","factory"],"mappings":"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","file":"zabbix.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\nimport * as utils from './utils';\nimport './zabbixAPI.service.js';\nimport './zabbixCachingProxy.service.js';\nimport './zabbixDBConnector';\n\n// Use factory() instead service() for multiple data sources support.\n// Each Zabbix data source instance should initialize its own API instance.\n\n/** @ngInject */\nfunction ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) {\n\n class Zabbix {\n constructor(url, options) {\n let {\n username, password, basicAuth, withCredentials, cacheTTL,\n enableDirectDBConnection, sqlDatasourceId\n } = options;\n\n // Initialize Zabbix API\n var ZabbixAPI = zabbixAPIService;\n this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials);\n\n if (enableDirectDBConnection) {\n this.dbConnector = new ZabbixDBConnector(sqlDatasourceId);\n }\n\n // Initialize caching proxy for requests\n let cacheOptions = {\n enabled: true,\n ttl: cacheTTL\n };\n this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions);\n\n // Proxy methods\n this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy);\n this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy);\n\n if (enableDirectDBConnection) {\n this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy);\n this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy);\n }\n\n this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);\n this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);\n this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);\n this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);\n this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);\n this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);\n this.getVersion = this.zabbixAPI.getVersion.bind(this.zabbixAPI);\n this.login = this.zabbixAPI.login.bind(this.zabbixAPI);\n }\n\n getItemsFromTarget(target, options) {\n let parts = ['group', 'host', 'application', 'item'];\n let filters = _.map(parts, p => target[p].filter);\n return this.getItems(...filters, options);\n }\n\n getAllGroups() {\n return this.cachingProxy.getGroups();\n }\n\n getGroups(groupFilter) {\n return this.getAllGroups()\n .then(groups => findByFilter(groups, groupFilter));\n }\n\n /**\n * Get list of host belonging to given groups.\n */\n getAllHosts(groupFilter) {\n return this.getGroups(groupFilter)\n .then(groups => {\n let groupids = _.map(groups, 'groupid');\n return this.cachingProxy.getHosts(groupids);\n });\n }\n\n getHosts(groupFilter, hostFilter) {\n return this.getAllHosts(groupFilter)\n .then(hosts => findByFilter(hosts, hostFilter));\n }\n\n /**\n * Get list of applications belonging to given groups and hosts.\n */\n getAllApps(groupFilter, hostFilter) {\n return this.getHosts(groupFilter, hostFilter)\n .then(hosts => {\n let hostids = _.map(hosts, 'hostid');\n return this.cachingProxy.getApps(hostids);\n });\n }\n\n getApps(groupFilter, hostFilter, appFilter) {\n return this.getHosts(groupFilter, hostFilter)\n .then(hosts => {\n let hostids = _.map(hosts, 'hostid');\n if (appFilter) {\n return this.cachingProxy.getApps(hostids)\n .then(apps => filterByQuery(apps, appFilter));\n } else {\n return {\n appFilterEmpty: true,\n hostids: hostids\n };\n }\n });\n }\n\n getAllItems(groupFilter, hostFilter, appFilter, options = {}) {\n return this.getApps(groupFilter, hostFilter, appFilter)\n .then(apps => {\n if (apps.appFilterEmpty) {\n return this.cachingProxy.getItems(apps.hostids, undefined, options.itemtype);\n } else {\n let appids = _.map(apps, 'applicationid');\n return this.cachingProxy.getItems(undefined, appids, options.itemtype);\n }\n })\n .then(items => {\n if (!options.showDisabledItems) {\n items = _.filter(items, {'status': '0'});\n }\n\n return items;\n })\n .then(this.expandUserMacro.bind(this));\n }\n\n expandUserMacro(items) {\n let hostids = getHostIds(items);\n return this.getMacros(hostids)\n .then(macros => {\n _.forEach(items, item => {\n if (utils.containsMacro(item.name)) {\n item.name = utils.replaceMacro(item, macros);\n }\n });\n return items;\n });\n }\n\n getItems(groupFilter, hostFilter, appFilter, itemFilter, options = {}) {\n return this.getAllItems(groupFilter, hostFilter, appFilter, options)\n .then(items => filterByQuery(items, itemFilter));\n }\n\n /**\n * Build query - convert target filters to array of Zabbix items\n */\n getTriggers(groupFilter, hostFilter, appFilter, options) {\n let promises = [\n this.getGroups(groupFilter),\n this.getHosts(groupFilter, hostFilter),\n this.getApps(groupFilter, hostFilter, appFilter)\n ];\n\n return Promise.all(promises)\n .then(results => {\n let filteredGroups = results[0];\n let filteredHosts = results[1];\n let filteredApps = results[2];\n let query = {};\n\n if (appFilter) {\n query.applicationids = _.flatten(_.map(filteredApps, 'applicationid'));\n }\n if (hostFilter) {\n query.hostids = _.map(filteredHosts, 'hostid');\n }\n if (groupFilter) {\n query.groupids = _.map(filteredGroups, 'groupid');\n }\n\n return query;\n }).then(query => {\n return this.zabbixAPI.getTriggers(query.groupids, query.hostids, query.applicationids, options);\n });\n }\n }\n\n return Zabbix;\n}\n\nangular\n .module('grafana.services')\n .factory('Zabbix', ZabbixFactory);\n\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * Find group, host, app or item by given name.\n * @param list list of groups, apps or other\n * @param name visible name\n * @return array with finded element or empty array\n */\nfunction findByName(list, name) {\n var finded = _.find(list, {'name': name});\n if (finded) {\n return [finded];\n } else {\n return [];\n }\n}\n\n/**\n * Different hosts can contains applications and items with same name.\n * For this reason use _.filter, which return all elements instead _.find,\n * which return only first finded.\n * @param {[type]} list list of elements\n * @param {[type]} name app name\n * @return {[type]} array with finded element or empty array\n */\nfunction filterByName(list, name) {\n var finded = _.filter(list, {'name': name});\n if (finded) {\n return finded;\n } else {\n return [];\n }\n}\n\nfunction filterByRegex(list, regex) {\n var filterPattern = utils.buildRegex(regex);\n return _.filter(list, function (zbx_obj) {\n return filterPattern.test(zbx_obj.name);\n });\n}\n\nfunction findByFilter(list, filter) {\n if (utils.isRegex(filter)) {\n return filterByRegex(list, filter);\n } else {\n return findByName(list, filter);\n }\n}\n\nfunction filterByQuery(list, filter) {\n if (utils.isRegex(filter)) {\n return filterByRegex(list, filter);\n } else {\n return filterByName(list, filter);\n }\n}\n\nfunction getHostIds(items) {\n let hostIds = _.map(items, item => {\n return _.map(item.hosts, 'hostid');\n });\n return _.uniq(_.flatten(hostIds));\n}\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/zabbixCachingProxy.service.js b/dist/datasource-zabbix/zabbixCachingProxy.service.js index 9ccf0f1..6445beb 100644 --- a/dist/datasource-zabbix/zabbixCachingProxy.service.js +++ b/dist/datasource-zabbix/zabbixCachingProxy.service.js @@ -29,10 +29,11 @@ System.register(['angular', 'lodash'], function (_export, _context) { /** @ngInject */ function ZabbixCachingProxyFactory() { var ZabbixCachingProxy = function () { - function ZabbixCachingProxy(zabbixAPI, cacheOptions) { + function ZabbixCachingProxy(zabbixAPI, zabbixDBConnector, cacheOptions) { _classCallCheck(this, ZabbixCachingProxy); this.zabbixAPI = zabbixAPI; + this.dbConnector = zabbixDBConnector; this.cacheEnabled = cacheOptions.enabled; this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default @@ -53,6 +54,11 @@ System.register(['angular', 'lodash'], function (_export, _context) { // Don't run duplicated history requests this.getHistory = callAPIRequestOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI), this.historyPromises, getHistoryRequestHash); + if (this.dbConnector) { + this.getHistoryDB = callAPIRequestOnce(_.bind(this.dbConnector.getHistory, this.dbConnector), this.historyPromises, getDBQueryHash); + this.getTrendsDB = callAPIRequestOnce(_.bind(this.dbConnector.getTrends, this.dbConnector), this.historyPromises, getDBQueryHash); + } + // Don't run duplicated requests this.groupPromises = {}; this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI), this.groupPromises, getRequestHash); @@ -209,6 +215,14 @@ System.register(['angular', 'lodash'], function (_export, _context) { return stamp.getHash(); } + function getDBQueryHash(args) { + var itemids = _.map(args[0], 'itemid'); + var consolidateBy = args[3].consolidateBy; + var intervalMs = args[3].intervalMs; + var stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs; + return stamp.getHash(); + } + return { setters: [function (_angular) { angular = _angular.default; diff --git a/dist/datasource-zabbix/zabbixCachingProxy.service.js.map b/dist/datasource-zabbix/zabbixCachingProxy.service.js.map index 9eda30f..e0fe15e 100644 --- a/dist/datasource-zabbix/zabbixCachingProxy.service.js.map +++ b/dist/datasource-zabbix/zabbixCachingProxy.service.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/datasource-zabbix/zabbixCachingProxy.service.js"],"names":["ZabbixCachingProxyFactory","ZabbixCachingProxy","zabbixAPI","cacheOptions","cacheEnabled","enabled","ttl","cache","groups","hosts","applications","items","history","trends","macros","globalMacros","historyPromises","getHistory","callAPIRequestOnce","_","bind","getHistoryRequestHash","groupPromises","getGroupsOnce","getGroups","getRequestHash","hostPromises","getHostsOnce","getHosts","appPromises","getAppsOnce","getApps","itemPromises","getItemsOnce","getItems","macroPromises","getMacrosOnce","getMacros","globalMacroPromises","getGlobalMacrosOnce","getGlobalMacros","cacheObject","object_age","Date","now","timestamp","request","params","hash","isExpired","Promise","resolve","value","then","result","proxyRequest","groupids","hostids","appids","itemtype","promises","all","flatten","time_from","time_till","historyStorage","full_history","expired","filter","keyBy","item","itemid","length","grouped_history","groupBy","forEach","map","func","promiseKeeper","argsHashFunc","arguments","apply","args","requestStamp","arg","undefined","isArray","sort","toString","join","getHash","itemids","stamp","angular","module","factory","String","prototype","i","chr","len","charCodeAt","indexBy"],"mappings":"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","file":"zabbixCachingProxy.service.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\n\n// Use factory() instead service() for multiple datasources support.\n// Each datasource instance must initialize its own cache.\n\n/** @ngInject */\nfunction ZabbixCachingProxyFactory() {\n\n class ZabbixCachingProxy {\n constructor(zabbixAPI, cacheOptions) {\n this.zabbixAPI = zabbixAPI;\n this.cacheEnabled = cacheOptions.enabled;\n this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default\n\n // Internal objects for data storing\n this.cache = {\n groups: {},\n hosts: {},\n applications: {},\n items: {},\n history: {},\n trends: {},\n macros: {},\n globalMacros: {}\n };\n\n this.historyPromises = {};\n\n // Don't run duplicated history requests\n this.getHistory = callAPIRequestOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI),\n this.historyPromises, getHistoryRequestHash);\n\n // Don't run duplicated requests\n this.groupPromises = {};\n this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI),\n this.groupPromises, getRequestHash);\n\n this.hostPromises = {};\n this.getHostsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getHosts, this.zabbixAPI),\n this.hostPromises, getRequestHash);\n\n this.appPromises = {};\n this.getAppsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getApps, this.zabbixAPI),\n this.appPromises, getRequestHash);\n\n this.itemPromises = {};\n this.getItemsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItems, this.zabbixAPI),\n this.itemPromises, getRequestHash);\n\n this.macroPromises = {};\n this.getMacrosOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getMacros, this.zabbixAPI),\n this.macroPromises, getRequestHash);\n\n this.globalMacroPromises = {};\n this.getGlobalMacrosOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGlobalMacros, this.zabbixAPI),\n this.globalMacroPromises, getRequestHash);\n }\n\n isExpired(cacheObject) {\n if (cacheObject) {\n let object_age = Date.now() - cacheObject.timestamp;\n return !(cacheObject.timestamp && object_age < this.ttl);\n } else {\n return true;\n }\n }\n\n /**\n * Check that result is present in cache and up to date\n * or send request to API.\n */\n proxyRequest(request, params, cacheObject) {\n let hash = getRequestHash(params);\n if (this.cacheEnabled && !this.isExpired(cacheObject[hash])) {\n return Promise.resolve(cacheObject[hash].value);\n } else {\n return request(...params)\n .then(result => {\n cacheObject[hash] = {\n value: result,\n timestamp: Date.now()\n };\n return result;\n });\n }\n }\n\n getGroups() {\n return this.proxyRequest(this.getGroupsOnce, [], this.cache.groups);\n }\n\n getHosts(groupids) {\n return this.proxyRequest(this.getHostsOnce, [groupids], this.cache.hosts);\n }\n\n getApps(hostids) {\n return this.proxyRequest(this.getAppsOnce, [hostids], this.cache.applications);\n }\n\n getItems(hostids, appids, itemtype) {\n let params = [hostids, appids, itemtype];\n return this.proxyRequest(this.getItemsOnce, params, this.cache.items);\n }\n\n getMacros(hostids) {\n // Merge global macros and host macros\n let promises = [\n this.proxyRequest(this.getMacrosOnce, [hostids], this.cache.macros),\n this.proxyRequest(this.getGlobalMacrosOnce, [], this.cache.globalMacros)\n ];\n\n return Promise.all(promises).then(_.flatten);\n }\n\n getHistoryFromCache(items, time_from, time_till) {\n var historyStorage = this.cache.history;\n var full_history;\n var expired = _.filter(_.keyBy(items, 'itemid'), (item, itemid) => {\n return !historyStorage[itemid];\n });\n if (expired.length) {\n return this.zabbixAPI.getHistory(expired, time_from, time_till).then(function(history) {\n var grouped_history = _.groupBy(history, 'itemid');\n _.forEach(expired, item => {\n var itemid = item.itemid;\n historyStorage[itemid] = item;\n historyStorage[itemid].time_from = time_from;\n historyStorage[itemid].time_till = time_till;\n historyStorage[itemid].history = grouped_history[itemid];\n });\n full_history = _.map(items, item => {\n return historyStorage[item.itemid].history;\n });\n return _.flatten(full_history, true);\n });\n } else {\n full_history = _.map(items, function(item) {\n return historyStorage[item.itemid].history;\n });\n return Promise.resolve(_.flatten(full_history, true));\n }\n }\n\n getHistoryFromAPI(items, time_from, time_till) {\n return this.zabbixAPI.getHistory(items, time_from, time_till);\n }\n }\n\n return ZabbixCachingProxy;\n}\n\nangular\n .module('grafana.services')\n .factory('ZabbixCachingProxy', ZabbixCachingProxyFactory);\n\n/**\n * Wrap zabbix API request to prevent multiple calls\n * with same params when waiting for result.\n */\nfunction callAPIRequestOnce(func, promiseKeeper, argsHashFunc) {\n return function() {\n var hash = argsHashFunc(arguments);\n if (!promiseKeeper[hash]) {\n promiseKeeper[hash] = Promise.resolve(\n func.apply(this, arguments)\n .then(result => {\n promiseKeeper[hash] = null;\n return result;\n })\n );\n }\n return promiseKeeper[hash];\n };\n}\n\nfunction getRequestHash(args) {\n var requestStamp = _.map(args, arg => {\n if (arg === undefined) {\n return 'undefined';\n } else {\n if (_.isArray(arg)) {\n return arg.sort().toString();\n } else {\n return arg.toString();\n }\n }\n }).join();\n return requestStamp.getHash();\n}\n\nfunction getHistoryRequestHash(args) {\n let itemids = _.map(args[0], 'itemid');\n let stamp = itemids.join() + args[1] + args[2];\n return stamp.getHash();\n}\n\nString.prototype.getHash = function() {\n var hash = 0, i, chr, len;\n if (this.length !== 0) {\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n }\n return hash;\n};\n\n// Fix for backward compatibility with lodash 2.4\nif (!_.keyBy) {_.keyBy = _.indexBy;}\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/datasource-zabbix/zabbixCachingProxy.service.js"],"names":["ZabbixCachingProxyFactory","ZabbixCachingProxy","zabbixAPI","zabbixDBConnector","cacheOptions","dbConnector","cacheEnabled","enabled","ttl","cache","groups","hosts","applications","items","history","trends","macros","globalMacros","historyPromises","getHistory","callAPIRequestOnce","_","bind","getHistoryRequestHash","getHistoryDB","getDBQueryHash","getTrendsDB","getTrends","groupPromises","getGroupsOnce","getGroups","getRequestHash","hostPromises","getHostsOnce","getHosts","appPromises","getAppsOnce","getApps","itemPromises","getItemsOnce","getItems","macroPromises","getMacrosOnce","getMacros","globalMacroPromises","getGlobalMacrosOnce","getGlobalMacros","cacheObject","object_age","Date","now","timestamp","request","params","hash","isExpired","Promise","resolve","value","then","result","proxyRequest","groupids","hostids","appids","itemtype","promises","all","flatten","time_from","time_till","historyStorage","full_history","expired","filter","keyBy","item","itemid","length","grouped_history","groupBy","forEach","map","func","promiseKeeper","argsHashFunc","arguments","apply","args","requestStamp","arg","undefined","isArray","sort","toString","join","getHash","itemids","stamp","consolidateBy","intervalMs","angular","module","factory","String","prototype","i","chr","len","charCodeAt","indexBy"],"mappings":"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","file":"zabbixCachingProxy.service.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\n\n// Use factory() instead service() for multiple datasources support.\n// Each datasource instance must initialize its own cache.\n\n/** @ngInject */\nfunction ZabbixCachingProxyFactory() {\n\n class ZabbixCachingProxy {\n constructor(zabbixAPI, zabbixDBConnector, cacheOptions) {\n this.zabbixAPI = zabbixAPI;\n this.dbConnector = zabbixDBConnector;\n this.cacheEnabled = cacheOptions.enabled;\n this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default\n\n // Internal objects for data storing\n this.cache = {\n groups: {},\n hosts: {},\n applications: {},\n items: {},\n history: {},\n trends: {},\n macros: {},\n globalMacros: {}\n };\n\n this.historyPromises = {};\n\n // Don't run duplicated history requests\n this.getHistory = callAPIRequestOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI),\n this.historyPromises, getHistoryRequestHash);\n\n if (this.dbConnector) {\n this.getHistoryDB = callAPIRequestOnce(_.bind(this.dbConnector.getHistory, this.dbConnector),\n this.historyPromises, getDBQueryHash);\n this.getTrendsDB = callAPIRequestOnce(_.bind(this.dbConnector.getTrends, this.dbConnector),\n this.historyPromises, getDBQueryHash);\n }\n\n // Don't run duplicated requests\n this.groupPromises = {};\n this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI),\n this.groupPromises, getRequestHash);\n\n this.hostPromises = {};\n this.getHostsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getHosts, this.zabbixAPI),\n this.hostPromises, getRequestHash);\n\n this.appPromises = {};\n this.getAppsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getApps, this.zabbixAPI),\n this.appPromises, getRequestHash);\n\n this.itemPromises = {};\n this.getItemsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItems, this.zabbixAPI),\n this.itemPromises, getRequestHash);\n\n this.macroPromises = {};\n this.getMacrosOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getMacros, this.zabbixAPI),\n this.macroPromises, getRequestHash);\n\n this.globalMacroPromises = {};\n this.getGlobalMacrosOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGlobalMacros, this.zabbixAPI),\n this.globalMacroPromises, getRequestHash);\n }\n\n isExpired(cacheObject) {\n if (cacheObject) {\n let object_age = Date.now() - cacheObject.timestamp;\n return !(cacheObject.timestamp && object_age < this.ttl);\n } else {\n return true;\n }\n }\n\n /**\n * Check that result is present in cache and up to date\n * or send request to API.\n */\n proxyRequest(request, params, cacheObject) {\n let hash = getRequestHash(params);\n if (this.cacheEnabled && !this.isExpired(cacheObject[hash])) {\n return Promise.resolve(cacheObject[hash].value);\n } else {\n return request(...params)\n .then(result => {\n cacheObject[hash] = {\n value: result,\n timestamp: Date.now()\n };\n return result;\n });\n }\n }\n\n getGroups() {\n return this.proxyRequest(this.getGroupsOnce, [], this.cache.groups);\n }\n\n getHosts(groupids) {\n return this.proxyRequest(this.getHostsOnce, [groupids], this.cache.hosts);\n }\n\n getApps(hostids) {\n return this.proxyRequest(this.getAppsOnce, [hostids], this.cache.applications);\n }\n\n getItems(hostids, appids, itemtype) {\n let params = [hostids, appids, itemtype];\n return this.proxyRequest(this.getItemsOnce, params, this.cache.items);\n }\n\n getMacros(hostids) {\n // Merge global macros and host macros\n let promises = [\n this.proxyRequest(this.getMacrosOnce, [hostids], this.cache.macros),\n this.proxyRequest(this.getGlobalMacrosOnce, [], this.cache.globalMacros)\n ];\n\n return Promise.all(promises).then(_.flatten);\n }\n\n getHistoryFromCache(items, time_from, time_till) {\n var historyStorage = this.cache.history;\n var full_history;\n var expired = _.filter(_.keyBy(items, 'itemid'), (item, itemid) => {\n return !historyStorage[itemid];\n });\n if (expired.length) {\n return this.zabbixAPI.getHistory(expired, time_from, time_till).then(function(history) {\n var grouped_history = _.groupBy(history, 'itemid');\n _.forEach(expired, item => {\n var itemid = item.itemid;\n historyStorage[itemid] = item;\n historyStorage[itemid].time_from = time_from;\n historyStorage[itemid].time_till = time_till;\n historyStorage[itemid].history = grouped_history[itemid];\n });\n full_history = _.map(items, item => {\n return historyStorage[item.itemid].history;\n });\n return _.flatten(full_history, true);\n });\n } else {\n full_history = _.map(items, function(item) {\n return historyStorage[item.itemid].history;\n });\n return Promise.resolve(_.flatten(full_history, true));\n }\n }\n\n getHistoryFromAPI(items, time_from, time_till) {\n return this.zabbixAPI.getHistory(items, time_from, time_till);\n }\n }\n\n return ZabbixCachingProxy;\n}\n\nangular\n .module('grafana.services')\n .factory('ZabbixCachingProxy', ZabbixCachingProxyFactory);\n\n/**\n * Wrap zabbix API request to prevent multiple calls\n * with same params when waiting for result.\n */\nfunction callAPIRequestOnce(func, promiseKeeper, argsHashFunc) {\n return function() {\n var hash = argsHashFunc(arguments);\n if (!promiseKeeper[hash]) {\n promiseKeeper[hash] = Promise.resolve(\n func.apply(this, arguments)\n .then(result => {\n promiseKeeper[hash] = null;\n return result;\n })\n );\n }\n return promiseKeeper[hash];\n };\n}\n\nfunction getRequestHash(args) {\n var requestStamp = _.map(args, arg => {\n if (arg === undefined) {\n return 'undefined';\n } else {\n if (_.isArray(arg)) {\n return arg.sort().toString();\n } else {\n return arg.toString();\n }\n }\n }).join();\n return requestStamp.getHash();\n}\n\nfunction getHistoryRequestHash(args) {\n let itemids = _.map(args[0], 'itemid');\n let stamp = itemids.join() + args[1] + args[2];\n return stamp.getHash();\n}\n\nfunction getDBQueryHash(args) {\n let itemids = _.map(args[0], 'itemid');\n let consolidateBy = args[3].consolidateBy;\n let intervalMs = args[3].intervalMs;\n let stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs;\n return stamp.getHash();\n}\n\nString.prototype.getHash = function() {\n var hash = 0, i, chr, len;\n if (this.length !== 0) {\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n }\n return hash;\n};\n\n// Fix for backward compatibility with lodash 2.4\nif (!_.keyBy) {_.keyBy = _.indexBy;}\n"]} \ No newline at end of file diff --git a/dist/datasource-zabbix/zabbixDBConnector.js b/dist/datasource-zabbix/zabbixDBConnector.js new file mode 100644 index 0000000..166a3c8 --- /dev/null +++ b/dist/datasource-zabbix/zabbixDBConnector.js @@ -0,0 +1,224 @@ +'use strict'; + +System.register(['angular', 'lodash'], function (_export, _context) { + "use strict"; + + var angular, _, _createClass, DEFAULT_QUERY_LIMIT, HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP, consolidateByFunc, consolidateByTrendColumns; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + /** @ngInject */ + function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) { + var ZabbixDBConnector = function () { + function ZabbixDBConnector(sqlDataSourceId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, ZabbixDBConnector); + + var limit = options.limit; + + + this.sqlDataSourceId = sqlDataSourceId; + this.limit = limit || DEFAULT_QUERY_LIMIT; + + // Try to load DS with given id to check it's exist + this.loadSQLDataSource(sqlDataSourceId); + } + + _createClass(ZabbixDBConnector, [{ + key: 'loadSQLDataSource', + value: function loadSQLDataSource(datasourceId) { + var ds = _.find(datasourceSrv.getAll(), { 'id': datasourceId }); + if (ds) { + return datasourceSrv.loadDatasource(ds.name).then(function (ds) { + console.log('SQL data source loaded', ds); + }); + } else { + return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found'); + } + } + }, { + key: 'getHistory', + value: function getHistory(items, timeFrom, timeTill, options) { + var _this = this; + + var intervalMs = options.intervalMs, + consolidateBy = options.consolidateBy; + + var intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + var aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + var grouped_items = _.groupBy(items, 'value_type'); + var promises = _.map(grouped_items, function (items, value_type) { + var itemids = _.map(items, 'itemid').join(', '); + var table = HISTORY_TO_TABLE_MAP[value_type]; + + var query = '\n SELECT itemid AS metric, clock AS time_sec, ' + aggFunction + '(value) as value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY time_sec DIV ' + intervalSec + ', metric\n '; + + query = compactSQLQuery(query); + return _this.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(function (results) { + return _.flatten(results); + }); + } + }, { + key: 'getTrends', + value: function getTrends(items, timeFrom, timeTill, options) { + var _this2 = this; + + var intervalMs = options.intervalMs, + consolidateBy = options.consolidateBy; + + var intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + var aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + var grouped_items = _.groupBy(items, 'value_type'); + var promises = _.map(grouped_items, function (items, value_type) { + var itemids = _.map(items, 'itemid').join(', '); + var table = TREND_TO_TABLE_MAP[value_type]; + var valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg'; + valueColumn = consolidateByTrendColumns[valueColumn]; + + var query = '\n SELECT itemid AS metric, clock AS time_sec, ' + aggFunction + '(' + valueColumn + ') as value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY time_sec DIV ' + intervalSec + ', metric\n '; + + query = compactSQLQuery(query); + return _this2.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(function (results) { + return _.flatten(results); + }); + } + }, { + key: 'handleGrafanaTSResponse', + value: function handleGrafanaTSResponse(history, items) { + var addHostName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + + return convertGrafanaTSResponse(history, items, addHostName); + } + }, { + key: 'invokeSQLQuery', + value: function invokeSQLQuery(query) { + var queryDef = { + refId: 'A', + format: 'time_series', + datasourceId: this.sqlDataSourceId, + rawSql: query, + maxDataPoints: this.limit + }; + + return backendSrv.datasourceRequest({ + url: '/api/tsdb/query', + method: 'POST', + data: { + queries: [queryDef] + } + }).then(function (response) { + var results = response.data.results; + if (results['A']) { + return results['A'].series; + } else { + return null; + } + }); + } + }]); + + return ZabbixDBConnector; + }(); + + return ZabbixDBConnector; + } + + /////////////////////////////////////////////////////////////////////////////// + + function convertGrafanaTSResponse(time_series, items, addHostName) { + var hosts = _.uniqBy(_.flatten(_.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate + var grafanaSeries = _.map(time_series, function (series) { + var itemid = series.name; + var datapoints = series.points; + var item = _.find(items, { 'itemid': itemid }); + var alias = item.name; + if (_.keys(hosts).length > 1 && addHostName) { + //only when actual multi hosts selected + var host = _.find(hosts, { 'hostid': item.hostid }); + alias = host.name + ": " + alias; + } + return { + target: alias, + datapoints: datapoints + }; + }); + + return _.sortBy(grafanaSeries, 'target'); + } + + function compactSQLQuery(query) { + return query.replace(/\s+/g, ' '); + } + return { + setters: [function (_angular) { + angular = _angular.default; + }, function (_lodash) { + _ = _lodash.default; + }], + execute: function () { + _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + DEFAULT_QUERY_LIMIT = 10000; + HISTORY_TO_TABLE_MAP = { + '0': 'history', + '1': 'history_str', + '2': 'history_log', + '3': 'history_uint', + '4': 'history_text' + }; + TREND_TO_TABLE_MAP = { + '0': 'trends', + '3': 'trends_uint' + }; + consolidateByFunc = { + 'avg': 'AVG', + 'min': 'MIN', + 'max': 'MAX', + 'sum': 'SUM', + 'count': 'COUNT' + }; + consolidateByTrendColumns = { + 'avg': 'value_avg', + 'min': 'value_min', + 'max': 'value_max' + }; + angular.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory); + } + }; +}); +//# sourceMappingURL=zabbixDBConnector.js.map diff --git a/dist/datasource-zabbix/zabbixDBConnector.js.map b/dist/datasource-zabbix/zabbixDBConnector.js.map new file mode 100644 index 0000000..db285ba --- /dev/null +++ b/dist/datasource-zabbix/zabbixDBConnector.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../src/datasource-zabbix/zabbixDBConnector.js"],"names":["ZabbixDBConnectorFactory","datasourceSrv","backendSrv","ZabbixDBConnector","sqlDataSourceId","options","limit","DEFAULT_QUERY_LIMIT","loadSQLDataSource","datasourceId","ds","_","find","getAll","loadDatasource","name","then","console","log","Promise","reject","items","timeFrom","timeTill","intervalMs","consolidateBy","intervalSec","Math","ceil","aggFunction","consolidateByFunc","grouped_items","groupBy","promises","map","value_type","itemids","join","table","HISTORY_TO_TABLE_MAP","query","compactSQLQuery","invokeSQLQuery","all","flatten","results","TREND_TO_TABLE_MAP","valueColumn","includes","consolidateByTrendColumns","history","addHostName","convertGrafanaTSResponse","queryDef","refId","format","rawSql","maxDataPoints","datasourceRequest","url","method","data","queries","response","series","time_series","hosts","uniqBy","grafanaSeries","itemid","datapoints","points","item","alias","keys","length","host","hostid","target","sortBy","replace","angular","module","factory"],"mappings":"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","file":"zabbixDBConnector.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\n\nconst DEFAULT_QUERY_LIMIT = 10000;\nconst HISTORY_TO_TABLE_MAP = {\n '0': 'history',\n '1': 'history_str',\n '2': 'history_log',\n '3': 'history_uint',\n '4': 'history_text'\n};\n\nconst TREND_TO_TABLE_MAP = {\n '0': 'trends',\n '3': 'trends_uint'\n};\n\nconst consolidateByFunc = {\n 'avg': 'AVG',\n 'min': 'MIN',\n 'max': 'MAX',\n 'sum': 'SUM',\n 'count': 'COUNT'\n};\n\nconst consolidateByTrendColumns = {\n 'avg': 'value_avg',\n 'min': 'value_min',\n 'max': 'value_max'\n};\n\n/** @ngInject */\nfunction ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {\n\n class ZabbixDBConnector {\n\n constructor(sqlDataSourceId, options = {}) {\n let {limit} = options;\n\n this.sqlDataSourceId = sqlDataSourceId;\n this.limit = limit || DEFAULT_QUERY_LIMIT;\n\n // Try to load DS with given id to check it's exist\n this.loadSQLDataSource(sqlDataSourceId);\n }\n\n loadSQLDataSource(datasourceId) {\n let ds = _.find(datasourceSrv.getAll(), {'id': datasourceId});\n if (ds) {\n return datasourceSrv.loadDatasource(ds.name)\n .then(ds => {\n console.log('SQL data source loaded', ds);\n });\n } else {\n return Promise.reject(`SQL Data Source with ID ${datasourceId} not found`);\n }\n }\n\n getHistory(items, timeFrom, timeTill, options) {\n let {intervalMs, consolidateBy} = options;\n let intervalSec = Math.ceil(intervalMs / 1000);\n\n consolidateBy = consolidateBy || 'avg';\n let aggFunction = consolidateByFunc[consolidateBy];\n\n // Group items by value type and perform request for each value type\n let grouped_items = _.groupBy(items, 'value_type');\n let promises = _.map(grouped_items, (items, value_type) => {\n let itemids = _.map(items, 'itemid').join(', ');\n let table = HISTORY_TO_TABLE_MAP[value_type];\n\n let query = `\n SELECT itemid AS metric, clock AS time_sec, ${aggFunction}(value) as value\n FROM ${table}\n WHERE itemid IN (${itemids})\n AND clock > ${timeFrom} AND clock < ${timeTill}\n GROUP BY time_sec DIV ${intervalSec}, metric\n `;\n\n query = compactSQLQuery(query);\n return this.invokeSQLQuery(query);\n });\n\n return Promise.all(promises).then(results => {\n return _.flatten(results);\n });\n }\n\n getTrends(items, timeFrom, timeTill, options) {\n let {intervalMs, consolidateBy} = options;\n let intervalSec = Math.ceil(intervalMs / 1000);\n\n consolidateBy = consolidateBy || 'avg';\n let aggFunction = consolidateByFunc[consolidateBy];\n\n // Group items by value type and perform request for each value type\n let grouped_items = _.groupBy(items, 'value_type');\n let promises = _.map(grouped_items, (items, value_type) => {\n let itemids = _.map(items, 'itemid').join(', ');\n let table = TREND_TO_TABLE_MAP[value_type];\n let valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';\n valueColumn = consolidateByTrendColumns[valueColumn];\n\n let query = `\n SELECT itemid AS metric, clock AS time_sec, ${aggFunction}(${valueColumn}) as value\n FROM ${table}\n WHERE itemid IN (${itemids})\n AND clock > ${timeFrom} AND clock < ${timeTill}\n GROUP BY time_sec DIV ${intervalSec}, metric\n `;\n\n query = compactSQLQuery(query);\n return this.invokeSQLQuery(query);\n });\n\n return Promise.all(promises).then(results => {\n return _.flatten(results);\n });\n }\n\n handleGrafanaTSResponse(history, items, addHostName = true) {\n return convertGrafanaTSResponse(history, items, addHostName);\n }\n\n invokeSQLQuery(query) {\n let queryDef = {\n refId: 'A',\n format: 'time_series',\n datasourceId: this.sqlDataSourceId,\n rawSql: query,\n maxDataPoints: this.limit\n };\n\n return backendSrv.datasourceRequest({\n url: '/api/tsdb/query',\n method: 'POST',\n data: {\n queries: [queryDef],\n }\n })\n .then(response => {\n let results = response.data.results;\n if (results['A']) {\n return results['A'].series;\n } else {\n return null;\n }\n });\n }\n }\n\n return ZabbixDBConnector;\n}\n\nangular\n .module('grafana.services')\n .factory('ZabbixDBConnector', ZabbixDBConnectorFactory);\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunction convertGrafanaTSResponse(time_series, items, addHostName) {\n var hosts = _.uniqBy(_.flatten(_.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate\n let grafanaSeries = _.map(time_series, series => {\n let itemid = series.name;\n let datapoints = series.points;\n var item = _.find(items, {'itemid': itemid});\n var alias = item.name;\n if (_.keys(hosts).length > 1 && addHostName) { //only when actual multi hosts selected\n var host = _.find(hosts, {'hostid': item.hostid});\n alias = host.name + \": \" + alias;\n }\n return {\n target: alias,\n datapoints: datapoints\n };\n });\n\n return _.sortBy(grafanaSeries, 'target');\n}\n\nfunction compactSQLQuery(query) {\n return query.replace(/\\s+/g, ' ');\n}\n"]} \ No newline at end of file diff --git a/dist/test/datasource-zabbix/config.controller.js b/dist/test/datasource-zabbix/config.controller.js new file mode 100644 index 0000000..4cf0090 --- /dev/null +++ b/dist/test/datasource-zabbix/config.controller.js @@ -0,0 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ZabbixDSConfigController = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _lodash = require('lodash'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var SUPPORTED_SQL_DS = ['mysql']; + +var defaultConfig = { + dbConnection: { + enable: false + } +}; + +var ZabbixDSConfigController = exports.ZabbixDSConfigController = function () { + /** @ngInject */ + function ZabbixDSConfigController($scope, $injector, datasourceSrv) { + _classCallCheck(this, ZabbixDSConfigController); + + this.datasourceSrv = datasourceSrv; + + _lodash2.default.defaults(this.current.jsonData, defaultConfig); + this.sqlDataSources = this.getSupportedSQLDataSources(); + } + + _createClass(ZabbixDSConfigController, [{ + key: 'getSupportedSQLDataSources', + value: function getSupportedSQLDataSources() { + var datasources = this.datasourceSrv.getAll(); + return _lodash2.default.filter(datasources, function (ds) { + return _lodash2.default.includes(SUPPORTED_SQL_DS, ds.type); + }); + } + }]); + + return ZabbixDSConfigController; +}(); + +ZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; diff --git a/dist/test/datasource-zabbix/datasource.js b/dist/test/datasource-zabbix/datasource.js index f78e0b3..e40c600 100644 --- a/dist/test/datasource-zabbix/datasource.js +++ b/dist/test/datasource-zabbix/datasource.js @@ -64,6 +64,9 @@ var ZabbixAPIDatasource = function () { this.dashboardSrv = dashboardSrv; this.zabbixAlertingSrv = zabbixAlertingSrv; + // Use custom format for template variables + this.replaceTemplateVars = _lodash2.default.partial(replaceTemplateVars, this.templateSrv); + // General data source settings this.name = instanceSettings.name; this.url = instanceSettings.url; @@ -88,10 +91,21 @@ var ZabbixAPIDatasource = function () { this.addThresholds = instanceSettings.jsonData.addThresholds; this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING; - this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL); + // Direct DB Connection options + this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable; + this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId; - // Use custom format for template variables - this.replaceTemplateVars = _lodash2.default.partial(replaceTemplateVars, this.templateSrv); + var zabbixOptions = { + username: this.username, + password: this.password, + basicAuth: this.basicAuth, + withCredentials: this.withCredentials, + cacheTTL: this.cacheTTL, + enableDirectDBConnection: this.enableDirectDBConnection, + sqlDatasourceId: this.sqlDatasourceId + }; + + this.zabbix = new Zabbix(this.url, zabbixOptions); } //////////////////////// @@ -197,26 +211,38 @@ var ZabbixAPIDatasource = function () { }; return this.zabbix.getItemsFromTarget(target, getItemOptions).then(function (items) { var getHistoryPromise = void 0; + options.consolidateBy = getConsolidateBy(target); if (useTrends) { - var valueType = _this2.getTrendValueType(target); - getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) { - return _responseHandler2.default.handleTrends(history, items, valueType); - }).then(function (timeseries) { - // Sort trend data, issue #202 - _lodash2.default.forEach(timeseries, function (series) { - series.datapoints = _lodash2.default.sortBy(series.datapoints, function (point) { - return point[c.DATAPOINT_TS]; - }); + if (_this2.enableDirectDBConnection) { + getHistoryPromise = _this2.zabbix.getTrendsDB(items, timeFrom, timeTo, options).then(function (history) { + return _this2.zabbix.dbConnector.handleGrafanaTSResponse(history, items); }); - - return timeseries; - }); + } else { + var valueType = _this2.getTrendValueType(target); + getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) { + return _responseHandler2.default.handleTrends(history, items, valueType); + }).then(function (timeseries) { + // Sort trend data, issue #202 + _lodash2.default.forEach(timeseries, function (series) { + series.datapoints = _lodash2.default.sortBy(series.datapoints, function (point) { + return point[c.DATAPOINT_TS]; + }); + }); + return timeseries; + }); + } } else { // Use history - getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) { - return _responseHandler2.default.handleHistory(history, items); - }); + if (_this2.enableDirectDBConnection) { + getHistoryPromise = _this2.zabbix.getHistoryDB(items, timeFrom, timeTo, options).then(function (history) { + return _this2.zabbix.dbConnector.handleGrafanaTSResponse(history, items); + }); + } else { + getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) { + return _responseHandler2.default.handleHistory(history, items); + }); + } } return getHistoryPromise; @@ -593,10 +619,23 @@ function bindFunctionDefs(functionDefs, category) { }); } +function getConsolidateBy(target) { + var consolidateBy = 'avg'; + var funcDef = _lodash2.default.find(target.functions, function (func) { + return func.def.name === 'consolidateBy'; + }); + if (funcDef && funcDef.params && funcDef.params.length) { + consolidateBy = funcDef.params[0]; + } + return consolidateBy; +} + function downsampleSeries(timeseries_data, options) { + var defaultAgg = _dataProcessor2.default.aggregationFunctions['avg']; + var consolidateByFunc = _dataProcessor2.default.aggregationFunctions[options.consolidateBy] || defaultAgg; return _lodash2.default.map(timeseries_data, function (timeseries) { if (timeseries.datapoints.length > options.maxDataPoints) { - timeseries.datapoints = _dataProcessor2.default.groupBy(options.interval, _dataProcessor2.default.AVERAGE, timeseries.datapoints); + timeseries.datapoints = _dataProcessor2.default.groupBy(options.interval, consolidateByFunc, timeseries.datapoints); } return timeseries; }); diff --git a/dist/test/datasource-zabbix/metricFunctions.js b/dist/test/datasource-zabbix/metricFunctions.js index 279d327..f6fc189 100644 --- a/dist/test/datasource-zabbix/metricFunctions.js +++ b/dist/test/datasource-zabbix/metricFunctions.js @@ -29,7 +29,8 @@ var categories = { Filter: [], Trends: [], Time: [], - Alias: [] + Alias: [], + Special: [] }; function addFuncDef(funcDef) { @@ -188,6 +189,14 @@ addFuncDef({ defaultParams: ['/(.*)/', '$1'] }); +// Special +addFuncDef({ + name: 'consolidateBy', + category: 'Special', + params: [{ name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] }], + defaultParams: ['avg'] +}); + _lodash2.default.each(categories, function (funcList, catName) { categories[catName] = _lodash2.default.sortBy(funcList, 'name'); }); diff --git a/dist/test/datasource-zabbix/module.js b/dist/test/datasource-zabbix/module.js index 10f88d0..6a44f8d 100644 --- a/dist/test/datasource-zabbix/module.js +++ b/dist/test/datasource-zabbix/module.js @@ -9,14 +9,10 @@ var _datasource = require('./datasource'); var _query = require('./query.controller'); +var _config = require('./config.controller'); + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var ZabbixConfigController = function ZabbixConfigController() { - _classCallCheck(this, ZabbixConfigController); -}; - -ZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; - var ZabbixQueryOptionsController = function ZabbixQueryOptionsController() { _classCallCheck(this, ZabbixQueryOptionsController); }; @@ -30,7 +26,7 @@ var ZabbixAnnotationsQueryController = function ZabbixAnnotationsQueryController ZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html'; exports.Datasource = _datasource.ZabbixAPIDatasource; -exports.ConfigCtrl = ZabbixConfigController; +exports.ConfigCtrl = _config.ZabbixDSConfigController; exports.QueryCtrl = _query.ZabbixQueryController; exports.QueryOptionsCtrl = ZabbixQueryOptionsController; exports.AnnotationsQueryCtrl = ZabbixAnnotationsQueryController; diff --git a/dist/test/datasource-zabbix/specs/datasource_specs.js b/dist/test/datasource-zabbix/specs/datasource_specs.js index b4c1fee..89e19ca 100644 --- a/dist/test/datasource-zabbix/specs/datasource_specs.js +++ b/dist/test/datasource-zabbix/specs/datasource_specs.js @@ -29,7 +29,10 @@ describe('ZabbixDatasource', function () { password: 'zabbix', trends: true, trendsFrom: '14d', - trendsRange: '7d' + trendsRange: '7d', + dbConnection: { + enabled: false + } } }; ctx.templateSrv = {}; diff --git a/dist/test/datasource-zabbix/zabbix.js b/dist/test/datasource-zabbix/zabbix.js index 3875006..6d0124b 100644 --- a/dist/test/datasource-zabbix/zabbix.js +++ b/dist/test/datasource-zabbix/zabbix.js @@ -18,6 +18,8 @@ require('./zabbixAPI.service.js'); require('./zabbixCachingProxy.service.js'); +require('./zabbixDBConnector'); + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -30,26 +32,44 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons // Each Zabbix data source instance should initialize its own API instance. /** @ngInject */ -function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) { +function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) { var Zabbix = function () { - function Zabbix(url, username, password, basicAuth, withCredentials, cacheTTL) { + function Zabbix(url, options) { _classCallCheck(this, Zabbix); + var username = options.username, + password = options.password, + basicAuth = options.basicAuth, + withCredentials = options.withCredentials, + cacheTTL = options.cacheTTL, + enableDirectDBConnection = options.enableDirectDBConnection, + sqlDatasourceId = options.sqlDatasourceId; + // Initialize Zabbix API + var ZabbixAPI = zabbixAPIService; this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials); + if (enableDirectDBConnection) { + this.dbConnector = new ZabbixDBConnector(sqlDatasourceId); + } + // Initialize caching proxy for requests var cacheOptions = { enabled: true, ttl: cacheTTL }; - this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions); + this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions); // Proxy methods this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy); this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy); + if (enableDirectDBConnection) { + this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy); + this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy); + } + this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); diff --git a/dist/test/datasource-zabbix/zabbixCachingProxy.service.js b/dist/test/datasource-zabbix/zabbixCachingProxy.service.js index 353d9cc..cb28b6a 100644 --- a/dist/test/datasource-zabbix/zabbixCachingProxy.service.js +++ b/dist/test/datasource-zabbix/zabbixCachingProxy.service.js @@ -22,10 +22,11 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons /** @ngInject */ function ZabbixCachingProxyFactory() { var ZabbixCachingProxy = function () { - function ZabbixCachingProxy(zabbixAPI, cacheOptions) { + function ZabbixCachingProxy(zabbixAPI, zabbixDBConnector, cacheOptions) { _classCallCheck(this, ZabbixCachingProxy); this.zabbixAPI = zabbixAPI; + this.dbConnector = zabbixDBConnector; this.cacheEnabled = cacheOptions.enabled; this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default @@ -46,6 +47,11 @@ function ZabbixCachingProxyFactory() { // Don't run duplicated history requests this.getHistory = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getHistory, this.zabbixAPI), this.historyPromises, getHistoryRequestHash); + if (this.dbConnector) { + this.getHistoryDB = callAPIRequestOnce(_lodash2.default.bind(this.dbConnector.getHistory, this.dbConnector), this.historyPromises, getDBQueryHash); + this.getTrendsDB = callAPIRequestOnce(_lodash2.default.bind(this.dbConnector.getTrends, this.dbConnector), this.historyPromises, getDBQueryHash); + } + // Don't run duplicated requests this.groupPromises = {}; this.getGroupsOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getGroups, this.zabbixAPI), this.groupPromises, getRequestHash); @@ -210,6 +216,14 @@ function getHistoryRequestHash(args) { return stamp.getHash(); } +function getDBQueryHash(args) { + var itemids = _lodash2.default.map(args[0], 'itemid'); + var consolidateBy = args[3].consolidateBy; + var intervalMs = args[3].intervalMs; + var stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs; + return stamp.getHash(); +} + String.prototype.getHash = function () { var hash = 0, i, diff --git a/dist/test/datasource-zabbix/zabbixDBConnector.js b/dist/test/datasource-zabbix/zabbixDBConnector.js new file mode 100644 index 0000000..6486527 --- /dev/null +++ b/dist/test/datasource-zabbix/zabbixDBConnector.js @@ -0,0 +1,203 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _angular = require('angular'); + +var _angular2 = _interopRequireDefault(_angular); + +var _lodash = require('lodash'); + +var _lodash2 = _interopRequireDefault(_lodash); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DEFAULT_QUERY_LIMIT = 10000; +var HISTORY_TO_TABLE_MAP = { + '0': 'history', + '1': 'history_str', + '2': 'history_log', + '3': 'history_uint', + '4': 'history_text' +}; + +var TREND_TO_TABLE_MAP = { + '0': 'trends', + '3': 'trends_uint' +}; + +var consolidateByFunc = { + 'avg': 'AVG', + 'min': 'MIN', + 'max': 'MAX', + 'sum': 'SUM', + 'count': 'COUNT' +}; + +var consolidateByTrendColumns = { + 'avg': 'value_avg', + 'min': 'value_min', + 'max': 'value_max' +}; + +/** @ngInject */ +function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) { + var ZabbixDBConnector = function () { + function ZabbixDBConnector(sqlDataSourceId) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, ZabbixDBConnector); + + var limit = options.limit; + + + this.sqlDataSourceId = sqlDataSourceId; + this.limit = limit || DEFAULT_QUERY_LIMIT; + + // Try to load DS with given id to check it's exist + this.loadSQLDataSource(sqlDataSourceId); + } + + _createClass(ZabbixDBConnector, [{ + key: 'loadSQLDataSource', + value: function loadSQLDataSource(datasourceId) { + var ds = _lodash2.default.find(datasourceSrv.getAll(), { 'id': datasourceId }); + if (ds) { + return datasourceSrv.loadDatasource(ds.name).then(function (ds) { + console.log('SQL data source loaded', ds); + }); + } else { + return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found'); + } + } + }, { + key: 'getHistory', + value: function getHistory(items, timeFrom, timeTill, options) { + var _this = this; + + var intervalMs = options.intervalMs, + consolidateBy = options.consolidateBy; + + var intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + var aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + var grouped_items = _lodash2.default.groupBy(items, 'value_type'); + var promises = _lodash2.default.map(grouped_items, function (items, value_type) { + var itemids = _lodash2.default.map(items, 'itemid').join(', '); + var table = HISTORY_TO_TABLE_MAP[value_type]; + + var query = '\n SELECT itemid AS metric, clock AS time_sec, ' + aggFunction + '(value) as value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY time_sec DIV ' + intervalSec + ', metric\n '; + + query = compactSQLQuery(query); + return _this.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(function (results) { + return _lodash2.default.flatten(results); + }); + } + }, { + key: 'getTrends', + value: function getTrends(items, timeFrom, timeTill, options) { + var _this2 = this; + + var intervalMs = options.intervalMs, + consolidateBy = options.consolidateBy; + + var intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + var aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + var grouped_items = _lodash2.default.groupBy(items, 'value_type'); + var promises = _lodash2.default.map(grouped_items, function (items, value_type) { + var itemids = _lodash2.default.map(items, 'itemid').join(', '); + var table = TREND_TO_TABLE_MAP[value_type]; + var valueColumn = _lodash2.default.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg'; + valueColumn = consolidateByTrendColumns[valueColumn]; + + var query = '\n SELECT itemid AS metric, clock AS time_sec, ' + aggFunction + '(' + valueColumn + ') as value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY time_sec DIV ' + intervalSec + ', metric\n '; + + query = compactSQLQuery(query); + return _this2.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(function (results) { + return _lodash2.default.flatten(results); + }); + } + }, { + key: 'handleGrafanaTSResponse', + value: function handleGrafanaTSResponse(history, items) { + var addHostName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + + return convertGrafanaTSResponse(history, items, addHostName); + } + }, { + key: 'invokeSQLQuery', + value: function invokeSQLQuery(query) { + var queryDef = { + refId: 'A', + format: 'time_series', + datasourceId: this.sqlDataSourceId, + rawSql: query, + maxDataPoints: this.limit + }; + + return backendSrv.datasourceRequest({ + url: '/api/tsdb/query', + method: 'POST', + data: { + queries: [queryDef] + } + }).then(function (response) { + var results = response.data.results; + if (results['A']) { + return results['A'].series; + } else { + return null; + } + }); + } + }]); + + return ZabbixDBConnector; + }(); + + return ZabbixDBConnector; +} + +_angular2.default.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory); + +/////////////////////////////////////////////////////////////////////////////// + +function convertGrafanaTSResponse(time_series, items, addHostName) { + var hosts = _lodash2.default.uniqBy(_lodash2.default.flatten(_lodash2.default.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate + var grafanaSeries = _lodash2.default.map(time_series, function (series) { + var itemid = series.name; + var datapoints = series.points; + var item = _lodash2.default.find(items, { 'itemid': itemid }); + var alias = item.name; + if (_lodash2.default.keys(hosts).length > 1 && addHostName) { + //only when actual multi hosts selected + var host = _lodash2.default.find(hosts, { 'hostid': item.hostid }); + alias = host.name + ": " + alias; + } + return { + target: alias, + datapoints: datapoints + }; + }); + + return _lodash2.default.sortBy(grafanaSeries, 'target'); +} + +function compactSQLQuery(query) { + return query.replace(/\s+/g, ' '); +} diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index b98283b..1666dad 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -18,6 +18,7 @@ pages: - Installation: - 'Installation': 'installation/index.md' - 'Configuration': 'installation/configuration.md' + - 'SQL Data Source Configuration': 'installation/configuration-sql.md' - 'Upgrade': 'installation/upgrade.md' - 'Troubleshooting': 'installation/troubleshooting.md' - User Guides: @@ -28,5 +29,6 @@ pages: - 'Triggers Panel': 'reference/panel-triggers.md' - 'Functions': 'reference/functions.md' - 'Alerting': 'reference/alerting.md' + - 'Direct DB Connection': 'reference/direct-db-connection.md' # - Tutorials: # - 'Building Host Dashboard': 'tutorials/host_dashboard.md' diff --git a/docs/sources/img/installation-datasource_config.png b/docs/sources/img/installation-datasource_config.png index f5ee615..ab3648d 100644 --- a/docs/sources/img/installation-datasource_config.png +++ b/docs/sources/img/installation-datasource_config.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b58742637f58519a5fab038db0c15b5525d1d330fe5e4a1de954b72f4f1cc3e -size 225446 +oid sha256:367b5fa51e9d05eb87afedd4ef6ed8ea1ce0e095f94bfdc58ebe6744fbaca71c +size 131343 diff --git a/docs/sources/img/installation-mysql_ds_config.png b/docs/sources/img/installation-mysql_ds_config.png new file mode 100644 index 0000000..3c8d221 --- /dev/null +++ b/docs/sources/img/installation-mysql_ds_config.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bac25f3d28c74f1f309476120bc67275e15f420e3343f0ff9668ead3a1e6170 +size 227988 diff --git a/docs/sources/installation/configuration-sql.md b/docs/sources/installation/configuration-sql.md new file mode 100644 index 0000000..a1cf37a --- /dev/null +++ b/docs/sources/installation/configuration-sql.md @@ -0,0 +1,22 @@ +# SQL Data Source Configuration + +In order to use _Direct DB Connection_ feature you should configure SQL data source first. + +![Configure MySQL data source](../img/installation-mysql_ds_config.png) + +Select _MySQL_ data source type and provide your database host address and port (3306 is default for MySQL). Fill +database name (usually, `zabbix`) and specify credentials. + +## Security notes + +As you can see in _User Permission_ note, Grafana doesn't restrict any queries to the database. So you should be careful +and create a special user with limited access to Zabbix database. Grafana-Zabbix plugin uses only `SELECT` queries to +`history`, `history_uint`, `trends` and `trends_uint` tables. So it's reasonable to grant only SELECT privileges to +these tables for grafana user. But if you want to use this MySQL data source for querying another data, you can +grant SELECT privileges to entire zabbix database. + +Also, all queries are invoked by grafana-server, so you can restrict connection to only grafana host. + +```sql +GRANT SELECT ON zabbix.* TO 'grafana'@'grafana-host' identified by 'password'; +``` diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index ae4f78d..9d7135e 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -52,7 +52,23 @@ Direct access is still supported because in some cases it may be useful to acces - **Cache TTL**: plugin caches some api requests for increasing performance. Set this value to desired cache lifetime (this option affect data like items list). +### Direct DB Connection + +Direct DB Connection allows plugin to use existing SQL data source for querying history data directly from Zabbix +database. This way usually faster than pulling data from Zabbix API, especially on the wide time ranges, and reduces +amount of data transfered. + +Read [how to configure](/installation/configuration-sql) SQL data source in Grafana. + +- **Enable**: enable Direct DB Connection. +- **SQL Data Source**: Select SQL Data Source for Zabbix database. + +#### Supported databases + +Now only **MySQL** is supported by Grafana. + ### Alerting + - **Enable alerting**: enable limited alerting support. - **Add thresholds**: get thresholds info from zabbix triggers and add it to graphs. For example, if you have trigger `{Zabbix server:system.cpu.util[,iowait].avg(5m)}>20`, threshold will be set to 20. @@ -65,10 +81,12 @@ or password, wrong api url. ![Test Connection](../img/installation-test_connection.png) ## Import example dashboards + You can import dashboard examples from _Dashboards_ tab in plugin config. ![Import dashboards](../img/installation-plugin-dashboards.png) ## Note about Zabbix 2.2 or less + Zabbix API (api_jsonrpc.php) before zabbix 2.4 don't allow cross-domain requests (CORS). And you can get HTTP error 412 (Precondition Failed). To fix it add this code to api_jsonrpc.php immediately after the copyright: @@ -83,17 +101,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { return; } ``` + before ```php require_once dirname(__FILE__).'/include/func.inc.php'; require_once dirname(__FILE__).'/include/classes/core/CHttpRequest.php'; ``` + [Full fix listing](https://gist.github.com/alexanderzobnin/f2348f318d7a93466a0c). For more details see zabbix issues [ZBXNEXT-1377](https://support.zabbix.com/browse/ZBXNEXT-1377) and [ZBX-8459](https://support.zabbix.com/browse/ZBX-8459). ## Note about Browser Cache + After updating plugin, clear browser cache and reload application page. See details for [Chrome](https://support.google.com/chrome/answer/95582), [Firefox](https://support.mozilla.org/en-US/kb/how-clear-firefox-cache). You need to clear cache diff --git a/docs/sources/reference/direct-db-connection.md b/docs/sources/reference/direct-db-connection.md new file mode 100644 index 0000000..8ad1a09 --- /dev/null +++ b/docs/sources/reference/direct-db-connection.md @@ -0,0 +1,43 @@ +# Direct DB Connection + +Since version 4.3 Grafana has MySQL data source, Grafana-Zabbix plugin can use it for querying data directly from +Zabbix database. + +One of the most hard queries for Zabbix API is history queries. For long time intervals `history.get` +returns huge amount of data. In order to display it, plugin should adjust time series resolution +by using [consolidateBy](/reference/functions/#consolidateby) function. Ultimately, Grafana displays this reduced +time series, but that data should be loaded and processed on the client side first. Direct DB Connection solves this +two problems by moving consolidation to the server side. Thus, client get ready-to-use dataset which has much smaller +size. Data loads faster and client don't spend time for data processing. + +Also, many users point better performance of direct database queries versus API calls. This caused by several reasons, +such as additional PHP layer and additional SQL queries (user permissions checks). + +## Query structure + +Grafana-Zabbix uses queries like this for getting history: + +```sql +SELECT itemid AS metric, clock AS time_sec, {aggFunc}(value) as value + FROM {historyTable} + WHERE itemid IN ({itemids}) + AND clock > {timeFrom} AND clock < {timeTill} + GROUP BY time_sec DIV {intervalSec}, metric +``` + +where `{aggFunc}` is one of `[AVG, MIN, MAX, SUM, COUNT]` aggregation function, `{historyTable}` is a history table, +`{intervalSec}` - consolidation interval in seconds. + +When getting trends, plugin additionally queries particular value column (`value_avg`, `value_min` or `value_max`) +depends on `consolidateBy` function value: + +```sql +SELECT itemid AS metric, clock AS time_sec, {aggFunc}({valueColumn}) as value + FROM {trendsTable} + WHERE itemid IN ({itemids}) + AND clock > {timeFrom} AND clock < {timeTill} + GROUP BY time_sec DIV {intervalSec}, metric +``` + +As you can see, plugin uses aggregation by given time interval. This interval is provided by Grafana and depends on the +panel with in pixels. Thus, Grafana always gets data in necessary resolution. diff --git a/docs/sources/reference/functions.md b/docs/sources/reference/functions.md index 17e800a..69aba1b 100644 --- a/docs/sources/reference/functions.md +++ b/docs/sources/reference/functions.md @@ -197,3 +197,14 @@ replaceAlias(/.*CPU (.*) time/, $1) -> system backend01: CPU system time replaceAlias(/(.*): CPU (.*) time/, $1 - $2) -> backend01 - system ``` + +## Special + +### consolidateBy +``` +consolidateBy(consolidationFunc) +``` + +When a graph is drawn where width of the graph size in pixels is smaller than the number of datapoints to be graphed, plugin consolidates the values to to prevent line overlap. The consolidateBy() function changes the consolidation function from the default of average to one of `sum`, `min`, `max` or `count`. + +Valid function names are `sum`, `avg`, `min`, `max` and `count`. diff --git a/src/datasource-zabbix/config.controller.js b/src/datasource-zabbix/config.controller.js new file mode 100644 index 0000000..226572c --- /dev/null +++ b/src/datasource-zabbix/config.controller.js @@ -0,0 +1,28 @@ +import _ from 'lodash'; + +const SUPPORTED_SQL_DS = ['mysql']; + +const defaultConfig = { + dbConnection: { + enable: false, + } +}; + +export class ZabbixDSConfigController { + /** @ngInject */ + constructor($scope, $injector, datasourceSrv) { + this.datasourceSrv = datasourceSrv; + + _.defaults(this.current.jsonData, defaultConfig); + this.sqlDataSources = this.getSupportedSQLDataSources(); + } + + getSupportedSQLDataSources() { + let datasources = this.datasourceSrv.getAll(); + return _.filter(datasources, ds => { + return _.includes(SUPPORTED_SQL_DS, ds.type); + }); + } +} + +ZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; diff --git a/src/datasource-zabbix/datasource.js b/src/datasource-zabbix/datasource.js index 99e1597..9f67f76 100644 --- a/src/datasource-zabbix/datasource.js +++ b/src/datasource-zabbix/datasource.js @@ -19,6 +19,9 @@ class ZabbixAPIDatasource { this.dashboardSrv = dashboardSrv; this.zabbixAlertingSrv = zabbixAlertingSrv; + // Use custom format for template variables + this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv); + // General data source settings this.name = instanceSettings.name; this.url = instanceSettings.url; @@ -43,10 +46,21 @@ class ZabbixAPIDatasource { this.addThresholds = instanceSettings.jsonData.addThresholds; this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING; - this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL); + // Direct DB Connection options + this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable; + this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId; - // Use custom format for template variables - this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv); + let zabbixOptions = { + username: this.username, + password: this.password, + basicAuth: this.basicAuth, + withCredentials: this.withCredentials, + cacheTTL: this.cacheTTL, + enableDirectDBConnection: this.enableDirectDBConnection, + sqlDatasourceId: this.sqlDatasourceId + }; + + this.zabbix = new Zabbix(this.url, zabbixOptions); } //////////////////////// @@ -140,27 +154,33 @@ class ZabbixAPIDatasource { return this.zabbix.getItemsFromTarget(target, getItemOptions) .then(items => { let getHistoryPromise; + options.consolidateBy = getConsolidateBy(target); if (useTrends) { - let valueType = this.getTrendValueType(target); - getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo) - .then(history => { - return responseHandler.handleTrends(history, items, valueType); - }) - .then(timeseries => { - // Sort trend data, issue #202 - _.forEach(timeseries, series => { - series.datapoints = _.sortBy(series.datapoints, point => point[c.DATAPOINT_TS]); + if (this.enableDirectDBConnection) { + getHistoryPromise = this.zabbix.getTrendsDB(items, timeFrom, timeTo, options) + .then(history => this.zabbix.dbConnector.handleGrafanaTSResponse(history, items)); + } else { + let valueType = this.getTrendValueType(target); + getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo) + .then(history => responseHandler.handleTrends(history, items, valueType)) + .then(timeseries => { + // Sort trend data, issue #202 + _.forEach(timeseries, series => { + series.datapoints = _.sortBy(series.datapoints, point => point[c.DATAPOINT_TS]); + }); + return timeseries; }); - - return timeseries; - }); + } } else { // Use history - getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo) - .then(history => { - return responseHandler.handleHistory(history, items); - }); + if (this.enableDirectDBConnection) { + getHistoryPromise = this.zabbix.getHistoryDB(items, timeFrom, timeTo, options) + .then(history => this.zabbix.dbConnector.handleGrafanaTSResponse(history, items)); + } else { + getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo) + .then(history => responseHandler.handleHistory(history, items)); + } } return getHistoryPromise; @@ -511,11 +531,24 @@ function bindFunctionDefs(functionDefs, category) { }); } +function getConsolidateBy(target) { + let consolidateBy = 'avg'; + let funcDef = _.find(target.functions, func => { + return func.def.name === 'consolidateBy'; + }); + if (funcDef && funcDef.params && funcDef.params.length) { + consolidateBy = funcDef.params[0]; + } + return consolidateBy; +} + function downsampleSeries(timeseries_data, options) { + let defaultAgg = dataProcessor.aggregationFunctions['avg']; + let consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg; return _.map(timeseries_data, timeseries => { if (timeseries.datapoints.length > options.maxDataPoints) { timeseries.datapoints = dataProcessor - .groupBy(options.interval, dataProcessor.AVERAGE, timeseries.datapoints); + .groupBy(options.interval, consolidateByFunc, timeseries.datapoints); } return timeseries; }); diff --git a/src/datasource-zabbix/metricFunctions.js b/src/datasource-zabbix/metricFunctions.js index 0f8d164..7089f75 100644 --- a/src/datasource-zabbix/metricFunctions.js +++ b/src/datasource-zabbix/metricFunctions.js @@ -8,7 +8,8 @@ var categories = { Filter: [], Trends: [], Time: [], - Alias: [] + Alias: [], + Special: [] }; function addFuncDef(funcDef) { @@ -204,6 +205,16 @@ addFuncDef({ defaultParams: ['/(.*)/', '$1'] }); +// Special +addFuncDef({ + name: 'consolidateBy', + category: 'Special', + params: [ + { name: 'type', type: 'string', options: ['avg', 'min', 'max', 'sum', 'count'] } + ], + defaultParams: ['avg'], +}); + _.each(categories, function(funcList, catName) { categories[catName] = _.sortBy(funcList, 'name'); }); diff --git a/src/datasource-zabbix/module.js b/src/datasource-zabbix/module.js index 35bb3af..2913139 100644 --- a/src/datasource-zabbix/module.js +++ b/src/datasource-zabbix/module.js @@ -1,8 +1,6 @@ import {ZabbixAPIDatasource} from './datasource'; import {ZabbixQueryController} from './query.controller'; - -class ZabbixConfigController {} -ZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html'; +import {ZabbixDSConfigController} from './config.controller'; class ZabbixQueryOptionsController {} ZabbixQueryOptionsController.templateUrl = 'datasource-zabbix/partials/query.options.html'; @@ -12,7 +10,7 @@ ZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annot export { ZabbixAPIDatasource as Datasource, - ZabbixConfigController as ConfigCtrl, + ZabbixDSConfigController as ConfigCtrl, ZabbixQueryController as QueryCtrl, ZabbixQueryOptionsController as QueryOptionsCtrl, ZabbixAnnotationsQueryController as AnnotationsQueryCtrl diff --git a/src/datasource-zabbix/partials/config.html b/src/datasource-zabbix/partials/config.html index 49e18b8..7f626c2 100644 --- a/src/datasource-zabbix/partials/config.html +++ b/src/datasource-zabbix/partials/config.html @@ -76,24 +76,53 @@
-

Alerting

- +

Direct DB Connection

+ - - -
- Min severity +
+
+ + SQL Data Source + + Select SQL Data Source for Zabbix database. + In order to use this feature you should create and + configure it first. Zabbix plugin uses this data source for querying history data directly from database. + This way usually faster than pulling data from Zabbix API, especially on the wide time ranges, and reduces + amount of data transfered. + +
-
+
+
+ +
+

Alerting

+ + +
+ + +
+ Min severity +
+ +
+
+
diff --git a/src/datasource-zabbix/specs/datasource_specs.js b/src/datasource-zabbix/specs/datasource_specs.js index 295f4fd..dec10a2 100644 --- a/src/datasource-zabbix/specs/datasource_specs.js +++ b/src/datasource-zabbix/specs/datasource_specs.js @@ -15,7 +15,10 @@ describe('ZabbixDatasource', () => { password: 'zabbix', trends: true, trendsFrom: '14d', - trendsRange: '7d' + trendsRange: '7d', + dbConnection: { + enabled: false + } } }; ctx.templateSrv = {}; diff --git a/src/datasource-zabbix/zabbix.js b/src/datasource-zabbix/zabbix.js index ea24873..61e378f 100644 --- a/src/datasource-zabbix/zabbix.js +++ b/src/datasource-zabbix/zabbix.js @@ -3,31 +3,45 @@ import _ from 'lodash'; import * as utils from './utils'; import './zabbixAPI.service.js'; import './zabbixCachingProxy.service.js'; +import './zabbixDBConnector'; // Use factory() instead service() for multiple data sources support. // Each Zabbix data source instance should initialize its own API instance. /** @ngInject */ -function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) { +function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) { class Zabbix { - constructor(url, username, password, basicAuth, withCredentials, cacheTTL) { + constructor(url, options) { + let { + username, password, basicAuth, withCredentials, cacheTTL, + enableDirectDBConnection, sqlDatasourceId + } = options; // Initialize Zabbix API var ZabbixAPI = zabbixAPIService; this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials); + if (enableDirectDBConnection) { + this.dbConnector = new ZabbixDBConnector(sqlDatasourceId); + } + // Initialize caching proxy for requests let cacheOptions = { enabled: true, ttl: cacheTTL }; - this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions); + this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions); // Proxy methods this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy); this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy); + if (enableDirectDBConnection) { + this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy); + this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy); + } + this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); diff --git a/src/datasource-zabbix/zabbixCachingProxy.service.js b/src/datasource-zabbix/zabbixCachingProxy.service.js index f450674..fa7a861 100644 --- a/src/datasource-zabbix/zabbixCachingProxy.service.js +++ b/src/datasource-zabbix/zabbixCachingProxy.service.js @@ -8,8 +8,9 @@ import _ from 'lodash'; function ZabbixCachingProxyFactory() { class ZabbixCachingProxy { - constructor(zabbixAPI, cacheOptions) { + constructor(zabbixAPI, zabbixDBConnector, cacheOptions) { this.zabbixAPI = zabbixAPI; + this.dbConnector = zabbixDBConnector; this.cacheEnabled = cacheOptions.enabled; this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default @@ -31,6 +32,13 @@ function ZabbixCachingProxyFactory() { this.getHistory = callAPIRequestOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI), this.historyPromises, getHistoryRequestHash); + if (this.dbConnector) { + this.getHistoryDB = callAPIRequestOnce(_.bind(this.dbConnector.getHistory, this.dbConnector), + this.historyPromises, getDBQueryHash); + this.getTrendsDB = callAPIRequestOnce(_.bind(this.dbConnector.getTrends, this.dbConnector), + this.historyPromises, getDBQueryHash); + } + // Don't run duplicated requests this.groupPromises = {}; this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI), @@ -195,6 +203,14 @@ function getHistoryRequestHash(args) { return stamp.getHash(); } +function getDBQueryHash(args) { + let itemids = _.map(args[0], 'itemid'); + let consolidateBy = args[3].consolidateBy; + let intervalMs = args[3].intervalMs; + let stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs; + return stamp.getHash(); +} + String.prototype.getHash = function() { var hash = 0, i, chr, len; if (this.length !== 0) { diff --git a/src/datasource-zabbix/zabbixDBConnector.js b/src/datasource-zabbix/zabbixDBConnector.js new file mode 100644 index 0000000..d1ee166 --- /dev/null +++ b/src/datasource-zabbix/zabbixDBConnector.js @@ -0,0 +1,183 @@ +import angular from 'angular'; +import _ from 'lodash'; + +const DEFAULT_QUERY_LIMIT = 10000; +const HISTORY_TO_TABLE_MAP = { + '0': 'history', + '1': 'history_str', + '2': 'history_log', + '3': 'history_uint', + '4': 'history_text' +}; + +const TREND_TO_TABLE_MAP = { + '0': 'trends', + '3': 'trends_uint' +}; + +const consolidateByFunc = { + 'avg': 'AVG', + 'min': 'MIN', + 'max': 'MAX', + 'sum': 'SUM', + 'count': 'COUNT' +}; + +const consolidateByTrendColumns = { + 'avg': 'value_avg', + 'min': 'value_min', + 'max': 'value_max' +}; + +/** @ngInject */ +function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) { + + class ZabbixDBConnector { + + constructor(sqlDataSourceId, options = {}) { + let {limit} = options; + + this.sqlDataSourceId = sqlDataSourceId; + this.limit = limit || DEFAULT_QUERY_LIMIT; + + // Try to load DS with given id to check it's exist + this.loadSQLDataSource(sqlDataSourceId); + } + + loadSQLDataSource(datasourceId) { + let ds = _.find(datasourceSrv.getAll(), {'id': datasourceId}); + if (ds) { + return datasourceSrv.loadDatasource(ds.name) + .then(ds => { + console.log('SQL data source loaded', ds); + }); + } else { + return Promise.reject(`SQL Data Source with ID ${datasourceId} not found`); + } + } + + getHistory(items, timeFrom, timeTill, options) { + let {intervalMs, consolidateBy} = options; + let intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + let aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + let grouped_items = _.groupBy(items, 'value_type'); + let promises = _.map(grouped_items, (items, value_type) => { + let itemids = _.map(items, 'itemid').join(', '); + let table = HISTORY_TO_TABLE_MAP[value_type]; + + let query = ` + SELECT itemid AS metric, clock AS time_sec, ${aggFunction}(value) as value + FROM ${table} + WHERE itemid IN (${itemids}) + AND clock > ${timeFrom} AND clock < ${timeTill} + GROUP BY time_sec DIV ${intervalSec}, metric + `; + + query = compactSQLQuery(query); + return this.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(results => { + return _.flatten(results); + }); + } + + getTrends(items, timeFrom, timeTill, options) { + let {intervalMs, consolidateBy} = options; + let intervalSec = Math.ceil(intervalMs / 1000); + + consolidateBy = consolidateBy || 'avg'; + let aggFunction = consolidateByFunc[consolidateBy]; + + // Group items by value type and perform request for each value type + let grouped_items = _.groupBy(items, 'value_type'); + let promises = _.map(grouped_items, (items, value_type) => { + let itemids = _.map(items, 'itemid').join(', '); + let table = TREND_TO_TABLE_MAP[value_type]; + let valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg'; + valueColumn = consolidateByTrendColumns[valueColumn]; + + let query = ` + SELECT itemid AS metric, clock AS time_sec, ${aggFunction}(${valueColumn}) as value + FROM ${table} + WHERE itemid IN (${itemids}) + AND clock > ${timeFrom} AND clock < ${timeTill} + GROUP BY time_sec DIV ${intervalSec}, metric + `; + + query = compactSQLQuery(query); + return this.invokeSQLQuery(query); + }); + + return Promise.all(promises).then(results => { + return _.flatten(results); + }); + } + + handleGrafanaTSResponse(history, items, addHostName = true) { + return convertGrafanaTSResponse(history, items, addHostName); + } + + invokeSQLQuery(query) { + let queryDef = { + refId: 'A', + format: 'time_series', + datasourceId: this.sqlDataSourceId, + rawSql: query, + maxDataPoints: this.limit + }; + + return backendSrv.datasourceRequest({ + url: '/api/tsdb/query', + method: 'POST', + data: { + queries: [queryDef], + } + }) + .then(response => { + let results = response.data.results; + if (results['A']) { + return results['A'].series; + } else { + return null; + } + }); + } + } + + return ZabbixDBConnector; +} + +angular + .module('grafana.services') + .factory('ZabbixDBConnector', ZabbixDBConnectorFactory); + +/////////////////////////////////////////////////////////////////////////////// + +function convertGrafanaTSResponse(time_series, items, addHostName) { + var hosts = _.uniqBy(_.flatten(_.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate + let grafanaSeries = _.map(time_series, series => { + let itemid = series.name; + let datapoints = series.points; + var item = _.find(items, {'itemid': itemid}); + var alias = item.name; + if (_.keys(hosts).length > 1 && addHostName) { //only when actual multi hosts selected + var host = _.find(hosts, {'hostid': item.hostid}); + alias = host.name + ": " + alias; + } + return { + target: alias, + datapoints: datapoints + }; + }); + + return _.sortBy(grafanaSeries, 'target'); +} + +function compactSQLQuery(query) { + return query.replace(/\s+/g, ' '); +}