<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: The Evolution of a Replacement for NSLog</title>
	<atom:link href="http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/feed" rel="self" type="application/rss+xml" />
	<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog</link>
	<description>Tips and Tricks for iPhone SDK Developers</description>
	<lastBuildDate>Thu, 11 Mar 2010 21:29:19 -0700</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Nick</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-1915</link>
		<dc:creator>Nick</dc:creator>
		<pubDate>Tue, 26 Jan 2010 23:08:20 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-1915</guid>
		<description>Thanks Bill!</description>
		<content:encoded><![CDATA[<p>Thanks Bill!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill Hollings</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-1914</link>
		<dc:creator>Bill Hollings</dc:creator>
		<pubDate>Tue, 26 Jan 2010 22:13:05 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-1914</guid>
		<description>Just came across this posting. Thanks for some great ideas here, Nick!

After reading this blog entry, I took these ideas, along with some other typical logging ideas such as logging levels, and created a Logging.h header file. In the spirit of appreciation, I thought I&#039;d contribute the code from that file back to this thread. The code below can be used as-is...just paste it into a central header file somewhere (as mentioned, we created a Logging.h file). There are a series of switches that can be set to customize formats, and turn specific logging levels on and off, or remove logging altogether.

I hope this proves useful to someone.

...Bill Hollings

/*
 * There are three levels of logging: debug, info and error, and each can be enabled independently
 * via the LOGGING_LEVEL_DEBUG, LOGGING_LEVEL_INFO, and LOGGING_LEVEL_ERROR switches below, respectively.
 * In addition, ALL logging can be enabled or disabled via the LOGGING_ENABLED switch below.
 *
 * To perform logging, use any of the following function calls in your code:
 *
 *		LogDebug(fmt, ...)   - will print if LOGGING_LEVEL_DEBUG is set on.
 *		LogInfo(fmt, ...)    - will print if LOGGING_LEVEL_INFO is set on.
 *		LogError(fmt, ...)   - will print if LOGGING_LEVEL_ERROR is set on.
 *
 * Each logging entry can optionally automatically include class, method and line information by
 * enabling the LOGGING_INCLUDE_CODE_LOCATION switch.
 *
 * Logging functions are implemented here via macros, so disabling logging, either entirely,
 * or at a specific level, removes the corresponding log invocations from the compiled code, 
 * thus completely eliminating both the memory and CPU overhead that the logging calls would add.
 */

// Set this switch to  enable or disable ALL logging.
#define LOGGING_ENABLED		1

// Set any or all of these switches to enable or disable logging at specific levels.
#define LOGGING_LEVEL_DEBUG		1
#define LOGGING_LEVEL_INFO		1
#define LOGGING_LEVEL_ERROR		1

// Set this switch to set whether or not to include class, method and line information in the log entries.
#define LOGGING_INCLUDE_CODE_LOCATION	1

// ***************** END OF USER SETTINGS  ***************


#if !(defined(LOGGING_ENABLED) &amp;&amp; LOGGING_ENABLED)
	#undef LOGGING_LEVEL_DEBUG
	#undef LOGGING_LEVEL_INFO
	#undef LOGGING_LEVEL_ERROR
#endif

// Logging format
#define LOG_FORMAT_NO_LOCATION(fmt, lvl, ...) NSLog((@&quot;[%@] &quot; fmt), lvl, ##__VA_ARGS__)
#define LOG_FORMAT_WITH_LOCATION(fmt, lvl, ...) NSLog((@&quot;%s [Line %d] [%@] &quot; fmt), __PRETTY_FUNCTION__, __LINE__, lvl, ##__VA_ARGS__)

#if defined(LOGGING_INCLUDE_CODE_LOCATION) &amp;&amp; LOGGING_INCLUDE_CODE_LOCATION
	#define LOG_FORMAT(fmt, lvl, ...) LOG_FORMAT_WITH_LOCATION(fmt, lvl, ##__VA_ARGS__)
#else
	#define LOG_FORMAT(fmt, lvl, ...) LOG_FORMAT_NO_LOCATION(fmt, lvl, ##__VA_ARGS__)
#endif
	
// Debug level logging
#if defined(LOGGING_LEVEL_DEBUG) &amp;&amp; LOGGING_LEVEL_DEBUG
	#define LogDebug(fmt, ...) LOG_FORMAT(fmt, @&quot;debug&quot;, ##__VA_ARGS__)
#else
	#define LogDebug(...)
#endif

// Info level logging
#if defined(LOGGING_LEVEL_INFO) &amp;&amp; LOGGING_LEVEL_INFO
	#define LogInfo(fmt, ...) LOG_FORMAT(fmt, @&quot;info&quot;, ##__VA_ARGS__)
#else
	#define LogInfo(...)
#endif

// Error level logging
#if defined(LOGGING_LEVEL_ERROR) &amp;&amp; LOGGING_LEVEL_ERROR
	#define LogError(fmt, ...) LOG_FORMAT(fmt, @&quot;***ERROR***&quot;, ##__VA_ARGS__)
#else
	#define LogError(...)
 #endif</description>
		<content:encoded><![CDATA[<p>Just came across this posting. Thanks for some great ideas here, Nick!</p>
<p>After reading this blog entry, I took these ideas, along with some other typical logging ideas such as logging levels, and created a Logging.h header file. In the spirit of appreciation, I thought I&#8217;d contribute the code from that file back to this thread. The code below can be used as-is&#8230;just paste it into a central header file somewhere (as mentioned, we created a Logging.h file). There are a series of switches that can be set to customize formats, and turn specific logging levels on and off, or remove logging altogether.</p>
<p>I hope this proves useful to someone.</p>
<p>&#8230;Bill Hollings</p>
<p>/*<br />
 * There are three levels of logging: debug, info and error, and each can be enabled independently<br />
 * via the LOGGING_LEVEL_DEBUG, LOGGING_LEVEL_INFO, and LOGGING_LEVEL_ERROR switches below, respectively.<br />
 * In addition, ALL logging can be enabled or disabled via the LOGGING_ENABLED switch below.<br />
 *<br />
 * To perform logging, use any of the following function calls in your code:<br />
 *<br />
 *		LogDebug(fmt, &#8230;)   &#8211; will print if LOGGING_LEVEL_DEBUG is set on.<br />
 *		LogInfo(fmt, &#8230;)    &#8211; will print if LOGGING_LEVEL_INFO is set on.<br />
 *		LogError(fmt, &#8230;)   &#8211; will print if LOGGING_LEVEL_ERROR is set on.<br />
 *<br />
 * Each logging entry can optionally automatically include class, method and line information by<br />
 * enabling the LOGGING_INCLUDE_CODE_LOCATION switch.<br />
 *<br />
 * Logging functions are implemented here via macros, so disabling logging, either entirely,<br />
 * or at a specific level, removes the corresponding log invocations from the compiled code,<br />
 * thus completely eliminating both the memory and CPU overhead that the logging calls would add.<br />
 */</p>
<p>// Set this switch to  enable or disable ALL logging.<br />
#define LOGGING_ENABLED		1</p>
<p>// Set any or all of these switches to enable or disable logging at specific levels.<br />
#define LOGGING_LEVEL_DEBUG		1<br />
#define LOGGING_LEVEL_INFO		1<br />
#define LOGGING_LEVEL_ERROR		1</p>
<p>// Set this switch to set whether or not to include class, method and line information in the log entries.<br />
#define LOGGING_INCLUDE_CODE_LOCATION	1</p>
<p>// ***************** END OF USER SETTINGS  ***************</p>
<p>#if !(defined(LOGGING_ENABLED) &amp;&amp; LOGGING_ENABLED)<br />
	#undef LOGGING_LEVEL_DEBUG<br />
	#undef LOGGING_LEVEL_INFO<br />
	#undef LOGGING_LEVEL_ERROR<br />
#endif</p>
<p>// Logging format<br />
#define LOG_FORMAT_NO_LOCATION(fmt, lvl, &#8230;) NSLog((@&#8221;[%@] &#8221; fmt), lvl, ##__VA_ARGS__)<br />
#define LOG_FORMAT_WITH_LOCATION(fmt, lvl, &#8230;) NSLog((@&#8221;%s [Line %d] [%@] &#8221; fmt), __PRETTY_FUNCTION__, __LINE__, lvl, ##__VA_ARGS__)</p>
<p>#if defined(LOGGING_INCLUDE_CODE_LOCATION) &amp;&amp; LOGGING_INCLUDE_CODE_LOCATION<br />
	#define LOG_FORMAT(fmt, lvl, &#8230;) LOG_FORMAT_WITH_LOCATION(fmt, lvl, ##__VA_ARGS__)<br />
#else<br />
	#define LOG_FORMAT(fmt, lvl, &#8230;) LOG_FORMAT_NO_LOCATION(fmt, lvl, ##__VA_ARGS__)<br />
#endif</p>
<p>// Debug level logging<br />
#if defined(LOGGING_LEVEL_DEBUG) &amp;&amp; LOGGING_LEVEL_DEBUG<br />
	#define LogDebug(fmt, &#8230;) LOG_FORMAT(fmt, @&#8221;debug&#8221;, ##__VA_ARGS__)<br />
#else<br />
	#define LogDebug(&#8230;)<br />
#endif</p>
<p>// Info level logging<br />
#if defined(LOGGING_LEVEL_INFO) &amp;&amp; LOGGING_LEVEL_INFO<br />
	#define LogInfo(fmt, &#8230;) LOG_FORMAT(fmt, @&#8221;info&#8221;, ##__VA_ARGS__)<br />
#else<br />
	#define LogInfo(&#8230;)<br />
#endif</p>
<p>// Error level logging<br />
#if defined(LOGGING_LEVEL_ERROR) &amp;&amp; LOGGING_LEVEL_ERROR<br />
	#define LogError(fmt, &#8230;) LOG_FORMAT(fmt, @&#8221;***ERROR***&#8221;, ##__VA_ARGS__)<br />
#else<br />
	#define LogError(&#8230;)<br />
 #endif</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steven Fisher</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-1116</link>
		<dc:creator>Steven Fisher</dc:creator>
		<pubDate>Fri, 11 Sep 2009 20:27:19 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-1116</guid>
		<description>DLog(aStringVariable) isn&#039;t really safe or useful anyway, unless you&#039;re sure the string won&#039;t contain any % sequences. And if you knew what the string was, you wouldn&#039;t really need to log it. If it&#039;s worth doing, it&#039;s worth doing right.

(It&#039;s usually a security issue, too, but I don&#039;t think that matters for a macro that isn&#039;t going to be in release builds.)</description>
		<content:encoded><![CDATA[<p>DLog(aStringVariable) isn&#8217;t really safe or useful anyway, unless you&#8217;re sure the string won&#8217;t contain any % sequences. And if you knew what the string was, you wouldn&#8217;t really need to log it. If it&#8217;s worth doing, it&#8217;s worth doing right.</p>
<p>(It&#8217;s usually a security issue, too, but I don&#8217;t think that matters for a macro that isn&#8217;t going to be in release builds.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-948</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Fri, 19 Jun 2009 15:28:21 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-948</guid>
		<description>Thanks for the handy logging code!

Just in case anyone has this same problem:

When I tried to add a User Defined GCC_PREPROCESSOR_DEFINITIONS I received the error that this was already defined, although I couldn&#039;t find it anywhere.

Instead I had to go to Show: All Settings and find: Preprocessor Macros under the GCC 4.2 - Preprocessing section and add DEBUG=1 to that item.

It seems Preprocessor Macros and GCC_PREPROCESSOR_DEFINITIONS are the same thing?

I&#039;m using the 3.0 sdk if that matters...</description>
		<content:encoded><![CDATA[<p>Thanks for the handy logging code!</p>
<p>Just in case anyone has this same problem:</p>
<p>When I tried to add a User Defined GCC_PREPROCESSOR_DEFINITIONS I received the error that this was already defined, although I couldn&#8217;t find it anywhere.</p>
<p>Instead I had to go to Show: All Settings and find: Preprocessor Macros under the GCC 4.2 &#8211; Preprocessing section and add DEBUG=1 to that item.</p>
<p>It seems Preprocessor Macros and GCC_PREPROCESSOR_DEFINITIONS are the same thing?</p>
<p>I&#8217;m using the 3.0 sdk if that matters&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: links for 2009-06-11 &#124; manicwave.com</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-936</link>
		<dc:creator>links for 2009-06-11 &#124; manicwave.com</dc:creator>
		<pubDate>Fri, 12 Jun 2009 03:28:17 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-936</guid>
		<description>[...] The Evolution of a Replacement for NSLog &#124; iPhone Development Blog an intelligent NSLog replacement (tags: iphone debugging logging) [...]</description>
		<content:encoded><![CDATA[<p>[...] The Evolution of a Replacement for NSLog | iPhone Development Blog an intelligent NSLog replacement (tags: iphone debugging logging) [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Al</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-932</link>
		<dc:creator>Al</dc:creator>
		<pubDate>Thu, 11 Jun 2009 10:34:16 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-932</guid>
		<description>Just incase anyone is as stupid as me and does a search and replace to change all existing NSLog calls to DLog - remember that the .pch file should not be included in this search!

The error message: implicit declaration of function DLog had me confused for a while until I realised I had also changed the definitions in the pch file!

Doooh.</description>
		<content:encoded><![CDATA[<p>Just incase anyone is as stupid as me and does a search and replace to change all existing NSLog calls to DLog &#8211; remember that the .pch file should not be included in this search!</p>
<p>The error message: implicit declaration of function DLog had me confused for a while until I realised I had also changed the definitions in the pch file!</p>
<p>Doooh.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jarek</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-770</link>
		<dc:creator>Jarek</dc:creator>
		<pubDate>Sun, 17 May 2009 04:58:00 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-770</guid>
		<description>Good post, smart technique. And easy to implement. Finally I&#039;ll get rid of all debug text from my releases.

Thanks</description>
		<content:encoded><![CDATA[<p>Good post, smart technique. And easy to implement. Finally I&#8217;ll get rid of all debug text from my releases.</p>
<p>Thanks</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mare</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-706</link>
		<dc:creator>mare</dc:creator>
		<pubDate>Thu, 07 May 2009 12:38:45 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-706</guid>
		<description>&lt;em&gt;If you are using OTHER_CFLAGS then set the value to -DDEBUG=1, if you are instead using GCC_PREPROCESSOR_DEFINITIONS then the value needs to be just DEBUG=1&lt;/em&gt;

That was it. Thanks!</description>
		<content:encoded><![CDATA[<p><em>If you are using OTHER_CFLAGS then set the value to -DDEBUG=1, if you are instead using GCC_PREPROCESSOR_DEFINITIONS then the value needs to be just DEBUG=1</em></p>
<p>That was it. Thanks!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nick</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-539</link>
		<dc:creator>Nick</dc:creator>
		<pubDate>Tue, 21 Apr 2009 23:39:12 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-539</guid>
		<description>If you get &quot;error: macro names must be identifiers&quot;, then make sure you have defined DEBUG properly.

If you are using OTHER_CFLAGS then set the value to -DDEBUG=1, if you are instead using GCC_PREPROCESSOR_DEFINITIONS then the value needs to be just DEBUG=1</description>
		<content:encoded><![CDATA[<p>If you get &#8220;error: macro names must be identifiers&#8221;, then make sure you have defined DEBUG properly.</p>
<p>If you are using OTHER_CFLAGS then set the value to -DDEBUG=1, if you are instead using GCC_PREPROCESSOR_DEFINITIONS then the value needs to be just DEBUG=1</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mare</title>
		<link>http://iPhoneIncubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog/comment-page-1#comment-536</link>
		<dc:creator>mare</dc:creator>
		<pubDate>Tue, 21 Apr 2009 20:13:16 +0000</pubDate>
		<guid isPermaLink="false">http://iPhoneIncubator.com/blog/?p=127#comment-536</guid>
		<description>Mmm, I tried to test my project in some not yet published SDK and it now fails with the same error as the people above had. I tried all their solutions but none works. Anybody got another bright idea. It would be a shame to have to remove all those nice DLog statements....</description>
		<content:encoded><![CDATA[<p>Mmm, I tried to test my project in some not yet published SDK and it now fails with the same error as the people above had. I tried all their solutions but none works. Anybody got another bright idea. It would be a shame to have to remove all those nice DLog statements&#8230;.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
