Thursday, March 29, 2007

IA: Log4J, Error logging in Java

Error logging is a very important element of application development. In a previous post I've discussed the importance of error reporting in my current job. Dr. Liddle suggested we take a look at an error logging application, and suggested Log4J.

Log4J revolves around three main concepts:
  1. public class Logger- responsible for handling the majority of logging operations
  2. public interface Appender- responsible for controlling the output of the logging operations
  3. public abstract class Layout- responsible for the layout format of the output from Appender

Config files can be used in order to not have to hard code the options in your application and have to recompile it if ever you decide to change the options.

A simple configuration file in Java property format.

# The root logger is assigned priority level DEBUG and an

# appender named myAppender.

log4j.rootLogger=debug, myAppender

# The appender's type specified as FileAppender, i.e. log output

# written to a file.


# The appender is assigned a layout SimpleLayout.

# SimpleLayout will include only priority level of the log

# statement and the log statement itself in log output.


Configuration file log4j.xml in XML format.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="">

<appender name="myAppender"
<layout class="org.apache.log4j.NAME_OF_LAYOUT"/>

<priority value="debug" />
<appender-ref ref="myAppender"/>


In order to use the config file in your logging application you must insert the following in the startup class of the application.

import org.apache.log4j.PropertyConfigurator;




The logger is the core component of the logging process. In log4j, there are 5 normal levels of logger available (not including custom Levels), the following is borrowed from the log4j API


  • static Level DEBUG
    • The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
  • static Level INFO
    • The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
  • static Level WARN
    • The WARN level designates potentially harmful situations.
  • static Level ERROR
    • The ERROR level designates error events that might still allow the application to continue running.
  • static Level FATAL
    • The FATAL level designates very severe error events that will presumably lead the application to abort.

In addition, there are two special levels of logging available: (descriptions borrowed from the log4j API

  • static Level ALL
    • The ALL Level has the lowest possible rank and is intended to turn on all logging.
  • static Level OFF
    • The OFF Level has the highest possible rank and is intended to turn off logging.

The following ways can be used to make a logger:

  • Logger logger = Logger.getRootLogger();
  • Logger logger = Logger.getLogger("MyLogger");
  • static Logger logger = Logger.getLogger(test.class);

The last is the most common and to set its level:

  • logger.setLevel((Level)Level.WARN);


The following Appenders are available:

  1. ConsoleAppender: appends log events to System.out or System.err using a layout specified by the user. The default target is System.out.
  2. DailyRollingFileAppender extends FileAppender so that the underlying file is rolled over at a user chosen frequency.
  3. FileAppender appends log events to a file.
  4. RollingFileAppender extends FileAppender to backup the log files when they reach a certain size.
  5. WriterAppender appends log events to a Writer or an OutputStream depending on the user's choice.
  6. SMTPAppender sends an e-mail when a specific logging event occurs, typically on errors or fatal errors.
  7. SocketAppender sends LoggingEvent objects to a remote a log server, usually a SocketNode.
  8. SocketHubAppender sends LoggingEvent objects to a set of remote log servers, usually a SocketNodes
  9. SyslogAppendersends messages to a remote syslog daemon.
  10. TelnetAppender is a log4j appender that specializes in writing to a read-only socket.

An Appender can be created like this:


appender = new ConsoleAppender(new PatternLayout());


appender = null;

try {

appender = new FileAppender(new PatternLayout(),"filename");

} catch(Exception e) {}


appender = null;

try {

appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));

} catch(Exception e) {}


An appender must have one of these associated layouts:

  1. HTMLLayout formats the output as a HTML table.
  2. PatternLayout formats the output based on a conversion pattern specified, or if none is specified, the default conversion pattern.
  3. SimpleLayout formats the output in a very simple manner, it prints the Level, then a dash '-' and then the log message.


IA: Model-Driven Architecture

What is MDA?

MDA provides the ability to automatically and systematically turn a diagram or model into a functional program with very little to no coding involved in the transition.

Principles and Value Proposition

The goal of MDA is to separate business and application logic from the underlying platform technology. Platform independant models (PIM) of an application or integrated system's business functionality behavior, built using UML or another modeling standard associated with OMG, can be realized through MDA on any given platform, open or proprietary, and even Web Services, .NET, JEE, CORBA, and others.

The business and technical aspects of an application don't have to be tied together anymore, each can develop at its own pace without slowing the pace of the other.

"OMG focuses Model-driven architecture on forward engineering, i.e. producing code from abstract, human-elaborated specifications. OMG's ADTF (Analysis and Design Task Force) group leads this effort. With some humour, the group chose ADM (MDA backwards) to name the study of reverse engineering. ADM decodes to Architecture-Driven Modernization. The objective of ADM is to produce standards for model-based reverse engineering of legacy systems . KDM (Knowledge Discovery Metamodel) is the furthest along of these efforts, and describes information systems in terms of various assets (programs, specifications, data, test files, database schemas, etc.)."

"An MDA tool is a tool used to develop, interpret, compare, align, measure, verify, transform, etc. models or metamodels."
Bézivin, J, Gérard, S, Muller, P-A, and Rioux, L (2003). "MDA components: Challenges and Opportunities

MDA Tool Types

  • Creation Tool: A tool used to elicit initial models and/or edit derived models.
  • Analysis Tool: A tool used to check models for completeness, inconsistencies, or error and warning conditions. Also used to calculate metrics for the model.
  • Transformation Tool: A tool used to transform models into other models or into code and documentation.
  • Composition Tool: A tool used to compose (i.e. to merge according to a given composition semantics) several source models, preferably conforming to the same metamodel.
  • Test Tool: A tool used to "test" models as described in Model Based Testing.
  • Simulation Tool: A tool used to simulate the execution of a system represented by a given model. This is related to the subject of model execution.
  • Metadata Management Tool: A tool intended to handle the general relations between different models, including the metadata on each model (e.g. author, date of creation or modification, method of creation (which tool? which transformation? etc.)) and the mutual relations between these models (i.e. one metamodel is a version of another one, one model has been derived from another one by a transformation, etc.)
  • Reverse Engineering Tool: A tool intended to transform particular legacy or information artifact portfolios into full-fledged models.

Pasted from <>

A list of MDA tool vendors can be found at:

Optimal J

I decided to do a little research on Optimal J. OptimalJ takes business models and transforms them into working Java EE applications, currently it is working on making the application compatible with .NET. It provides UML 2.0 diagram support to quickly visualize design artifacts in a few quick steps, and quickly generate documentation from these diagrams in PDF and HTML format.

OptimalJ uses the Domain Process Model to define and describe application flow and control. The Domain Process Model is a logical progression, starting with a defining structure and behavior definition that is then unified into predictable and repeatable sequences.

OptimalJ’s UID is a rich WYSIWYG editor that is used by UI designers to build screens rapidly from a comprehensive palette of widgets. The OptimalJ UID also enables designers to graphically orchestrate the flow of an application at the presentation layer.

The Karolinska University Hospital did a comprehensive research project on MDA tools to find out which one was the best.

The following tools were evaluated:
  • Optimal J
  • Arcstyler
  • Constructor
  • Codagen Architect
  • Objecteering
  • Ameos
  • Together Architect
  • MDE Studio

Optimal J came out as the top tool, particularly for its Platform Specific Model transformation capabilities

Personal Application

I have accepted a job with Hewlett Packard as an IT Programmer/Analyst. The most I know so far about the position I will be filling is that I will be working with an internal website making sure that the necessary tools exist for the employees to get their jobs done. A Model Driven Architecture tool could easily be one of the tools that the employees are in need of, or it could be used to develop the applications that would help them to more easily complete their job.

An MDA tool seems to be more of use to an upper level employee, someone who is in charge of the analysis and design of a systems implementation in the organization. This management position would likely have some sort of technical background, or at least understanding of how an application should be modeled. I could definitely see myself in a similar position years down the road, where I could be responsible for such decisions.

The fact that a business model can be the focus of your organization's efforts, instead of having to limit or alter it due to restrictions or complexities in coding structures will be greatly minimized with the implementation of MDA.

Mormons Aren't Christians, Are They? Aren't They a Cult?

The following is an excerpt of an excellent article by Orson Scott Card on Mitt Romney and the presidential race. I highly suggest reading it.

Let me save everybody a lot of time. If by "Christian" you mean "believes in the version of God and Christ taught in the Nicene Creed," then absolutely not. Right from the start, the founding prophet of the Mormon Church, Joseph Smith, rejected that view of God as a fantasy.

Of course, by our definition of "Christian theology," we're the only Christians. That's why we send out missionaries to preach to Baptists and Methodists right along with the heathens.

And let's remember that Catholics have historically had a pretty low opinion of the doctrines of Lutherans and Quakers and Presbyterians -- and vice versa.

But in America, we all agree to get along. In fact, it says it right there in Article 6 of the Constitution: "No religious test shall ever be required as a qualification to any office or public trust under the United States."

We've had plenty of Presidents who weren't Christians, most prominently Thomas Jefferson. But most of them hadn't served as missionaries for their atheistic or deistic beliefs, either.

So let's pretend that it matters. Theologically, Mormons are way outside the mainstream of Christianity.

But how do Mormons actually live?

Despite the efforts of our opponents to paint us as a "cult," we don't live in communes in Guyana. We hold regular jobs. Most Mormon kids go to regular schools.

We wear regular clothes. (OK, maybe a little more modest than most, but that's a good thing, isn't it?)

We don't smoke or drink or do drugs -- but that makes us safer drivers and more reliable employees and better company in small closed rooms, doesn't it?

Let's forget about doctrinal religion and look at practical religion. Mormons are people who take their worship of God seriously. We really try to live by the commandments of God, as we understand them -- and they're not a bad list of commandments.

In fact, they sound kind of like what most American Christians would aspire to. Get married, be faithful to your spouse, have babies and raise them right. Don't let your life be taken over by drugs or alcohol. Hold down a job and support a family. Go to Church. Contribute to charity. Help your neighbor when he needs a hand. Be honest in your business dealings.

If you think we're not Christians, fine. But we make decent neighbors and co-workers, most of the time. And since we all agree there should be no religious test to be President, then what difference can our doctrines possibly make?

In fact, when you come right down to it, can you think of any significant point on which Mormons would disagree with an ordinary conservative Christian's view of what a President ought to do?

We may have different opinions about the nature of God, but we still pray to the God of the New Testament and recognize Jesus Christ as the Savior of the world, and try to obey his commandments, like any other practical Christians.

We Mormons treat President Bush's religious faith with respect and regard him as a Christian even though we think his theology is wrong; I think Methodists and Baptists and Catholics are mature and generous enough to treat a Mormon President the same way.

Monday, March 26, 2007

IA: MySQL Optimization

Dr. Liddle recommended that we watch Jay Pipes' Google video presentation on MySQL Optimization. I compiled what I got out of the presentation with some of my own research and have summed up all of it into the following points:
  • Joins are more effective than sub-queries
  • Use a covering index; if MySQL can get everything for a query from the index records, it's much faster
  • Understand selectivity
    • For lower selective fields, tack them on to a multi-column index
  • As your DB grows, you will need to reevaluate your index strategy
  • Use the smallest data types possible, don't use BIGINT if you don't have to.
  • Index partial fields
    • if a field is of type VARCHAR(50 or 200), you can set an index on just the first 10 characters, this will allow for quicker parsing of the data
  • In a table with many nullable columns, split off the less used data and join the two on a one to one relationship
    • understand vertical and horizontal splitting
  • With InnoDB, the primary key index is appended to every field in the table
  • Don't use surrogate keys when naturally occurring primary keys already exist
  • Use stored procedures
  • Don't use current_date when you don't need the current time stamp, the query will not be stored. If you need to, have a script populate the fields with a date, that way the query will be stored at least for the day.
  • EXPLAIN is a very useful command
    • From best to worst, Type= system, const, eq_ref, ref, range, index, all
    • Extra=using temporary or filesort
  • Optimize where clauses by eliminating unnecessary parentheses

Bowling Scores (Updated)

I just have to brag. So, stop reading if you don't want to be jealous. Last Thursday was our League Day. Each team has 3 bowlers, and we're each supposed to bowl 2 games in our 50 minute class. If one player is missing, than the two bowlers bowl 3 games a piece. Well, I was rather unfortunate last week, and none of my team mates showed up! So I thought I'd try to bowl all six games! Here's the results
  1. 98
  2. 136
  3. 138
  4. 126
  5. 146
  6. 148
I was rather impressed, that as the hour went on, my game got better. I even had to switch to a lighter ball, because the one I usually bowl with (12lbs.) was slipping out of my hand, I was so tired. I really do think this class is helping me improve, I just don't know how often I'll need to go after class is over to keep somewhat consistent. Maybe I'll try documenting all the new things I'm doing...

IA: Logging and Error Messages

In an enterprise you have various groups of users that access a varying number of systems. These users include, but are not limited to:
  1. Admins
  2. Power Users
  3. Management (Execs.)
  4. Middle mgmt.
  5. Clerks
  6. Testers
  7. Developers
  8. External Users
  9. Monkeys (e.g., hackers, or others who shouldn't be accessing the system)
Each group will not have the same level of access, which makes error reporting much more difficult. Some error messages will contain data only pertinent to a certain group of users, while others may only get a message telling them to contact their local system administrator.

In class we came up with a list of what a good error message should consist of:
  • Dialog box
  • Identifier that tells you what caused the error
  • Attention directing icon
  • Possible actions to take
  • Log a copy of the message
  • Action buttons (undo, restore, etc.)
  • Auto report to the developer
  • Description, context (ability to reproduce the error, timestamp)
You don't necessarily need to log all of your error messages, just the important ones (e.g., don't log every time someone submits a form with a null field in it.) The message should be able to tie back to a specific location in the actual program (a line number). There should be a level defined to permit the appropriate groups to access the error messages, and a time stamp should be in place to better troubleshoot the error.

Personal Application
I've dealt a lot with error messages in the last few jobs I've worked. Currently I work in conjunction with the university's monitoring group making sure all the systems on-campus are being monitored correctly, and that the correct notifications are sent to the appropriate people when something goes wrong. I guess you could say I'm part of the error message team at BYU.

I specifically write the scripts that monitor the thousands of servers on campus that report to the Operations Center what is going on. I haven't written all several thousand of them, but I've written a good share of them. Also, part of the process includes making sure that documentation exists so that when an alert goes off for one of the checks I've written, the appropriate people are contacted, and the correct actions are taken.

For instance, just recently we've been asked to write a check that will better monitor the state of the LDAP connections to the campus' databases. My co-worker and I had to interface with the DBA's and try to understand the process they wanted to monitor. We then wrote and tested the script, and confirmed the error messages with the DBA's. Next in line we have to document how the check is to be handled, test it, and move it into production.

Wednesday, March 21, 2007

Out of the Ordinary Bowling Games

I've really been enjoying my bowling class. I never realized that there were other games you could play with a bowling ball besides the standard game. Here's a list of the games we've learned so far. If you know of any other game, or if the instructions aren't very clear, please feel free to comment.

Bowling Bingo

You need two people per team, each team with a bingo card, with numbers (repeats are OK) ranging from 1-20. is a good place to print up bingo cards online. The first player from each team bowls the first ball and remembers the number of pins knocked down (if the ball ends up in the gutter, you have to start over). Player one doesn't bowl a second time, but resets the pins so that all ten pins are back up. Player two then bowls and combines his pins knocked down with his team mates and then marks the appropriate bingo square. Once one of the two teams gets Bingo, the cards are cleared and play starts again.

Lowest score wins.

1. Strike = birdie (-1)
2. Each additional consecutive strike = eagle (-2)
3. Spare = par (0)
4. 1 pin left standing = bogey (+1)
5. Any number of pins left standing is plus that many pins to your score

The object of this game is to get the lowest score. It's not as easy as it sounds. The basic rules for scoring are

1. Gutter = Strike
2. Hitting no pins and not ending up in the gutter = 5 pins
3. Everything else is normal

A perfect Low-ball score is 20, with one pin being knocked down in each frame.

Example situation:
-Lets say you have 25 pins in the 5th frame and in the sixth frame you bowl a gutter and then spare, in the seventh frame you then first knock down 7 pins. Your score in the sixth frame would be 52 (10 for the spare, 10 for a gutter ball, and then 7 for the first bowl of the 7th frame.

One-frame each, against teams
You need two teams right next to each other with an equal number of players. The first two players step up and switch lanes on the first bowl. If either gets a gutter ball, it counts as a strike for the other team. After the first bowl each player must try to pick up the spare in their own lane on the second bowl.

(What about hitting 0 pins and not a gutter) Highest score wins.

Rock, paper, scissors to see who gets to go first. The first person to get a strike is 'X'. After that each spare or strike wins you the opportunity to mark your respective 'X' or 'O'. If you bowl a strike or spare and your opponent doesn't get a strike or a spare, you may get chance to go two times in a row!

Scotch Doubles
Find a partner. You and your partner will bowl using the same ten frames. One of you will start off with the first bowl. If you strike, your partner then starts the next frame. If you don't strike, your partner then must try to pick up the spare. After your partner bowls, you start the next frame again. Scoring is normal.

Tuesday, March 20, 2007

Annalee's two week visit

Annalee went to the doctor today for her two week check up. The doctor said that normally babies are doing good if they're back up to their birth weight by their two week visit. Annalee was a full pound over her birth weight, 7 lbs. 14 oz. and she's 19.75 inches high! She's doing really well.

One thing we'll need to work on is getting her to lean her head more to her right. She always leans her head on her left shoulder, and the doctor said it is probably because she was in that position while in the womb, and her muscles developed that way. So we have to help her stretch that muscle by holding her head to her right side 3 times for 10 seconds each. This will help stretch out that other muscle and keep her from any possible head deformations. Other ways to help her are to keep boring things on her left side (e.g., a wall) and the rest of the room on the right, getting her to try to move her head to the more active part of the room, hopefully getting her to exercise the right neck muscle on her own.

WA: Campaign Management

Campaign Management, in the context of web analytics, deals with the tracking of the success events stemming from email blasts, banner ads, or other forms of online marketing. The way these campaigns are tracked is via the URL (e.g., that is clicked (on the actual banner, or in the email body). The part of the URL that matters is called the query string parameter (everything after the '?'). The javascript on the page will then grab the query string parameter and report it to SiteCatalyst where you will be able to see the results of your campaigns in the Tracking Code Report.

Each element in a marketing campaign should have a unique tracking code associated with it. There are two ways to populate the campaign variable in the javascript on the web page.
  1. getQueryParam plug-in- retrieves the query string from the URL
  2. Assign a value to the campaign variable in the HTML on the web page (you may want to do this if you have a sales promotion web page)
A problem occurs when users entering a page through a campaign URL navigate to another page, then press the back button to take them back to the landing page and grabbing the query string parameter again. "To avoid this inflation of click-throughs, it is recommended to use the getValOnce plug-in to force each campaign click-through to be counted only once per session." (Omniture Implementation Guide).

Expiration setting allow you to track the tracking code over a certain period of time. If some one comes to your website via campaign tracked URL, bookmarks the page, and then returns a few days later and makes a purchase; as long as the expiration of the campaign variable is set to more than a few days, the campaign will be credited with the sale.

Setting Campaign Classifications allows you to track various campaign elements under one category. For instance your could have several banners hosted by Yahoo, each one with a separate query string parameter, but if they are all assigned to the Yahoo classifications, they will all be able to be seen in the Yahoo Classification Report.

Wednesday, March 14, 2007

WA: Choice Skills, Inc. Website Analysis

For class yesterday we had George Rogers come and talk to us about his website It is really an awesome idea, something this world really needs. He has published a couple lesson plan manuals that tie into schools' core curriculum requirements and at the same time teach the students character building principles. He has also published Benjamin Franklin's "The Art of Virtue," and a little kids book entitled, "Mac and Zach from Hackensack." All of these items are aimed at building character.

For class we are going to be using SiteCatalyst on the website. This time though, we will get to see it from the beginning of the implementation, see carious implementations put into production and hopefully be able to see the results of our suggestions.

The part that stood out most to me was the lesson finder. This seems like a very useful tool to have and to show visitors the contents of the manuals before they buy them. There's nothing special about the way it is presented, just in a simple html table. The information seems rather intimidating, not very inviting to the reader. It is possible that they see so many things that it has to be great. But I can also see a lot of people wanting to see a more organized list of topics. The different sections help a little bit, but those sections aren't even mentioned at the top. A reader needs to be given some sort of a summary of what type of material they are about to peruse in order to get them to peruse it. Just like the blurb on the back of a book, or even the preface.

It might also be useful to have the Activity titles categorized into a list for each of the Core Curriculum Requirements, CCR, (e.g., Reading Comprehension, Communication, Science, etc.). This would help visitors see the variety of lessons for each CCR. The lists could be viewed in any of the previous ways.

I would also recommend doing away with the detailed table being completely visible, it is rather intimidating. If the lists are made as recommended above, you could make each item dynamic so that when the person hovered over the item, or clicked on the item, the list expanded enough to show more detailed information for that line item. This idea is very similar to the left menu bar that expands for the various topics. This would require a little more technical prowess,
perhaps implementing some Javascript and/or Ajax.

This organization would be most beneficial to a click map, so that you could see what it is users most click on, which categories draw the most traffic/interest. This info could be used in certain promotions (email, website, etc.).

It would also make it easier for teachers to see if there are many lesson plans that would benefit them if they could search to find lesson plans on specific topics or browse by category. With an internal searching function, at first it may not be very successful, but with SiteCatalyst you could trace the terms that are searched and better design the site to help visitors find what they are looking for.

(I'd like to thank my wife for helping me in this analysis. She is a teacher and had some very good insights.)

Worthwhile Financial Blogs

I've found myself frequently checking up on a few blogs with some pretty useful financial information.

Personal Finance Advice
Some of the topics include interviews with ex-theives on where not to hide your money in your house; various ways to save money on cell phone plans, pizza, etc.; and investing information. There's plenty more, so check out Personal Finance Advice.

The Simple Dollar
Similar to PFAdvice, the Simple Dollar provides a lot of financial advice. Some of the recent topics have included money saving techniques with replacing your light bulbs with CFL's; Information on mortgaging; saving on household cleaners by making your own non-toxic ones, etc.

Hope you enjoy these!

Monday, March 12, 2007

WA: Google Analytics

I was feeling kind of left out in my web analytics class because I don't have any website that I could monitor to see who's visiting it, where most of my traffic is coming from, and make improvements and see their affects. All I had was my lonely blog on google's blogger. I did wish I could monitor my blog, but I thought that you had to be the actual owner of the website to track its analytics. As we were going over the features of Google analytics in class, I thought I'd at least search for a possibility of tracking my blog. To my surprise and pleasure I found that it is possible and Google tells you how right here. Let me outline the steps you have to take.
  1. Open/Create an account at
  2. Sign into your blogger account
  3. Navigate to Layout, and then view HTML
  4. Paste the Analytics tracking code directly above the closing tags, don't include them (</body> and </html>, it's at the very bottom):

    <script src="" type="text/javascript">
    <script type="text/javascript">
    _uacct = "UA-xxxxxx-x";


5. Where xxxxxx-x is the tracking code that you are assigned when you create your account at (they'll provide you with the snippet of code above with your tracking number already in it.)
6. Save changes and republish your blog.
7. You're done!

One of my favorite reports to see is the Geo-map Overlay report under geo-segmentation in the Marketing reports. This shows you how many visits you've received from visitors all over the world, and what cities they come from. I've seen visits from Argentina, China, Germany, and all over the U.S.A.

Be careful though, it can be rather addicting.

Saturday, March 10, 2007

IA: Scaling a PostgreSQL DBMS

At first the research for this topic of scaling a PostgreSQL DBMS seemed rather daunting. I thought I would be able to simply enter "scaling postgres DBMS" into a google search, and there would be plenty of information. It wasn't quite that easy. The other groups in my class that were working on MySQL and SQL Server are probably having a lot more luck because those DBMS' are more widely used.

I haven't been totally unsuccessful with finding information on this topic. Some of the most helpful websites have been:
    • This site has a good list of postmaster options to adjust in order to drastically increase performance on your DBMS. It also includes a list of hardware that can be upgraded or its capacity increased in order to further increase the scalability of your database. There is also a short section on query tuning.
    • Another list of hardware configuration recommendations
    • There are several blog articles/entries by Josh Berkus on PostgreSQL performance enhancing and query tuning. These very well worth looking into.
I'll post more sources as I wrap up my portion of the research, and even post the summary of my research.

Monday, March 05, 2007

I'm a daddy!!!

As of March 4, 2007, 8:24am Sherrie and I are parents to a 6 lb. 14 oz. 19 in. little girl! It is the most amazing feeling. Saturday night as Sherrie was having her contractions I was realizing how much different our lives will be now. They will never be the same. We're so excited. I'll update this post with pictures as soon as I get the cable for my camera.

It took us two days of deliberation after her birth to come up with a name. We were deciding between Caitlin, Lorelei, and Annalee. Annalee won out. Her full name is Annalee Sherrie Anderson.