Hi everyone,
I’ve been receiving a lot of helpful responses regarding this topic, and I truly appreciate the support. However, I’m currently stuck on how to execute a Python script via a button in Splunk and display the results on a dashboard.
Here’s the Python script I’m using:
import json
import requests
import logging
class ZabbixHandler:
def __init__(self):
self.logger = logging.getLogger('zabbix_handler')
self.ZABBIX_API_URL = "http://localhost/zabbix/api_jsonrpc.php" # Replace with your Zabbix API URL
self.ZABBIX_USERNAME = "user" # Replace with your Zabbix username
self.ZABBIX_PASSWORD = "password" # Replace with your Zabbix password
self.SPLUNK_HEC_URL = "http://localhost:8088/services/collector" # Replace with your Splunk HEC URL
self.SPLUNK_HEC_TOKEN = "myhectoken" # Replace with your Splunk HEC token
self.HEC_INDEX = "summary" # Splunk index for the logs
self.HEC_SOURCETYPE = "zabbix:audit:logs" # Splunk sourcetype
def authenticate_with_zabbix(self):
payload = {
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"username": self.ZABBIX_USERNAME,
"password": self.ZABBIX_PASSWORD,
},
"id": 1,
}
response = requests.post(self.ZABBIX_API_URL, json=payload, verify=False)
response_data = response.json()
if "result" in response_data:
return response_data["result"]
else:
raise Exception(f"Zabbix authentication failed: {response_data}")
def fetch_audit_logs(self, auth_token):
payload = {
"jsonrpc": "2.0",
"method": "auditlog.get",
"params": {
"output": "extend",
"filter": {
"action": 0 # Fetch specific actions if needed
}
},
"auth": auth_token,
"id": 2,
}
response = requests.post(self.ZABBIX_API_URL, json=payload, verify=False)
response_data = response.json()
if "result" in response_data:
return response_data["result"]
else:
raise Exception(f"Failed to fetch audit logs: {response_data}")
def send_logs_to_splunk(self, logs):
headers = {
"Authorization": f"Splunk {self.SPLUNK_HEC_TOKEN}",
"Content-Type": "application/json",
}
for log in logs:
payload = {
"index": self.HEC_INDEX,
"sourcetype": self.HEC_SOURCETYPE,
"event": log,
}
response = requests.post(self.SPLUNK_HEC_URL, headers=headers, json=payload, verify=False)
if response.status_code != 200:
self.logger.error(f"Failed to send log to Splunk: {response.status_code} - {response.text}")
def handle_request(self):
try:
auth_token = self.authenticate_with_zabbix()
logs = self.fetch_audit_logs(auth_token)
self.send_logs_to_splunk(logs)
return {"status": "success", "message": "Logs fetched and sent to Splunk successfully."}
except Exception as e:
self.logger.error(f"Error during operation: {str(e)}")
return {"status": "error", "message": str(e)}
if __name__ == "__main__":
handler = ZabbixHandler()
response = handler.handle_request()
print(json.dumps(response))
My restmap.conf
[script:zabbix_handler]
match = /zabbix_handler
script = zabbix_handler.py
handler = python
output_modes = json
The script is working correctly, and I am successfully retrieving data from Zabbix and sending it to Splunk. The logs are being indexed in Splunk’s summary index, and I can verify this via manual execution of the script.
After the button is clicked and the script is executed, I would like to display the query results from index="summary" on the same dashboard.
@kamlesh_vaghela can u help me on this task.?im kind of stuck on this and ur videos helped me a lot ..!
Your script won't work on my machine so I have created a sample script which returns simple "Hello world" text on click of dashboard button. You just create a similar configuration and Python file as per your requirement. Below is the code and file/folder structure.
hello_world.py
import splunk, sys
from json import dumps
class HelloWorld(splunk.rest.BaseRestHandler):
'''
Class for service custom endpoint.
'''
def handle_POST(self):
'''
This endpoint handler
:return: None
'''
payload = {
"text": "Hello world!"
}
response = dumps({"data": payload, "status": "OK", "error": "None"})
self.response.setHeader('content-type', 'application/json')
self.response.write(response)
#handle verbs, otherwise Splunk will throw an error
handle_GET = handle_POST
restmap.conf
[script:my_custom_endpoint]
match = /my_custom_endpoint
handler = hello_world.HelloWorld
web.conf
[expose:my_custom_endpoint]
pattern = my_custom_endpoint
methods = GET, POST
XML
<dashboard script="fetch_data.js" version="1.1">
<label>My Dashboard</label>
<description>Dynamic Result Example</description>
<row>
<panel>
<html>
<div>
<button id="fetch-data-button">Fetch Data</button>
<div id="div_result" style="margin-top: 10px; border: 1px solid #ccc; padding: 10px;">Result will be displayed here.</div>
</div>
</html>
</panel>
</row>
</dashboard>
fetch_data.js
require([
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/simplexml/ready!'
], function($, mvc) {
$('#fetch-data-button').on('click', function() {
var service = mvc.createService();
service.post('/services/my_custom_endpoint', {}, function (err, response) {
console.log(response);
console.log(response.data);
console.log(response.data.data);
console.log(response.data.data.text);
$('#div_result').html(response.data.data.text);
});
return false;
});
});
Screenshot
Try this code to learn and understand the custom endpoint and develop a new endpoint as per your needs.
I hope this will help you.
Thanks
KV
An upvote would be appreciated if any of my replies help you solve the problem or gain knowledge.
"I followed your previous instructions but encountered an error in my console, which is consistent with the issue in my primary use case. I suspect the problem lies in the placement of my JavaScript file.
Currently, the directory structure is as follows:
Could you please help me identify if this directory setup might be causing the issue?"
It looks like there is some error in the endpoint.
Can you please check logs in "splunk/var/log/splunk/python.log"?
Sharing my sample code.
KV
I did not observe any errors in the python.log file, but I noticed errors in the splunkd.log file.
Here is the relevant log entry:
01-16-2025 12:01:24.958 +0530 ERROR ScriptRunner [40857 TcpChannelThread] - stderr from '/opt/splunk/bin/python3.9 /opt/splunk/bin/runScript.py zabbix_handler.Zabbix_handler': Traceback (most recent call last):
01-16-2025 12:01:24.958 +0530 ERROR ScriptRunner [40857 TcpChannelThread] - stderr from '/opt/splunk/bin/python3.9 /opt/splunk/bin/runScript.py zabbix_handler.Zabbix_handler': File "/opt/splunk/bin/runScript.py", line 72, in <module>
01-16-2025 12:01:24.958 +0530 ERROR ScriptRunner [40857 TcpChannelThread] - stderr from '/opt/splunk/bin/python3.9 /opt/splunk/bin/runScript.py zabbix_handler.Zabbix_handler': os.chdir(scriptDir)
01-16-2025 12:01:24.958 +0530 ERROR ScriptRunner [40857 TcpChannelThread] - stderr from '/opt/splunk/bin/python3.9 /opt/splunk/bin/runScript.py zabbix_handler.Zabbix_handler': FileNotFoundError: [Errno 2] No such file or directory: ''
This error occurs because the scriptDir variable is empty or invalid, which leads to the os.chdir(scriptDir) function attempting to change to a directory that does not exist.
Could you assist in identifying why the scriptDir value might be undefined or improperly set in this context?
The python file should be in bin folder of your app.
Can you please confirm whether the individual script is working fine?
Have you tried my shared app on your local machine? If my app is working fine then try to add your Python code to this app.
Thanks
KV