Thursday, March 31, 2016

Gotcha of the day: AWS EC2 Instance Periodically Gets Database Connection Timeout Errors

I recently migrated a client from a single server environment to a dynamic AWS environment. The migration went smoothly enough. But we ended up with an odd conundrum: at 3 minutes after the hour, various requests would fail with a database Connection Timeout error. It was like clockwork. 9:03. 10:03. 11:03. You get the idea. The problem struck for just a few seconds, but it absolutely impacted customers.

What the heck was going on?!

The Connection Timeout error (specifically, a MySQL Client error, 2002) seemed like a network issue. Was the network being restarted once an hour? Maybe we were getting a new IP from DHCP? Or perhaps there was some DNS action happening once an hour? To help determine this, I ran this recipe from the command line:

while sleep .5; \
  do date ; \
   echo | nc -vv  db.server.com 3306 ; \
   echo ; echo; echo; \
done

The above command uses netcat to establish a connection to the database. The output looks something like so:

Thu Mar 31 14:37:53 UTC 2016
Connection to db.server.com 3306 port [tcp/mysql] succeeded!
adfasfdafda^mysql_native_password

While much of that is gibberish - the -vv shows me that the connection was successful.

I kicked this off at 9:02pm. By 9:04pm, the usual alerts had come in saying that various DB connections had timed out. But my command line above, showed no such error.

So it wasn't a Linux networking issue. The network was stable throughout the event. Ugh.

After much more debugging, I whipped up this PHP script:

<?php
require_once('system/config.php');

$count = mysql_value("SELECT COUNT(*) FROM users");
echo date('c') . " | $count\n";
?>

The idea was to create a trivial PHP script (which of course, isn't really trivial because it's loading up our system config which pulls in a huge number of files) that runs a single, simple, database query.

I ran this bad boy in loop like so:

while sleep .5; \
  do php -f script.php ; done

10:03pm rolled around, and sure enough, the script hung and finally failed with a Connection Timeout. Now this was progress!

To truly figure out what I was missing, I turned to my good friend strace. I ran the above like so:

while sleep .5; \
  do strace -o /tmp/snapshot.out php -f script.php ; done

I waited for the command to hang and reviewed the file. The tail of the file was like so:

recvfrom(3, "\344\341\201\200\0\1\0\1\0\1\0\staging.db.server.com"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.2.0.74")}, [16]) = 208
close(3)                                = 0
gettimeofday({1459436115, 155678}, NULL) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("58.28.1.102")}, 16) = -1 EINPROGRESS (Operation now in progress)

As is typical with strace most of the output was meaningless to me. But, it was clear what those last lines were showing me. First, it was stuck trying to connect to 58.28.1.102. Which was odd, because that wasn't our database's IP. And further more, it did a name lookup of: staging.db.server.com. Aha, so that's where the random IP address was coming from! It wasn't random, it was from our staging server.

In other words, at 3 minutes past the hour, something funky was happening that was causing our system configuration to fallback on communicating with our staging database. With this information in hand, the problem was trivial to debug. We had a process happening once an hour in cron, and when it ran, it refreshed a configuration file. While that configuration file was getting refreshed the system fell back to using the staging setup. It took swapping two lines of code to fix this monster of a problem.

So netcat, strace and traditional Unix skills won the day. However, I learned another incredibly valuable lesson. Whenever you report any sort of network error, you should also report the host and port you're trying to connect with. Had I included this in the database connection error, no Linux heroics would have been necessary. Lesson learned.

Tuesday, March 29, 2016

This May Sting a Bit: Embracing Your Life Calendar

And here's yet another TED Talk that's both entertaining and insightful: Tim Urban: Inside the mind of a master procrastinator. Here, take a few minutes and watch the talk:

I'm actually not much of a traditional procrastinator. My Computer Science degree, mainly filled with long running projects, played to my (then unknown) strength of living with, and chipping away at a problem. From timed math tests in 3rd grade to the SATs, I've never been much of a must-perform-this-minute kind of student. Just watching Tim discuss his academic career started to make my palms sweat. But his points are none the less well taken: we're all good at putting off the important for the fun and easy.

Tim's thesis is that where procrastination is truly a problem is when there's no due date to spur you into gear. Or as he scientifically explains: there's nothing to conjure up the Panic Monster to scare off your Instant Gratification Monkey. But Tim also provides us with a solution: the Life Calendar. Near the end of the talk he shows a grid of boxes which corresponds to one week for 90 years of an individual's life. Turns out, there is--if you pardon the pun-- a deadline for all our tasks, and it's going to happen before you think.

I saw this grid and immediately knew I needed to create a Life Calendar web app. So I did. You can access it here. The instructions are simple: enter in your birth day, hit refresh, wait a few seconds, and take it all in. Now cue the Panic Monster. You're welcome.

Here's my calendar. Almost half way filled in. Gulp.

You're welcome to view and modify the code for the calendar here. In truth it's little more than one of those beginner exercises they used to give us to learn about loops and working with dates.

Now if you excuse me, I've got a Panic Monster to wrestle with.

Monday, March 28, 2016

Garden Prep, 2016 - The Adventure Begins

Come over I said. We'll do some gardening, I said. What I meant was, help me clean up a winter's worth of debris from my yard and deck. This wasn't gardening, this was yard maintenance. And despite the fact that it would have been far more fun (and far less back-breaking) to tour some Civil War Battlefield, my parents came over and helped me get ready for Garden 2016, Ben Tries Again.

That's not to say that we didn't squeeze in a little planting while doing bed-preparation and such. My Mom planted some pretty pansy's and I seeded the X-Garden for yet another year of experimentation. My Dad dubbed the X-Garden the Evolution Garden, as we'll see which seeds are fittest to survive. We got a nice rain last night and today so hopefully everything's off to a reasonable start.

We still need the dreaded trip to Home Depot to pick up veggies and herbs to planted in the raised beds. But at least the beds are ready to go, so hopefully that process won't be too painful. I keep stressing to myself that this isn't a one-day activity. Baby steps is the way to go.

One of the lessons I learned from last year's X-Garden was that I needed to be far more careful about how I labeled the seeds. My casual attempts to keep track of what got planted where, failed almost immediately. Not this year! I neatly marked off the various zones and I've documented them below. Again, slowly but surely, I'm figuring this out.

And here's the seed layout:

(With my back to the house, facing our rear property line)

(Rear property line)
Zinnias
Wando PeasBorage
Heirloom OrachGround Cherry / Camellia Sinensis (Tea)
Heirloom PurslaneBlack Henbane
Heirloom Cabbage Danish BallheadCommon Milkweed
Bunching Onion Red WelshPeppermint
(Front property line)
(Rear property line)
Heirloom Cabbage Danish Ballhead Bunching Onion Red Welsh Wando Peas
(Front property line)

Friday, March 25, 2016

More Cherry Blossoms, More Tulips and More Good Times

Do I mind that we took the same Cherry Blossom walk yesterday that we did last year, and I re-took the same photos? No, not at all. It was sunny and beautiful and the exact right place to be.

Alright, next time I'll mix it up. Next Cherry Blossom Walk's theme: What the Flowers See. There, that should be a different perspective.

Mom and Me

Just Mom and Me enjoying Purim services. Boooooooo Haman!

Thursday, March 24, 2016

Camels: Who knew they could teach you so much?

I saw this TED talk on Camels, and in honor of my Mother-in-Law (who has quite the camel collection!), figured I should watch it. In short, it's fantastic. Here, take a few minutes to watch it and then read my comments below:

Well done, right?

First off, talk about excellent storytelling. Injecting pre-recorded audio clips into what feels like a casual talk is really powerful. The voice of the scientist is literally heard, even though the talk is being given by a historian.

And the overall thesis: that new information should result in a new world view is something we simply don't embrace often enough. I'm all for having bedrock principles and such, but when you learn something, it can and should change you. This is a core scientific idea that's often hard to appreciate. Yes, we know X is true. And we have to operate as though X is true. But, we also have to accept that more data may show that in fact, X isn't true. Frustrating, but the alternative has you twisted in knots and at odds with the truth.

Deep stuff, and all from a camel! Oh TED, you simple never disappoint.

Wednesday, March 23, 2016

Fishing at Gravelly Point: It's all about how you define success

So let's review last night's Gravelley Point fishing adventure:

  • David "caught" a duck decoy (giving him the ultimate bath toy / lawn ornament, no?)
  • My Dad caught 2 catfish, one being so large he couldn't land it
  • I caught countless photos of the sunset and planes landing at nearby National Airport

So yeah, it was a success.

Note to self: thar be plenty of catfish in the Potomac! One only needs to show up with chicken livers and the patience to wait for a bite, and you should be good to go. Or at least that's what my Dad (who actually caught fish) tells me.

Tuesday, March 22, 2016

Useful Woods Hack: Making Wooden Rings

Here's an outdoor hack I'm going to have to try in the field: creating rings from split branches. I know, that hardly sounds exciting. But as this video shows, you can do quite a few things with these small hoops. Specifically, it shows them being used to: (1) to keep a plastic bag's mouth open, (2) to assemble a tripod and (3) to hang the open bag from the tripod. Here's a screencap of the tripod setup:

While not a true field test, I did pick up some branches at the end of my trail run and today fiddled around with making some rings. I was actually able split the branches using the P-51 can opener that lives on my keychain:

However, I failed to actually construct the rings: I think the wood I picked up was just too dead and dried out to be pliable enough to for the job. Still, with practice, I could see this working.

Here, watch the video below. It's far from exciting stuff, but it's the kind of complete demonstration that's actually useful for learning a new skill.

Boil Water in Plastic Bag Over Camp Fire

Caption Me: Trail Running Gawker Edition

Share your brilliant caption suggestions using the comments below.

As seen on yesterday's run.

Monday, March 21, 2016

Birthdays, Bricks and Bouncing in Boston

I'm typing this post as another whirl-wind trip to Boston comes to a close. We started the trip by picking up Gavriella early from her play-group and taking her to Jump On In, an indoor bouncy house extravaganza. She wasn't immediately in love with this. When asked what she wanted to try first, she explained she'd like to put her shoes back on and leave.

But after a bit of cajoling and demonstration by Shira and Myself, she finally warmed up to the place and ended up having a ball. After two hours of jumping, we were all completely exhausted. We hit Jump On In on Friday morning, before school had let out, so it was almost completely empty. We nearly had the place to our self, which made getting Gavriella warmed up to the surroundings even easier.

After lunch, we picked up Tzipora and ran some errands. And being Uncles and Aunts, we had no qualms about stopping at the froyo place to have a treat. Gavriella enjoyed her watermelon yogurt and Tzipora devoured her strawberry.

One of the main reasons for the trip: it was the Twins' 7th birthday on Friday night. We celebrated with cake, balloons and themed napkins (My Little Pony for Chana, Thomas for Dovid). It's hard to believe that the little tykes are 7 years old. That's like little people! I can still remember sitting next to them in the NICU, two little bundles barely bigger than a handful (exhibit A, exhibit B). Actually, come to think of it, they're still a handful.

We passed an enjoyable Shabbat playing with Legos (the kids are really getting the hang of following the instructions) and taking a 4 mile(!) hike to Brookline Reservoir. We decided to name the destination 'Thirsty Pond' as the kids were absolutely parched when they arrived. The reservoir has a nice running path around it and apparently allows fishing. Also, to our surprise, there were wild turkeys wandering around. Though, there wasn't a great place for the kids to play there (I mean, they're fine with playing inches from the edge of the water, us, not so much) so I doubt we'll be returning anytime soon. The kids passed Reservoir T-Station on the way which has some large rocks practically screaming out for kids to play lava games on. So they did. This definitely helped make the hike a success. They were also a perfect spot for a cookie break. Our little hikers continue to march pretty much wherever we ask them. As long as we can put up with their constant pleas for snacks, we're all good.

Shira and I started this morning with breakfast at Tresca's Eating Place. If you ever want to take a trip back in time to when breakfast was a simpler affair, this is the place to go. No pesky gluten free or heart-healthy menu options. I got egg and cheese on a bagel, and there was no discussion of what artesian bagel I wanted, or how aged the cheese should be. It was a good 'ol plain bagel, with good 'ol American cheese, with a good 'ol egg on top. What's to discuss? (And for the record, it tasted awesome). Oh, and it's cash only, too. This was a nice contrast to the dinner the night before at Zhu. We tried this Asian Vegan restaurant for the first time and were quite impressed. We'll absolutely have to go back to try more items on the menu, as the Mushroom Seitan and General Tzo's were both quite delectable.

This morning we awoke to a feels like of 19°F. So yeah, an outdoor activity was pretty much out of the question. While searching for an indoor activity we learned that there's a Legoland Discovery Center in town and the kids had never been. Having had a positive experience in Legoland in Florida we thought we'd give the Boston version a try. Yelp reported that folks generally had a good time, though some thought it was a bit small for the hefty sized entrance fee. Given our need for a fresh indoor activity, and having just played Legos the day before, we thought we'd give it a try.

Yelp was right, the place isn't huge. Somehow Legoland manages to fit an introductory movie, two small'ish amusement park rides, a 4D movie, a Lego Boston Miniland, various Lego building stations and a kids play area in one large upper story building of what amounts to an outdoor mall. All 4 kids enjoyed the space immensely. Chana and Dovid loved the rides and 4D movie, Tzipora and I enjoyed building and racing cars, and Gavriella enjoyed hugging the (to her) giant Lego characters. Shira and I enjoyed the closed in play area, where all 4 kids could climb and run with wild abandon. Gavriella, to her credit, managed to climb to the tippy top of one of the structures in the play area and just hung out there enjoying the view. When she was ready to come down, Chana helped her make the trek back to ground level.

Shira tells me that she was especially impressed with the staff at Legoland, something we couldn't really say about the Florida version. So, in the end, was it worth the small fortune to get in? Given the kids' ages and the weather outside, heck yeah. For what we spent, we could have probably gone on Craigslist and bought a lifetime supply of Legos, but what the heck, the kids loved the experience.

And then it was off to the airport for us, where our plane was delayed just long enough for us to get lunch.

View Photos

Friday, March 18, 2016

Painless Linux Cloud Backups From The Command Line

\ A few nights ago I was talking with my Dad about backup strategies and hit me: I don't have a method in place for backing up photos on my Linux box. On Windows, I use both Carbonite and Google Photo. But on Linux, I've got nothing. Well that's not good. I needed a simple solution, and I needed one fast.

I know that there are number of fancy sync options for Linux, but what I really wanted was something Unix'y. In fact, what I really wanted was rsync pushing to Google Drive. And turns out, you can get essentially this using rclone. I grabbed the binary (a yum install would have been sweet, but doesn't appear to be available) and typed:

 rclone config

I answered a few questions, and authenticated my Google Drive account using OAuth. And then syncing was as simple as running the command:

  rclone sync ~/Pictures personal_gdrive:Backups/Pictures

The command churned away, and 27 Gigs later, finished. I put the above command in cron and now I've got my backup solution in place.

rclone is definitely going into the toolbox for future use as it elegantly bridges the modern cloud with the old school Unix world.

Thursday, March 17, 2016

Let's Bloom

So they're calling for snow tomorrow. Whatever. I'm with the trees on this one: it's time for Spring!

Defying Gravity and Other Sights from Last Night's Game

Shira scored tickets to last night's Bulls vs. Wizards game. I'm not a follower of pro-sports, but I'm always glad to hit up a live event. And I've got to say, I was really impressed with last night's game. No doubt the ridiculously close seats helped. I mean, I know on paper these guys are big, but up close, they're absolutely huge. And yet, they can move with incredible grace and precision. There were definitely sequences where it seemed that the players managed to hang in mid air for an unnaturally long time. All in all, very impressive.

A few photos of the action are below. I missed the tip-off, but in my defense I had this going on in front of me, which served as, uh a, distraction.

Fun times, and it was great to see the home team victory!

Wednesday, March 16, 2016

The Lazy Upcycler: Quick and Easy Mesh Bags

Don't get me wrong, I love me an impressive upcycle, where someone takes trash and turns it into a magnificent object. But that's just not me. Me, I'm strictly opportunistic (read: lazy). I see an interesting container, I'll toss it in the dishwasher. Maybe I'll find a use for it, maybe it'll end up in the recycle bin. No biggie.

My latest reuse hack: with a minute or two of TLC, turn the plastic mesh bags that clementines come in, into little drawstring bags. The process is embarrassingly simple:

That is: cleanly cut one end of the bag, ziptie the other end, cleanly cut it, thread a shoe lace through the first opening. And you're done.

The result looks like, well, a mesh bag:

I wish these bags weren't made from plastic mesh, as I bet old school string would be quite strong. But still, the bags are surprisingly useful. They are lightweight, pack down to nothing, allow the contents to "breathe" and best of all, if one gets damaged or generally nasty, it can be recycled like it was going to be in the first place. Zero guilt.

Tuesday, March 15, 2016

The technology that powered geeks from Newton to Aldrin

Pop Quiz: What do Issac Newton, Buzz Aldrin and My Dad all have in common? They all solved math problems, at one time or another, using the same device: the mighty slide rule. After watching this video I realized I've never done a post on the slide rule, and as an aficionado of all things simultaneously basic and techy, I needed to correct that.

The technology really does go back hundreds of years, with Issac Newton clearly describing a device which anyone doing math in the 1960's or before would appreciate:

Mr. Newton, with the help of logarithms graduated upon scales by placing them parallel at equal distances or with the help of concentric circles graduated in the same way, finds the roots of equations. Three rules suffice for cubics, four for biquadratics. In the arrangement of these rulers, all the respective coefficients lie in the same straight line. From a point of which line, as far removed from the first rule as the graduated scales are from one another, in turn, a straight line is drawn over them, so as to agree with the conditions conforming with the nature of the equations; in one of

And here's an actual shot of Buzz Aldrin in space with a slide ruler floating in the background:

One can imagine that nearly every major undertaking involving complex math utilized the slide rule in one way or another. Consider this description of the building of the Golden Gate Bridge:

Charles Ellis and Leon Moisseiff calculated forces for the Golden Gate Bridge with only a circular slide rule and a manual adding machine. They worked for months -- by hand -- sometimes solving equations with more than thirty unknowns.

Those guys weren't messing around.

My favorite slide rule store does happen to come from the space program, specifically from the Apollo 13 mission:

Perhaps the most impressive use of the slide rule was during the Apollo 13 crisis. Engineers had to recalculate data to guide the crew safely back to Earth—and they had to do it quickly. Richard Ogle describes how it went down:

""NASA had at its disposal whole banks of sophisticated computers, of course, but these were not programmed to do the basic calculations [Commander Jim Lovell] needed. So the engineers reverted to that most mundane pre-pocket calculator workhorse, the slide rule. Had the engineers at Mission Control been forced to do the necessary calculations on paper, Apollo 13 might well have missed the trajectory needed to bring it back to earth altogether. Instead the slide rule, designed specifically to exploit human beings’ highly developed visual acuity, allowed them to perform a set of complicated calculations in seconds.""

OK, we all get that the slide rule is an amazing device. But how do you truly grok it? You could pick one up on eBay for under $10 or so and work towards mastering it. Or, you could install the App on your phone for free, and start playing with it right now. But, as they say, if you truly want to understand something, teach it. And I know of no more recalcitrant a student than the computer. So I decided to program a slide rule.

Here's my solution:

(struct scale (symbol location abs-fn scale-fn) #:prefab)

(define C (scale 'C 'slide
   (lambda (s)
     (log s))
   (lambda (a)
     (exp a))))

(define D (scale 'D 'body
   (lambda (s)
     (log s))
   (lambda (a)
     (exp a))))

(define CI (scale 'CI 'slide
    (lambda (s)
      (log (/ s (/ 1 s))))
    (lambda (a)
      (/ 1 (exp a)))))

(define DI (scale 'CI 'body
    (lambda (s)
      (log (/ s (/ 1 s))))
    (lambda (a)
      (/ 1 (exp a)))))


(define A (scale 'A 'body
   (lambda (s)
     (log (expt s (/ 1 2))))
   (lambda (a)
     (expt (exp a) 2))))

(define B (scale 'B 'slide
   (lambda (s)
     (log (expt s (/ 1 2))))
   (lambda (a)
     (expt (exp a) 2))))

(define R (scale 'R 'slide
   (lambda (s)
     (log (expt s 2)))
   (lambda (a)
     (sqrt (exp a)))))

(define K (scale 'K 'body
   (lambda (s)
     (log (expt s (/ 1 3))))
   (lambda (a)
     (expt (exp a) 3))))



(define (make-slide-rule)  
  (let ((offset 0))
    (lambda (action . args)
      (define (align s1 v1 s2 v2)
 (cond ((and (eq? (scale-location s1) 'body)
      (eq? (scale-location s2) 'slide))
        (set! offset
       (- ((scale-abs-fn s1) v1)
   ((scale-abs-fn s2) v2)))
        offset)
       ((and (eq? (scale-location s1) 'slide)
      (eq? (scale-location s2) 'body))
        (align s2 v2 s1 v1))
       (else
        (error (format "Must align body to slide, not ~a to ~a"
         (scale-location s1) (scale-location s2))))))
      (define (read s1 v1 s2)
 (cond ((and (eq? (scale-location s1) 'body)
      (eq? (scale-location s2) 'slide))
        ((scale-scale-fn s2) (- ((scale-abs-fn s1) v1) offset)))
       ((and (eq? (scale-location s1) 'slide)
      (eq? (scale-location s2) 'body))
        ((scale-scale-fn s2) (+ ((scale-abs-fn s1) v1) offset)))
       (else
        (error (format "Must read from slide to body, or body to slide. Not ~a to ~a"
         (scale-location s1) (scale-location s2))))))
      (case action
 ((align)
  (apply align args))
 ((offset) offset)
 ((read)
  (apply read args))
 (else
  (error (format "Unknown slide rule command: ~a" action)))))))

I found this page especially useful in developing my implementation.

What I learned from this little coding exercise was that there's really only two operations that you can perform with a slide rule: slide it and read it. So I implemented those two operations: align and read. For example, to perform basic multiplication, you align the C and D scales, and then read the value off the D scale relative to the C scale. Or, in code:

(define sr (make-slide-rule))
(sr 'align C 1 D 5)
(sr 'read C 3 D) ;; => 15

And here's an example of computing X3 using the K scale:

(define sr (make-slide-rule))
(sr 'align C 1 D 1)
(sr 'read C 3 K) ;; => 9

I definitely appreciate that by implementing more advanced scales, you could knock out some pretty hairy math with relative ease.

Don't get me wrong, I love me a calculator (even with its flaws) and gladly perform even the most basic mathematics on it. But from a design and hacking perspective, you really can't beat the mighty slide rule. It's definitely worth taking the time to understand how it works and why it was such an effective tool for so long.

Monday, March 14, 2016

Thursday, March 10, 2016

Fore! Golfing with The Parents, A Surprisingly Successful Adventure

My parents are golfers. Me, not so much. Actually, make that not at all. Years and years ago my parents tried to help interest me in the sport but it didn't take. I think I played a grand total of one par 3 course. Yet when I realized that we were merely minutes from the East Potomac Golf Course, and that the course was not only open to the public, but quite affordable, I suggested to my parents that I play a round with them. I figured I'd hit a few balls, and if nothing else, get a nice walk in while I watched them show off their skills.

And this week the stars aligned: my parents were in town, the weather was perfect and I could book a 1:06pm tee time. And so I did.

We arrived at the Golf Course 45 minutes early in the hope that I could hit a few balls on the driving range. Our plan came together nicely. My Mom gave me about 10 minutes worth golf lessons, the three of us hit a bucket of balls and off we went.

We played the White Course, which consists of 9 holes. And I've got to say, when we started that first hole and I couldn't even see the flag at the other end, I was a bit intimidated. Actually, make that very intimidated. My brain tried to process what I was seeing: 141 yards away was a tiny little cup that I was expected to get a tiny little ball into.

Still, I followed my Mom's advice (keep that back swing short!; keep that left arm straight!; relax!) and what do you know, I actually managed to do OK. In fact, I left the course feeling quite proud of myself. I'd spent most, though not all, of the time on the actual fairway, didn't hurl a club, didn't throw a temper tantrum and managed to eek out a few beginner's luck shots. I did get in that nice walk as well as the joy of sharing a game with parents that they love.

Good times!


Wednesday, March 09, 2016

Up Close and Personal: Building and Using A $3.00 Digital Microscope

This DIY digital microscope project looked like a no-brainer to experiment with. So, I did. What makes the project work is the lens from a cheapy keychain laser pointer. I picked one up at CVS (the Laser Chase II) for under $3.00:

I took a needle nose pliars to it and ripped it shreds. When I was done, I had the tiny lens extracted. As suggested here, I mounted the lens by fitting it into a bobby pin and taping the bobby pin to the phone. Here was my setup, minus a tripod:

Yes, I'm using a bit Play-Doh to keep the flashlight upright in that plastic cup. And yes, I used the packaging of the laser pointer to make a slide and base for my samples. Hey, use what you've got, right?

And the results? Well, I certainly got up-close photos. I'm not sure I really captured anything that remarkable, but I'll have to keep an eye out for some more interesting specimens. The photos below are of a snippet of leaf and my saliva. As quick experiments go, I've got to say, this is a fun one. For $3.00 and 20 minutes of your time, it's hard to beat.

What the video that inspired this all: