Simon's suggestions are good.

The CVS tip of log4j provides a number of capabilities you may find useful, if you are 
in a position to use it.

1. You could use a logger naming convention as Simon mentioned and a custom Appender 
to set the first part of the logger name as a 'userid' Property on the LoggingEvent 
prior to appending.

2. If you set the userid as an NDC entry called 'userid', and used your process name 
as the logger, there is now an ExpressionFilter which supports arbitrarily complex 
expressions - including all of LoggingEvent's fields (NDC/NDC/Properties, etc):

   <appender name="X" class="org.apache.log4j.ConsoleAppender">
      <layout class="org.apache.log4j.SimpleLayout"/>
        <filter class="org.apache.log4j.varia.ExpressionFilter">
        <param name="Expression" value="logger == p1 && NDC.userid == u23" />
        <param name="AcceptOnMatch" value="true"/>
        <param name="ConvertInFixToPostFix" value="true"/>
        </filter>
        <filter class="org.apache.log4j.varia.DenyAllFilter"/>
   </appender>

See 
http://cvs.apache.org/viewcvs.cgi/logging-log4j/src/java/org/apache/log4j/varia/ExpressionFilter.java?rev=1.3&view=auto
 for more information.

3. you could log all of the events to a file, socket, etc., and use Chainsaw v2, which 
provides expression-based filtering and searching in a Swing UI.  

See http://logging.apache.org/log4j/docs/chainsaw.html - if you are interested in 
trying it out, run the ant script in the 'installation' section of the page.

Related to #3 - if you normally log to a text file using a PatternLayout, you may want 
to check out using Chainsaw v2 with LogFilePatternReceiver - a new receiver which can 
parse regular (not XMLLayout-based) log files (and tail the file if requested).

See  
http://cvs.apache.org/viewcvs.cgi/logging-log4j/src/java/org/apache/log4j/varia/LogFilePatternReceiver.java?rev=1.4&view=auto
 for more information 

Hope this helps,

Scott

-----Original Message-----
From:   Simon Kitching [mailto:[EMAIL PROTECTED]
Sent:   Wed 3/24/2004 9:55 PM
To:     Log4J Users List
Cc:     
Subject:        Re: Need to log based on criteria other than simply levels
On Thu, 2004-03-25 at 17:25, Mak Carson wrote: 
> Hi,
> 
> I'm comtemplating using log4j in an application that takes input from users(u1 - 
> u99) with in 10 different processes -programs/classes- (p1 - p10).
> 
> I understand how to use log4j to turn logging on and off based on a trace level. 
> However, I also need to be able to selectively log based on any combination of 
> u1-u99 and p1-p10. For example, I want all INFO debugs from messages generated by U3 
> in process p3 and p5.
> 
> Log4j seems to be my best bet. Any idea on how I can most efficiently achieve this 
> slightly complex logging requirement? Another thing to keep in mind is that I need 
> to 'log' to a custom application that provides its own API for sending data to it.
> 
> Any insights will be mucho appreciated,

I'm looking at some similar issues at the moment.

Sending data to your external logging server is just a matter of
implementing a custom Appender (subclass AppenderSkeleton). If you
download the log4j source from CVS, there are plenty of Appenders in
there to borrow code from.

You can model your different "processes" by using log4j categories, eg

  // app #1
  Logger applog = Logger.getLog("apps.app1");
  applog.debug("a debug msg");
  applog.error("an error msg");
  Logger applog2 = Logger.getLog("apps.app1.subcat1");
  log2.debug("a msg from app1 about topic subcat1");

  // app #2
  Logger applog = Logger.getLog("apps.app2");
  applog.debug("a debug msg");
etc.

You can then have a single log4j configuration file which all the apps
read from yet still configure filtering separately for each app, or even
for different categories within an app.

By using different categories, you can get control on a per-user basis, 
provided you don't have *too* many users:

  // app #1
  String username = "sam";
  Logger userlog = Logger.getLog("users." + username);
  userlog.debug("a debug msg about sam");

This allows you to control logging on a per-user basis, but each
"Logger" uses memory, and they are cached once used. So if you have
thousands of users, this will chew up a lot of memory. If you definitely
only have a max of 100 users, you might get away with this.

If you use a separate configuration file per application, then the above
will allow you to control on both app and user axes, by enabling logging
for user "sam" only in the config file for app "app1".

I don't know of any way in log4j to be able to use a single
configuration file to configure based on multiple variables, ie
configure filtering level where (user="..." and app="...").

There is this thing called "Nested Diagnostic Contexts" that would at
least ensure that all messages for a user were labelled with the
username or userid of the user they relate to. But there isn't any
facility for filtering based on NDC values.

Regards,

Simon


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to