Page 1 of 1

Dashboard: health of servers

Posted: September 13th, 2012, 2:17 am
by sander
Here is my feature request for a dashboard in SABnzbd. The dashboard will show the health of the newsservers that are defined (and enabled?) by sabnzbd.ini.
The health will be expressed in a score from 0 - 6 (or 10): higher is better.
This way it will be clear in one glimpse what is going on, and what needs to be solved (network, firewall, newsserver settings (name or login), etc).



The score will be presented:
- in a summary format in the main screen in the upper right corner (just like the sysload), and
- in a separate screen http://localhost:8080/dashboard/ with more details, including explanation

I see a few ways to fill the info in the dashbaord, that should work parallel to each other:
- based on actual downloads
- at startup of SAB & at intervals (each 30 minutes)
- a seperate button (in the dashboard screen) to run tests on all servers

Rationale: a working SAB is great. However, if things don't work, it is often a mystery what is going on (even for experienced users). And it takes manual analysis (and possibly forum questions) to see what's going on. With the dashboard it should be clear in one glimpse what's going on, and what needs to be solved.

The "Test Server" button in Config -> Server is already helpful and a good start (and possibly code can be reused), but the Dashboard would do more pro-active testing and more pro-actively presented.

A server can have different levels of health:
0: test for outside network connectivity: can we ping http://www.google.com? If so: good, we have network & DNS. If not ... very bad.
1: we can reach a generic, predefined newsserver (random picked from list of 25 well known newsservers, like news.giganews.com). If it works: good! That means we have network and there is no firewall blocking NNTP connections
2: newsserver's hostname does not even resolve. That's bad. Possible reasons: hostname does not exist.
3: hostname does resolve, but no connection on defined port. Possible reasons: the defined hostname is no NNTP server at all, wrong port, or server down, or firewall.
4: newsserver does respond as NNTP server. Good.
5: newsserver does respond, and we can login (if needed). So: correct credentials. Good!
6: newsserver has alt.binaries.test (and/or other well known binary newsgroups), and it actually has articles available in those groups. This is good sign it is a binary newsserver (and not a text newsserver)
7: scoring on real NZB downloads, for example completeness. This is the walhalla level! :)

Below is a manual NNTP session, that shows a healthy setup. Score is 6.

Code: Select all

sander@R540:~$ telnet newszilla6.xs4all.nl nntp
Trying 2001:888:0:18::119...
Connected to newszilla.ipv6.xs4all.nl.
Escape character is '^]'.
201 dreader35.news.xs4all.nl NNRP Service Ready - newsmaster@xs4all.nl (no posting).

group alt.binaries.test
211 1999999 563562416 565562414 alt.binaries.test

stat 565562414
223 565562414 <Part62of252.5FAD9EF781AD4FB3860C16D3A5225D7D@1347481954.local> status

stat 939393939
423 No such article number in this group

quit
205 Transferred 265 bytes in 0 articles, 1 group.  Disconnecting.
Connection closed by foreign host.
sander@R540:~$

I can write the python code to do the above and give a score. However, I don't know how to get it the info into SAB's GUI ...

So ... looking forward to replies ...

Re: Dashboard: health of servers

Posted: September 13th, 2012, 3:44 pm
by shypike
Looking forward to your code :)
Actually, item 7 is probably the easiest to do.

I agree that the current Connections tab sucks big time and needs work.

Re: Dashboard: health of servers

Posted: September 13th, 2012, 3:59 pm
by sander
shypike wrote:Looking forward to your code :)
Actually, item 7 is probably the easiest to do.

I agree that the current Connections tab sucks big time and needs work.
I'm writing some code. I'll try to finish it.

Item 7 alone is not so useful, I would say.

Another item for the dashboard: some python / system performance benchmarks.

Re: Dashboard: health of servers

Posted: September 16th, 2012, 4:48 pm
by sander
First results of the dashboard python code below. As a side effect, the dashboard code also determines the ... retention (in days).

Still buggy, so to be continued, but the idea is working ...

Code: Select all

sander@toverdoos:~/newsservercheck$ python dashboard-score.py 

newsserver is news.doesnotexist.nl
Score for  news.doesnotexist.nl is: 0

newsserver is weathergirl-ipv6.tele2.net
Score for  weathergirl-ipv6.tele2.net is: 101

newsserver is free.tweaknews.nl
502761296 561236818 58475522
Retention is 140
Score for  free.tweaknews.nl is: 102

newsserver is newszilla6.xs4all.nl
564230615 566230613 1999998
Retention is 10
Score for  newszilla6.xs4all.nl is: 102

newsserver is www.google.com
Score for  www.google.com is: 1

sander@toverdoos:~/newsservercheck$

Re: Dashboard: health of servers

Posted: September 19th, 2012, 2:32 pm
by sander
OK, it's ready: the dashboard code checks finds the score for a certain server / port / login credentials combination.

Call the function:

Code: Select all

print checknewsserver(server='newszilla6.xs4all.nl'), ENTER
print checknewsserver(server='reader.xsusenet.com', username='wrong', password='bla'), ENTER
Output for a set of different combinations:

Code: Select all

sander@toverdoos:~/newsservercheck$ python dashboard-score-2.py 
Let's check some newsservers:

newsserver and port (no login credentials provided): news.doesnotexist.nl 119
0 : Could not resolve the newsserver name: check newsserver name and your network & DNS 

newsserver and port (no login credentials provided): weathergirl-ipv6.tele2.net 119
10 : Everyting looks good 

newsserver and port (no login credentials provided): newszilla6.xs4all.nl 119
10 : Everyting looks good 

newsserver and port (no login credentials provided): newsreader.eweka.nl 119
4 : Authentication required, but no username provided 

newsserver and port (with login credentials provided): reader.xsusenet.com 119
10 : Everyting looks good 

newsserver and port (with login credentials provided): reader.xsusenet.com 119
6 : Authentication failed 

newsserver and port (with login credentials provided): newszilla6.xs4all.nl 1234
1 : Could not get a connection: check newsserver name and port 

newsserver and port (no login credentials provided): http://www.google.com 119
1 : Could not get a connection: check newsserver name and port 

Finished
sander@toverdoos:~/newsservercheck$
Score is on a scale from 0 (bad) to 10 (good binary server).

So, Shypike, what do think of this? Useful in SABnzbd?

Re: Dashboard: health of servers

Posted: September 19th, 2012, 2:36 pm
by sander
Code is here:

Code: Select all

import sys
import telnetlib
import socket

debug = True
debug = False

scoreNORESOLVE = '0 : Could not resolve the newsserver name: check newsserver name and your network & DNS'
scoreNOCONNECTION = '1 : Could not get a connection: check newsserver name and port'
scoreNNTPCONNECTIONOK = '3 : NNTP connection, but nothing else'
scoreAUTHNOUSERNAME = '4 : Authentication required, but no username provided'
scoreAUTHREQUIRED = '5 : Authentication required, but did not succeed'
scoreAUTHFAILED = '6 : Authentication failed'
scoreNOBINARY = '7 : No binary newsgroup available'
scoreALLOK = '10 : Everyting looks good'

ENTER = "\r\n"

def sendcommand(session,cmd):
	if debug: print cmd
	session.write(cmd);
	# now read the response until we get something else than an empty line
	while True:
		responseline = session.read_until("\n",3).rstrip()
		if len(responseline) > 2: break
	if debug: print responseline
	return responseline
	

def checknewsgroup(session,newsgroup):
	cmd = "group " + newsgroup + ENTER
	responseline = sendcommand(session,cmd)
	if debug: print responseline
	return responseline

def checknewsserver(**kwargs):

	# First get parameters
	newsserver =kwargs.get('server')
	if newsserver is None:
		return 'No newsserver defined'
	
	port = kwargs.get('port')
	if port is None: 
		port = 119

	username = kwargs.get('username')
	#if username is not None: print "username is", username

	password = kwargs.get('password')
	#if password is not None: print "password is", password

	if username is None:
 		print "newsserver and port (no login credentials provided):", newsserver, port
	else:
 		print "newsserver and port (with login credentials provided):", newsserver, port
	


	if debug: print "\nnewsserver is", newsserver
	score = -1	# default. Should not be returned ...

	try: 
		socket.getaddrinfo(newsserver,119)
	except:
		# Could not resolve newsserver
		return scoreNORESOLVE

	# OK, we could resolve the server. Now let's connect

	try:
		tn = telnetlib.Telnet(newsserver,port,5)
	except:
		# no connection
		return scoreNOCONNECTION

	responseline = tn.read_until("\n",3)
	if responseline.startswith("20"):
		# We got a 20. (201), so that's good: the newsserver responds with a 20. on the port used
		score = scoreNNTPCONNECTIONOK

	# Now let's do a dummy group check to see if a login is needed ...

	responseline = checknewsgroup(tn,'alt.blabla.bla')

	if responseline.startswith("480"):
		if debug: print "Auth required"
		# authentication required
		# return scoreAUTHREQUIRED
		'''
		480 Authentication Required*
		authinfo user halo
		381 PASS required
		authinfo pass gek
		502 Authentication Failed
		482 Authentication Rejected
		'''

		if username == None:
			if debug: print "Auth required, but not provided"
			return scoreAUTHNOUSERNAME
		else: 
			cmd = 'authinfo user ' + username + ENTER
			responseline = sendcommand(tn,cmd)

			cmd = 'authinfo pass ' + password + ENTER
			responseline = sendcommand(tn,cmd)
			
			if responseline.startswith('502') or responseline.startswith('482') :
				return scoreAUTHFAILED
			if responseline.startswith('281'):
				# login OK
				score = 'login OK'
				if debug: print "Login was succesful"

	# OK, if we get here, a login was not needed, or a login was needed and it was succesful
	# So let's check for binary newsgroups

	responseline = checknewsgroup(tn,'alt.binaries.boneless')
	if responseline.startswith("411"):
		# 411 No such group alt.binaries.test
		# Hmm. Not good. To be sure, let's try another newsgroup
		responseline = checknewsgroup(tn,'alt.binaries.test')
		if responseline.startswith("411"):
			# Again no such group ... so we're now quite sure it's no a binary newsserver
			return scoreNOBINARY
	elif responseline.startswith("211"):
		# OK, the group does exist on this newsserver
		# 211 1999999 564097456 566097454 alt.binaries.test

		# weathergirl-ipv6.tele2.net:
		# group alt.binaries.boneless
		# 211 14950768 1553412576 1568363343 alt.binaries.boneless
		return scoreALLOK
	elif responseline.startswith("480"):
		# still not logged in?!
		return scoreAUTHREQUIRED
	else:
		print "Strange ... response not understood:", responseline

	# OK. Done. Close the connection
	tn.close()
	return score

print "Let's check some newsservers:\n"

print checknewsserver(server='news.doesnotexist.nl'), ENTER
print checknewsserver(server='weathergirl-ipv6.tele2.net'), ENTER
print checknewsserver(server='newszilla6.xs4all.nl'), ENTER
print checknewsserver(server='newsreader.eweka.nl'), ENTER
print checknewsserver(server='reader.xsusenet.com', username='goodname', password='goodpassword'), ENTER
print checknewsserver(server='reader.xsusenet.com', username='wrong', password='bla'), ENTER

print checknewsserver(server='newszilla6.xs4all.nl', port=1234, username='hallo', password='geheim'), ENTER
print checknewsserver(server='www.google.com'), ENTER


print "Finished"

Re: Dashboard: health of servers

Posted: September 19th, 2012, 3:05 pm
by shypike
Typo in line 151.

Re: Dashboard: health of servers

Posted: September 19th, 2012, 3:32 pm
by sander
shypike wrote:Typo in line 151.
Fixed!