It's all connected

Somehow

TransactionManagerLookupFactory - No TransactionManagerLookup Configured

I spent the best part of yesterday afternoon fighting the message above. I post this so that the next person fighting it may save some time.
 
One of the problems was that none ofthesolutionssuggestedhelped. After some beer, sleep and a fresh start I foundthis messagethat talks about replacing
 
<tx:annotation-driven transaction-manager=”transactionManager” />
With“


factory-method=”aspectOf”>


And suddenly it all worked. Another example of GDD - Google Driven Development.
 
If anyone knows why this works - please explain.
 
 

Monitoring Twisted Applications With Nagios

This post is inspired by a question on theTwisted mailinglist by Michele:

I'm currently working on a PoC with twisted, Python, to prove the<span class="moz-txt-citetags"></span>technology as an alternative to more<span class="moz-txt-citetags"></span>established enterprise choices (java app servers, etc..).<span class="moz-txt-citetags"></span>the question is: if I have N number of processes running in a M number<span class="moz-txt-citetags"></span>of machines, given that there are no network restriction,<span class="moz-txt-citetags"></span>and that at least http and hhtps are always available, how these<span class="moz-txt-citetags"></span>services would be efficiently monitored?<br />

What I do is to have the service listen to a http connection that returns some monitoring data. The service returns a simple xml message containing some datapoints.

Then I use a custom Nagios plugin to request this url and Nagios-PNP to make graphs of the datapoints the monitor produces. It it doesn’t return anything I know the service is down.

The plugin setup is done by providing an url (sayhttp://myservice:893/monitor) to monitor. The plugin will then both monitor the application and graph it.

I have also added an extra field for”errors”that I use to report odd exceptions or other types of failures that are non-fatal but should be investigated. If the error count exceeds a set level the may also go into the reporting.

The twisted page
The page looks like this:


 1

 2

 3from cStringIOimport StringIO

 4from nevowimport loaders, rend, static, inevow, guard, url, tags

 5from xml.etreeimport cElementTreeas ET

 6

 7class Monitor(rend.Page):

 8    ”””

 9    Basic monitoring interface 

10    XML format:

11    

12     

13    min=”0”max=”300”/>

14    

15        Exception

16        …

17    

18    

19    UOM (unit of measurement) is one of:

20      no unit specified - assume a number (int or float) of things (eg, users, processes, load averages)

21      s - seconds (also us, ms)

22      % - percentage

23      B - bytes (also KB, MB, TB)

24      c - a continous counter (such as bytes transmitted on an interface)

25

26    ”“”

27    def init(self, config):

28        self.isLeaf =True

29        self.config = config

30

31    def renderHTTP(self, ctx):

32        inevow.IRequest(ctx).setHeader(‘Content-Type’,‘text/xml; charset=UTF-8’)

33

34        #que_length = str(len(getter.get_ids(0, -1)))

35        #num_updated = str(get_nr_updated_last_day(self.config.get_db()))

36        num_errors =str(len(self.config.getErrors()))

37                

38        _root = ET.Element(‘status’, {‘service’ :‘PDFIndexer’})

39        if ‘total’ in self.config.stats:        

40            _doc = ET.SubElement(_root,‘total’, {‘value’:str(self.config.stats[‘total’]) })

41        

42        _doc = ET.SubElement(_root,‘runnerStatus’, {‘value’:str(self.config.checksStatus()) })

43        #doc = ET.SubElement(root,’itemsAddedlast24’, {‘value’: num_updated})

44        _errors = ET.SubElement(_root,‘errors’, {‘value’: num_errors,‘critical’:“3” ,‘warning’:“2”})

45        

46        for errorin self.config.getErrors():

47            t = ET.SubElement(_errors,‘error’, text = error)

48        

49        _xmlcontainer = StringIO()

50        ET.ElementTree(_root).write(_xmlcontainer, encoding=“UTF-8”)

51        return _xmlcontainer.getvalue()


The Nagios plugin is foundhereand should be fairly self explanatory.

Note: I haven’t managed to get all the bugs out of it yet with regard to graphing differend datapoints. Also, it is probably not the most efficient Nagios plugin around.

Could Not Initialize Class javax.crypto.SunJCE_b

Today when deploying a new version of a webapplication to Tomcat I got the following error:

Could not initialize class javax.crypto.SunJCE_b

Since I had just upgraded Java, I started looking there. After a lot of digging around, including changing from Suns java to Openjdk (this was on Centos 5.2) I got this error:

    java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.DefaultSSLContextImpl)

After some digging around I found two things that were wrong:

a) I am quite sure that the /usr/lib/jvm/jre-openjdk/lib/security/cacerts file should be larger than 32 bytes.

b) The main problem was that I had set the CLASSPATH all wrong.

Morals? No morals, just check those two if you ever get this error.

Using a Libdir in Maven Projects

Quite often I’ve cursed Maven for missing the simplest usecase: Being able to place a .jar file in a lib/ directory in the project directory and make Maven use the jar file as if it was part of the dependencies.

The odd thing is that this is both easy and simple to do - if you happen to know every Maven detail. Fortunately there is Google Driven Development (GDD), where I ended up findingthis post.

The post says that if you define a dependency as”system”and add a path, then you are good to go. Here’s what I use to get the latest version of the Rome rss library installed:

<br /><dependency><br /><groupId>rome</groupId><br /><artifactId>rome</artifactId><br /><version>1.0RC1</version><br /><scope>system</scope><br /><systemPath>${basedir}/lib/rome-1.0RC1.jar</systemPath><br /><br /></dependency><br />

Update:I ended up findingthis bugthat says that if you use a system scoped jar then it will not be included in a war file. It seems that the only way around this is create a central repository for your projects and add the jar files there. I wish this was easier.

Testing SoGO 64bit

I’ve been planning to testScalable OpenGroupware.orgfor some time now, but all my email boxes are 64 bit and Inverse only provides 32bit rpms.

Recompiling the RPMS hit some unfortunate problems, andthe maillinglist didn’tprovide much help. The project got shelved for not being workable - until a client asked for a calendar solution.

This time I tried to use the 32bit rpms without recompiling them. This works very well except for one part: mod_ngobjweb needs to be 64 bit as it is part of apache.

Back to what stopped me the last time: Compiling Sope for a 64 bit machine.

Toiling away with a new version of SOGO + deps, this little gemappeared. It describes all the variables that may be used when compiling Sope. With this information the project moved forward by adding

%define apache_modules_dir %{usr}/lib/httpd/modules
%define apache_conf_dir    %{
sysconfdir}/httpd/conf.d
%define ngobjweb_requires  httpd
%define sope_major_version 4
%define sope_minor_version 7
%define sope_source SOPE.tar.gz
%define sope_version %{sope_major_version}.%{sope_minor_version}
%define sope_release 1626
%define sope_buildcount 1
%define dist_suffix el5
%define sope_prefix /usr/GNUstep/System
%define sope_makeflags all

To the top of the sope.spec file. Installing just mod_ngobjweb worked fine and Sogo is now up and running. Yay!

The Simple Things

One of the things I often miss with Netbeans is better navigation between different files.

 

For example, I miss the CTRL-e shortcut from Eclipse that lets me easily move between different files I am editing. Another example si being able to click on a line in the output from running a Junit test and be transported to that file and line number.

 

Void Methods Throwing Exceptions in Easymock

When you have written a few tests using Easymock you might get into the fun situation that you need to mock a method that returns void and you want the method to throw an exception. What do you do?

Usually you would write something like:

expect(mockSender.send(message)).andThrow(new Exception());

But this does not work with void methods because expect() cannot work with a void return value.

Solution

Use expectLastCall():

mockSender.send(message);expectLastCall().andThrow( new SendFailedException("Error"));

 

 

Goodbye Zenoss

5 months ago, I switched jobs. One of the things I needed to implement at my new workplace was a systems monitoring and management solution. I decided to useZenoss.

The reasons were many, but the main ones were:

  • Auto discovery of hosts and services
  • Nice, modern python feel (not very rational, I know)
  • Nice and usable UI
  • Good graphing
  • User management
  • Agent-less monitoring
  • Support forNagiosplugins

I am now in the process of throwing out Zenoss and switching to Nagios. Why? Because Zenoss may fit very well when you need to monitor simple devices such as routers and switches, but I needed to monitor various processes that were not as easy to fit into the normal Zenoss way of thinking.

Take Virtual hosts for example. I wanted to use the Nagios check_http to check every virtual host so that I could catch deployment errors early. This proved to be hard to do with Zenoss for two reasons. First, I had to create a template for each virtual host, something that takes a lot of clicks, second, Zenoss barfs if one IP is connected to multiple devices. Thus, I cannot represent the different virtual hosts as separate devices.

Another problem is that I feel Zenoss hides a bit of how it works. I was getting the feeling that I didn’t completely understand how I could change different values. This became a problem when I needed to adjust a set of values to reflect that different hosts behave differently.

Graphing

A problem with the Zenoss graphs is that some of them are in the prefs tab and the others you’ll need to click into each file system to find. The result is that you get Repetitive Strain Injury (RSI) before you know it. Nagios doesn’t have a graphing solution so Zenoss beats it there.

To solve this I have ended up with a combined approach. I’ve installedMuninon most of the hosts in question - this was something I did before I started using Zenoss, and Munin gives a lot of nice graphs out of the box. I find Munin a bit of a PITA to configure at times though. I wish someone wrote a quick test script to check that a munin.conf file works correctly.

The final graphing solution I am planning to use is Munin combined withNagios-PNP. Nagios-PNP works, is easy to set up and has the great feature that it will graph any performance data you provide with your pluginWITHOUT ANY EXTRA CONFIG! I just love it.

Auto discovery

My conclusion is that auto discovery is very nice when you want get started, but that you will quickly tire of it. Instead I suggest a combination of nmap with xml output and a custom script to create services. I might write one some day. For now, I ended up just using a simple list of my hosts and a couple of Perl scripts to generate per host configurations where they were needed.

Further needs

After this rant, I hope to come back later with a couple of posts that are more detailed with regard to configuring Nagios NRPE and also some simple autodiscovery tools.

Quick tip at the end: Use Nagios 3

It is realy worth compiling Nagios form source to get the latest version - this eases configuring Nagios-PNP a lot!