logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Anders Kristensen <akristen...@dynamicsoft.com>
Subject Re: Making object rendering more extensible
Date Wed, 13 Feb 2002 04:00:05 GMT
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

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.

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.  Wouldn't it be much more useful to be able to 
assign new conversion characters to those different fields of the 
FTPCommandInfo and have them blend in with PatternLayout like other 
conversion characters?


Lance Larsen wrote:

> Note, it would be helpful if you could copy me on the response to this. I am
> following the dev list, but  am not subscribed to it at the moment, so it is
> difficult to respond on the thread unless I get the e-mail directly.
> I can't speak for Anders, but it does sound like he is interested in
> addressing the same issue I am trying to face currently. Hopefully he will
> express more of his thoughts later, but here is my shot at answering your
> questions:
>>Ceki says:
>>I still don't see the *practical* use of having the renderer depend on
>>the layout or appender. Would it be possible for you to describe a
>>practical case where such functionality would be useful.
> I wouldn't necessarily say the 'ObjectRenderer(s)' should depend on
> 'Layout(s)' or 'Appender(s)', but rather that there can exist multiple
> 'ObjectRenderer' sets (refered to as 'ObjectRendererBundle' from here on
> out), and that the log4j configuration include the ability to specify per
> 'Layout' an 'ObjectRendererBundle' that the 'Layout' will use. The
> 'ObjectRendererBundle' is independant of the 'Layout' and can be associated
> with multiple 'Layout(s)' in the same sense that a 'Layout' is independant
> of an 'Appender' and can be associated with multiple 'Appender(s)'.
> In the architecture, it appears that 'Layout(s)' are responsible for
> formatting log data that is sent to the 'Appender', but 'ObjectRenderer(s)'
> are also responsible for part of this formatting process. I am running a few
> cases where I have multiple 'Layout(s)' and each of these 'Layout(s)' need
> to coordinate with the 'ObjectRenderer(s)' to format text correctly. In
> other words, the result each of these 'Layout(s)' need from the
> 'ObjectRender' is different for the same object, and there does not seem to
> be a way to address this in log4j at present.
> I will try to give a practical example here. You will have to let me know if
> this helps, or if there are things I need to clarify. Lets say we have an
> FTP server written in java. We include the capability to log FTP commands
> that the FTP server receives. The FTP command info is stored in an instance
> of the following class:
> public class FTPCommandInfo
> {
>    public String m_fromIP; // FTP client IP
>    public String m_toIP; // FTP server IP
>    public int    m_port; // FTP port
>    public String m_username; // User for connection
>    public String m_password; // Password for connection
>    public String m_command; // The FTP command that was issued
>    public String m_filePath; // The file
>    public String m_result; // The FTP server result
>    ...
> }
> In some FTP server class we have some code like the following:
> Logger log = ...;
> ...
> FTPCommandInfo ftpInfo = ...;
> // The FTP command info gets populated in ftpInfo
> ...
> log.info(ftpInfo);
> ...
> The logging occurs for each FTP command that get called. In configuring
> log4j, we decide we want a few different 'Appender(s)' to listen to this
> 'Logger', with the ability to run them all at the same time. We would like
> the 'Layout' associated with a first 'Appender' to return result to be in a
> comma separated list of all the info stored in the 'FTPCommandInfo' object:
> <FTP client IP>,<FTP Server IP>,<FTP port> ... <FTP Password>
... <FTP
> result>\r\n
> The 'Layout' for the second 'Appender' should return results in an XML
> format such as the following:
> <FTPCommand client_ip="<FTP client IP>" server_ip="<FTP server IP>" ...
> result="<FTP result>"/>
> The 'Layout' for the third 'Appender' should return a comma separated list
> similar to the first 'Layout'. But in this case we do not want to include
> the 'm_password' value in the log file because the log is made public and we
> do not want to expose passwords. So the format might be exactly like the
> first case, but without the passwords included.
> It is the job of the 'Layout' to format the text. The 'Layout(s)' supposedly
> are fairly generic and delegate rendering of object data to the
> 'ObjectRenderer(s)'. This is very handy since the 'Layout' does not have to
> understand each object that comes in. Making an 'ObjectRenderer' to hand bac
> k a correct 'String' to the 'Layout' in any one of these cases is fairly
> trivial. It is fairly trivial to make an 'ObjectRenderer' that returns ftp
> info in a comma separated list, or one that returns the ftp info as a set of
> xml attributes, or even one that excludes certian info the loggable object
> contains that should not be displayed. However these does not seem to be a
> way for these 'ObjectRenderer(s)' to coexist in log4j at the same time and
> associated with the respective 'Layout(s)'.
> A workaround is to ignore 'ObjectRenderer(s)' and add the
> 'ObjectRender(ing)' capabilities to the 'Layout' directly but this is not
> ideal since it supervents a part of the architecture and does not allow for
> an extensible way to render new objects. It would really be much better to
> be able to use the 'ObjectRenderer' architecture, but there is only one
> unchangable 'ObjectRenderer' set so I have to deal with a workaround.
> I think it is justifiable that you may want multiple log files for different
> purposes (we run into that fairly often), and it is quite possible that each
> of the log files may need to render the object data in different formats.
> The example above is just one case. The best way I can think of to address
> this is to allow 'ObjectRendererBundle(s)' that allow you to render object
> differently in different 'Appender(s)' (or more correctly in different
> 'Layout(s)'). In the case that you only use a default 'ObjectRendererBundle'
> the architecture reduces to the current one. I expect that this change would
> have minor impact on the API overall, but would allow more flexibility as
> necessary.
> Is this a practical enough example? It is similar to a problem I am
> currently trying to address and I hope my explaination did it justice. I am
> feeling the limitations of the current 'ObjectRenderer' configuration
> options. I need to have a way to render the same object in multiple ways
> within the same program. I believe that the changes I have suggested would
> help make log4j fundamentally for extensible. It is not a huge leap from
> where things are at right now and seems to be a logical extension.
> Log4j really is an excellent product. I hope that you will consider the
> changes I have suggested because I think it would help make log4j more
> extensible to meet a broader set of needs in a clean and clear fashion.
> Please let me know if there is anything I can clarify, or that does not seem
> entirely sound in the discussion above. Thanks again for an excellent
> product.
> -Lance Larsen
>>This might be another case where Anders is a few steps ahead of me. It
>>has happened in the past... so I am all ears.
>>TIA, Ceki
>>ps: Would it be sufficient if Appender and layouts accepted configuration
>>directives for elements unknown at compile time? For example, appenders
>>are known to contain a layout element and there is code to handle layout
>>directives within an appender. The idea is to support unknown element
>>types... such as object renderers.
> ----- Original Message -----
> From: Lance Larsen
> To: log4j-dev@jakarta.apache.org
> Sent: Thursday, February 07, 2002 11:54 AM
> Subject: Making object rendering more extensible
> I have looked through the dev list to see if this has come up, but I haven't
> seen anything so far. I have been using log4j on a few projects, and like
> the configurability and extensibility it provides - very nice - thankyou for
> the excellent tool.
> However, there seems to be one part of the architecture where I have run
> into limitations, and would like to submit a feature request. Log4j provides
> a mechanism to register 'ObjectRenderer(s)' in the configuration. This is
> very handy since it allows you to log various types of objects that log4j
> would not natively understand by simply creating a new 'ObjectRenderer'
> class and including this in the log4j configuration (no other changes). This
> part is very nice. The problem I have run into is cases where I would like
> the set of 'ObjectRenderer(s)' to be different for various 'Layout(s)' used
> at the same time. There does not appear to be a way to do this.
> The current assumption seems to be that there is one application global
> fundamental 'String' mapping for each loggable object type. There seem to be
> many cases where you may want to object to be rendered differently in
> different contexts. Log4j gives you this flexibility in the relationship of
> 'Appender(s)' to 'Layout(s)', but for some reason did not extend this to the
> relationship between 'Layout(s)' and 'ObjectRenderer(s)'.
> One case where having different object renderers is useful is in a case
> where there are several things you can pull out of an object. One 'Appender'
> (or more correctly 'Formatter') may log part of the info and another
> 'Appender' may log different info from the same object. In another case, two
> 'Layout(s)' may need the same info, but the string format may need to be
> different for each. I do not see a clean way to currently handle either of
> these cases.
> My suggestion would be to add a new concept of 'ObjectRendererBundle(s)'
> which includes a set of 'ObjectRenderer(s)' that a 'Layout' will use. In the
> configuration, the 'Layout' can be assigned an 'ObjectRendererBundle' in a
> similar way that an 'Appender' is assigned a 'Layout'. The 'Layout' class
> could include a couple of new methods something like
> 'setObjectRendererBundle' and 'getObjectRendererBundle' to access the set of
> object renders for the 'Layout'. There would probably be a default
> 'ObjectRendererBundle' that was global as in the current case, but the
> 'ObjectRenderer' model would be more extensible.
> Are there any other thoughts or somments on this? Does this seem like a
> reasonable approach? Is this something that you are interested in including
> into 'log4j'?
> -Lance Larsen
> --
> To unsubscribe, e-mail:   <mailto:log4j-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:log4j-dev-help@jakarta.apache.org>

To unsubscribe, e-mail:   <mailto:log4j-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:log4j-dev-help@jakarta.apache.org>

View raw message