computer geek gone chef and back again
 
 


graciously hosted by neverblock
http://www.neverblock.com/

blog.josephhall.com


Saturday, May 30, 2009

Replacing AWStats

Don't get me wrong; I've been a big fan of AWStats for years. It's great for giving me a high-level overview of how my sites are doing, traffic-wise. The day-by-day breakdown is nice, and if I don't mind looking at the big picture for my site a month at a time (which is usually good), then it's perfect. When I started working on a more complex setup than just a few low-traffic blogs, then it started to show its limitations. Let me tell you what I mean.

In our current setup at work (or at least the one that we've been moving toward), we have three web servers. Each server is behind a load balancer, and serves exactly the same sites. When I started monitoring, we had 200+ sites active. We wanted to have stats for each domain on each server, plus the stats for each domain across all servers, plus the stats for all domains on each individual server.

AWStats requires one separate config file per domain, per server, plus another separate config file per domain for all servers, plus a separate config for the server-wide stats. That means we're looking at 800+ separate config files. I wrote a script to automatically generate all of these for me, but they're still a pain to keep track of.

Before I parse out the log files, I need to combine multiple log files into massive composite log files (domain-wide and server-wide), in chronological order so that AWStats doesn't choke. As you can imagine, this requires a considerable amount of resources.

AWStats also maintains a flat data file per config file per month, all in the same directory. Assuming we keep just a year's worth of data, we're looking at 9600+ separate files in that directory. At this point, one wonders why we can't just store everything in a database.

Now that you've seen the kind of management nightmare that I have to deal with, with just the features that AWStats does have, I think you can see where my frustrations begin. But I can't be content just being unhappy with existing features; I want new features too. And anybody that's ever looked at the main awstats.pl file knows how much of a beast it is to figure out just what's going on, much less change anything.

I ended up adding some glue of my own to make things a little easier. Remember, not only do I have hundreds of config files and thousands of data files, I also have to pull them up in the first place. As it turns out, the script that I wrote to automate building config files also builds an HTML file with links to all of the AWStats pages in it. I even added a quick ping script to periodically hit each domain, and place a colored dot next to the domain name to indicate its active status (green is good, red is bad, blue and yellow are proprietary indicators that a site responded, but not in a normal manner). I even have other indicators set up to tell me things like whether a site has an SSL cert, today's hits so far, yesterday's hits, green up arrows to tell me if today's hits are higher then yesterdays, red down arrows if they are lower, yellow right arrows if the traffic is the same, you get the idea.

Maybe I'm just selfish, but I want a stats program that can handle all of this gracefully, and for not a lot of money. Free (as in freedom, and beer) is ideal. But since I ultimately decided to write my own, it certainly wasn't free as in time. But it was fun, and I learned a lot about AWStats while I was at it.

Incidentally, it turns out AWStats does support clusters kind of like our load balancer setup, but I didn't find that out until I spent a lot of time in the various parts of it. And I haven't taken the time to figure out how they do it; I already had a solution in mind anyway.

I hope this post gives you an idea of why I started thinking about replacing the great AWStats, I program which I still love and respect. If you're interested in looking at my code so far, I have packed it up for public consumption. Information about its operation and shortcomings are in the README.

Clicky!


Friday, May 22, 2009

Not So Inspirational Thoughts

I believe I've mentioned before that my primary responsibilities at work are as the systems administrator. It's something that Ive dabbled in with several previous companies, and taught a lot of classes on at my last job. Now I do it full time.

I was talking to my brother about it some months ago, explaining a few of the concepts of server security that I've either learned from others before me, or have picked up on my own. We might even have talked a little bit about social engineering and corporate security. After a while, my brother said to me, "so basically, good security is a fascist regime."

I thought about it for a moment, and said, "yeah, I guess it is."

Yesterday I mentioned this conversation to my boss. He laughed and said, "yeah, that makes perfect sense. In fact, any mechanical process that is a democracy is a failure."

Hope you all enjoy those thoughts as we head into the Memorial Day weekend. Me, I've got a few company servers to enforce martial law on.


Friday, May 08, 2009

Soundex

Today at work we were talking about spelling issues that have come up with phone reps, while trying to look up customer names in our database. For instance, it might sound like the customer is saying her name is Cassy, when in fact she spells it Cassie or Cassi. I used to know a guy who spelled his name Eron (instead of the more traditional Aaron).

How does one deal with this problem? Some of the solutions that were coming up were pretty scary-sounding, and started to drift into areas of serious security concerns. I finally spoke up and said something to the effect of, "if I could offer a suggestion, how do you all feel about looking up records by soundex?" I suddenly had three very interested faces looking in my direction.

Soundex is something that any serious genealogist is well familiar with, but for some reason it doesn't seem to be that common in the programming world. That's a real shame, because it's so useful. And fortunately for Perl and MySQL developers, tools already exist for you.

First, the basics:
  • Take a word, and write down the first letter of that word.

  • Drop all of the vowels remaining in the word.

  • Remove all duplicate letters (i.e. LL becomes L).

  • If "H" or "W" separate two letters with the same soundex code, the consonant to the right is ignored.

  • Convert the remaining consonants to numbers:

    • b, f, p, v => 1

    • c, g, j, k, q, s, x, z => 2

    • d, t => 3

    • l => 4

    • m, n => 5

    • r => 6

  • Save only the first three numbers. If you run out before you reach three digits, pad with zeros.

Using this code, the name "Joseph" would be encoded as "J100". "McAllister" would be "M242". See how easy that is?

MySQL has a couple of built-in functions that utilize soundex. The first, amazingly enough, is the "SOUNDEX()" function. This function doesn't give a standard soundex value; it actually encodes the whole word, giving you a minimum of 4 characters, but an arbitrary maximum. For instance:

mysql> select soundex('mcallister');
+-----------------------+
| soundex('mcallister') |
+-----------------------+
| M24236 |
+-----------------------+
1 row in set (0.00 sec)

If you want it to return a standard soundex with a maximum of four characters, you can use the "SUBSTRING()" function:

mysql> select substring(soundex('mcallister'),1,4);
+--------------------------------------+
| substring(soundex('mcallister'),1,4) |
+--------------------------------------+
| M242 |
+--------------------------------------+
1 row in set (0.00 sec)

MySQL also has a built-in function called "SOUNDS LIKE" that actually performs a SOUNDEX() function in the background:

mysql> select distinct first_name from customer where first_name sounds like 'corey' limit 10;
+------------+
| first_name |
+------------+
| Corey |
| cherie |
| Cory |
| Carrie |
| corri |
| cheri |
| cesar |
| CHERRY |
| Cierra |
| cora |
+------------+
10 rows in set (0.00 sec)

On one hand, we got a few names that most definitely weren't "corey". But on the other hand, the query was inherently case-insenstive, and offered a lot of wiggle room.

Perl also has a couple of Soundex modules available in CPAN, such as Text::Soundex. This module is also pretty easy to use:

use Text::Soundex;
print soundex("Ashcraft"), "\n"; # prints: A226
print soundex_nara("Ashcraft"), "\n"; # prints: A261

That second function, "soundex_nara()", is pretty important for doing US Census work, since the National Archives and Records Administration (NARA) uses a slightly different encoding scheme. Theirs is probably the version that most genealogists are going to be familiar with.

This is something that's definitely handy for looking up a lot of data, when the actual spelling is a little fuzzy. Maybe it will find its way into your database queries at some point now.


Wednesday, April 22, 2009

The Other Joseph Halls

I thought I'd take a moment to tell you about some of the other Joseph Halls. As it turns out, it's kind of a common name. When I was a kid, there were four Joseph Halls in the Salt Lake phone book. I don't know how many there are now, since I haven't even opened a phone book for years, but I can tell you that none of them are me (unlisted).

When I was a newish Perl hacker, I came across a book called Effective Perl Programming, by Joseph N Hall. It felt odd to have another one of me in my community, especially since the other one was published, and his co-author was the great Randal Schwartz. I ended up buying his book, mostly because I liked the reviews. The fact that I could keep a Perl book with my name on the cover at my desk was a bonus. As it turns out, it's a pretty good book. If you're into Perl and want to get better, I highly recommend it.

The next Joseph Hall that I would run into was Joseph Lorenzo Hall. You see, around the same time I found Joseph N Hall's book, I ended up buying josephhall.com, josephhall.net and josephhall.org. I did nothing with them for years, and eventually let the .net and .org expire. Not long after, I decided to check up on them to see if they were still available. The .org was not. But I couldn't help find the new owner of josephhall.org fascinating. He's yet another smarter me, with a PhD. I've been following his blog in my feed reader for a while, and yesterday's post was truly interesting to me. He's a Neil Gaiman fan too! I also know from his site and his blog that he's a computer geek and even a bit of a food geek. You should check out his blog just on principle.

That of course leaves josephhall.net. A few months ago I got a call from a man wanting to buy josephhall.com from me. I told him that it was not for sale. He told me that it was for his son, another Joseph Hall, and that it didn't look like I was even using www.josephhall.com. I told him that it was because I had that redirecting to blog.josephhall.com. He looked, and found that I was indeed actively using my site. He eventually realized that it was futile to try and buy my domain, and I wished him luck in finding another solution. As I spoke with him, I ran a whois on josephhall.net and found it avaialable. Figuring he might buy that, I checked an hour later and found that his name was indeed listed. Some weeks later, I visited the site and found out why this new Joseph Hall needed a site: he's apparently an up and coming Elvis impersonator. There's a part of me that thinks that's just awesome. So go check him out as well.


Tuesday, April 07, 2009

Mirepoix


One of the most important components of classical French cooking is mirepoix. A classic French mirepoix is composed of a 2:1:1 ratio of onions to carrots to celery, meaning that four cups of mirepoix would contain two cups of onions, one cup of carrots and one cup of celery. Some of you may also have heard of the cajun version of mirepoix, called trinity. The ratio is the same, but the carrots have been replaced with green bell peppers.

Mirepoix is used as the basis of a number of dishes, not only in French cooking, but in other cuisines. The ratios may vary a little, and the name may change (or not even exist at all), but the combination of onions, carrots and celery is classic. Recently some stores have even started selling both mirepoix and "cajun-style mirepoix" in the frozen foods aisles, which is convenient. But if you're willing to take the time to cut your own mirepoix and maybe even freeze it yourself, it will likely be cheaper, plus you can have a little better control over the quality.

I'm going to show you a few knife cuts here suitable for home use. You've probably seen all sorts of ways to cut these vegetables, and if you've been to cooking school, these methods are probably not what you were taught. They certainly weren't what I was taught, and if I were working for somebody like Thomas Keller, I wouldn't be using them either. But since I'm just cooking for me and my family, they will suffice.

Let's start with carrots. Go ahead and wash them, but don't bother to peel them. There's no reason to waste good carrot like that. With most carrots I see in grocery stores, you should be able to chop them in half, then cut the smaller half lengthwise into four pieces, and the larger half lengthwise into six pieces.

Go ahead and cut up a few carrots like this. When you have enough, there's a tip you can use to save yourself some time. Spread them out in a line across your cutting board, and start working your way across with your knife, dicing them up into pieces with as uniform a size as you can manage. Remember, accuracy is more important than speed, especially considering the sharp knife that I expect you to be working with.

Let's turn our attention to the celery. This is actually a little more difficult to cut, because it has kind of an awkward shape to it. The key is to bring it down to the same level as the carrots. First, grab a bunch of celery and cut the end off. Don't go crazy with it, you just want to be able to separate the stalks from each other. Don't be getting all wasteful on me.

When it's separated, go ahead and wash it in cold water. There were plenty of places for dirt to hide when it was together, and you need to get rid of it. With that out of the way, go ahead and lay a stalk down and slice off a piece of it length-wise.

With that piece cut away, go ahead and make the next cut. Be careful with these! It's easy to get carried away and go too fast. I've lost track of the number of times that I started to think I was a big-shot chef with ninja knife skills, only to end up slicing myself. Remember, accuracy before speed.

Now you have a bunch of long sticks of celery, ready to be diced just like the carrots. Lay 'em out the same way, and chop 'em up.

Last up, onions. These are actually very easy to cut, but they have their own dangers. You know what I'm talking about: the tears. I can give you a few tips, but when it comes down to it, you really just need to learn to suck it up. Take a step back if you start crying too hard, give it a break, then go back to it. First things first, you need to cut the stem end off.

Be careful not to cut too much of it off, because you actually need some of it to hold the onion together for a moment. Cut the flower end off too. Then go ahead and slice it in half, from end to end, so that you have two halves that are both held together at the stem.

At this point you can go ahead and peel away the papery part and throw it away. You might even want to put the cut sides face-down on the cutting board for a few minutes. Believe it or not, this seems to help dissipate some of the sting. When you're ready, slice the onion on the side, but not all the way to the stem. You still need that holding it all together.

Keep making slices like this at an angle, working your way around the onion. What you're going for are little fingers of onions held together by the stem. Another little tip here: try not to stand directly over the onions when you're cutting them. I think everybody does it, and it just puts you in the line of fire for onion fumes. Stand back a little and you will have fewer tears.

When you've worked your way around, it's time to actually dice the onion. Being careful not to cut your fingers, you want to slice across the cuts that you've already made. This is much easier, because that stem is still holding the onion together.

Keep going until you get almost to the stem. Feel free to cut as close to the stem as you want, but don't cut up the stem itself, I don't think you'd really like it.

Now that you have your vegetables cut up, you have a few options. If you bought way too many vegetables like I did when I was shooting these pictures, you'll probably want to freeze some of them for later use. You'll want some cookie sheets, or if you have a restaurant supply store nearby you can pick up "half-sheet pans", which are basically just commercial-grade cookie sheets.

I like to lay down a sheet of parchment on each sheet pan. You don't have to, but keep this in mind: the frozen veggies will stick to the pan itself a lot easier than to a sheet of parchment. Lay out the veggies on the pan, in as thin a layer as you can get it. If you have a lot of veggies like I did, you can put a cooling rack on top of the veggies, add another pan and repeat, but I wouldn't go more than three sheet pans high. The more you stack, the longer it will take to freeze, and you really do want these veggies to freeze as quickly as possible.

Move the sheet pans into the freezer and leave them there for at least two or three hours. Try not to open the door for the first couple of hours; it just slows down the freezing process. When they're nice and cold, you can move the veggies into a resealable plastic bin or bag, and then directly back into the freezer (once you've written the day's date on them, of course).

It's up to you whether you want to store them separately, or mix together the ratios yourself for freezer storage. Personally, I like to keep them separate. It offers me a little more freedom if I end up needing, say, a cup of carrot puree. I can't think of any reason offhand why I would need such a thing, but stranger things have happened.

I have another post written that makes excellent use of this mirepoix, but I have no photos to accompany it. Stay tuned, and as soon as I have photos I will post them.


Wednesday, April 01, 2009

Geek/Maker Calendar

I don't know if anybody else has noticed, but Make seems to be posting a lot of "Maker Birthdays" lately. I thought it might be fun to put together a calendar with as many days as possible filled with not only birthdays of makers, but also birthdays of other notable geeks, and various other noteworthy days for geeks. I know I'm stretching it on a few of these, but hopefully not too far.

My list so far is not comprehensive, but I'm running low on ideas. I thought I'd open it to my geekier readers, to see if we can fill the comments on this post with other geek days. I have Wikipedia links where available, and links elsewhere otherwise. I'm trying to remain as unbiased as possible, which is why you see certain names on the list that I'm not necessarily a fan of. Please try to be unbiased too. Here's what I have so far:

Jan 1864: George Washington Carver - http://en.wikipedia.org/wiki/George_Washington_Carver
Jan 1942: Brian Kernighan - http://en.wikipedia.org/wiki/Brian_Kernighan
Jan 1, 1894: Satyendra Nath Bose - http://en.wikipedia.org/wiki/Bose-Einstein_condensation
Jan 2, 1920: Isaac Asimov - http://en.wikipedia.org/wiki/Isaac_Asimov
Jan 3, 1892: J.R.R. Tolkien - http://en.wikipedia.org/wiki/J._R._R._Tolkien
Jan 4, 1643: Isaac Newton - http://en.wikipedia.org/wiki/Isaac_Newton
Jan 4, 1809: Louis Braille - http://en.wikipedia.org/wiki/Louis_Braille
Jan 5, 1940: FM Radio first demonstrated to the FCC - http://en.wikipedia.org/wiki/Jan_5
Jan 8, 1942: Stephen Hawking - http://en.wikipedia.org/wiki/Stephen_hawking
Jan 21, 1953: Paul Allen - http://en.wikipedia.org/wiki/Paul_Allen
Feb 4, 1943: Ken Thompson - http://en.wikipedia.org/wiki/Ken_Thompson
Feb 5, 1943: Nolan Bushnell - http://en.wikipedia.org/wiki/Nolan_Bushnell
Feb 8, 1828: Jules Verne - http://en.wikipedia.org/wiki/Jules_Verne
Feb 11, 1847: Thomas Edison - http://en.wikipedia.org/wiki/Thomas_edison
Feb 18, 1745: Alessandro Volta - http://en.wikipedia.org/wiki/Alessandro_Volta
Feb 24, 1955: Steve Jobs - http://en.wikipedia.org/wiki/Steve_jobs
Mar 3, 1847: Alexander Graham Bell - http://en.wikipedia.org/wiki/Alexander_Graham_Bell
Mar 11, 1952: Douglas Adams - http://en.wikipedia.org/wiki/Douglas_Adams
Mar 13, 1733: Joseph Priestley - http://en.wikipedia.org/wiki/Joseph_Priestley
Mar 14, 1879: Albert Einstein - http://en.wikipedia.org/wiki/Albert_Einstein
Mar 14 : Pi Day
Mar 16, 1953: Richard Stallman - http://en.wikipedia.org/wiki/Richard_Stallman
Mar 17, 1948: William Gibson - http://en.wikipedia.org/wiki/William_Gibson
Mar 24 : Ada Lovelace Day - http://blog.makezine.com/archive/2009/03/today_is_ada_lovelace_day_celebrati.html
Mar 31, 1811: Robert Bunsen - http://en.wikipedia.org/wiki/Robert_Bunsen
Apr 16, 1867: Wilbur Wright - http://en.wikipedia.org/wiki/Wright_brothers
May 11, 1918: Richard Feynman - http://en.wikipedia.org/wiki/Richard_Feynman
Jun 6, 1954: Tim O'Reilly - http://en.wikipedia.org/wiki/Tim_O%27Reilly
Jun 8, 1955: Tim Berners-Lee - http://en.wikipedia.org/wiki/Tim_Berners-Lee
Jun 19, 1623: Blaise Pascal - http://en.wikipedia.org/wiki/Blaise_Pascal
Jun 23, 1912: Alan Turing - http://en.wikipedia.org/wiki/Alan_turing
Jun 26, 1824: William Thomson, 1st Baron Kelvin - http://en.wikipedia.org/wiki/William_Thomson,_1st_Baron_Kelvin
Jul 10, 1856: Nikola Tesla - http://en.wikipedia.org/wiki/Nikola_Tesla
Jul 17, 1971: Cory Doctorow - http://en.wikipedia.org/wiki/Cory_Doctorow
Jul 20, 1969: Apollo 11 lands on the moon
Jul 30, 1863: Henry Ford - http://en.wikipedia.org/wiki/Henry_ford
Jul 30, 1962: Alton Brown - http://en.wikipedia.org/wiki/Alton_brown
Aug 8, 1901: Ernest Lawrence - http://en.wikipedia.org/wiki/E._O._Lawrence
Aug 11, 1950: Steve Wozniak - http://en.wikipedia.org/wiki/Steve_Wozniak
Aug 12, 1887: Erwin Schrodinger - http://en.wikipedia.org/wiki/Erwin_Schr%C3%B6dinger
Aug 19, 1871: Orville Wright - http://en.wikipedia.org/wiki/Wright_brothers
Aug 19, 1906: Philo Farnsworth - http://en.wikipedia.org/wiki/Philo_Farnsworth
Aug 20, 1970: John Carmack - http://en.wikipedia.org/wiki/John_Carmack
Sep 9, 1941: Dennis Ritchie - http://en.wikipedia.org/wiki/Dennis_Ritchie
Sep 24, 1954: Larry Wall - http://en.wikipedia.org/wiki/Larry_Wall
Oct 7, 1885: Niels Bohr - http://en.wikipedia.org/wiki/Niels_Bohr
Oct 17, 1984: Randall Munroe - http://en.wikipedia.org/wiki/Randall_Munroe
Oct 28, 1955: Bill Gates - http://en.wikipedia.org/wiki/Bill_gates
Oct 31, 1959: Neal Stephenson - http://en.wikipedia.org/wiki/Neal_Stephenson
Nov 7, 1867: Marie Curie - http://en.wikipedia.org/wiki/Marie_Curie
Nov 8, 1954: Bill Joy - http://en.wikipedia.org/wiki/Bill_Joy
Dec 9, 1906: Grace Hooper - http://en.wikipedia.org/wiki/Grace_Hopper
Dec 10, 1815: Ada Lovelace - http://en.wikipedia.org/wiki/Ada_lovelace
Dec 24, 1818: James Prescott Joule - http://en.wikipedia.org/wiki/James_Prescott_Joule
Dec 26, 1791: Charles Babbage - http://en.wikipedia.org/wiki/Charles_Babbage
Dec 26, 1937: John Conway - http://en.wikipedia.org/wiki/John_H._Conway
Dec 27, 1822: Louis Pasteur - http://en.wikipedia.org/wiki/Louis_Pasteur
Dec 28, 1969: Linus Torvalds - http://en.wikipedia.org/wiki/Linus_Torvalds
Dec 29, 1800: Charles Goodyear - http://en.wikipedia.org/wiki/Charles_Goodyear

I have a few other names that I've come up with that either I don't have birthdays for, or am not sure if they warrant being on the list.

E.G. Kingsford (Kingsford Charcoal)
Jul 22, 1968: Alan Cox - http://en.wikipedia.org/wiki/Alan_Cox
Damian Conway - http://en.wikipedia.org/wiki/Damian_Conway
Dave Bradley (CTRL-ALT-DEL) - http://en.wikipedia.org/wiki/David_Bradley_(engineer)
JD Frazer (User Friendly) - http://en.wikipedia.org/wiki/J.D._Frazer
Guido van Rossum - http://en.wikipedia.org/wiki/Guido_van_Rossum
Robert Morris - http://en.wikipedia.org/wiki/Robert_H._Morris_(cryptographer)

Anyone else want to submit some names?


Monday, March 30, 2009

More Harm Than Good

I ran across an interesting item in my feed reader the other day. In brief, there is a site that claims to be an energy-efficient version of Google, just because it uses a black background instead of white. The problem is, black screens are actually less energy-efficient on LCD monitors than on CRTs. And since the world is trying to leave CRTs behind, Blackle is actually doing more harm than good with its black backgrounds.

This reminded me of another site that I happened upon recently. The basic gist is, peta, an organization that claims to be saving animals, is actually killing them by the boatload. In my opinion, the problem isn't so much that they're euthanizing animals, as it is that they're trying to cover it up. But the focus of this site seems to be the other part of it: an organization that claims to be saving animals is actually killing animals. More harm than good.

While I was mentioning these things to my brother, he brought up another one. Sorry, no link on this one, but I'm sure there's something out there. Ordinary indandescent bulbs are being replaced by compact flourescent bulbs everywhere. The problem is, flourescent bulbs contain mercury, a known toxin. At our house we've been systematically replacing indandescent bulbs with flourescent bulbs, as the indandescent bulbs burn out. I haven't had a flourescent bulb burn out yet (we moved in less than a year ago, and are supposed to expect many years to come), but when one does burn out we're supposed to take it to a special center or something to dispose of it, because of the mercury.

I don't know about you, but I don't know where this magical, mystical place of compact flourescent bulb recycling is. And I'd be willing to bet that most of America has no clue either. In fact, I'd be surprised if the majority of Americans knew that they were screwing in little mercury capsules into all of those electrical sockets in their house.

I guess there's a few lessons to take away here. I think I may have said some of them before, like don't take medical advice from me because I'm not a doctor and in fact can't even manage to open a computer without cutting myself. Also, logic that seems infallable to you might be absolutely idiotic to somebody who actually knows what they're talking about. And let's not forget that just because some big, faceless organization claims to be helping you help the environment, doesn't mean they're telling the whole story.

Maybe it's time to start questioning things instead of taking them for granted.

UPDATE: Okay, it was weird enough that so many people posted about the CFLs. But I didn't mind because some intelligent things were being said. Then somebody posted without reading the other comments, and it seemed a little less intelligent.

Look, if you're that worried about the CFLs, just get an LED-based light bulb. They have no mercury, they use even less power than the CFLs, and they'll last much, much longer. They're also terribly expensive right now, but if you're that worried about both mercury and incandescent bulbs, they're really your best shot.

And that's it. I'm shutting of comments on this post.


Sunday, March 29, 2009

Three Cheesecakes

I did a little experimenting with cheesecakes recently. Now, when I say experimenting, I mean these probably aren't what you think of when you think of cheesecake. And you know, that's a real shame, because these really are delicious. But if you're feeling a little iffy about them, don't worry. If you remember my mini gnome cheesecakes, you'll know that you can make little tiny versions of the cheesecakes to sample, and if you like it then just quadruple the recipe and make a big cheesecake. That's right, these cheesecakes can be made with empty tuna cans. Let's take them one at a time, and I apologize in advance for the monotonous photos.

Cheddar Apple Cheesecake



This may seem a little strange to anyone that lives outside of New England, but cheddar and apple really do go well together. And while this is a sweet cheesecake, I didn't want it to be too sweet, so I went with a pretzel crust. The sugar is actually an attempt to make the crust hold together a little better. After a few tests both ways, I think it worked. As you can see in the photo, I added a little cinnamon on top of the cheesecakes, which I think really makes it.

Crust:

5 Tbsp pretzel crumbs
1 Tbsp sugar
1 1/2 Tbsp butter

Filling:

8 oz cream cheese, softened
1/4 cup sugar
1 large egg
3 Tbsp unsweetened applesauce
1/2 cup shredded cheddar

Garnish:

Ground cinnamon, as needed

* Preheat oven to 350F.
* Prepare 4 empty tuna cans, as per the mini Gnome cheesecake recipe.
* Melt the butter, and toss with pretzel crumbs and sugar. Divide evenly among the tuna cans, about 2 Tbsp per can.
* Press crusts into the bottom of the cans.
* Blind-bake the crusts at 350F for 10 minutes.
* Allow crusts to cool completely on counter, and drop the oven temperature to 275F.
* Cream together the cream cheese and sugar.
* Mix in the egg.
* Mix in the apple sauce and cheddar.
* Divide the cream cheese mixture among the tuna cans.
* Sprinkle cinnamon on top of the cheesecakes.
* Bake at 275F for 15 minutes.
* Turn off the oven and leave the door open for one minute.
* Close the door and allow the cheesecakes to cool for 45 minutes with the oven.
* Chill overnight before serving.


Bacon and Onion Cheesecake



I'm not going to lie here. Savory cheesecakes freak people out, just like you already started freaking out when you read the name of this cheesecake. I think that this kind of cheesecake is actually what the tuna can form factor is perfect for. Yes, they are kind of intense to eat on their own. No, you wouldn't ever serve it for dessert. Tell you what, instead of thinking of it as cheesecake, how about if you think about it as a dip? The only difference between this and a cheeseball is that this is flat, and tastes way better.

Crust:

5 Tbsp pretzel crumbs
1 Tbsp sugar
1 1/2 Tbsp butter

Filling:

4 strips bacon
1 cup diced onion
1/2 cup diced red bell pepper
1/2 tsp chopped garlic
dash Worcestershire sauce
8 oz cream cheese, softened
1/4 cup sour cream
1 large egg
2 Tbsp whole milk

* Preheat oven to 350F.
* Prepare 4 empty tuna cans, as per the mini Gnome cheesecake recipe.
* Melt the butter, and toss with pretzel crumbs and sugar. Divide evenly among the tuna cans, about 2 Tbsp per can.
* Press crusts into the bottom of the cans.
* Blind-bake the crusts at 350F for 10 minutes.
* Allow crusts to cool completely on counter, and drop the oven temperature to 275F.
* Fry the bacon till nice and crispy. Remove from the pan to cool, but save the drippings.
* Saute the onion and bell pepper in the bacon drippings until nice and browned. When the onion gets transluscent, add the garlic and Worcestershire sauce. Allow to cool completely.
* Cream together the cream cheese and sour cream.
* Mix in the egg.
* Mix in the milk.
* Crumble the bacon, and fold into the cream cheese mixture with the veggies.
* Divide the cream cheese mixture among the tuna cans.
* Bake at 275F for 15 minutes.
* Turn off the oven and leave the door open for one minute.
* Close the door and allow the cheesecakes to cool for 45 minutes with the oven.
* Chill overnight before serving.


Chinese Five-Spice Cheesecake



Okay, so maybe the savory cheesecake was a little weird. And this one probably seems weird too. Don't worry, this is probably the most normal of these cheesecakes. Depending on who makes it, Chinese Five-Spice tends to have ingredients like cinnamon, cloves, nutmeg, ginger, allspice, things like that. Kind of like a pumpkin pie. I even threw in a gingersnap crust, which is excellent. You'll like this one.

Crust:

5 Tbsp gingersnap crumbs
1 Tbsp sugar
1 1/2 Tbsp butter

Filling:

8 oz cream cheese, softened
1/4 cup sugar
1 large egg
1 tsp Chinese Five-Spice powder

* Preheat oven to 350F.
* Prepare 4 empty tuna cans, as per the mini Gnome cheesecake recipe.
* Melt the butter, and toss with gingersnap crumbs and sugar. Divide evenly among the tuna cans, about 2 Tbsp per can.
* Press crusts into the bottom of the cans.
* Blind-bake the crusts at 350F for 10 minutes.
* Allow crusts to cool completely on counter, and drop the oven temperature to 275F.
* Cream together the cream cheese and sugar.
* Mix in the egg.
* Mix in the spices.
* Divide the cream cheese mixture among the tuna cans.
* Bake at 275F for 15 minutes.
* Turn off the oven and leave the door open for one minute.
* Close the door and allow the cheesecakes to cool for 45 minutes with the oven.
* Chill overnight before serving.


Friday, February 27, 2009

Checking for open files

A coworker presented me with an interesting problem today. We have an SFTP server set up, where a client is uploading a series of files on a pretty regular basis. My coworker needed to process the files as soon as they were finished uploading, but he didn't know how to tell when it was finished. Since the SFTP server would be keeping the file open until it was finished writing it, all we needed to do was find out whether the file was still open.

In Bash, there's an easy way to check for this. When called without any arguments, the lsof program shows a list of all open files on the system. You can also call it with the full path of the filename that you are checking, and it will show only the processes that have that file open. For example, we can look at /dev/null, which seems to pretty much always be open on my system:

$ lsof /dev/null
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
gconfd-2 6668 jhall 0u CHR 1,3 6663 /dev/null
gconfd-2 6668 jhall 1u CHR 1,3 6663 /dev/null
gconfd-2 6668 jhall 2u CHR 1,3 6663 /dev/null
...snip...

The lsof program also has an exit status of 0 if it returns any information, and an exit status of 1 if it did not. Since we're only interested in that error status and not in any of the information returned, we can throw it away by redirecting STDOUT and STDERR to /dev/null with &>:

$ lsof /dev/null &> /dev/null && echo "The file is open" || echo "The file is not open"
The file is open

Breaking this down a little further, if "lsof /dev/null &> /dev/null" was successful (returned an error status of 0), then it will run the first echo command. If not, that will make both the lsof command and the first echo command unsuccessful (error status of 1 for both) and the echo command after the pipes will run.

If it's a little confusing having "/dev/null" in that command twice, try running it on a file that's likely to not be open, like /proc/cpuinfo:

$ lsof /proc/cpuinfo &> /dev/null && echo "The file is open" || echo "The file is not open"
The file is not open

Just a handy little bit of Bash Fu to brighten your day.


Wednesday, February 25, 2009

Ginger Beer Test #1



Those who know me well know that one of my favorite things in life is a good ginger beer. Not sugary-sweet ginger ale, but real, spicy, knock-you-off-your-feet ginger beer. I've been wanting to make it for a couple of years now, I just hadn't gotten around to it. Well, this week I finally got off my butt and gave it a try. This batch was a test run, to help me get my bearings. There will be more.

But first, we need to define what exactly makes a good ginger beer. It depends on who you are really, and I'm going to guess that my definition is probably not the same as yours. My three favorite brands are, in order:

Okay, so Vernors is really a ginger ale, but it's still up there. There are a few properties to look for in ginger ale and ginger beer. First of all, ginger ales are generally divided into two categories: golden and dry. I've found golden to be a little darker, sweeter, and more strongly-flavored. Unfortunately, it's near-impossible to find. Dry ginger ale is lighter, and extremely common. Being a Utah boy, I grew up on Canada Dry and Schweppes, but when I lived in New Hampshire I got used to Seagrams too.

But these really lack something in my opinion, and that's real ginger. I like mine spicy, but not harsh. Smoothness is also important to me, but not so much as spiciness. And that's where ginger beer comes in. It's stronger, tastes more like ginger, is often brewed, and the good stuff almost always has little fibers of real ginger in it.

I've tried a lot of different kinds of ginger beer, and I've divided (most of) my favorites into two categories: Jamaican-style and Australian-style. Jamaican ginger beer is spicy, strong, and has been known to make me cough, just getting a whiff of a newly-opened bottle. Unfortunately, it generally seems to be harsh, overly-spicy, and flavored with other spices in addition to ginger. In the small, relatively unknown world of ginger beers, this seems to be the most common, and I've probably tried a good 20 or 30 different brands, but few more than once.

Australian ginger beer is different. I've had a good dozen or so different types of this, and few of them miss their mark. They're strongly-flavored, spicy, but also smooth. They seem to be true to the ginger flavor, and when I get ahold of a few bottles, they don't remain full for long. It was this variety that I was looking to reproduce.

The first task of course was to find some recipes. I wasn't sure yet whether I was going to make a composite recipe, I was just looking to see what I could find. Most of the recipes I came across were long and ridiculously complex. One of them had a longer list of equipment than actual ingredients. Finally, I found a recipe on Recipezaar that was simple, but kind of long and very poorly-written. It seemed to be more of a Jamaican recipe, but I figured you've gotta start somewhere.

I didn't use the recipe as-is of course. I made a few changes, and then took notes while I more or less followed their directions. My ingredient list was as follows:

1/2 tsp yeast
1/2 cup warm water (110F)
1 3/4 liter water
3/4 oz/wt freshly-grated ginger
1/4 tsp anise
5 whole cloves
1/2 cup sugar

I sprinkled the year in the 1/2 cup of warm water and set it aside. I then mixed together all of the other ingredients in a sauce pan, brought it to a boil, and then dropped it to a simmer for 5 minutes. I then killed then heat and let it cool on the counter to 110F (actually, 112F to be exact, but anything below 120F is fine), and then poured in the yeast/water mixture.

I poured all of this (whole spices and all) into a clean 2-liter bottle, pressed in the sides a little, screwed on the cap and let it sit overnight on the counter. In the morning, the bottle was completely inflated, and you could tell by feeling it that there was a lot of pressure inside. I moved this to the fridge and let it sit until the next evening.

I tasted the brew before I added the yeast, and I knew I was already in trouble. It was extremely spicy, and the anise overpowered everything. But I was determined to let it age for a couple of days so that I could get a good idea of what it would be like.

When we uncorked it, there was a lot of sediment. This is to be expected with home-brewed drinks. But it's not something I would want to drink, so I poured it through a tea strainer into some cups and tasted it with my wife and her friend visiting from Wisconsin. Unfortunately, this means I also strained out the ginger fibers, but since we were just about to drink it, I figured it wouldn't be adding any more flavor anyway.

First of all, the color. It was more cloudy than I expected. I'm okay with that. Next, the carbonation. It was lightly carbonated, not as much as commercial ginger beer, but still decent. Finally, the flavor. It was very spicy, but not as bad as I had feared. The anise still overpowered everything, but it still had a lot of ginger in the finish, to come back and bite you. I suspect the clove was about right (if you like that sort of thing; I'm currently undecided), but that anise just screwed it all up. It was just a little bit sweet for me, but not bad.

Just a quick note on drinks carbonated with yeast. This is exactly how beer is made. When the yeast gets going, it produces lots of carbon dioxide and a little bit of alcohol. That's what makes bread rise, and makes beer fizzy. Since my brew had only a tiny amount of yeast, and was only allowed to ferment for a couple of days, the alcohol content was negligable. If that is of concern to you, this is the wrong recipe for you.

I will be starting another bottle tomorrow night, when this one is used up. Now that I have my bearings, I think I have an idea of where I want to take it. I'm going to try multiple changes at first, and then fine-tune it as I get closer to what I want. The next batch will have no anise. That was just a bad idea. I will leave the cloves in there, and probably use the same amount of ginger. This time I'm thinking I may add some lemon juice, and drop the sugar down to 1/3 of a cup. I hope to post results this weekend.