Skip to content

Instantly share code, notes, and snippets.

@tozevv
Last active August 29, 2015 14:21
Show Gist options
  • Save tozevv/6e7fc1e43fa8b4ba55d9 to your computer and use it in GitHub Desktop.
Save tozevv/6e7fc1e43fa8b4ba55d9 to your computer and use it in GitHub Desktop.
Splunk MergeSearchManager
/**
* 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