I did know that there were some hot discussions going on about Ubuntu’s 10.4 positioning of the window controls in the titlebar; they moved from the right to the left. However I thought that it was just an idea so I was in a bit of a shock when I upgraded to the latest beta and saw they they were actually at the left hand side…
Apart from something useless to get used to the whole UI becomes inconsistent as well; for example Chrome with it’s own titlebar has the min/max/close buttons on the right.

Luckily it’s easily fixed with

gconftool-2 --set /apps/metacity/general/button_layout --type string “menu:minimize,maximize,close,spacer”

Oh and if you run into any problems with installing fglrx, here’s a work around https://bugs.launchpad.net/ubuntu/+source/fglrx-installer/+bug/546917

 

With the recent new attempt of Microsoft to conquer the search engine market I wondered how often the Bing crawler hit http://www.ehour.nl versus Google’s bot.

The Bing bot identifies itself with msnbot/2.0 while Google’s crawler uses Googlebot.

Checking my log files for both crawlers:
grep -i msnbot/2.0 ehour.nl-access_log* | wc -l
5727
grep -i googlebot ehour.nl-access_log* | wc -l
34912

5.727 hits from Bing, 34.912 from Google. That’s 6 times as much hits from Google than Bing’s bot. In all fairness Microsoft seem to use their old bot (msnbot/1.1) for Bing as well:

grep -i msnbot ehour.nl-access_log* | wc -l
18157

With 18.157 hits still not even close to Google’s bot. Can I conclude that Google’s index is 6 times the size of Bing or is Google’s crawler just a bit more aggressive aka up-to-date? ;)

 

Reading Dmitri Maximovich’s blog posting about plotting JVM memory into MRTG graphs had to trigger my interest as I’m a statistics addict. Earlier on I tried to get JVM stats using SNMP but it took me more than 30 minutes to get any data so I dropped it. The interesting thing about Dmitri’s method is that it uses jstat which is far more easier, read his posting for more details.

Anyway, I’m not using MRTG anymore but RRDTool. RRDTool is a lot more flexible and graphs aren’t created every 5 minutes but whenever you request them – at least with rrdcgi.

To get JVM data into RRD is easy. First create a RRD database with 6 datasources; a capacity and utilization datasource for eden, old & permanent size. The following script creates a heapsize.rrd which is the actual database.

/usr/bin/rrdtool create
heapsize.rrd
--start N
--step 300
DS:edencap:GAUGE:600:0:10000000
DS:edenut:GAUGE:600:0:10000000
DS:oldcap:GAUGE:600:0:10000000
DS:oldut:GAUGE:600:0:10000000
DS:permcap:GAUGE:600:0:10000000
DS:permut:GAUGE:600:0:10000000
RRA:AVERAGE:0.5:1:600
RRA:AVERAGE:0.5:6:700
RRA:AVERAGE:0.5:24:775
RRA:AVERAGE:0.5:288:797
RRA:MAX:0.5:1:600
RRA:MAX:0.5:6:700
RRA:MAX:0.5:24:775
RRA:MAX:0.5:288:797

With the database created it needs to be filled every 5 minutes or so. Slightly modifying Dmitri’s MRTG script the JVM data is fed into rrd using rrdupdate. In the following example I query a Tomcat instance, change the ‘grep tomcat’ if you want to monitor something else.
Add this script as a cronjob to have it executed every 5 minutes. Also make sure that it can access the heapsize.rrd file.

#!/bin/sh
JAVA_HOME=/opt/java
PID=`sudo $JAVA_HOME/bin/jps -lv | grep tomcat| awk '{print $1}'`
DATA=`sudo $JAVA_HOME/bin/jstat -gc $PID | grep -v S0C`

EC=`echo $DATA | awk '{print $5}'`
EU=`echo $DATA | awk '{print $6}'`
OC=`echo $DATA | awk '{print $7}'`
OU=`echo $DATA | awk '{print $8}'`
PC=`echo $DATA | awk '{print $9}'`
PU=`echo $DATA | awk '{print $10}'`

`/usr/bin/rrdupdate heapsize.rrd N:$EC:$EU:$OC:$OU:$PC:$PU`

The last thing to do is creating the graph with RRDCGI. RRDCGI is part of the RRDTool and parses a HTML template replacing RRD::Graph tags with the… graph ;)
Store the following cgi somewhere on your webserver (don’t forget it’s a CGI so it must be executable) and make sure your webserver has read access on the heapsize.rrd file.

The end result is a graph stacking the three space capacities on eachother so you’ll have a clear view of the total usage. Current utilization is drawn into each space.

#!/usr/bin/rrdcgi

<HTML>
<HEAD><TITLE>stats</TITLE>
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<meta http-equiv="refresh" content="300">
</HEAD>
<BODY>

<RRD::GRAPH heapsize.gif  --title="tomcat heapsize"
--rigid
--height=120
--width=400
--start=-1d
--alt-autoscale-max
--vertical-label="byte"
          DEF:edencap_=/var/rrd/heapsize.rrd:edencap:AVERAGE
          DEF:edenut_=/var/rrd/heapsize.rrd:edenut:AVERAGE
          DEF:oldcap_=/var/rrd/heapsize.rrd:oldcap:AVERAGE
          DEF:oldut_=/var/rrd/heapsize.rrd:oldut:AVERAGE
          DEF:permcap_=/var/rrd/heapsize.rrd:permcap:AVERAGE
          DEF:permut_=/var/rrd/heapsize.rrd:permut:AVERAGE
        CDEF:edencap=edencap_,1024,*
        CDEF:edenut=edenut_,1024,*
        CDEF:oldcap=oldcap_,1024,*
        CDEF:oldutval=oldut_,1024,*
        CDEF:oldutgrap=oldutval,edencap,+
        CDEF:permcap=permcap_,1024,*
        CDEF:permutval=permut_,1024,*
        CDEF:permutgraph_=permutval,edencap,+
        CDEF:permutgraph=permutgraph_,oldcap,+

        AREA:edencap#00cf00:"eden cap "
        GPRINT:edencap:LAST:"Current:%8.2lf %s"
        GPRINT:edencap:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:edencap:MAX:"Max:%8.2lf %sn"

        STACK:oldcap#8fea00:"old cap  "
        GPRINT:oldcap:LAST:"Current:%8.2lf %s"
        GPRINT:oldcap:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:oldcap:MAX:"Max:%8.2lf %sn"

        STACK:permcap#EACA00:"perm cap "
        GPRINT:permcap:LAST:"Current:%8.2lf %s"
        GPRINT:permcap:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:permcap:MAX:"Max:%8.2lf %sn"

        LINE1:edenut#0000ff:"eden util"
        GPRINT:edenut:LAST:"Current:%8.2lf %s"
        GPRINT:edenut:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:edenut:MAX:"Max:%8.2lf %sn"

        LINE1:oldutgrap#002f8f:"old util "
        GPRINT:oldutval:LAST:"Current:%8.2lf %s"
        GPRINT:oldutval:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:oldutval:MAX:"Max:%8.2lf %sn"

        LINE1:permutgraph#008fea:"perm util"
        GPRINT:permutval:LAST:"Current:%8.2lf %s"
        GPRINT:permutval:AVERAGE:"Avg:%8.2lf %s"
        GPRINT:permutval:MAX:"Max:%8.2lf %sn">
</body>
</html>

 

When you distribute your application a common task is to create the database tables and prefill them with some static data. You could do this using an SQL script but this complicates the installation process, especially if you use an embedded database such as Derby. By utilizing DdlUtils and a Jetty life cycle you can automate this whole process, creating the database just before your application starts.

DdlUtils reads the table definitions and static data from XML files you distribute along with your application. The easiest way to create those XML’s is to generate them from an existing database with an Ant task.
The build.xml example below generates two XML files (ddl.xml & dml.xml) out of a MySQL database.

Take note that the Maven 2 Ant tasks are used to construct the classpath. If you don’t use Maven 2, make sure ddlutils and your jdbc driver are on the classpath.

<project name="eHourDdlExport"
		default="database-dump"
		basedir="."
		xmlns:artifact="antlib:org.apache.maven.artifact.ant">

	<artifact:dependencies pathId="dependency.classpath">
		<dependency groupId="org.apache.ddlutils" artifactId="ddlutils" version="1.0"/>
		<dependency groupId="log4j" artifactId="log4j" version="1.2.13"/>
		<dependency groupId="mysql" artifactId="mysql-connector-java" version="5.0.5"/>
	</artifact:dependencies>

	<target name="database-dump" description="Dumps the database structure">
		<taskdef name="databaseToDdl" classname="org.apache.ddlutils.task.DatabaseToDdlTask">
			<classpath refid="dependency.classpath"/>
		</taskdef>

		<databaseToDdl modelName="MyModel">
			<database url="jdbc:mysql://127.0.0.1/db" driverClassName="com.mysql.jdbc.Driver" />
			<writeSchemaToFile outputFile="src/main/resources/db/ddl.xml"/>
			<writeDataToFile outputFile="src/main/resources/db/dml.xml"/>
		</databaseToDdl>
	</target>
</project>

Now that the data you want to preload is exported into a portable XML format it’s time to configure Jetty.

First register a JDNI datasource in the jetty.xml. In this example I’m using Derby with the create flag set since DdlUtils
can’t auto-create the database itself.

<New id="Datasource"
	class="org.mortbay.jetty.plus.naming.Resource">
	<Arg>jdbc/eHourDS</Arg>
	<Arg>
		<New class="org.apache.derby.jdbc.EmbeddedDataSource">
			<Set name="DatabaseName">ehourDb</Set>
			<Set name="createDatabase">create</Set>
		</New>
	</Arg>
</New>

Next thing is adding a new Jetty life cycle. Since Jetty executes the life cycles in the order they’re listed in
the jetty.xml, add it before the WebAppDeployer lifecycle (or whichever you use to boot up your main application)
as you want the database to be prepared before the actual application boots.

	<Call name="addLifeCycle">
		<Arg>
			<New class="net.rrm.ehour.db.DbValidatorLifeCycle" />
		</Arg>
	</Call>

Creating the DbValidatorLifeCycle is easy, extend Jetty’s AbstractLifeCycle and override the doStart method. The JNDI
tree is already available so the datasource can be plucked from there.

public class DbValidatorLifeCycle extends AbstractLifeCycle
{
    public void doStart() throws Exception
    {
		DataSource dataSource = getDataSource();

		checkDatabaseState(dataSource);
    }

    private DataSource getDataSource() throws NamingException
    {
		InitialContext initialContext = new InitialContext();
		DataSource datasource = (DataSource)initialContext.lookup("jdbc/eHourDS");

		return datasource;
    }

	private void checkDatabaseState(DataSource datasource)
	{
		..
	}
}

The final part is using DdlUtils to create the tables and load the data into the database.
The ddl.xml and dml.xml files were created by the ant task so make sure you distribute them along
with your application.

private checkDatabaseState(DataSource dataSource)
{
	Connection connection = dataSource.getConnection();
	Platform platform = PlatformFactory.createNewPlatformInstance(dataSource);

	// create the tables
	Database ddlModel = readModelFromXML("db/ddl.xml");
	platform.createTables(ddlModel, false, false);

	// insert the static data
	DatabaseDataIO	dataIO = new DatabaseDataIO();
	DataReader dataReader = dataIO.getConfiguredDataReader(platform, ddlModel);
	dataReader.getSink().start();
    dataIO.writeDataToDatabase(dataReader, new File(""db/dml.xml").getAbsolutePath());
}

In this example the current state of the datamodel is not checked so if there’s any existing data
already in the model you might end up with some conflicts when you try to recreate the tables.
One solution is of course to drop everything beforehand but this is probably not preferred when you want to
retain existing data during an upgrade.
A possible solution is to version your datamodel. Create a separate ‘configuration’ table which holds a
record containing the version of the existing datamodel. Now based on the existence of the version you
can decide whether you have to do a platform.createTables or a platform.alterTables when the version doesn’t match.

 

On archive.org I found a screenshot of the first site I ever made, RAW Online anno 1996 :) Funny to see how things evolved since then.

Even found my first applets made in ’97

 

Today I had a little MSX deja-vu. At my current client the buildserver started to bug out with a


Embedded error: Failed to copy full contents from D:workspaces---CustomerPre
ferenceInterfacetargetcloverclasses----customerpreferencetransferobjectrequestassemblers
CreateRequestObjectAssembler$__CLOVER_b0f1uej5ik.class to d:workspaces---Cus
tomerPreferenceInterfacetargetcloverCustomerPreferenceInterface-0.0.1-SNAPSHOT-cloverWEB-INFcla
sses----customerpreferencetransferobjectrequestassemblersCreateRequestObjectAssembler$__CLO
VER_b0f1uej5ik.class

When I tried to manually copy the file to the WAR dir, Windows gave an invalid filename alert. After some fiddling around it turned out that Windows has a 255 character limit on the complete path… never knew it and never ran into it. Good thing is that it gave me an 8-bit MSX deja-vu, bad thing is that we have to refactor the package names.

 

Why does partition corruption always occur on places I least want it to occur? After an uptime of over 3 months suddenly my linux box started to act up. After some searching around 1 one the partitions seem to had issues and of course it was where the /home dirs were mounted. To make it worse the .maildir of the virtual mail user was gone after checking the disk. And if it wasn’t good enough not some mailinglist archive was gone but no, all the e-mail of my company’s address was gone. Great! Luckily I found most of it in lost+found but still, a complete Sunday evening went up in smoke..

© 2011 Thies' blog Suffusion theme by Sayontan Sinha