Skip to content

Moved to new hosting Media Temple

For a very long time I was a happy customer with hostgator. Recently I faced couple of downtime with the reseller hosting package. For some reason due to another account the apache kept dieing without notice. So I decided to move my blog to cloud based hosting. Couple of months back my colleague Shuja had suggested me about Media Temple. Now I thought it was the right time to move.

I subscribed for Grid Service hosting which is for 20$ monthly. After moving my blog I did a load test and it seems to be pretty stable.

The good thing about this hosting is for 20$ you get fixed 1000 hours of GPU. And based on load and usage it gets consumed. Suppose if you see a sudden spike in the traffic your website will be scaled automatically. If you cross 1000 hours it charges 10 cents per hour. If anyone is looking for scaling your website I suggested you do a test drive with media temple.
;-)

Apache Log Format for Amazon EC2 with Elastic Load Balancer

The journey through the Amazon Cloud (AWS) is quite amazing. Recently I had to use two EC2 instance with Elastic Load balancer. Once the website was served with load balancer only the load balancer IP was logged as remote IP.

After Googling for few hour and with trial and error method I got the correct Apache log format so that the real remote IP is logged.

I created a custom log format with a name “combined_new” and used it in all the virtual host configured in Apache. But you can use the format however you want.

#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
#
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_new
#....

#...
#
# START_HOST example.com
<VirtualHost *:80>
	ServerName example.com
	DocumentRoot "/var/www/example.com/html"
	<Directory "/var/www/example.com/html">
		Options Includes FollowSymLinks
		AllowOverride All
		Order allow,deny
		Allow from all
	</Directory>
	CustomLog /var/www/logs/example.com/access_log combined_new
	ErrorLog /var/www/logs/example.com/error_log
</VirtualHost>
# END_HOST example.com

Before you make any changes to httpd.conf please go through Apache log module.

I hope this small tip helps ;-)

Note: Always backup your original httpd.conf before you make any changes.

Download & Process Amazon Cloudfront Logs with Awstats

These days we use Amazon Cloudfront for content delivery. Amazon has made it very easy to deliver files in a Amazon Simple Storage Service (S3) bucket using Amazon Cloudfront distribution. If you are using Cloudfront as Content Delivery Network (CDN) your next task will be monitoring the usage. For this Amazon Cloudfront has a provision to store access logs to a S3 bucket. My hurdle was to process the log files stored by Cloudfront. For sites hosted with apache I use Awstats for reading the logs. So my vote was for awstats. Please follow the steps one by one ;-)

1. Need to download the log files stored in the S3 bucket. For this I had to use the a python script done by wpstorm.net but I had to make some modification so that it worked for me. Please follow the blog post if you need any help setting up the required libraries.

get-aws-logs.py

#! /usr/bin/env python
"""Download and delete log files for AWS S3 / CloudFront

Usage: python get-aws-logs.py [options]

Options:
  -b ..., --bucket=...    AWS Bucket
  -p ..., --prefix=...    AWS Key Prefix
  -a ..., --access=...    AWS Access Key ID
  -s ..., --secret=...    AWS Secret Access Key
  -l ..., --local=...     Local Download Path
  -h, --help              Show this help
  -d                      Show debugging information while parsing

Examples:
  get-aws-logs.py -b eqxlogs
  get-aws-logs.py --bucket=eqxlogs
  get-aws-logs.py -p logs/cdn.example.com/
  get-aws-logs.py --prefix=logs/cdn.example.com/

This program requires the boto module for Python to be installed.
"""

__author__ = "Johan Steen (http://www.artstorm.net/)"
__version__ = "0.5.0"
__date__ = "28 Nov 2010"

import boto
import getopt
import sys, os
from boto.s3.key import Key

_debug = 0

class get_logs:
    """Download log files from the specified bucket and path and then delete them from the bucket.
    Uses: http://boto.s3.amazonaws.com/index.html
    """
    # Set default values
    AWS_BUCKET_NAME = '{AWS_BUCKET_NAME}'
    AWS_KEY_PREFIX = ''
    AWS_ACCESS_KEY_ID = '{AWS_ACCESS_KEY_ID}'
    AWS_SECRET_ACCESS_KEY = '{AWS_SECRET_ACCESS_KEY}'
    LOCAL_PATH = '/tmp'
    # Don't change below here
    s3_conn = None
    bucket = None
    bucket_list = None

    def __init__(self):
        s3_conn = None
        bucket_list = None
        bucket = None

    def start(self):
        """Connect, get file list, copy and delete the logs"""
        self.s3Connect()
        self.getList()
        self.copyFiles()

    def s3Connect(self):
        """Creates a S3 Connection Object"""
        self.s3_conn = boto.connect_s3(self.AWS_ACCESS_KEY_ID, self.AWS_SECRET_ACCESS_KEY)

    def getList(self):
        """Connects to the bucket and then gets a list of all keys available with the chosen prefix"""
        self.bucket = self.s3_conn.get_bucket(self.AWS_BUCKET_NAME)
        self.bucket_list = self.bucket.list(self.AWS_KEY_PREFIX)

    def copyFiles(self):
        """Creates a local folder if not already exists and then download all keys and deletes them from the bucket"""
        # Using makedirs as it's recursive
        if not os.path.exists(self.LOCAL_PATH):
            os.makedirs(self.LOCAL_PATH)
        for key_list in self.bucket_list:
            key = str(key_list.key)
            # Get the log filename (L[-1] can be used to access the last item in a list).
            filename = key.split('/')[-1]
            # check if file exists locally, if not: download it
            if not os.path.exists(self.LOCAL_PATH+filename):
                key_list.get_contents_to_filename(self.LOCAL_PATH+filename)
                print "Downloaded				"+filename
            # check so file is downloaded, if so: delete from bucket
            if os.path.exists(self.LOCAL_PATH+filename):
                key_list.copy(self.bucket,'archive/'+key_list.key)
                print "Moved					"+filename
                key_list.delete()
                print "Deleted					"+filename

def usage():
    print __doc__

def main(argv):
    try:
        opts, args = getopt.getopt(argv, "hb:p:l:a:s:d", ["help", "bucket=", "prefix=", "local=", "access=", "secret="])
    except getopt.GetoptError:
        usage()
        sys.exit(2)
    logs = get_logs()
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt == '-d':
            global _debug
            _debug = 1
        elif opt in ("-b", "--bucket"):
            logs.AWS_BUCKET_NAME = arg
        elif opt in ("-p", "--prefix"):
            logs.AWS_KEY_PREFIX = arg
        elif opt in ("-a", "--access"):
            logs.AWS_ACCESS_KEY_ID = arg
        elif opt in ("-s", "--secret"):
            logs.AWS_SECRET_ACCESS_KEY = arg
        elif opt in ("-l", "--local"):
            logs.LOCAL_PATH = arg
    logs.start()

if __name__ == "__main__":
    main(sys.argv[1:])

Note: The above script will download the s3 logs to specified folder. Please make sure you put your Amazon access keys.

2. Now we have bash script which will uses the above python script to download the log files and combine all of them into a single log file and then it will be analyzed by awstats.

Warning: Please read through the script files and make necessary changes needed.
Note: You should have awstats installed on your system. The bellow script uses awstats.
Note: You can download the script files at the end of this blog post where awstats configuration with custom setup for cloudfront log format is also provided.

get-aws-logs.sh

#!/bin/bash
# Initial, cron script to download and merge AWS logs
# 29/11 - 2010, Johan Steen

# 1. Setup variables
date=`date +%Y-%m-%d`
static_folder="/tmp/log_static_$date/"

mkdir -pv $static_folder
python /var/www/scripts/get-aws-logs.py --prefix=logs/www.imthi.com --local=$static_folder
gunzip --quiet  ${static_folder}*

/usr/local/awstats/tools/logresolvemerge.pl ${static_folder}* | sed -r -e 's/([0-9]{4}-[0-9]{2}-[0-9]{2})\t([0-9]{2}:[0-9]{2}:[0-9]{2})/\1 \2/g'  >> /var/www/logs/www.imthi.com.log

rm -vrf $static_folder
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -config=imthi -update

I would suggest you to test run the above scripts on a staging / testing environment before moving to a production. Again please change the scripts with your domain details and Amazon access keys.

Download the scripts to download and process Amazon Cloudfront Logs with Awstats.

Have a nice journey exploring the cloud ;-)

UIScreen Notifications for connecting external display in iOS

UIScreen class has three main notifications which gets triggered when a new screen (external display) is attached to the device.

UIScreenDidConnectNotification

This notification is posted when a new screen is connected to the device. The object of the notification is the UIScreen object representing the new screen. There is no userInfo dictionary. Connection notifications are not sent for screens that are already present when the application is launched. The application can instead use the screens method to get the current set of screens at launch time.

UIScreenDidDisconnectNotification

This notification is posted when a screen is disconnected from the device. The object of the notification is the UIScreen object that represented the now disconnected screen. There is no userInfo dictionary.

UIScreenModeDidChangeNotification

This notification is posted when the current mode of a screen changes. The object of the notification is the UIScreen object whose currentMode property changed. There is no userInfo dictionary. Clients can use this notification to detect changes in the screen resolution.

Simple code to listen to the notification


- (void)awakeFromNib{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(screenDidConnect:) name:UIScreenDidConnectNotification object:nil];
    [center addObserver:self selector:@selector(screenDidDisconnect:) name:UIScreenDidDisconnectNotification object:nil];
    [center addObserver:self selector:@selector(screenModeDidChange:) name:UIScreenModeDidChangeNotification object:nil];
}

- (void) screenDidConnect:(NSNotification *)aNotification{
    NSLog(@"A new screen got connected: %@", [aNotification object]);
}

- (void) screenDidDisconnect:(NSNotification *)aNotification{
    NSLog(@"A screen got disconnected: %@", [aNotification object]);
}

- (void) screenModeDidChange:(NSNotification *)aNotification{
    UIScreen *someScreen = [aNotification object];
    NSLog(@"The screen mode for a screen did change: %@", [someScreen currentMode]);

}

- (void)dealloc{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center removeObserver:self name:UIScreenDidConnectNotification object:nil];
    [center removeObserver:self name:UIScreenDidDisconnectNotification object:nil];
    [center removeObserver:self name:UIScreenModeDidChangeNotification object:nil];
	//....
	[super dealloc];
}

If anyone is interested in screen mirroring in iPhone / iPad check this UIScreen Additions.

Working with Amazon Web Services (AWS)

Today I started my journey to explore and learn more about Amazon Web Services (AWS). My mission is to setup a wordpress blog completely in the cloud. This blog post is just a mention about the journey and will be posting things in detail in the days to come.

What I did so far as follows..

  • Created a new EC2 instance with Basic 32-bit Amazon Linux
  • Logged into the instance and installed Apache, PHP and mysql client tools
  • Created a new RDS instance with mysql version 5.1.50
  • Added EC2 instance IP in RDS for allowing access.
  • Installed wordpress on the EC2 instance and configured the database
  • Created a new elastic volume storage for 1GB and attached the same to EC2 instance
  • Formatted the elastic volume storage and mounted the same for wordpress upload directory.
  • Created a new Elastic IP and attached the EC2 instance to the IP.
  • Created a cname cloud for imthi.com and pointed the A level record to the Elastic IP
  • The blog cloud.imthi.com is ready that is hosted in Amazon cloud :-)

Phew, trust me it was not easy and I had to create and delete many EC2 instances to understand how things work. I am not sure whether the setup I had done is the best way.. I did some load test on the setup and it was not looking good

My next mission is to fire up multiple EC2 instances and to use a load balancer to handle the load so that the graph will look better in the days to come ;-)

iPhone RSS Reader with source code

Last week I had prepared simple RSSReader application for demoing at Arabnet Shift Digital Summit. Since there was not much time to really explain I had to cut short my presentation with a very basic application demo. I promised to few programmers at Arabnet that I will release the source code for this application on my blog.

Unlike my previous version of RSSReader this version is much cleaner and simple to understand. Removed lots of unwanted methods and made it as simple as possible to understand. When I released the last RSSReader code I received lots of emails asking for updates and some people wanted to fix and update few things to it. To enable all this I am releasing this source code at gitHub.

https://github.com/hmimthiaz/RSSReader

This source code does not have any license nor warranty. Please feel free to use this in any of your projects and don’t have to email me.

Enjoy, Happy Coding ;-)