May 18, 2010

Microlog, Microlog4Android, SLF4J and Other Stuff

Right now a lot of interesting stuff are happening with both Microlog and Microlog4Android. I have been working with Microlog, while Jarle has been working on Microlog4Android (M4A). Let me start with Microlog.

I have started the work on Microlog V3.0. To start with I have been able to make the structure a little bit easier. For example I have removed some abstract classes, like the AbstractFileAppender. This was created for one purpose only, to be able to re-use parts of the file logging functionality between Microlog and M4A. A nice side effect of this construction is that we save some memory, both in terms of the memory footprint and run-time memory. Some bugs are fixed and there are some minor improvements.

Even though Microlog is my long time sweetheart, the most exciting things are happening within the M4A project. When moving the code from the Microlog to M4A, we skipped a lot of code. It was the core and only a few appenders that was moved. Working with the Android platform is quite different and the needs are a little bit different. For example, there is not really a need to log to the console. Instead we have replaced the ConsoleAppender with the LogCatAppender. This works as the built in log classes.  The reason for moving Microlog to the Android platform was to give Android developers more opportunities than the built in logging facilities. It is possible to use the logcat tool to log to file, but in that case you do not get the normal logcat logging in Eclipse. I have never heard of any way of logging to a file on the SD card or on the device, using the Android logging classes. With M4A it is possible to log to a file on the SD card. Just use the modified FileAppender to use M4A to log to file.

Another unique feature in Microlog is the ability to log to a remote server. This far we have the HTTPAppender which logs to a HTTP server. This is definitely something that is not possible with the standard Android logging facility. The HTTP logging is ideal for field test or similar, where the developers need to collect logs in a central place. No need to transfer log file manually. Note that during the development it might be more natural for individual developers to log to a file.

But that is not all! The most prominent addition is the SLF4J implementation. This gives you as a developer freedom to change the logging implementation whenever you feel like it. For example you want to use M4A during development for file logging, but want to remove the logging at deployment time. Just replace the M4A jar with the NOP implementation. If you want to revert back to good old Android LogCat logging (only), use the SLF4J implementation.

Last but not least, we have changed the PropertyConfigurator to read configuration files from an Android resource directory. The microlog.properties file could either be stored in the /res/raw or the /assets directory.

For those of you that want to try it out, it is available for download at: http://code.google.com/p/microlog4android/downloads/list
 
Please note that the latest release (V0.5) is rather experimental, but please try it out and give us feedback.

23 comments:

Jarle Hansen said...

Excellent blog article. I think the m4a is an excellent project that will make logging in Android very similar to any Java SE project. It is also important to note that we are not in any way depent on the slf4j-android implementation. We use the standard slf4j jar so we are able to stay up to date easily.

Hopefully documentation and user guides will be added to the m4a Google code site soon.

My Open Source Software Development Blog said...

Note that we have adopted Microlog4Android to Java 1.5, instead of Java 1.3 used in Java ME. For example, we use the Java Collection framework instead of the old legacy classes.

Christine Kühnel said...

Hi,

Seems like m4a would be just the thing I need for our android-based research project. Only I don't get it to work.

code snippet:
public FileAppender appender = new FileAppender();

appender.setFileName("log.txt");
appender.setFormatter(formatter);

rootLogger.addAppender(appender);

when trying to log (rootLogger.info("test")) I get the error:
ERROR/Microlog.FileAppender(1808): Failed to create the log file (no stream)

Any hint would be greatly appreciated.

Christine

My Open Source Software Development Blog said...

Nice that you have tried out M4A. Sorry that it did not work directly. I will try to help you. Here are some short instructions:

1. Add the following static variable in your main Activity:

private static final Logger logger = LoggerFactory.getLogger();

2. Add the following to your onCreate() method:

PropertyConfigurator.getConfigurator(this).configure();

3. Create a file named microlog.properties and store it in /assets

4. Edit the microlog.properties file as follows:

microlog.level=DEBUG
microlog.appender=LogCatAppender;FileAppender
microlog.formatter=PatternFormatter
microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T

5. Add logging statements like this:

logger.debug("M4A");

For each class you create a logger object as specified in 1)

I hope this helps. We will write a better setup guide before doing the final release.

Please contact me again if it does not work.

Christine Kühnel said...

Thanks for the answer. I followed your suggestions step by step. Unfortunately, it does not work quite as intended. I get logs printed to LogCat but I still get the error
ERROR/Microlog.FileAppender(928): Failed to create the log file (no stream)

And my pattern seems to be ignored.

This is what my microlog.properties (in assets directory) looks like:

microlog.level=DEBUG
microlog.appender=LogCatAppender;FileAppender
microlog.formatter=PatternFormatter
microlog.formatter.PatternFormatter.pattern=%d %r %c [%P] %m

and here is the output on LogCat:
INFO/Microlog.PropertyConfiguration(928): Configure using the simple style (aka classic style)
INFO/Microlog.PropertyConfiguration(928): Root level: DEBUG
INFO/Microlog.PropertyConfiguration(928): Adding appender com.google.code.microlog4android.appender.LogCatAppender
INFO/Microlog.PropertyConfiguration(928): Adding appender com.google.code.microlog4android.appender.FileAppender
ERROR/Microlog.FileAppender(928): Failed to create the log file (no stream)
INFO/Microlog(928): Microlog 0:[INFO]-started

I have some further questions:
I would like to write my own formatter for the logs. Is there a way to set the formatter for an appender added via properties file?
And is it possible to define the name of the logfile (and where does it get saved)?

Thanks a lot.

My Open Source Software Development Blog said...

It seems that you have done everything right according to my instructions.

Here are some more things to consider:

The log file is written to the SD card. If you are using the emulator, please ensure that you have mounted a SD card.

If you are using a phone you need to disconnect the phone after you have transferred the APK file. The file transfer mode locks the SD card for other usage than transferring files via USB.

These questions are really good and I will add these to the instructions and/or the FAQ. Thanks for taking time to try M4A out.

My Open Source Software Development Blog said...

BTW The pattern is ignored, since the implementation of the new PropertyConfigurator has no support for it. This will be released next week.

My Open Source Software Development Blog said...

One last comment...

You may need to add this to your manifest file:

My Open Source Software Development Blog said...

I have problems with adding the XML code :(

You may be add the following permission:

android.permission.WRITE_EXTERNAL_STORAGE"

Christine Kühnel said...

Thanks :-). After mounting an sdcard I can now log to a file. Now I wait for the next release of m4a to use my own patterns or even my own formatter if possible.

My Open Source Software Development Blog said...

Really glad that I could help you out. The discussion here will help me to provide better documentation for M4A. I will get back when I have released a new version.

Unknown said...
This comment has been removed by the author.
Anonymous said...

didn't find a way to contact you on your blog. can you pls get in touch with me over email? I have something to run by you. Thanks. ditkis @ gmail . com

print and promotional solutions in chicagoland said...

Nice blog, I enjoy to read this blog. Such a lovely blog that you have. Thanks for sharing.

Unknown said...

Nice blog, software development phoenix is providing the services of Website Design, SEO Internet Marketing, Software Development and Computer Network Services, which is very useful and good.

Oscommerce Solutions said...

Thanks for this good stuff. I like your blog very much. Your blog i full of informational content.

Software Development India said...

Thanks a lot for sharing the information with us. Keep it up.

Alok said...

Can you please guide me how to specify a max file size for the log. I dont want to exceed the size of log to say more than 500kb on the sdcard.
Also what is the easy way to turn off the logging so as to differentiate Debug and Production releases of the app.
Thanks,
Alok

My Open Source Software Development Blog said...

Anok:

There is no way to set the max size of a file log. I will put it on my feature request list.

You could have different configuration files for the debug and release build. Use your build script, or similar, to switch to the correct when doing a build.

DZONEMVB said...

Hello,

Our Managing Editor, Lyndsey Clevesy, recently enjoyed reading a post on your blog and wants to invite you to join DZone's Most Valuable Blogger program. 

The MVB program allows DZone's editors to occasionally feature entries from your blog on our site under your DZone user profile. It has provided a great way for many of our participants to drive extra traffic and visibility to their blogs.

Please contact karyl@dzone.com for more information about joining the program!

Best,
Karyl Gomoll

Andrey Chernyh said...

Hello, I tried to use microlog4android, downloaded from
http://code.google.com/p/microlog4android
I read these comments and tried everything, but it did not work.

My properties:
microlog.level=DEBUG
microlog.appender=FileAppender;LogCatAppender
microlog.formatter=PatternFormatter
microlog.appender.FileAppender.fileName=mylog.txt
microlog.appender.FileAppender.append=true
microlog.formatter.PatternFormatter.format=%d %P %c - %m %T

It was placed into correct place and I used this code for initialization:
propertyConfigurator = PropertyConfigurator.getConfigurator( this );
propertyConfigurator.configure();

Only after 2 changes I made it working.
1) initialization must be done _before_ first call of any logging method!
2) I did initialization programmatically:

Logger rootLogger = DefaultLoggerRepository.INSTANCE.getRootLogger();
FileAppender fileAppender = new FileAppender();
fileAppender.setFileName( "witrac.txt" );
fileAppender.setAppend( true );
rootLogger.addAppender( fileAppender );
rootLogger.addAppender( new LogCatAppender() );

PatternFormatter formatter = new PatternFormatter();
formatter.setPattern( "%d %P %c - %m %T" );
int numberOfAppenders = rootLogger.getNumberOfAppenders();
for( int appenderNo = 0; appenderNo < numberOfAppenders; appenderNo++ )
{
Appender appender = rootLogger.getAppender( appenderNo );
appender.setFormatter( formatter );
}
cat.debug( "Logger configured!!!" );

Can you please tell what I did wrong with properties?

My Open Source Software Development Blog said...

Chernyh;

Microlog4Android is constructed to be setup once before starting the logging a simple call to configure() before the first logging statement will fix it, just like you found out.

The second problem is that not all functionality has been ported from Microlog. Setting properties on formatter is not yet supported in Microlog4Android.

Mihai said...

There is a possibility to set different log levels for packages?

I tried something like this
microlog.level=INFO
microlog.logger.com.psx.display=DEBUG
but I didn't obtain the debug level for that package..
Thank you