i try to run an script to monitor elastic but when i add sensor i get the error :

XML: Structural error in xml file, 1 open items. -- JSON: The returned JSON does not match the expected structure (Invalid JSON.). (code: PE231)

my script is :

import requests
import json
import sys
from paepy.ChannelDefinition import CustomSensorResult


if __name__ == '__main__':
	#load the prtg parameters into a dictionary and make call to ES host
	data = json.loads(sys.argv[1])
	url = 'http://{elastic server IP}:9200/_cluster/health'.format(data['host'])
	req = requests.get(url)
	
	#load the json response into a dictionary
	output = json.loads(req.text)
	
	#Turn status color into a number so that it can be viewed in prtg
	if output['status'] == 'green':
		status = 0
	elif output['status'] == 'yellow':
		status = 1
	elif output['status'] == 'red':
		status = 2
	
	#turn timed out into a number so that it can be viewed in prtg
	if output['timed_out'] == False:
		timedOut = 0
	else:
		timedOut = 1
		
	#create a prtg sensor and add the channel data. Each key/value in the json response from ES gets channelized
	sensor = CustomSensorResult(output['status'])
	sensor.add_channel(channel_name='Status',unit='Count',value=status,is_limit_mode=True,limit_max_error=1.5,limit_max_warning=0.5)
	sensor.add_channel(channel_name='Number Of Data Nodes',unit='Count',value=output['number_of_data_nodes'])
	sensor.add_channel(channel_name='Number of Nodes',unit='Count',value=output['number_of_nodes'])
	sensor.add_channel(channel_name='Percent of Shards Active',unit='Percent',value=output['active_shards_percent_as_number'])
	sensor.add_channel(channel_name='Delayed Unassigned Shards',unit='Count',value=output['delayed_unassigned_shards'])
	sensor.add_channel(channel_name='In Flight Fetches',unit='Count',value=output['number_of_in_flight_fetch'])
	sensor.add_channel(channel_name='Relocating Shards',unit='Count',value=output['relocating_shards'])
	sensor.add_channel(channel_name='Pending Tasks',unit='Count',value=output['number_of_pending_tasks'])
	sensor.add_channel(channel_name='Initializing Shards',unit='Count',value=output['initializing_shards'])
	sensor.add_channel(channel_name='Unassigned Shards',unit='Count',value=output['unassigned_shards'])
	sensor.add_channel(channel_name='Task Queue Time (max)',unit='Milliseconds',value=output['task_max_waiting_in_queue_millis'])
	sensor.add_channel(channel_name='Timed Out',unit='Count',value=timedOut,is_limit_mode=True,limit_max_error=0.5,limit_error_msg='Timed Out = True')
	
	#send the sensor data back to the prtg process in json format
	print(sensor.get_json_result())

Please Help...


Article Comments

What does the actual output look like?


Kind regards,
Stephan Linke, Tech Support Team


Jul, 2018 - Permalink

XML: Structural error in xml file, 1 open items. -- JSON: The returned JSON does not match the expected structure (Invalid JSON.). (code: PE231)


Jul, 2018 - Permalink

When you execute the script using python, what's that output saying? Something like this: C:\Program Files (x86)\PRTG Network Monitor\Python34\python.exe <path-to-python-script>


Jul, 2018 - Permalink

Traceback (most recent call last): File "c:\elasticprtg.py", line 10, in <module> data = json.loads(sys.argv[1]) IndexError: list index out of range


Jul, 2018 - Permalink

Hold on, is the script really saying {elastic server IP} in the URL? You probably want to modify that. Additionally, you might need to pass the host to the script:

C:\Program Files (x86)\PRTG Network Monitor\Python34\python.exe <path-to-python-script> <host>

edit sorry for the late reply, this somehow got posted into another thread instead of this one.


Kind regards,
Stephan Linke, Tech Support Team


Jul, 2018 - Permalink

From the PRTG version 20.3.61.1649 and above, PRTG use the new Python 3.7 distribution because the end-of-life Python 3.4. For more information please read this page: https://helpdesk.paessler.com/en/support/solutions/articles/76000063532-after-updating-to-prtg-20-1-55-my-python-script-advanced-sensors-are-down You need to update the script with new library

import requests
import json
import sys

from prtg.sensor.result import CustomSensorResult
from prtg.sensor.units import ValueUnit


if __name__ == '__main__':
	#load the prtg parameters into a dictionary and make call to ES host
	data = json.loads(sys.argv[1])
	url = 'http://{elastic server IP}:9200/_cluster/health'
	req = requests.get(url)
	
	#load the json response into a dictionary
	output = json.loads(req.text)
	
	#Turn status color into a number so that it can be viewed in prtg
	if output['status'] == 'green':
		status = 0
	elif output['status'] == 'yellow':
		status = 1
	elif output['status'] == 'red':
		status = 2
	
	#turn timed out into a number so that it can be viewed in prtg
	if output['timed_out'] == False:
		timedOut = 0
	else:
		timedOut = 1
		
	#create a prtg sensor and add the channel data. Each key/value in the json response from ES gets channelized
	sensor = CustomSensorResult(output['status'])
	sensor.add_channel(name='Status',unit='Count',value=status,is_limit_mode=True,limit_max_error=1.5,limit_max_warning=0.5)
	sensor.add_channel(name='Number Of Data Nodes',unit='Count',value=output['number_of_data_nodes'])
	sensor.add_channel(name='Number of Nodes',unit='Count',value=output['number_of_nodes'])
	sensor.add_channel(name='Percent of Shards Active',unit='Percent',value=output['active_shards_percent_as_number'])
	sensor.add_channel(name='Delayed Unassigned Shards',unit='Count',value=output['delayed_unassigned_shards'])
	sensor.add_channel(name='In Flight Fetches',unit='Count',value=output['number_of_in_flight_fetch'])
	sensor.add_channel(name='Relocating Shards',unit='Count',value=output['relocating_shards'])
	sensor.add_channel(name='Pending Tasks',unit='Count',value=output['number_of_pending_tasks'])
	sensor.add_channel(name='Initializing Shards',unit='Count',value=output['initializing_shards'])
	sensor.add_channel(name='Unassigned Shards',unit='Count',value=output['unassigned_shards'])
	sensor.add_channel(name='Task Queue Time (max)',unit='Milliseconds',value=output['task_max_waiting_in_queue_millis'])
	sensor.add_channel(name='Timed Out',unit='Count',value=timedOut,is_limit_mode=True,limit_max_error=0.5,limit_error_msg='Timed Out = True')
	
	#send the sensor data back to the prtg process in json format
	print(sensor.json_result)

Oct, 2020 - Permalink