You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10 KiB

Splunk Dashboard JavaScript MVC Guide

Overview

This guide explains how to properly implement JavaScript in Splunk dashboards to trigger searches and handle token values.

1. Basic Structure for Dashboard JavaScript

Required Libraries

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(
    _,
    $,
    mvc,
    SearchManager
) {
    // Your code here
});

Important: Wait for Dashboard Ready

The splunkjs/mvc/simplexml/ready! module ensures the dashboard is fully loaded before your code runs.

2. Accessing MVC Components

Get Dashboard Tokens

// Get default token model
var tokens = mvc.Components.get("default");

// Get submitted token model
var submittedTokens = mvc.Components.get("submitted");

// Get a specific token value
var tokenValue = tokens.get("mytoken");

// Set a token value
tokens.set("mytoken", "new_value");

Get Dashboard Elements

// Get a search manager by ID
var searchManager = mvc.Components.get("my_search");

// Get a visualization by ID
var chart = mvc.Components.get("my_chart");

// Get an input by ID
var dropdown = mvc.Components.get("my_dropdown");

3. Creating and Executing Searches Programmatically

var mySearch = new SearchManager({
    id: "my_programmatic_search",
    search: "index=socradar_incidents | stats count",
    earliest_time: "-24h@h",
    latest_time: "now",
    preview: true,
    cache: false,
    autostart: false  // Don't start automatically
});

// Start the search
mySearch.startSearch();

Create a Search with Token Values

// Using mvc.tokenSafe for token-aware searches
var mySearch = new SearchManager({
    id: "update_status_search",
    search: mvc.tokenSafe("| sendalert update_socradar_incident_status param.incident_id=$incident_id$ param.new_status=$new_status$"),
    earliest_time: "-1m",
    latest_time: "now",
    autostart: false
});

// Token values will be automatically resolved when the search runs

4. Handling Search Results

Listen for Search Events

mySearch.on('search:done', function(properties) {
    console.log("Search completed!");
    
    // Get the results
    var results = mySearch.data("results");
    
    results.on("data", function() {
        var data = results.data();
        console.log("Results:", data);
        
        // Process results
        if (data && data.rows && data.rows.length > 0) {
            // Handle successful results
            alert("Status updated successfully!");
        }
    });
});

mySearch.on('search:error', function(properties) {
    console.error("Search error:", properties.content.messages);
});

mySearch.on('search:fail', function(properties) {
    console.error("Search failed:", properties.content.messages);
});

5. Complete Example: Button Click Handler

HTML Button (in dashboard XML)

<html>
    <button id="update_status_btn" class="btn btn-primary">Update Status</button>
</html>

JavaScript Implementation

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(
    _,
    $,
    mvc,
    SearchManager
) {
    
    // Get token models
    var tokens = mvc.Components.get("default");
    var submittedTokens = mvc.Components.get("submitted");
    
    // Button click handler
    $("#update_status_btn").on("click", function() {
        
        // Get token values
        var incidentId = tokens.get("incident_id");
        var newStatus = tokens.get("new_status");
        
        // Validate inputs
        if (!incidentId || !newStatus) {
            alert("Please select an incident and status");
            return;
        }
        
        // Create search to update status
        var updateSearch = new SearchManager({
            id: "update_status_search_" + Date.now(),  // Unique ID
            search: "| sendalert update_socradar_incident_status param.incident_id=\"" + incidentId + "\" param.new_status=\"" + newStatus + "\"",
            earliest_time: "-1m",
            latest_time: "now",
            autostart: false
        });
        
        // Handle search completion
        updateSearch.on('search:done', function(properties) {
            console.log("Status update completed");
            
            // Refresh the main search to show updated data
            var mainSearch = mvc.Components.get("incident_details_search");
            if (mainSearch) {
                mainSearch.startSearch();
            }
            
            alert("Status updated successfully!");
        });
        
        // Handle search errors
        updateSearch.on('search:error search:fail', function(properties) {
            console.error("Status update failed:", properties);
            alert("Failed to update status. Please try again.");
        });
        
        // Start the search
        updateSearch.startSearch();
    });
});

6. Best Practices

1. Always Wait for Dashboard Ready

require(['splunkjs/mvc/simplexml/ready!'], function() {
    // Dashboard is ready
});

2. Use Token-Safe Strings

// Good - tokens will be resolved
search: mvc.tokenSafe("index=main sourcetype=$sourcetype$")

// Bad - tokens won't be resolved
search: "index=main sourcetype=$sourcetype$"

3. Unique Search Manager IDs

// Add timestamp to ensure uniqueness
id: "my_search_" + Date.now()

4. Clean Up Search Managers

// Dispose of search when done
updateSearch.on('search:done', function() {
    updateSearch.finalize();
});

5. Handle Token Changes

// Listen for token changes
tokens.on("change:mytoken", function(model, value) {
    console.log("Token changed:", value);
    // React to token change
});

7. Common Patterns

Execute Search on Token Change

tokens.on("change:incident_id", function(model, value) {
    if (value) {
        var detailSearch = new SearchManager({
            id: "incident_detail_" + Date.now(),
            search: "index=socradar_incidents alarm_id=\"" + value + "\" | head 1",
            autostart: true
        });
    }
});

Conditional Search Execution

$("#run_search_btn").click(function() {
    var searchType = tokens.get("search_type");
    
    var searchQuery;
    switch(searchType) {
        case "high_risk":
            searchQuery = "index=socradar_incidents alarm_risk_level=HIGH";
            break;
        case "recent":
            searchQuery = "index=socradar_incidents | head 100";
            break;
        default:
            searchQuery = "index=socradar_incidents";
    }
    
    var search = new SearchManager({
        id: "conditional_search_" + Date.now(),
        search: searchQuery,
        autostart: true
    });
});

8. Debugging Tips

1. Check if Components Exist

var component = mvc.Components.get("my_component");
if (component) {
    console.log("Component found:", component);
} else {
    console.error("Component not found!");
}

2. List All Components

console.log("All components:", mvc.Components.toJSON());

3. Debug Token Values

console.log("All tokens:", tokens.toJSON());
console.log("Submitted tokens:", submittedTokens.toJSON());

4. Monitor Search Progress

mySearch.on('all', function(eventName) {
    console.log("Search event:", eventName);
});

Example: Complete Status Update Implementation

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, SearchManager) {
    
    console.log("Dashboard JavaScript loaded");
    
    // Get token models
    var tokens = mvc.Components.get("default");
    var submittedTokens = mvc.Components.get("submitted");
    
    // Debug: List all components
    console.log("Available components:", Object.keys(mvc.Components.toJSON()));
    
    // Set up button click handler
    $(document).on("click", "#update_status_btn", function(e) {
        e.preventDefault();
        
        // Get current token values
        var incidentId = tokens.get("incident_id");
        var newStatus = tokens.get("new_status");
        
        console.log("Updating incident:", incidentId, "to status:", newStatus);
        
        if (!incidentId || !newStatus) {
            alert("Please select an incident and a new status");
            return;
        }
        
        // Disable button during update
        var $btn = $(this);
        $btn.prop('disabled', true).text('Updating...');
        
        // Create the update search
        var updateSearch = new SearchManager({
            id: "status_update_" + Date.now(),
            search: '| sendalert update_socradar_incident_status param.incident_id="' + incidentId + '" param.new_status="' + newStatus + '"',
            earliest_time: "-1m",
            latest_time: "now",
            cache: false,
            autostart: true
        });
        
        // Handle completion
        updateSearch.on('search:done', function() {
            console.log("Status update successful");
            
            // Re-enable button
            $btn.prop('disabled', false).text('Update Status');
            
            // Show success message
            alert("Status updated successfully!");
            
            // Refresh the incidents table
            var tableSearch = mvc.Components.get("incident_details_table_search");
            if (tableSearch) {
                tableSearch.startSearch();
            }
            
            // Clean up
            updateSearch.finalize();
        });
        
        // Handle errors
        updateSearch.on('search:error search:fail', function(state, job) {
            console.error("Status update failed:", state);
            
            // Re-enable button
            $btn.prop('disabled', false).text('Update Status');
            
            // Show error message
            alert("Failed to update status. Please check the logs.");
            
            // Clean up
            updateSearch.finalize();
        });
    });
    
    // Monitor token changes for debugging
    tokens.on("change", function() {
        console.log("Token changed:", tokens.toJSON());
    });
});

This guide provides the foundation for implementing JavaScript in Splunk dashboards with proper MVC integration, token handling, and search execution.