<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Schauderhaft &#187; good practice</title>
	<atom:link href="http://blog.schauderhaft.de/tag/good-practice/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.schauderhaft.de</link>
	<description>Softwaredevelopment, Projectmanagement, Qualitymanagement and all things &#34;schauderhaft&#34;</description>
	<lastBuildDate>Sun, 05 Feb 2012 20:46:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Are You a Software Developer or a Dabbler</title>
		<link>http://blog.schauderhaft.de/2009/11/01/are-you-a-software-developer-or-a-dabbler/</link>
		<comments>http://blog.schauderhaft.de/2009/11/01/are-you-a-software-developer-or-a-dabbler/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 08:38:23 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[dabbler]]></category>
		<category><![CDATA[good practice]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[solid software]]></category>
		<category><![CDATA[source code]]></category>
		<category><![CDATA[version control system]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=307</guid>
		<description><![CDATA[When reading blogs you get the impression, that everybody works in high end environments, using the latest greatest distributed version control system. Writing tons of tests, before they even dream about writing actual code and of course the tests a executed by the continuous integration system after every commit, which happens about 30 times per [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_308" class="wp-caption alignleft" style="width: 310px"><a href="http://www.sxc.hu/photo/289526"><img class="size-medium wp-image-308" title="289526_6178" src="http://blog.schauderhaft.de/wp-content/uploads/2009/10/289526_6178-300x225.jpg" alt="Tools" width="300" height="225" /></a><p class="wp-caption-text">Tools</p></div>
<p>When reading blogs you get the impression, that everybody works in high end environments, using the latest greatest distributed version control system. Writing tons of tests, before they even dream about writing actual code and of course the tests a executed by the continuous integration system after every commit, which happens about 30 times per day and developer. But when I look around in the real world, this is not <a href="/2009/09/20/your-perspective-is-biased/">what I see</a>. Instead the way people work on their code like ancient &#8216;doctors&#8217;. Drilling holes in heads in the hope it will reduce the headache of the patient. It probably did. In many cases in a very final way. I urge you: Don&#8217;t let that happen to your code (or your career). Practice solid software development. And in order to help you with that I compiled a simple list of things you really really should do. Those are basic practices. If you don&#8217;t even adhere to those then I have only two possible explanations: You are not involved in software development at all. Go away, this blog isn&#8217;t for you. Or &#8230; you are a dabbler.</p>
<ul>
<li>Use a Version Control System (VCS). I am not even going to comment on this one.</li>
<li>Commit your changes at least once a day. This does not mean you should commit what ever is on your filesystem at 5pm, but you should break your tasks in so small pieces, that you finish one or two of them on a normal day.</li>
<li>Tag or label everything in the VCS you hand out to somebody outside your team (testers, salespersons and of course customers)</li>
<li>Have a complete and working build script. This means you can build everything you hand of to the customer by getting the source code out of the VCS and start the script. Necessary adjustments are made in a tiny file which contains settings for the local machine. A well commented template for such a file is in the VCS. And NO, hitting the compile button in your IDE is not the same as a build script.</li>
<li>You must have the complete environment necessary to run your application under your control. That means if your application needs a database, you have a database available. One per developer that is, or at least one schema per developer. If you need a queue or ten queues, you have those, again once for every developer. If you have systems that you interface to, that can&#8217;t be installed once per developer, you have mocks, stubs or similar available. In the year 2009 a single developer database for 5 developers is no longer acceptable.</li>
<li>You have an extensive set of automatic Unit tests. These test should cover at the minimum the main execution paths.</li>
<li>Let a Continuous Integration system execute your build script, i.e it compiles your code, executes the automatic tests and builds a setup or jar, or what ever you are deploying.</li>
<li>Have a specification of what a piece of software is supposed to do, before you try to write the software. You don&#8217;t need a full specification of the complete application upfront. Maybe you have just the first user story for the first feature, or only a test. But you must have something that tells you where to go. And where not to go. Flying blindfolded is not the same as being agile.</li>
<li>Adhere to a style guide that describes your naming conventions, indenting and so on. Ideally this gets enforced by the IDE and automatic tests. Fighting about the content of such code conventions is useless. Not having one is dumb. Remember that your tests are code too, so the conventions apply to tests as well.</li>
<li>Document how your code is structured. It should at least describe the different layers, and the way two layers may depend on each other, and it should not allow for circular dependencies. These rules as well should be enforced by automatic tests. Even if the language you use doesn&#8217;t support packages you should use a similar concept, possibly through naming conventions.</li>
</ul>
<p>These are my points. What did I miss?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2009/11/01/are-you-a-software-developer-or-a-dabbler/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Good Logging Practices</title>
		<link>http://blog.schauderhaft.de/2009/09/16/good-logging-practices/</link>
		<comments>http://blog.schauderhaft.de/2009/09/16/good-logging-practices/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 12:00:46 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[good practice]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[meta logga]]></category>
		<category><![CDATA[slf4j]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=210</guid>
		<description><![CDATA[Nearly everybody does some kind of logging in their application, but few do it in a well structured way. I&#8217;d like to point out some practices that I consider helpful in order to get the most out of your logging. This post will also work as a handout for my talk about logging at the [...]]]></description>
			<content:encoded><![CDATA[<p>Nearly everybody does some kind of logging in their application, but few do it in a well structured way. I&#8217;d like to point out some practices that I consider helpful in order to get the most out of your logging. This post will also work as a handout for my <a href="http://www.herbstcampus.de/hc09/program/sessions.html#29">talk about logging</a> at the herbstcampus conference. So here we go:</p>
<ol>
<li><strong>Know your audience</strong>. If you look at the log files of many applications you quickly realize who the intended audience is: Developers. The log is full with technical detail, but not much of it makes sense to anybody else. The groups you probably should have on your list are: <strong>Developers</strong> on the search for bugs, performance issues, <strong>Administrators</strong> trying to install, start or shutdown your application and <strong>Support</strong> personal trying to detect and analyze problems or trying to verify that a problem did not occur. Once you realize there are different audiences you&#8217;ll understand what kind of information is helpfull in the logs.</li>
<li><strong>Use a framework</strong>. The major options are: <a href="http://logging.apache.org/log4j/1.2/index.html">Log4j</a>, <a href="http://www.slf4j.org/">SLF4J</a>, <a href="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html">JUL</a>, <a href="http://commons.apache.org/logging/">Commons Logging</a> or <a href="http://logback.qos.ch/">Logback</a>. Each one has it&#8217;s pros and cons, but they are all better then System.out.println. They allow you to configure at deploy or runtime, what gets logged where and in what format. If you don&#8217;t want to do any research, and don&#8217;t have special requirements, use SLF4J.</li>
<li><strong>Logging must be rock solid</strong>. If a logging causes problems. Throw it out. Don&#8217;t do experiments like remote logging, if you can avoid it.</li>
<li><strong>Define rules, when to use which Log Level</strong>: I propose the following:
<ul>
<li>DEBUG: Not important, except if you are researching a very specific problem.</li>
<li>INFO: General information like startup, shutdown, version and configuration of an application. Information about important decisions in the code or changes in the configuration.</li>
<li>WARN: Things that are fishy, but don&#8217;t represent a problem in themself, but might indicate a problem when appearing very often. E.g. a failed log in attempt is such a candidate. If it happens sometime it is not a problem, but if it happens a lot somebody might want to look into that.</li>
<li>ERROR: This should only be used when a problem occurs that somebody needs to look into. Typically but not necessarily relating to an exception in the code. Use this when only a limited part of the application is affected.</li>
<li>FATAL: If something goes completely wrong, rendering the application unable to recover this log level is appropriate, very likely accompanied by a shutdown of the application or the session.</li>
</ul>
<p>Of course your rules need some tayloring for your context, but absolutely need rules, and every developer must know and understand those.</li>
<li><strong>Log everything you log exactly once</strong>: When analyzing log files I often see log messages that always come in groups. This happens often when exceptions get caught, logged, and rethrown. Don&#8217;t do that. Log at the place where you actually do handle the exception. This is the only way to log an exception exactly once and also being able to decide which log level to use.</li>
<li><strong>Include useful information and data</strong>: The information should typically include answers to the following questions
<ul>
<li>Why are you logging this, typically the root cause of an exception.</li>
<li>What is the affected use case? Did it happen during creation of an order or when importing product data from a remote site?</li>
<li>What effect has it on the use case that was executing? Does the user need to repeat the action, or did it succeed? Did the complete batch fail, or just a single step?</li>
<li>What instance of the use case was effected? For example an order id.</li>
</ul>
<p>In order to make all this information available to your logs <a href="http://logback.qos.ch/manual/mdc.html">MDC (Mapped Diagnostic Context)</a> is tremendously helpful. If you don&#8217;t know MDC, follow the link and read about it NOW. MDC exists also in <a href="http://www.slf4j.org/api/org/slf4j/MDC.html">SLF4J</a> and <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html">Log4J</a> and should be easy to port for other frameworks as well.</li>
<li><strong>Use <a href="/2009/02/24/logging/">more then one logging hierachy</a></strong>: The link contains more information about why. The simple idea is, that you can seperate different aspects you want to log by using different prefixes. This becomes especially usefull when adhering to the following points</li>
<li><strong>Log the time needed for stuff which might be intersting for tuning</strong>: Of course this includes the time used for access to remote resources (e.g. webservices or databases) and execution of complex algorithms, but possibly also the time spend in the various layers in the application. You can use different log level for three categories, a separate logging hierarchy for separating performance logging from other stuff. Performance problems a notorious difficult to hunt down, especially when they appear over time. You&#8217;ll love this logs, when performance becomes an issue.</li>
<li><strong>Log stuff that worked, not only what failed</strong>: Distributed systems become common place more and more. When debugging distributed system one often has the situation that requests just disappear, and it can be extremely challenging to decide which component failed. After all not everybody does such a fine logging as us, right? So I recommend the following log events:
<ul>
<li>RECEIVED: The application received a request through the UI, a Webservice or any kind of interface offered.</li>
<li>SEND: The application send a request to some other component.</li>
<li>GOT ANSWER:  The application got a reply to a request it send.</li>
<li>ANSWERED: The application answered to a request it received.</li>
</ul>
</li>
<li><strong>Log how often stuff happens</strong>: One possible reason for decreasing performance is a changed usage pattern. So logging how often per day, hour or minute a certain kind of use case is triggered can help tremendously.</li>
</ol>
<p>While obviously I recommend a lot of logging, it isn&#8217;t free of cost. So when doing some logging you should be sure to avoid it in tight loops that get executed millions of times. Also MDC keeps a reference to everything you put into, so make sure to clear it when you are done and think twice before putting complex objects in. And finally think about data privacy. A lot of people might have access to the log files. They shouldn&#8217;t find passwords, credit cards or similar information their.</p>
<p>Probably somewhere around point number 8 you might have started to think: &#8220;Man this guy is crazy. I&#8217;ll have more highly repetitive logging code than anything else in my application!&#8221; And if you do everything by hand you are probably right. But if you have cleanly structured code where you can deduct use cases, application layers, access to remote connections and so on from the method signature and the packages involved, most of these logging statement can get injected using AOP. So what is left is to create a framework that handles all this.</p>
<p>Since I couldn&#8217;t find an Open Source Solution I started my own: <a href="http://code.google.com/p/metalogga/">Meta Logga</a>. It is still in an extremely early stage, definitely not ready to be used, but possibly ready to understand where I am heading.</p>
<p>If you agree with me that this is indeed something that would be useful you can help in many extremely easy ways. Comment on this post, <a href="http://twitter.com/jensschauder">tweet</a> it, dzone it, blog about or in any other way make this post more visible to others. All this will help me to keep motivated, thus it will help the project.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2009/09/16/good-logging-practices/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

