Created
May 28, 2015 10:42
-
-
Save tozevv/fcae39f5a5867c296246 to your computer and use it in GitHub Desktop.
Splunk Javascript Search Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Javascript Search Manager | |
* | |
* Search Managers with javascript queries. Enables the combination of two or more Splunk results into a single result. | |
* Useful for implementing joins of precalculated {@link http://docs.splunk.com/Documentation/Splunk/6.2.3/Report/Acceleratereports|accelerate reports}. | |
* | |
* To use, follow the following steps: | |
* | |
* 1. Create your dashboard. Create a placeholder for the javascript search / panel. | |
* 2. Convert your splunk dashboard to an {@link http://dev.splunk.com/view/webframework-htmldashboards/SP-CAAAEM2|HTML dashboard} | |
* 3. Copy this code and paste it between the require.config declaration and the requires section. | |
* 4. Change the require.config to: | |
* | |
* require.config({ | |
* baseUrl: "{{SPLUNKWEB_URL_PREFIX}}/static/js", | |
* // add require for merge search manager locally. | |
* 'javascriptsearchmanager': 'empty:', | |
* waitSeconds: 0 // Disable require.js load timeout | |
* }); | |
* | |
* 5. Create the JavacriptSearchManager after the other search managers: | |
* | |
* var jsmanager = new JavascriptSearchManager({ | |
* "id": "jsmanager", | |
* "search": { | |
* "from": [search1, search2], | |
* "query": function(search1, search2) | |
* { | |
* // filter, sort and project the 2 results into a single one. | |
* return search1 | |
* .join(search2, function(c, b) { | |
* if (c.key === b.key) | |
* { | |
* return { | |
* key: c.key | |
* value: a.value + b.value | |
* } | |
* } | |
* }) | |
* .sort(function(a,b) { | |
* return b.value - a.value; | |
* }) | |
* .map(function(row) { | |
* return { | |
* "key_field": row.key, | |
* "value_field": row.value | |
* } | |
* }); | |
* | |
* return sorted; | |
* } | |
* } | |
* }, {tokens: true, tokenNamespace: "submitted"}); | |
* | |
* | |
*/ | |
define('javascriptsearchmanager',['require','exports','module','underscore', | |
'splunkjs/mvc/postprocessmanager','splunkjs/mvc/searchmodel','splunkjs/mvc/splunkresultsmodel'], function(require, exports, module) { | |
var _ = require("underscore"); | |
var PostProcessManager = require('splunkjs/mvc/postprocessmanager'); | |
var SplunkResultsModel = require('splunkjs/mvc/splunkresultsmodel'); | |
var manager = PostProcessManager.extend({ | |
defaults: { | |
managerid: null, | |
search: {} | |
}, | |
constructor: function(attributes, options) { | |
attributes = attributes || {}; | |
options = options || {}; | |
this.search = attributes.search || search; | |
return PostProcessManager.prototype.constructor.apply(this, arguments); | |
}, | |
data: function(source, args) { | |
var search = this.search; | |
var JavascriptSearchResultsModel = SplunkResultsModel.extend({ | |
fetch: function(options) | |
{ | |
var that = this; | |
var fromData = []; | |
// hookevents | |
search.from.forEach(function(fromSearchManager, i) { | |
var searchResults = fromSearchManager.data("results"); | |
searchResults.on("data", function(obj, data) { | |
fromData[i] = data; | |
var completeSearchCount = fromData.filter(function(value) { return value !== undefined }).length; | |
if (completeSearchCount == search.from.length) | |
{ | |
that.query(fromData); | |
} | |
}); | |
}); | |
this._fetched = true; | |
}, | |
query: function(fromData) | |
{ | |
// convert the Splunk result data to a nicer row object representation | |
var from = fromData.map(function(splunkResult) | |
{ | |
var rows = splunkModelToObjectRows(splunkResult); | |
// add join method to the rows list | |
rows.join = function(other, on) { | |
var result = []; | |
this.forEach(function (thisRow) { | |
other.forEach(function (otherRow) { | |
var joined = on(thisRow, otherRow); | |
if (joined !== undefined) { | |
result.push(joined); | |
} | |
}); | |
}); | |
return result; | |
} | |
return rows; | |
}); | |
// execute the query | |
var rows = search.query.apply(null, from); | |
// convert rows to splin | |
var splunkData = objectRowsToSplunkModel(rows); | |
this._data = splunkData; | |
this.trigger("data", this, splunkData); | |
return; | |
function splunkModelToObjectRows(result) | |
{ | |
return result.rows.map(function(row) { | |
return arrayToObject(result.fields, row); | |
}); | |
function arrayToObject(names, values) | |
{ | |
var r = {}; | |
for (var i=0;i<names.length;i++) | |
{ | |
r[names[i]] = values[i]; | |
} | |
return r; | |
} | |
} | |
function objectRowsToSplunkModel(rows) | |
{ | |
// convert back to the Splunk result data representation | |
var fields = rows.length > 0 ? Object.keys(rows[0]): []; | |
var splunkRows = rows.map(function(row) { | |
return fields.map(function(key, i) | |
{ | |
return row[key]; | |
}); | |
}); | |
// project as columns as necessary for some charts... | |
var splunkColumns = fields.map(function (key, i) { | |
return rows.map(function(row) | |
{ | |
return row[key]; | |
}); | |
}); | |
var data = { | |
preview: false, | |
messages: [], | |
init_offset: 0, | |
fields: fields, | |
rows: splunkRows, | |
columns: splunkColumns | |
}; | |
return data; | |
} | |
} | |
}); | |
args = _.defaults({ manager: this, source: source }, args); | |
return new JavascriptSearchResultsModel(args); | |
} | |
}); | |
return manager; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment