Pages

Friday, 28 February 2014

How to add Google +1 to Your tumblr Theme

You can easily add a Google +1 button to your Tumblr theme, all you have to do is to follow the next steps:

  • Go to Google’s +1 Button page and use the customisation panel to style your +1 button.

  • Once you’re done, copy the second part of the code located on the right, which looks like this:

    <!-- Place this tag after the last +1 button tag. -->
    <script type="text/javascript">
    (function() {
        var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
        po.src = 'https://apis.google.com/js/platform.js';
        var s = document.getElementsByTagName('script')[0];             s.parentNode.insertBefore(po, s);
    })();
    </script> 
    

    You should place this code snippet just before the </body> tag.

To add a +1 button for your entire blog:

Copy the first part of the code snippet, add data-url=“{BlogURL}” and add it to your blog.

<div class="g-plusone" data-size="medium" data-url="{BlogURL}"></div>

To add a +1 button to every post:

Copy the first part of the code snippet, add data-url=“{Permalink}” and add it to your blog between each {block:…} … {/block:…} section.

{block:Text} 
    <div class="g-plusone" data-size="medium" data-href="{Permalink}" data-annotation="none"></div>
{/block:Text}

Thursday, 27 February 2014

Syntax highlighting of code snippets in Tumblr

In this blog I use Google code prettify for syntax highlighting.

The setup for Tumblr is pretty easy:

  1. Go to your template and choose Edit HTML, right below the <body> tag add:

    <script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=sunburst"></script>
    

    Note: the skin parameter is optional, different skins are available here.

  2. Choose avandced options (at the bottom of the customize pane) and add this under Add Custom CSS

    h4 {
        font-size: 18px;
    }
    
    pre {
        overflow: auto;
    
        white-space: pre-wrap;       /* css-3 */
        white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
        white-space: -pre-wrap;      /* Opera 4-6 */
        white-space: -o-pre-wrap;    /* Opera 7 */
        word-wrap: break-word;       /* Internet Explorer 5.5+ */
    }
    
    .prettyprint {
        font-size: 10pt;
    }
    
  3. Wrap your code in a code block

    <pre class="prettyprint"><code>
        ...Some code...
    </code></pre>
    

Optional: specify the code language:

<pre class="prettyprint lang-java"> 
    ...Some java code..     
</pre>

Optional: add line numbers:

<pre class="prettyprint linenums">
    ...Some java code..     
</pre>

References:

Wednesday, 26 February 2014

Setting up a static ip on Arch Linux

The current Arch release comes with netctl enabled out of the box, so we will use that for our setup.
  • Create a new netctl profile and open it in your editor.
    sudo cp /etc/netctl/examples/ethernet-static /etc/netctl/static
    sudo vim /etc/netctl/static
    
  • Adjust the config file to your network setup. Here’s an example:
    Description='A basic static ethernet connection'
    Interface=eth0
    Connection=ethernet
    
    IP=static
    Address=('192.168.1.31/24')
    #Routes=('192.168.0.0/24 via 192.168.1.2')
    Gateway='192.168.1.1'
    DNS=('192.168.1.1')
    
  • Execute
    netctl enable static
    netctl start static
    
If you reboot you RPI to test this setup you’ll notice that it reboots fine, but when it comes up, you’ll end up with another ip?

Apparently your Pi is still using a DHCP config!?

However, if you execute systemctl is-enabled dhcpcd it will tell you that that service is disabled.
You can also use systemctl –type=service to ensure that no other service is running that may want to configure the network. Now, if you execute this command you’ll notice a service in the returned list called netctl-ifplugd@eth0.service

Here’s what the documentation tells you about that service:

Automatic switching of profiles
netctl provides two special systemd services for automatic switching of profiles:
  • For wired interfaces: netctl-ifplugd@interface.service. Using this netctl profiles change as you plug the cable in and out.
  • For wireless interfaces: netctl-auto@interface.service. Using this netctl profiles change as you move from range of one network into range of other network.
A few lines below, you also find the following statement:
netctl-ifplugd@interface.service will prefer profiles which use DHCP. To prefer a profile with a static IP, you can use AutoWired=yes

That was my ‘aha erlebnis’! So as long as you don’t add AutoWired=yes to your config, it will use a DHCP profile, if available.
  • Adjust your config to:
    Description='A basic static ethernet connection'
    Interface=eth0
    Connection=ethernet
    
    AutoWired=yes
    
    IP=static
    Address=('192.168.1.31/24')
    #Routes=('192.168.0.0/24 via 192.168.1.2')
    Gateway='192.168.1.1'
    DNS=('192.168.1.1')
    
Reboot and you’re all set!

Tuesday, 25 February 2014

Resolve hostname with Arch linux on a Raspberry Pi

Note: you can change your hostname by editing: /etc/hostname

  • Install the following packages on your Raspberry Pi:

    sudo pacman -S avahi nss-mdns
    
  • Start the avahi daemon:

    sudo systemctl enable avahi-daemon.service
    sudo systemctl start avahi-daemon.service
    
  • Edit /etc/nsswitch.conf

    sudo vim /etc/nsswitch.conf
    

    Change the line:
    hosts: files myhostname dns
    to
    hosts: files myhostname mdns_minimal [NOTFOUND=return] dns

  • Reboot

From now on you will be able to access your Pi through your hostname (don’t forget to add .local).
For example:

ssh archuser@arch-pi.local

ping arch-pi.local

Reference: https://wiki.archlinux.org/index.php/avahi

Monday, 24 February 2014

Setup Arch Linux on Raspberry Pi

After you finished the setup of Arch on your SD card, you can start configuring this Linux Distro to your needs. Here’s my config…
Note: In case you need to resize your root partition it’s best to do it before you do anything else, this way you avoid the risk to loose any data. You can find a tutorial to this here.

Configure Arch

Change Root Password
passwd 
Update all packages
pacman -Syu 
Install some extra handy packages. These are all optional except for the sudo package. I use vim as my default editor, change it to nano if that’s your editor of choice.
pacman -S sudo screen vim git htop tmux

Setting up correct time

Install Network Time Protocol
pacman -S ntp 
Install the NTP service
systemctl enable ntpd.service 
Enable NTP
timedatectl set-ntp 1 
Check your time settings
timedatectl status
Check your time zone. If it is not correct, call the list of available time zones (<space> for next page, <b> for previous page, <q> to quit):
timedatectl list-timezones
Set your time zone
timedatectl set-timezone Europe/Brussels

Add a new user

It’s a best practice to create a new user instead of doing everything under root.
  • Add a new user (ex. pi)
    useradd -m -g users -s /bin/bash pi
    
  • Set the password for the new user
    passwd pi
    
  • Allow your new user to use sudo
    EDITOR=vim visudo
    
  • Search for root ALL=(ALL) ALL and add the following line just below:
    pi   ALL=(ALL) ALL
    

Configure your environment

Add Color to your Bash Prompt

  • Go to https://wiki.archlinux.org/index.php/Color_Bash_Prompt and copy the text located under /etc/bash.bashrc somewhere in the middle of the page. Then open your .bashrc in your editor:
    sudo vim ~/.bashrc
    
  • Paste the copied text in this file. At the bottom of the file add the following line to set your default editor:
    export EDITOR=vim
    
  • Save and quit.
  • Go back to your browser (https://wiki.archlinux.org/index.php/Color_Bash_Prompt) and copy the text under /etc/DIR_COLORS and create a new file:
    sudo vim /etc/DIR_COLORS
    
  • Paste the copied text in this file, save and quit.
  • Open /etc/pacman.conf
    sudo vim /etc/pacman.conf
    
  • Uncomment the #Color line.
  • Save and quit.

Change your hostname

sudo vim /etc/hostname
change alarmpi to [your_new_hostname]

Get yourself a nice Welcome Screen

  • Install Archey
    sudo pacman -S yaourt
    yaourt archey
    
  • Choose option 1
  • Launch Archey on startup
    sudo vim .bash_profile
    
  • Add 'command archey3' at the beginning of the file.
  • Save and quit.

Take a backup

On linux you can use something like this:
  • Locate your SD card:
    sudo fdisk -l
    
  • Backup the card:
    sudo dd bs=4M if=/dev/sdf | gzip > /home/macuser/image-arch-`date +%d%m%y`.gz
    
  • (Restore:)
    sudo gzip -dc /home/macuser/image.gz | sudo dd bs=4M of=/dev/sdf
    
In my next post I will cover the network config on Arch.

Saturday, 15 February 2014

Static website hosting on Amazon S3 and Google Apps configuration

Static Web Hosting With Amazon S3


It seems that Amazon S3 is a great choice to host static websites. The setup is quite easy, all you have to do to set it up, is to follow these nice tutorials:
If you want to know more about setting up a static website with Amazon S3 you can find some extra info here.

Configuring Amazon Route 53 for Google Apps


The moment I setup Google Apps, I also purchased a domain name. At that moment Google configured this domain behind the scenes through Enom.

As described above and in order to get your static website up and running on S3, it is key to configure Amazon Route 53 as your Domain Name System (DNS). The how-to is described in detail in step 3 and 4 of the Amazons static website hosting walkthrough.

In case of a Google Domain name registration through Enom, your configuration will consist the following steps:
  1. Go to the Google Apps Admin Console
  2. Select Domains
  3. Go to Advanced DNS settings

  4. Follow the instruction to get access to Enom’s Domain Management
  5. Change Enom’s DNS settings from Default to Custom
  6. Fill in the DNS servers names copied from Amazon

By now your website should be online and accessible through your domain name. The only thing missing is the conversion of the MX records from Enom to Amazon’s Route 53. Without this conversion it will be impossible to deliver your domain’s emails.

The conversion of the MX records is also quite easy:
  1. Go to Amazon Route 53
  2. Select your Hosted zone
  3. Select Go to Record sets
  4. Click the Create Record set button.


Fill in the following values:
  • name: blank
  • type: MX
  • Alias: No
  • TTL: 300
  • Value: MX record values
  • Routing Policy: Simple

Save the record. You’re all set!

Sunday, 9 February 2014

How to Configure Logstash to handle Glassfish’s server logs

Logstash is a nice tool for managing events and logs. After you finished the setup, the next step is the configuration of the agents/shippers. Since one of the strengths of logstash is the ability to query your logs and make some nice statistics about them, it is key to ‘convert’ your logs somehow in a more structured way. Here’s a little example on how to do this…
The configuration of a shipper is done through a config file (ex. logstash.conf). Below is an example to handle Glassfish’s server log.
input {
    file {
        codec => multiline {
            'negate' => true
            'pattern' => '^\[\#\|\d{4}'
            'patterns_dir' => '/opt/logstash/agent/etc/patterns'
            'what' => 'previous'
        }
        'path' => '/var/log/glassfish/greyhound/server.log'
        'type' => 'glassfish'
    }
}

filter {
    mutate {
        'add_field' => ['application', '%{type}']
    }

    if [message] =~ /\[GLF_INT\]/ {
        mutate {
            'update' => ['type', 'application']
        }
        grok {
            'keep_empty_captures' => true
            'named_captures_only' => true
            'pattern' => '(?m)\[\#\|%{TIMESTAMP_ISO8601:timestamp}\|%{LOGLEVEL}\|%{DATA:server_version}\|%{JAVACLASS}\|%{DATA:thread}\|\[GLF_INT\]%{DATA:category}\|%{DATA:loglevel}\|%{DATA:class}\|line:%{DATA:linenumber}\|%{DATA:message_detail}\|\#\]'
            'patterns_dir' => '/opt/logstash/agent/etc/patterns'
        }
    } else {
        mutate {
            'add_field' => ['category', 'technical']
            'update' => ['type', 'internal']
        }
        grok {
            'keep_empty_captures' => true
            'named_captures_only' => true
            'pattern' => '(?m)\[\#\|%{TIMESTAMP_ISO8601:timestamp}\|%{LOGLEVEL:loglevel}\|%{DATA:server_version}\|%{JAVACLASS:class}\|%{DATA:thread}\|%{DATA:message_detail}\|\#\]'
    'patterns_dir' => '/opt/logstash/agent/etc/patterns'
        }
    }

    if [type] == 'application' and [category] == '' {
        mutate {
            'update' => ['category', 'technical']
        }
    }

    date {
        'match' => ['timestamp', 'ISO8601']
    }
}

output {
    redis {
        'data_type' => 'list'
        'host' => '172.168.1.250'
        'key' => 'logstash'
    }
}
This file is also available on Github: https://gist.github.com/glnds/8774267


Some remarks

Multiline filter

By default Logstash will treat every new line from your log as a new event. Since events often consists of multiple lines, you have to tell Logstash how to group multiple lines into a single event. For Glassfish’s server logs the Logstash multiline filter from my example will start a new event for every line starting with ‘[#|’ + 4 digits. You can easily test this here: http://rubular.com

Grok that log

One of the basic things you’ll do with your logs is applying a grok filter to them. This process is all about parsing the arbitrary text and structure it.
Here are two grok examples based on the above config.
Example 1
[#|2014-02-02T02:08:50.114+0000|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=45;_ThreadName=Thread-2;|[GLF_INT]functional|INFO|com.ex.controller.AuthenticationController|line:148|[LOGIN] Successful re-login with token for user ...|#]
This pattern will be parsed by the first grok pattern (through the occurrence of [GLF_INT]) resulting in the following structure:
{
    "timestamp": ["2014-02-02T02:08:50.114+0000"],
    "server_version": ["glassfish3.1.2"],
    "thread": ["_ThreadID=45;_ThreadName=Thread-2;"],
    "category": ["functional"],
    "loglevel": ["INFO"],
    "class": ["com.ex.controller.AuthenticationController"],
    "linenumber": ["148"],
    "message_detail": ["[LOGIN] Successful re-login with token for user ..."]
} 
Example 2
[#|2014-02-01T17:50:17.139+0000|INFO|glassfish3.1.2|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=1;_ThreadName=Thread-2;|GlassFish Server Open Source Edition 3.1.2.2 (5) startup time : Felix (7,359ms), startup services(76,273ms), total(83,632ms)|#]
This pattern will be parsed by the second grok pattern resulting in the following structure:
{
    "timestamp": ["2014-02-01T17:50:17.139+0000"],
    "loglevel": ["INFO"],
    "server_version": ["glassfish3.1.2"],
    "class": ["javax.enterprise.system.core.com.sun.enterprise.v3.server"],
    "thread": ["_ThreadID=1;_ThreadName=Thread-2;"],
    "message_detail": ["GlassFish Server Open Source Edition 3.1.2.2 (5) startup time : Felix (7,359ms), startup services(76,273ms), total(83,632ms)"]
}
Here’s a nice tool to test your own grok patterns: http://grokdebug.herokuapp.com


A Little about SLF4J and Logback

Under the hood my java application is using SLF4J and Logback. Although Logback is not the most common choice, it has a nice advantage compared to other logging frameworks: currently it is the only framework implementing SLF4J Markers. Since my application contains both functional and technical log messages it was a requirement to have both types of messages marked properly in logstash. Although there are multiple solutions to handle this, I solved it through the use of an SLF4J Marker. Here’s an example.
Java Class:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

    ...
    private static final Marker FM = MarkerFactory.getMarker("functional");
    private static final Logger LOG = LoggerFactory.getLogger(AuthenticationController.class);
    ...
    LOG.info(FM, "[LOGIN] Successful login with username/password for user " + user.getName());
    ...
Logback config:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <Pattern>[GLF_INT]%marker|%level|%logger|line:%line|%msg%n</Pattern>
    </layout>
</appender>

Kibana

Here are some screenshots from the end result in kibana:
Kibana Functional Kibana Technical