Feb 28, 2009

Microlog the Next Generation

Developing Microlog for the last couple of weeks has been like working with a strait jacket. A lot of the requested features would break the compatibility. Thus I had to postpone these requests and only implement simple features with low priority. On the other hand I wanted the V1.1.0 release to be really stable. This has been very frustrating. Yesterday I decided to release V1.1.0 in order to start my work on Microlog the next generation (V2.0).

The most important new features for Microlog V2.0 are
  • Client identification
  • New configuration
  • Re-send functionality
  • Improved packaging
The client identification is needed when you have several mobile client logging to the same server. To analyze the logs it is important to be able to identify each client with an unique id. I have not yet decided how the id will be generated. Perhaps the IMEI number? I will have to think about this a little bit more before deciding.

The configuration of Microlog is kind of old fashioned as it is today. Each appender and formatter is responsible for pulling its properties from the properties classes. A much more modern way ought to be dependency injection. Another problem today is that you have a dependency to the MIDlet class. One must remember that Microlog is possible to run in any CLDC environment, not just with the MIDP profile. In such situations it not possible use the properties classes that is used today, but you have to do the setup programatically. I plan to use the Microproperties classes as the default configuration option. However it should be possible to use any dependency injection framework like fallme.

All appenders that log to a server has no recovery function. Let us assume that a MIDlet logs and then crashes. When the MIDlet starts again it should try to re-send the log to the server. Another scenario is that the connection to the server is lost. The logging should continue and try to re-send when the connection is established again. It is all about making remote logging more robust.

Improved packaging is actually not a new feature, but I think it is an important thing to implement. The packaging of Microlog is a little bit confusing. There are many sub projects within Microlog, each with its own deliverable. My guess is that this could confuse any new user of Microlog.

Of course this list is subject to changes, but these are the main ideas as of today. This will give you some idea what is in store for you. Stay tuned for more information about the development of Microlog the next generation. Meantime you could download the all new fresh version of Microlog.

Feb 27, 2009

Microlog Feature on the Mobile & Embedded Community and SourceForge

The news that we have released V1.1.1 of Microlog has not gone by without notice. First of all, the Microlog news submission at SourceForge was selected to be headline news on the SourceForge site. This is nice since only a fraction of all project news gets selected for the front page. Secondly Microlog got a project spotlight at the Mobile & Embedded community.

I am honored that we got selected at both these places. Let us hope that this will make the Microlog community even bigger, since this will benefit all users of Microlog.

Feb 22, 2009

Microlog with Global Log Levels

This is the first day in ages that I have been able to work with Microlog. It is very nice to be back again and do some development.

There has been several users that have asked for a global log level in Microlog. My initial thought was that this is hard to do, if we should not implement a logging hierarchy. I would like to avoid logging hierarchies, since I think that this would make the Microlog core to complicated and big. Anyway I found a solution to add a global log level to the existing Microlog version, without implementing a logger hierarchy.

The solution is rather simple. You have a method called setGlobalLogLevel() in the Logger class. This is used for all Logger instances, except for those who override it. We have added the method getEffectiveLevel() to check the effective level for each Logger. This method is also found in Log4j, but in that case is has another semantic meaning. In Microlog we have a global level and an individual level, whereas in Log4j it is the hierarchy of Logger objects that decide the effective level.

The setup in the properties file looks like this:

The first line is used for setting the global log level. This is similar to how it was before. The new ability is used on the 2nd line, where the log level is set for a particular class.

I hope that this solution would suffice for most users. The next step is probably to introduce a hierachy of loggers. Since this will break the compability, this will be introduced in Microlog 2.0. But we have not still decided whether or not we will introduce a Logger hierarchy. What do you think?

Feb 14, 2009

Formatting Your Log in Microlog

When adding logging to your application, it is important that you log the right information. Otherwise you have no use of your log when examining it afterwards. In Microlog you have the possibility to format the logging output. The formatting is not formatting the log message, but rather you add information like the time when the logging was done.

The formatting in Microlog is done using a an instance of a Formatter. There are three formatters available out-of-the-box when downloading Microlog:
  • SimpleFormatter
  • ConfigurableFormatter
  • PatternFormatter
The SimpleFormatter is the default formatter for Microlog. Is is the smallest and fastest formatter. It prints the time, the level, the message and the Throwable object if there is one available. This is always a good starting point when using Microlog for the first time. You could set the formatter in code like this:
ConsoleAppender appender = new ConsoleAppender();
SimpleFormatter formatter = new SimpleFormatter();

The final string looks like this:

494:[INFO]-Starting app

The ConfigurableFormatter gives you a little bit more control of the formatting. The order is pre-defined, but you get to choose what to log. You get to choose if you want to log the level, message and the name of the logger. You could set the time format and specify which delimiter that is used between each printed field. If you choose to print the time as date it looks like this:

2009-02-10 19:38:00.188:[INFO]:Starting app

The available properties are:
  • PrintName - Set to true if you wish to print the name of the Logger instance.
  • PrintLevel - Set to true if you wish to print the current Level.
  • TimeFormat - Specifies which time format to use. The possible values are: NO_TIME, DATE_TO_STRING and TIME_IN_MILLIS. The DATE_TO_STRING uses the toString() of the current Date object (now). The TIME_IN_MILLIS writes the time in milliseconds.
  • PrintMessage - Set to true if you wish to print the logged message.
  • Delimiter - Set the delimiter to separate each printed part. Use a String of your choice.

The PatternFormatter is the Formatter with the most opportunities. It works by defining your own formatting pattern. The pattern could be set in your code or by a property in a properties file. For example it could look like this in your property file:

microlog.formatter.PatternFormatter.pattern=%d [%P] %m %T

The formatted string look like this:
15:38:49,199 [INFO] Starting app

The available formatting options are:

  • %c - prints the name of the Logger
  • %d - prints the date (absolute time)
  • %m - prints the logged message
  • %P -prints the priority, i.e. Level of the message.
  • %r - prints the relative time of the logging. (The first logging is done at time 0.)
  • %t - prints the thread name.
  • %T - prints the Throwable object.
  • %% - prints the '%' sign.

If you are not satisfied with the supplied Formatter implementations, you could create your own Formatter. This is done by creating a class that implements the Formatter interface. The interface looks like this:
public interface Formatter {

* Format the given message and the Throwable object.
* @param name
* the name of the logger.
* @param time
* the time since the first logging has done (in milliseconds).
* @param level
* the logging level
* @param message
* the message
* @param t
* the exception.
* @return a String that is not null.
String format(String name, long time, Level level, Object message,
Throwable t);

* Configure the appender.
* @param properties
* Properties to configure with
void configure(PropertiesGetter properties);

The format() method is where the actual formatting is done. It creates a String object that is the actual String that is logged. Nothing more, nothing less. The configure() method is used for configuration of the Formatter. The PropertiesGetter object is used for fetching the properties that the Formatter is interested in. Thus you could define your own properties that you use for your Formatter implementation.

I hope that you have learned how to master the art of formatting in Microlog by reading this. If you still have any questions about this, please use the official Microlog forums to find your answers.

Feb 10, 2009

Netbeans is Getting Better

I am currently writing an article about how to do formatting with Microlog. When doing this I felt that I needed some examples of how the formatting really looks like. Since there are a bunch of example MIDlets in Microlog, it should be as simple as executing them. But that is not the case! As described in an earlier article, it seems that Eclipse is not always fit for fight, it does not manage to start the wireless toolkit.

I tested NetBeans back in 2005 when learning Java ME, although I was an Eclipse fan. For some time I actually used both, I used Eclipse for the development and NetBeans when executing the MIDlets. The reason for this was that EclipseME plug-in was not as good as the NetBeans counterpart. But gradually I started to use Eclipse exclusively. One reason for this was that Eclipse ME matured. When the EclipseME was migrated into Mobile Tools for Java, I have not felt that I was missing NetBeans. But at times when Eclipse fail, I am missing NetBeans. It is a real shame that after all these years, Eclipse still have problems when it comes to Java ME development.

I could spend hours on getting Eclipse to work, while downloading and installing NetBeans should be easy. Said and done! I downloaded NetBeans. Unfortunately my Windows Vista decided to download updates as well, so it took quite some time to download it. I wish I had a faster Internet. Downloading using a 512kbit/s ADSL modem is not the best solution for downloading 211 MB of NetBeans, while at the same time downloading Windows updates.

When writing this article, NetBeans has been installed in the background and everything seems to be working as it should. My first impression is that NetBeans has matured since the last time I used it.

Feb 8, 2009

New Microlog Snapshot Version Available

This week I did a new snapshot release of Microlog. The most important addition is the MemoryBufferAppender. This appender logs to the memory. This could either be a cyclic buffer or a buffer with a fixed size. When the fixed buffer is filled, the logging stops. You get the log by calling the method getLogBuffer(). The method returns a Vector of the logged String objects. It is then up to you to show the log in some useful way, for example showing it as a list in your MIDlet. I hope that the MemoryBufferAppender is something that you feel is useful.

The snapshot release could be found here.

Feb 3, 2009

Working on a Microlog Presentation

Today I have spent the entire evening preparing a presentation of Microlog. I am going to do this presentation on Friday for some of my colleagues. When it was decided that I was going to do this presentation, I had a clear vision about what to include. But now I am a little bit without inspiration. I think I will have to have some rest and give it another try tomorrow.

Feb 2, 2009

Memory Logging Available for Microlog with MemoryBufferAppender

Ever since the holidays I have been busy doing other things than working on my open source projects. Fortunately there are other that have been working hard.

The most important improvement is the new MemoryBufferAppender. It is used when you want to log into memory. I think that this is good in scenarios where you want to log, but has very little performance impact. Logging to file or the RMS could be slow on some platform, whereas memory logging should be the fastest solution on all platforms. You could choose if you want to log into a cyclic buffer or to a fixed buffer. When the fixed buffer is full, the logging stops.

The code is only available from the repository. If you already have the latest snapshot of Microlog available, it would be enough to only download the MemoryBufferAppender. I will be doing a snapshot release within a few day.