java - Log4j2: Ability to log data with different log levels in multi user environment -
i'm using log4j2 in oracle adf 12c application.
one of requirements of our customer have different log levels different logged-in users , change log levels dynamically user.also administrator should have control stop logging.
i.e lets 'user a' needs trace log level , 'user b' needs error log level. if both users logged in simultaneously, application should log in trace level 'user a' , in error level 'user b'. , if 'user b' wants log in fatal level should able change configuration dynamically.
following log4j2 config file.
<?xml version="1.0" encoding="utf-8"?> <configuration status="trace"> <mapfilter onmatch="accept" operator="or"> <keyvaluepair key="$${ctx:loglevelyn}" value="y"/> </mapfilter> <appenders> <file name="file" filename="./adfappcustomlogs/testlog4j2.log"> <patternlayout> <pattern>%d{yyyy-mm-dd hh:mm:ss.sss} %-5level %class %l %m - %msg%xex%n</pattern> </patternlayout> </file> <console name="stdout" target="system_out"> <patternlayout pattern="%m%n"/> </console> <routing name="approuting"> <routes pattern="$${ctx:loggedsessionid}"> <!-- route chosen if threadcontext has no value key routingkey. --> <route key="$${ctx:loggedsessionid}"> <rollingfile name="rolling-all" filename="./adfappcustomlogs/defaultall.log" filepattern="./adfappcustomlogs/archive/${date:yyyy-mm}/defaultall-%d{mm-dd-yyyy}-%i.txt.gz"> <patternlayout> <pattern>%d{yyyy-mm-dd hh:mm:ss.sss} %-5level %t %msg%xex%n</pattern> </patternlayout> <policies> <timebasedtriggeringpolicy interval="6" modulate="true"/> <sizebasedtriggeringpolicy size="10 mb"/> </policies> </rollingfile> </route> <!-- route chosen if threadcontext has value 'user' key routingkey. --> <route> <rollingfile name="rolling-other-${ctx:loggedsessionid}" filename="./adfappcustomlogs/${ctx:loginid}-${ctx:loggedsessionid}.log" filepattern="./adfappcustomlogs/archive/${date:yyyy-mm}/${ctx:loginid}-%d{mm-dd-yyyy}-%i.txt.gz"> <patternlayout> <pattern>%d{yyyy-mm-dd hh:mm:ss.sss} %-5level %t %msg%xex%n</pattern> </patternlayout> <policies> <timebasedtriggeringpolicy interval="6" modulate="true"/> <sizebasedtriggeringpolicy size="10 mb"/> </policies> <!-- <defaultrolloverstrategy max="100"/> --> </rollingfile> </route> </routes> </routing> <async name="async" buffersize="1000" includelocation="true"> <appenderref ref="approuting"/> </async> </appenders> <loggers> <root level="trace"> <!--<appenderref ref="file" level="debug"/> --> <appenderref ref="async"/> <!-- uncomment following if want log printed in weblogic console --> <appenderref ref="stdout"/> </root> </loggers> </configuration>
i'm trying create multiple loggers different loglevel each 1 nothing worked.
it great if can give me pointers or hints.
one of requirements of our customer have different log levels different logged-in users , change log levels dynamically user. administrator should have control stop logging.
this require having separate logger each user assume means each thread
. can't possibly configure of these loggers in advance since don't know how many users have @ runtime. therefore need dynamically create loggers @ runtime calls log4j2 apis. can refer log4j2 manual full details.
furthermore need create administrative controls allow access log4j2 configuration , provide ability modify configuration @ runtime.
here small example of how can achieve goal of having 1 logger per thread
, how change log level during runtime:
here log4j2.xml configuration file:
<?xml version="1.0" encoding="utf-8"?> <configuration status="warn"> <appenders> <console name="stdout" target="system_out"> <patternlayout pattern="%m%n" /> </console> </appenders> <loggers> <logger name="example" level="trace"> <appenderref ref="stdout" /> </logger> <root level="warn"> <appenderref ref="stdout" /> </root> </loggers> </configuration>
here java code:
package example; import org.apache.logging.log4j.level; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.apache.logging.log4j.core.loggercontext; import org.apache.logging.log4j.core.config.appenderref; import org.apache.logging.log4j.core.config.configuration; import org.apache.logging.log4j.core.config.loggerconfig; public class loglvlbythreadmain { public static void main(string[] args) { thread t1 = new thread(new runnable(){ public void run() { addlogger(thread.currentthread().getname()); logger log = logmanager.getlogger(thread.currentthread().getname()); log.info("here's first thread"); try { thread.sleep(5000); } catch (interruptedexception e) { e.printstacktrace(); } log.debug("some debug in first thread"); log.info("finishing first thread"); }}, "thread1"); thread t2 = new thread(new runnable(){ public void run() { addlogger(thread.currentthread().getname()); logger log = logmanager.getlogger(thread.currentthread().getname()); log.info("here's second thread"); changeloglevel(thread.currentthread().getname(), level.debug); log.debug("some debug in second thread"); }}, "thread2"); t1.start(); t2.start(); } public static synchronized void addlogger(string name){ appenderref ref = appenderref.createappenderref("stdout", null, null); appenderref[] refs = new appenderref[] {ref}; loggercontext ctx = (loggercontext) logmanager.getcontext(false); configuration config = ctx.getconfiguration(); loggerconfig loggerconfig = loggerconfig.createlogger("false", level.info, name, "true", refs, null, config, null ); loggerconfig.addappender(config.getappender("stdout"), null, null); config.addlogger(name, loggerconfig); ctx.updateloggers(); } public static synchronized void changeloglevel(string loggername, level lvl){ loggercontext ctx = (loggercontext) logmanager.getcontext(false); configuration config = ctx.getconfiguration(); loggerconfig loggercfg = config.getloggerconfig(loggername); loggercfg.setlevel(lvl); ctx.updateloggers(); } }
note have think synchronization problems multiple threads changing logging configuration on fly - notice how 2 methods above alter configuration synchronized
.
output above code:
here's second thread here's first thread debug in second thread finishing first thread
this proves 2 threads have different log levels because if had changed both of them have seen 2 "debug" logs not 1 second thread.
Comments
Post a Comment