> Your example illustrates the problem well but, IMHO, the proposed > solution falls far short of what's needed. > > It is common to let admins control the format of log files. If you > consider HTTP servers rather than ftp servers they probably all have > configurable formatting of log entries. It is really not sufficient to > be able to have different ObjectRenderers for different layouts. > > For a really useful solution it is necessary to have > > 1) the ability to configure how objects are rendered > 2) have the mechanism fit in well with PatternLayout
I would like to note that the solution I proposed does not preclude a solution that addresses item '2)' above. I do think it is a natural way to address item '1)' with minimal impact on the current log4j design. In many cases you may want to use the same 'ObjectRenderer' and reorganize how the string are placed. In other cases, you may actually want to render different 'String(s)'. This allows you the configurability to at least change the 'String' representations as necessary. You may not necessarily even use different 'ObjectRenderer(s)', but the same 'ObjectRenderer' configuraed differently to return results in a more convenient form. > To use your example, I'd like to be able to configure a category to log > FTPCommandInfo objects using a *mixture* of FTPCommandInfo specific > conversion characters and built-in PatternLayout characters. I would > also like to have the existing set of format *modifiers* apply to any > FTPCommandInfo specific conversion characters. I can see what you are saying here, and this is a very interesting idea overall. One of the cases I was trying to address came up while using the 'PatternLayout'. I wanting more flexibility to mix various info from the logged object into the 'PatternLayout' log String. When I ran into this problem, I spent some time thinking about how this might work. But the immediate problem was that this seemed to involve changes to the relationship between 'Layout' and 'ObjectRenderer'. By definition of the log4j interfaces 'Layout' only knows how to retrieve a single 'String' from an 'ObjectRenderer', and this is a limitation that makes it difficult to make a 'Layout' like 'PatternLayout' more flexible in the way it logs object data. It may be a good idea to have defined a richer interaction between the 'Layout' and 'ObjectRenderer' interfaces. For example, the 'ObjectRenderer' may have included the ability to return various 'String(s)' that were requested from a 'Layout'. The 'Layout' could then place these 'String(s)' in the resulting Layout 'String' in arbitrary ways. This would lead to some very flexible ways of rendering 'Layout' 'String(s)' from an object that was logged. However this requires some architectural changes that may cause backward compatibility problems. It also gives rise to some immediate issues that would have be addressed in some way, the main one (in my mind) being: How does an 'ObjectRenderer' expose multiple 'String(s)' in a way that they can be interpreted meaningfully by the 'Layout'? If the 'ObjectRenderer' can return an arbitrary number of 'String(s)' the 'Layout' needs to have a way to determine the 'correct' place to put each of these 'String(s)'. You can have the 'ObjectRenderer' act sort of like a 'Hashtable' and have keys for the various 'String(s)' an 'ObjectRenderer' exposes. For example, an 'ObjectRenderer' for 'FTPCommandInfo' might expose keys like "Client IP", "Server IP", "Port", etc. that were associated with the correspoding values. Of course 'ObjectRenderer(s)' for different object types might all have different descriptive keys since the data the objects contain is different. For example, an 'ObjectRenderer' for another object type might expose the keys "Name", "Social Security #", "Eye Color", etc. that are natural for the other object class. For the purpose of something like the 'PatternLayout', you would likely want to expose the same set of keys for various types of objects that are logged. You could resolve this by allowing key remapping in the 'ObjectRenderer' configuration (note that in this case, the idea of and 'ObjectRendererBundle' is still useful). For example, looking at the FTPCommandInfo object again you might remap the "Client IP" key to a "from" key, and "Server IP" to a "to" key. Various 'ObjectRenderer(s)' could remap their default key values to the ones expected by the given 'Layout'. Then the 'Layout' could use the generic key names to get the appropriate 'String' values. In the case of the 'PatternLayout', you may have a converion pattern like the following: "%c,%t,%{from},%{to}..." for a comma separated list, or "<Message from='%{from}' to='%{to}' ... \>" for an XML formatted log. The point is that there are probably some things you could do to make the interaction between 'Layout(s)' and 'ObjectRenderer(s)' more rich and thus make for much more flexible 'Layout' capabilities. However, I cannot think of a way of doing this sort of thing without making fairly significant changes to the API. I think this is an interesting idea to explore, and has some great merrit. I have made some speculations here about how you could accomplish more flexible interaction between 'Layout(s)' and 'ObjectRenderer(s)', of course you will have to indicate whether this is along the line of the changes you were suggesting. > If I understand what you're correctly, you're suggesting that instead of > that, we have multiple ObjectRenderers that format FTPCommandInfo > objects differently. IMHO, that goes totally against the strength of > log4j, which is configurability. If someone decides they want to format > FTPCommandInfo objects slightly differently they actually have to go > and write a new class. I would say that the solution I proposed increases the configurability of log4j to an administrator rather than 'going against' it. It does mean that you may have multiple 'ObjectRenderer' classes for a single object in the same way that you may have multiple 'Layout(s)' that are compatible with an 'Appender'. The architecture does not seem less configurable because people have programmed multiple 'Layout(s)'. If a 'Layout' is available that meets your needs, you use it. If there is not one, you have to program it. The same concept applies with 'ObjectRenderer(s)'. However the various 'ObjectRenderer(s)' may tend to be less generic than the typical 'Layout'. It would however allow you to do some things you cannot do now (as I described), and I think would allow you to do some things that may not be possible even if you include a solution to item '2)'. I don't think that the changes you suggest (as far as I understand them) are contradictory to the changes I suggested. I think they are complimentary. The changes you suggest require a way to be able to configure 'ObjectRenderer(s)' differently for different 'Appender(s)' (or rather 'Layout(s)'), and the approach I suggested allow you to do this fairly well in a way that is consistent with the current architecture. The approach I suggest would gain benefits if there was a way to work with 'ObjectRenderer(s)' more flexibly in that you would likely have to write less code to meet specific log formatting needs isnce there would be more flexibility in working with 'Layout(s)' such as the 'PatternLayout'. It seems that the changes I suggested would be relatively easy to include, and would set the stage for making other changes to make the interaction between 'Layout(s)' and 'ObjectRenderer(s)' more flexible if that is the direction the log4j developers agree to go. -Lance Larsen -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>