Blog

Home Server Setup – Useful Links

I’ve mentioned in a couple of previous posts that I’ve refreshed my home server recently. In setting everything up I spent a lot of time googling around looking for information on how to do things that for the most part I’d done before on my previous server.

To help me avoid future googling if/when I need to go through this process again, I’ve been creating a whole bunch of bookmarks this time around. I thought I’d share them in case they’re useful to anybody else.

oVirt Hypervisor

Linux Server

Windows Server

Blog

Learn Version Control with Git

Recently I’ve been reading the eBook “Learn Version Control with Git” online, and I’d recommend it.

image

I’ve been using Git for a while, but certainly not to its full potential, and not even really for its intended purpose. The book is great because it:

“…doesn’t require a master’s degree in computer science to read it. It’s aimed at beginners of programming, at designers, at project managers… It tries not to require too much prior knowledge on the technical side. It tries to go slowly.”

You can read it online for free, or purchase it in PDF, ePub or Mobi format for your device.

Enjoy!

Blog

Why Great Ideas Always Come In the Shower (and How to Harness Them)

Never in my life have I had a good idea in a meeting.

All my good ideas come at other times. During my commute, when I’m out for a walk, and – of course – when I’m in the shower.

Why Great Ideas Always Come In the Shower (and How to Harness Them)

Blog

The Monkey Parable

My friend Andrew told me what I now call “the monkey parable” several years ago, and it’s stuck with me ever since.

There are five monkeys, locked in a cage. There’s a banana hanging from the ceiling and a ladder set up on the floor.

Predictably, one of the monkeys immediately starts to climb the ladder in an attempt to get the banana, at which point *FOOOSH* the monkey gets sprayed with icy-cold water from a hose. This repeats as the other monkeys try climbing the ladder, only to each get sprayed. The monkeys give up, resigning themselves to the fact that the banana is unobtainable.

Next, one of the monkeys in the cage gets replaced. The new monkey sees the banana and the ladder and starts to climb. Right away the other four monkeys, familiar with the consequences grab the new guy, pull him off the ladder and beat him. New guy gets the message – the banana is off-limits.

This process then repeats as, over time, each of the monkeys gets replaced. Each new monkey’s first instinct is to reach for the banana, at which point he’s immediately grabbed and pulled away by his peers.

Eventually, none of the original monkeys are left. There are still five monkeys in the cage, but none of them have ever been sprayed by the hose, and none of them are attempting to get the banana hanging from the ceiling.

When another new monkey is introduced to the cage and is prevented from attempting to reach the banana he’s confused, and he asks the existing monkeys why they beat him when he tries. The other four monkeys shrug their shoulders.

“Don’t know, but that’s the way we do things around here.”

You may be able to draw parallels between this and process improvement initiatives you’ve attempted to run. I certainly can. This parable illustrates one of what I believe are the two most poisonous BPR dangers, and I’ll be writing more about them both in the not too distant future.

Watch this space!

Blog

The Monkey Parable

My friend Andrew told me what I now call “the monkey parable” several years ago, and it’s stuck with me ever since.

There are five monkeys, locked in a cage. There’s a banana hanging from the ceiling and a ladder set up on the floor.

Predictably, one of the monkeys immediately starts to climb the ladder in an attempt to get the banana, at which point *FOOOSH* the monkey gets sprayed with icy-cold water from a hose. This repeats as the other monkeys try climbing the ladder, only to each get sprayed. The monkeys give up, resigning themselves to the fact that the banana is unobtainable.

Next, one of the monkeys in the cage gets replaced. The new monkey sees the banana and the ladder and starts to climb. Right away the other four monkeys, familiar with the consequences grab the new guy, pull him off the ladder and beat him. New guy gets the message – the banana is off-limits.

This process then repeats as, over time, each of the monkeys gets replaced. Each new monkey’s first instinct is to reach for the banana, at which point he’s immediately grabbed and pulled away by his peers.

Eventually, none of the original monkeys are left. There are still five monkeys in the cage, but none of them have ever been sprayed by the hose, and none of them are attempting to get the banana hanging from the ceiling.

When another new monkey is introduced to the cage and is prevented from attempting to reach the banana he’s confused, and he asks the existing monkeys why they beat him when he tries. The other four monkeys shrug their shoulders.

“Don’t know, but that’s the way we do things around here.”

You may be able to draw parallels between this and process improvement initiatives you’ve attempted to run. I certainly can. This parable illustrates one of what I believe are the two most poisonous BPR dangers, and I’ll be writing more about them both in the not too distant future.

Watch this space!

Blog

New Home Server Setup

As I mentioned briefly in a previous post, my home server is in desperate need of an update. Last weekend I took the plunge and bought the hardware necessary to build a replacement.

I don’t need anything especially powerful – the chief function of this device is as network-attached storage – but I do want room to grow and do things with this new server that weren’t possible with the hacked pogoplug device I was using previously.

image

I bought a Celeron-powered Intel NUC, a 750gb harddrive, 8gb of RAM and an 8gb USB drive. My intent was to use the 8gb drive as the boot device, keeping the harddrive entirely free for storage purposes.

I chose the Intel NUC primarily because of its small size and low power consumption (it uses a particularly small amount of electricity with the Celeron processor in the model I opted for). I’m a big fan of this platform though, and when the time comes to replace the media-centre PC that lives underneath the TV in our living room I will probably buy another one of these. That said, the platform is not not without its problems. Read on, to learn how I set mine up.

Hardware Installation

First things first is hardware installation, and this was especially simple. You remove four screws from the base of the computer and the lid slides off. Inside you’ll find a metal chassis for the 2.5” HDD, and you lift that out to revel the motherboard.

image

In my model of NUC there’s a single SODIMM slot for the RAM, so I slotted that in. Next up is the HDD itself. The chassis includes brackets to hold the drive in place and the power and data connectors are already positioned. The drive just slots in, and you insert a couple of screws to hold it in place.

image

And that’s really all there is to it! You put the cover back on, and tighten the four screws on the base of the unit. Done.

BIOS Update

The first thing to do is update the system’s BIOS, and this really is an essential step. This thing comes with Intel’s visual BIOS, and the version it ships with has some issues.

image

Updating isn’t difficult: Head on over to Intel’s website, download the latest firmware and put it on a USB drive, boot into the BIOS and hit F7.

Even with the latest version installed, the BIOS is where this thing falls down, in my opinion. If you’re planning on installing Windows 7 or 8 on this thing then you probably won’t run into any problems. My plan was to install an alternate OS though, and I ran into a whole bunch of issues. I believe this was because of bugs in the BIOS and its implementation of EFI, but I don’t know enough to say this for sure.

Software Installation

My plan was to install vSphere Hypervisor and use this thing to host a couple of virtual servers. vSphere has a hardware compatibility list and none of my hardware is on it, but I’d done some reading and learned that I could slipstream drivers for the HDD and network card into the install. Nevertheless, I never did manage to install vSphere – the install just froze every time and I couldn’t get through it no matter what I tried.

The next hypervisor I tried was Proxmox VE. The install completed just fine, but I couldn’t get the server to boot. While the problems I had with vSphere may well have been in relation to my use of unsupported hardware, I firmly believe my problems installing Proxmox were related to the BIOS, or at least an incompatibility between the EFI implementation in Proxmox’s version of the Linux kernel and the BIOS’ EFI implementation. I never did manage to get this working either, except for briefly with a cludgy workaround involving booting from a live-CD and entering the relevant commands to make GRUB boot the OS installed on the HDD instead.

After a day of frustration and failed attempts to install an OS, I moved on to my third VM hypervisor, oVirt. With vSphere’s proprietary solution the OS and the hypervisor are closely intertwined. It’s possible to install Proxmox on top of an existing Debian install, but it’s not the recommended way of doing things and the process seems complex. oVirt, by contrast, seems to have been designed to be installed on top of an installation of CentOS. An all-in-one install image is offered, but after the previous day’s failures I didn’t even bother with this – I did a (successful!) minimal install of CentOS and then used the yum package manager to add oVirt on top.

With the hypervisor up and running, I used the web-interface to install Ubuntu Server into one VM and Windows Server 2008 into another. I plan on adding two more virtual machines, one Linux and one Windows, for testing and playing around.

image

Blog

Kaizen Widsom

See, I do have my occasional moments of profanity profoundness!

We were talking yesterday morning about an upcoming Kaizen event that one of my colleagues will be running as part of a process improvement initiative that she’s spearheading. Apparently there’s a whole blame game thing going on between the groups that participate in the process over why it’s broken, and she’s concerned this might influence the way her event unfolds.

This was my advice: Acknowledge in the introduction that there are issues, but affirm that everyone in the room owns the whole process (even though they may only be a subject matter expert for a part of it). Recognize that all the participants are there because they see there’s a problem, but certainly not because they are the problem. Quite the opposite, in fact.

Blog

Making Google Analytics Work for Me (and You)

When I put my website together back whenever it was that I did that, I knew I wanted to get analytics from it: at the beginning the site was fairly simple (this blog, for example, was an entirely separate entity back then and it wasn’t integrated into the site in the way it is today), but from the start I wanted to know how many visitors I was getting, where they were in the world, how they were finding me, and a little about how they were interacting with my site.

I’d used Google Analytics on past projects, but this time around I felt a little uneasy about providing Google with an easy way to gather data on all my site visitors. Those guys have enough power without me contributing. I went with clicky.com for my analytics, and all was well.

In researching this post I found an article called Seven Reasons Why You Should NOT Use Google Analytics. My concerns about giving Google too much power rank number four in their list, but they ultimately reach the same conclusion I did – Google’s product offering in this space is simply better than the alternatives out there, especially when you consider the price (free). With Clicky the basic service is free but limited – you need to fork over some cash if your site generates a lot of traffic, or you want to retain data for longer than 31 days, or add advanced features… the list goes on.

I switched back to Google’s service a couple of weeks ago and I haven’t looked back. While I was at it I not only added the relevant code to this site, I also added it to Flo’s blog and the jnf.me landing page. Clicky limited me to tracking a single site but Google doesn’t, so why not?

image

For a website like mine adding the relevant JavaScript to the site and then forgetting about it is a reasonable approach, but I’ve discovered very quickly that if you’re prepared to put in a little more effort then you can get much improved results. For me, this was highlighted by the extremely limited usefulness of the data I’ve been getting from JNF.me, but the way I’m solving that problem could apply anywhere. Read on!

The Problem

When I bought the domain jnf.me my primary concern was getting something short. My plan all along was to use sub-domains for the various bits of content that lived under it (www.jason.jnf.me, www.asiancwgrl.jnf.me, and so on). The J stands for Jason, the F for Flo, and the N for ‘n, but that’s not really relevant. Since it is the root of my domain, I knew I should put something there so I created a quick, fairly simple, single-page site. The page is divided into two with me on the left and Flo on the right, and if you click one of our faces then the whole thing slides over to reveal a little about us and some links to our online content.

In terms of analytics data, the very fact that this is a single-page site is what’s causing issues. With a larger like jason.jnf.me even taking the most basic approach to installing Google Analytics tells me, for example, that the average visitor views three pages. I know which pages are the most popular, which blog topics generate the most interest, and so on.

With JNF.me I know that people visit the page and then their next action is to leave again – but of course it is, there is only that one page.

What are they doing while they’re there? Are they leaving through one of the links on the page? I have no idea, but I can find out.

Manually Sending Pageviews

The first thing I opted to do was manually send a pageview to Google Analytics when somebody clicks one of our pictures to slide out the relevant content from the side of the page.

My rationale for this approach is that if this were a site with a more traditional design, clicking a link to view more content from the site would indeed cause another page to be loaded. The fact that my fancy design results in the content sliding in from the side instead really makes no difference.

The approach is extremely simple, and adding a single line of JavaScript to the code that makes the content slide in is all it took:

ga('send', 'pageview', {'page': '/' + p });

So how does this work? ga() is a function that Google Analytics creates when it’s first loaded by the page, and in fact if you’re using Google Analytics at all then you’re already using this. Let’s take a quick look at the code Google has you paste into your page in order to start feeding data to Analytics in the first place. It ends with these two lines:

ga('create', 'UA-XXXXXXXX-X', 'auto');
ga('send', 'pageview');

The first line initializes things and lets Google know (via the UA-XXXXXXXX-X bit) which Analytics account it’s going to be getting data for. The second line sends a pageview to Analytics because, well, if the code is being executed then that means somebody is viewing the page.

By default Analytics makes the perfectly reasonable assumption that the page that executes this code is the one it should be recording a pageview for, but here’s the thing: it doesn’t have be that way.

Back to my example, and you’ll notice I’ve added a third argument to the ga() function call. Google’s help page on the subject discusses the options in terms of possible parameters, but essentially what I’m doing is passing a JavaScript object that describes exactly what Analytics should track. The page field is the page address against which a pageview is registered, and the p variable is used elsewhere in my code that makes the sliding content work: it stands for person, and it contains either “jason” or “flo” as appropriate.

The important thing to note here is that these pages don’t exist – there is nothing on my website at either /jason or /flo – but this doesn’t matter. Analytics registers a pageview for one of these addresses anyway, and I know when I see it in my data that it means that somebody opened the sliding content.

Sending Events

In addition to sending pageviews to Analytics you can also send events, and this is the approach I took to help me understand how people are leaving the page.

When I first started learning about events I spent some time trying to understand the right way to use them. Google’s Event Tracking help page provides an example, and you can find some good reading material about it on the web. The conclusion I’ve reached from my brief research is that there is no “right” way to use events – you just define them in whatever way works best for you, your site, and your desired outcome.

The important thing to know is that events have, as a minimum, an associated category and action. You can also optionally define a label and a value.

I can see that the value parameter would be extremely useful in some scenarios, such as tracking e-commerce sales (you could, for example, use Analytics to track which traffic sources result in the highest sales figures in this way) but I don’t need that. I will be using the other three parameters, though.

When you view data regarding events in the Analytics interface, they’re in something of a hierarchical structure. Categories are treated separately from one another, but you can view summary data at the category level, then drill-down to segment that data by action, then drill down further to segment by label.

For the events fired when a site visitor clicks an external link on my page I arbitrarily decided that the category would be ‘extlink,’ the action would be the person the link relates to (either jason or flo), and the label would be indicative of the link destination itself (blog, twitter, etc).

To implement this, the first thing I did was add a class and a custom data attribute to the links on the page:

<a href="http://twitter.com/JayWll" class="outbound" data-track="jason/twitter">Twitter</a>

The class of outbound defines this as an outbound link as opposed to one of the links that helps visitors navigate around the page, slide content in and out, etc, and the data-track attribute defines what will become the event’s action and label.

Next, the JavaScript. This time around it’s slightly more in-depth than the single line of code we used to send a pageview. That’s not necessarily a function of events as compared to pageviews, but it’s due to the nature of what I’m tracking here: when a user clicks a link that takes them away from the current page, they (by default) leave immediately. In order to track outbound links, I actually need to hold them up and make sure the event is registered with Analytics before I let them go anywhere. Happily, Google has thought of that and the ga() function accepts a hitCallback property. This is a function that’s fired only once the event has been properly recorded.

Here’s my code:

$('a.outbound').click(function(e) {
   e.preventDefault();
   trURL = $(this).attr('data-track');
   nvURL = $(this).attr('href');

   ga('send', 'event', {
      'eventCategory': 'extlink',
      'eventAction': trURL.split('/')[0],
      'eventLabel': trURL.split('/')[1],
      'nonInteraction': 1,
      'hitCallback': function() {
         location.href = nvURL;
      }
   });
});

The first thing I do is prevent the link’s default behaviour with the line

e.preventDefault();

Next, I capture the link’s data-track and href attributes – we’ll need both of those later.

Finally, we’re back to the ga() function to send data to Analytics. We send an event, and define its parameters within the JavaScript object: the category is ‘extlink,’ the action and label are obtained by splitting the link’s data-track attribute, we define this as a non-interaction event (LMGTFY) and, once this data has been successfully sent, the hitCallback function is executed which takes us to the page specified by the link’s href attribute.

Easy, when you know how.

Taking it Further

The possibilities here are endless, and how use them really depends on your site and the data you’d like to get from it. My plan is to take some of what I’ve learned for jnf.me and extend it to this site, particularly in regards to event tracking.

In addition to tracking outbound links, I have two other ideas for how I might use this:

  1. Page length and scroll tracking
    Some of my posts – this one is potentially a prime example – are pretty long. I do tend to ramble on a bit at times. If a post is more than, say, two screen heights in length then I could track how many people scroll beyond the halfway point and how many people scroll to the end to help me understand if my audience is OK with long posts or if I should split in-depth content into some kind of mini-series.
  2. Form tracking
    There’s a contact me page on this site, and each post in this blog has a comment form at the bottom. With events I could gain a much better understanding of how these are working and how visitors interact with these forms. For example, do people begin filling out the contact me form but then abandon it at some point before submitting? Do people begin to write comments on my posts but then refrain from posting it when they find out I require them to at least provide their email address?

Hopefully you have ideas for how you can use these techniques to provide better insight into visitor behaviour on your site too. Come back here and leave a comment to let me know how it goes! I do require your email address for that, but I promise not to spam you or pass it on to any third party.