Ruby Singleton Logger

I have been working on a module lately that parses a XML file structure into a hash and writes it to a database. The module includes some classes and methods and I needed a central logger class.

I created a class that inherits from Ruby´s Logger class.

class MyLogger < Logger
end

I decided to make this class a Singleton. Singleton is a design pattern that restricts instantiation of a class to only one instance that is globally available. This can e.g. be done by simply including the Singleton Module.

class MyLogger < Logger
  include Singleton
end

I wanted this class to be able to either log to STDOUT or a file. The standard way to do this, is to pass the log device to the Logger class during instantiation. The problem is that the singleton module creates the singleton instance before it is actually needed, called eager instantiation. In order to tell the singleton instance to which log device it should log to, we need to set a member variable in the initialize method. Secondly we need a method to reassign the log device.

class MyLogger < Logger
  include Singleton

  LOG_FILE = File.open("myfile.log","a")

  def initialize
    @logdev = Logger::LogDevice.new(LOG_FILE)
    @level = INFO
  end

  def change_logdev_to_stdout
    @logdev = Logger::LogDevice.new(STDOUT)
  end

end

I could now use the logger methods from everywhere in my code, e.g.:

MyModule::MyLogger.instance.info("Hello World!")

In order to make things a little bit shorter, I added an additional method to the module:

def self.logger
  return MyModule::MyLogger.instance
end

Logging can now been done from everywhere by calling:

MyModule::logger.info("Hello Universe!")

I have got my ticket, yeah!

Railsberry badge It was a huge run, but I was lucky. to get a ticket for Railsberry in Kraków, Poland, in April 2012.

How to get rid of bundle exec

I you feel bored by entering bundle exec (a command that executes a command in the context of the current bundle) if you want to execute a rake task, the folloowing code could help to get rid of it:
bundle install --binstubs; export PATH="./bin:$PATH"

How to ssh into your pogoplug

Seagate dockstar

I recently had to fix something on my pogoplug attached harddrive. When attaching it to my Mac the hdd was read-only, so I decided to attach it to the pogoplug again and try it using ssh.

To enable SSH, login to http://my.pogoplug.com, navigate to the Settings page, select Security Settings, and from the main pane, enable SSH for your Pogoplug. Choose your own SSH password.

Open up a terminal and login:

ssh root@your-host-or-ip

Go to hdd (in my case):

cd /tmp/.cemnt/mnt_sda1

Have fun!

How to get rid of Bundler::GemNotFound error at domainfactory

Today I got stuck with an issue using Bundler at domainfactory for the first time. Although a gem was installed and bundle install ran fine, passenger reclaimed:
Could not find activesupport-2.3.11 in any 
of the sources (Bundler::GemNotFound)
Thanks to my friend Stack Overflow, I could get rid of this problem by running:
bundle install --path vendor/cache

render :action in :rails

Although the Rails Guides say it is a newcomers issue, I also get sometimes confused with the render command:

"Using render with :action is a frequent source of confusion for Rails newcomers. The specified action is used to determine which view to render, but Rails does not run any of the code for that action in the controller. Any instance variables that you require in the view must be set up in the current action before calling render."

My first ever ruby gem (pre-alpha)

Today I released my first-ever ruby gem, still pre-alpha but maybe of use for someone. The gem adds a climate classification parameter to a location object based upon observed or projected climate data. It is based upon the Köppen climate classification, one of the most widely used climate classification systems.

Test it: https://github.com/tpunkt/koeppen-geiger

Map Application Performance Tuning - Part 2

An advice for optimizing the performance of Mapserver was to use FastCGI.

1. I installed the FastCGI library with yast and downloaded the Apache2 module mod_fastcgi-2.4.6.tar.gz. After extracting it, I followed the configure, make, make install dance as described. Unfortunately the compiler complained about some missing stuff and I couldn´t figure out how to get the module installed. I gave it up and tried the mod_fcgid module from Apache itself that seemed to be quite similar.

3. I extracted mod_fcgid-2.3.4.tar.gz to my home directory and followed the steps described in the README:
# APXS=/usr/sbin/apxs2 ./configure.apxs
# and following 'make'

The compiler returned the same problem and complained about a missing mpm.h and mpm_default.h in /usr/include/apache2.

I came around the problem by symlinking both files using:
ln -s ../apache2-prefork/mpm.h mpm.h
ln -s ../apache2-prefork/mpm_default.h mpm_default.h

After doing that both modules were build successfully into /usr/lib64/apache2.

4. I added a configuration file to load the module in /etc/apache2/conf.d with the following entry:

LoadModule fastcgi_module /usr/lib64/apache2/mod_fastcgi.so

5. I restarted Apache with apache2ctl restart. The error_log in /var/log/apache2/ indicates that the module was loaded successfully:

Apache/2.2.10 (Linux/SUSE) mod_ssl/2.2.10 OpenSSL/0.9.8h mod_fastcgi/2.4.6 Phusion_Passenger/2.2.5 configured -- resuming normal operations

Map Application Performance Tuning - Part 1

My current task is to improve the performance of a web application that runs on Apache 2.2.10 on OpenSuse 10.6, 64bit. It is a map application that works with Google Maps JavaScript API, OpenLayers JavaScript API on the client side and a Mapserver on the server side.

After discovering that the response time of my server was sometimes quite long (using firebug), I decided to start optimizing the server side application first.

1. First step I did was installing Tilecache, a Python-based server that caches tiles from different sources on disk. Installation is easy and straightforward. The test run worked correctly.

2. Figuring out how my application or better a OpenLayers.Layer.WMS object could request tiles via Tilecache that were formerly requested from Mapserver was a little bit harder. First I had to install Python MapScript (to enable communication between Tilecache and Mapserver). which I managed by following the advices "Building and Installing Python MapScript" in Chapter 7 from the "Beginning MapServer" book from Bill Kropla. As far as I know now, each map that should be cached by and requested via Tilecache has to have a correct entry in tilecache.cfg.

Example:
[worldtest]
layers = country
spherical_mercator = yes
extension = png
mapfile = mapfile.map
data_extent = -198.0,-115.542749339,198.0,109.146905833
type = MapServer
metatile = no
srs = EPSG:4326
metabuffer = 10,10
bbox = -198.0,-115.542749339,198.0,109.146905833
metasize = 5,5
extent_type=loose

This layer can requested via an OpenLayers.Layer.WMS object as follows:

var layer = new OpenLayers.Layer.WMS("name",
  "http://localhost/cgi-bin/tilecache/tilecache.cgi", {
  maxExtent:new OpenLayers.Bounds(1,2,3,4),
  maxResolution:156543.0339,
  layers:"worldtest",
  transparent:true
});

gem server

Great tip! Running "gem server' fires up a server page on localhost:8808 that lets you crawl rdocs of all locally installed gems.