Last active
August 29, 2015 14:21
-
-
Save tozevv/6e7fc1e43fa8b4ba55d9 to your computer and use it in GitHub Desktop.
Splunk MergeSearchManager
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
/** | |
* Merge Search Manager | |
* | |
* Merge results from 2 SearchManagers. Enables the combination of two 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 merged 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 required. | |
* 4. Change the require.config to: | |
* | |
* require.config({ | |
* baseUrl: "{{SPLUNKWEB_URL_PREFIX}}/static/js", | |
* // add require for merge search manager locally. | |
* 'mergesearchmanager': 'empty:', | |
* waitSeconds: 0 // Disable require.js load timeout | |
* }); | |
* | |
* 5. Create the MergeSearchManager after the other search managers: | |
* | |
* var mergedSearch = new MergeSearchManager({ | |
* "id": "mergedSearch", | |
* "merge": { | |
* // reference to the existing search managers | |
* "left": search1, | |
* "right": search2, | |
* | |
* // join predicate function | |
* "on": function(current, baseline) | |
* { | |
* return baseline.api_route == current.api_route; | |
* }, | |
* | |
* // output fields with names and calculation formula | |
* "fields": { | |
* "api_route": function(current, baseline) { return baseline.api_route; }, | |
* "total_api_count": function(current, baseline) { return parseInt(current.api_count) + parseInt(baseline.api_count); } | |
* } | |
* } | |
* }); | |
* | |
*/ | |
define('mergesearchmanager',['require','exports','module','underscore', | |
'splunkjs/mvc/postprocessmanager','splunkjs/mvc/searchmodel','splunkjs/mvc/splunkresultsmodel'], function(require, exports, module) { | |
// Extend array prototype with innerJoin method | |
Array.prototype.innerJoin = function(other, predicate) | |
{ | |
var result = []; | |
this.forEach(function (thisRow) { | |
other.forEach(function (otherRow) { | |
if (predicate(thisRow, otherRow)) | |
{ | |
result.push([ | |
thisRow, | |
otherRow | |
]); | |
} | |
}); | |
}); | |
return result; | |
} | |
var _ = require("underscore"); | |
var PostProcessManager = require('splunkjs/mvc/postprocessmanager'); | |
var SplunkResultsModel = require('splunkjs/mvc/splunkresultsmodel'); | |
var merge = {} | |
var manager = PostProcessManager.extend({ | |
defaults: { | |
managerid: null, | |
search: '' | |
}, | |
constructor: function(attributes, options) { | |
attributes = attributes || {}; | |
options = options || {}; | |
merge = attributes.merge || merge; | |
return PostProcessManager.prototype.constructor.apply(this, arguments); | |
}, | |
data: function(source, args) { | |
var MergeSearchResultsModel = SplunkResultsModel.extend({ | |
fetch: function(options) | |
{ | |
var that = this; | |
hookEvents(merge.left); | |
hookEvents(merge.right); | |
return; | |
function hookEvents(search) | |
{ | |
var searchResults = search.data("results"); | |
search.on("search:done", function() { | |
var data = searchResults.data(); | |
search._searchData = data; | |
mergeSearches(); | |
}); | |
} | |
function mergeSearches() | |
{ | |
var leftResults = merge.left._searchData; | |
var rightResults = merge.right._searchData; | |
// don't merge partial results... | |
if (!leftResults || !rightResults) | |
{ | |
return; | |
} | |
console.log("Merging:", merge.left._searchData, merge.right._searchData); | |
leftObjects = leftResults.rows.map(function(row) { return arrayToObject(leftResults.fields, row); }); | |
rightObjects = rightResults.rows.map(function(row) { return arrayToObject(rightResults.fields, row); }); | |
var mergedResults = {}; | |
mergedResults.rows = leftObjects | |
.innerJoin(rightObjects, function(leftRow,rightRow) { | |
return merge.on(leftRow, rightRow); | |
}) | |
.map(function(mergedRow) { | |
var leftRow = mergedRow[0]; | |
var rightRow = mergedRow[1]; | |
return Object.keys(merge.fields).map(function(key, i) | |
{ | |
return merge.fields[key].call(this, leftRow, rightRow); | |
}); | |
}) | |
mergedResults.fields = Object.keys(merge.fields); | |
mergedResults.preview = false; | |
mergedResults.messages = []; | |
mergedResults.init_offset = 0; | |
mergedResults.post_process_count = mergedResults.rows.length; | |
that._data = mergedResults; | |
that.trigger("data", that, mergedResults); | |
} | |
function arrayToObject(names, values) | |
{ | |
var r = {}; | |
for (var i=0;i<names.length;i++) | |
{ | |
r[names[i]] = values[i]; | |
} | |
return r; | |
} | |
} | |
}); | |
args = _.defaults({ manager: this, source: source }, args); | |
return new MergeSearchResultsModel(args); | |
} | |
}); | |
return manager; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment