锘??xml version="1.0" encoding="utf-8" standalone="yes"?> The first two lines of the doGet method look up the MBeanServer. Log4J registers the root logger with the name log4j:logger=root. This MBean provides a property to set the logging level of the root logger. You set the priority of the root logger by passing the ObjectName of the MBean to operate on, along with an instance of javax.management.Attribute to the MBean Server. In this case, you want to set the "priority" attribute. The value will be the new logging level you have specified Although this technique seems simple, if your Tomcat cluster hosts a number of Web applications鈥攅ach with its own Log4J configuration that allows it to log to a separate log file鈥攖hen you will run into your first problem. Given multiple Log4J configurations, only the first one loaded by the JVM will have a root logger MBean associated with it. The reason for this is Log4J hard-codes the JMX Domain that it uses when registering its MBeans as log4j, and the JMX server doesn't allow duplicate names. The way round this is to leave a Tomcat server Log4J configuration (jars under server/lib and property files under server/classes) registered under the default Log4J name log4j:logger=root. Then register the root logger for each Web application in a startup servlet, using the Web application name to identify the domain: You will end up with an MBean named <web-app-name>: logger=root for each Web application. The webappName is retrieved from the <display-name> element in your application's web.xml file, and the application's root logger is retrieved by calling To create a distinct ObjectName for the new MBean, you should use the Web application name as the JMX domain (this is the text before the colon) and then register the Root Logger MBean with the new ObjectName. This will guard against conflicts with other Log4J MBeans.
Now that you have registered your Root Logger under a different domain, you must modify the servlet that sets the logging level. So in SetLog4JlevelServlet, change this: To this: When setting up your Log4J configuration, give your Log4J appenders unique names. Otherwise, they will not get registered to the JMX server and you will get lots of the following errors in your log files at startup: Again, the reason for this is because the JMX domain name his hard-coded to log4j, so if you have repeated appender names then only the first of these will be registered.
At this point, configuring the MX4J HTTP adaptor in your Tomcat server might be useful. This will give you a visual representation of the MBeans you are creating and manipulating, and show you what else is exposed via MBeans within Tomcat. To do this, you must put the mx4j-tools.jar file (download it at mx4j.sourceforge.net) in your common/lib directory. Then configure your server.xml file to set up the connector as follows: When you start your server, you will be able to access the MX4J HTTP connector through your browser at http://localhost:8013, assuming you have no other Tomcat connector running on port 8010.
Once you have made the previously discussed changes, you will be able to set the Log4J logging level dynamically for any application running in Tomcat. The next challenge is to make sure you can set the logging level for every node in the cluster. You could either call this servlet manually on each node in the cluster or get the servlet to send a message to every other node in the cluster so the logging levels are always the same across the cluster It may seem strange, but you must use JMX over RMI to send the message to the cluster because the interface implemented in Listing 1 is defined within the Tomcat server class loader (i.e., it exists in a jar file in the server directory). You will instantiate that class in a Web application, which uses a totally separate class loader (it exists in the WEB-INF directory of your Web application). This means that the cluster message you instantiate in your Web application and send to the SimpleTcpCluster class will be different from the cluster message definition that is placed in the Tomcat server class loader. If you try to send your message directly through JMX, your cluster message instance will not match the cluster message definition accessible to the SimpleTcpCluster class and the call will fail. (See the Tomcat documentation on class loaders for a definition of how the class loaders are configured for the Tomcat server.)
The workaround is to use JMX over RMI so the cluster message is serialized in the Web application class loader, instantiated in the Tomcat server class loader (and that is the important point), and then de-serialized. The following method opens a connection to the local JVM's JMX server over RMI, looks up the MBean that wraps the SimpleTcpCluster, and then invokes the You should call this method in your SetLog4JLevelServlet to ensure that a message is sent to the other members of the cluster when you set the logging level.
You will need to configure your Tomcat server to allow a JMX connection to be opened up over RMI. Simply add the following line to your catalina.bat file in the bin directory: For a quick guide on applying security to this configuration, see the Tomcat documentation. For a more in-depth look at configuring JMX Remote, see the Sun documentation.
You must deploy this class in the server directory and enter it in the Tomcat server.xml file as a ClusterListener within the You should now be able to set the logging level for any application, over all nodes, in the cluster by calling SetLog4JLevelServlet on any node in the cluster.
聽
by Jon Dickinson
henever you have to fix a problem in a production environment, one of the most common issues is retrieving some useful debug information to tell you what happened. Of course, to avoid needless notifications and enormous log files, most production systems are configured to log only errors. To avoid having to modify your Log4J configuration and then redeploy the correct version of the code with the modified logging level, why not just implement a mechanism for dynamically changing the logging level?聽
Log4J registers a number of MBeans, one of which provides access to the root logger. You can dynamically modify the logging level of the root logger by implementing the following servlet to set the appropriate MBean property through JMX:
public class SetLog4jLevelServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(SetLog4jLevelServlet.class);
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
List list = MBeanServerFactory.findMBeanServer(null);
MBeanServer server = (MBeanServer)list.iterator().next();
try {
String loggingLevel = request.getParameter("level");
Attribute attribute = new Attribute("priority", loggingLevel);
ObjectName objectName = new ObjectName("log4j:logger=root");
server.setAttribute(objectName, attribute);
} catch (Exception e) {
log.error("log4j:logger=root", e);
}
}
}
A Log4J MBean for Each Log4J Configuration
public class RegisterLog4JMBeanServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(RegisterLog4JMBeanServlet.class);
public void init(ServletConfig servletConfig)
throws ServletException {
ServletContext context = servletConfig.getServletContext();
String webappName = context.getServletContextName();
Hashtable<String, String> nameParameters = new Hashtable<String, String>();
nameParameters.put("logger", "root");
Logger rootLogger = LogManager.getRootLogger();
LoggerDynamicMBean mbean = new LoggerDynamicMBean(rootLogger);
List list = MBeanServerFactory.findMBeanServer(null);
MBeanServer server = (MBeanServer)list.iterator().next();
ObjectName objectName = null;
try {
objectName = new ObjectName(webappName, nameParameters);
server.registerMBean(mbean, objectName);
} catch (Exception e) {
log.error("Problems registering Log4J MBean", e);
}
}
}
LogManager.getRootLogger()
. Then you can use the LoggerDynamicMBean class from Log4J to create your MBean from the root logger definition.
ObjectName objectName = new ObjectName("log4j:logger=root");
ServletContext context = servletConfig.getServletContext();
String webappName = context.getServletContextName();
Hashtable<String, String> nameParameters = new Hashtable<String, String>();
nameParameters.put("logger", "root");
ObjectName objectName = new ObjectName(webappName, nameParameters);
ERROR main org.apache.log4j.jmx.LoggerDynamicMBean ? - Could not add appenderMBean for [<appender_name>].
javax.management.InstanceAlreadyExistsException: log4j:appender=<appender_name>
<Connector port="8010"
handler.list="mx"
mx.enabled="true"
mx.httpHost="localhost"
mx.httpPort="8013"
protocol="AJP/1.3"/>
Set the Logging Level for All the Nodes in Your Cluster
send(ClusterMessage)
method on the org.apache.catalina.cluster.SimpleTcpCluster class. When implementing a ClusterMessage, you must populate the details of the cluster node that was responsible for sending the request. (Listing 1 provides an example that retrieves the information through the Tomcat MBeans.) The first step is to provide an implementation of the ClusterMessage interface to pass the new logging level and to determine for which application you want to set the logging level.
send(ClusterMessage)
operation on the MBean:
public static void sendLogMessageEvent(String applicationName, String logLevel) {
String port = System.getProperty("com.sun.management.jmxremote.port");
String urlForJMX = JMX_SERVICE_PREFIX + HOST + ":" + port + JMX_SERVICE_SUFFIX;
try {
JMXServiceURL url = new JMXServiceURL(urlForJMX);
JMXConnector connector = JMXConnectorFactory.connect(url, null);
MBeanServerConnection server = connector.getMBeanServerConnection();
ObjectName cluster = new ObjectName("Catalina:type=Cluster,host=localhost");
log.debug("Cluster cluster: " + cluster.toString());
LogLevelMessage message = new LogLevelMessage();
message.setLoggingLevel(logLevel);
message.setApplication(applicationName);
Object[] params = new Object[] {message};
String[] types = new String[] {"org.apache.catalina.cluster.ClusterMessage"};
server.invoke(cluster, "send", params, types);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=8012
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Receiving the Message in the Other Nodes
Once you are able to send these messages to the other nodes in the cluster, you will need to implement a Tomcat ClusterListener to receive the events. This implementation will set the logging level for the correct MBean determined by the application name that is passed as part of the message:
public class ClusterLoggingListener extends ClusterListener {
private static final Log log = LogFactory.getLog(ClusterLoggingListener.class);
public void messageReceived(ClusterMessage message) {
if(message instanceof LogLevelMessage) {
LogLevelMessage logMessage = (LogLevelMessage) message;
List list = MBeanServerFactory.findMBeanServer(null);
MBeanServer server = (MBeanServer)list.iterator().next();
Hashtable<String, String> nameParameters = new Hashtable<String, String>();
nameParameters.put("logger", "root");
try {
ObjectName logBean = new ObjectName(logMessage.getApplication(), nameParameters);
Attribute attribute = new Attribute("priority", logMessage.getLoggingLevel());
server.setAttribute(logBean, attribute);
} catch (Exception e) {
log.error("Problem setting the logging level for application " +
logMessage.getApplication() + " to level " +
logMessage.getLoggingLevel(),e);
}
}
}
public boolean accept(ClusterMessage message) {
return message instanceof LogLevelMessage;
}
}
<Cluster>
element:
<ClusterListener className="dynamiclogging.tomcat.ClusterLoggingListener"/>
Deploying the Example Code
To deploy the example code for setting the logging level in your cluster, take the following steps: /setLogLevel?level=debug
) to set the logging level and use PerformLogTestServlet (/testLogLevel
) to test the logging level changes.
]]>
1銆変嬌鐢?strong>springframework鍦╳eb.xml涓厤緗?br />//璁劇疆webAppRootKey鐨勫埆鍚嶏紝
//濡傛灉涓嶈緗紝鍦╨og4j.xml涓緗負<param name="File" value="${webapp.root}/WEB-INF/log/frame.log " />
//鍚﹀垯錛屽彲浠ヨ緗負<param name="File" value="${demo.root}/WEB-INF/log/frame.log " />
//濡傛灉涓嶄嬌鐢?font color="#0000ff">${webapp.root}錛屽氨浼氭寚鍚?{TOMCAT_HOM},涔熷氨鏄痶omcat鐨勫畨瑁呯洰褰?font color="#ff0000">銆?/font>
聽<context-param>
聽聽<param-name>webAppRootKey</param-name>
聽聽<param-value>demo.root</param-value>
聽</context-param>
//璁劇疆閰嶇疆鏂囦歡聽聽聽
<context-param>
聽聽聽聽聽聽聽 <param-name>log4jConfigLocation</param-name>
聽聽聽聽聽聽聽 <param-value>/WEB-INF/log4j.xml</param-value>
聽聽聽 </context-param>
//璁劇疆鐩戝惉鍣?br />聽 <listener>
聽聽<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
聽</listener>
榪欐牱log4j.xml 灝卞彲浠EB-INF閲岄潰鐨勪換浣曡礬寰勩?br />
Source:
initLogging->
{
聽聽聽聽聽聽WebUtils.setWebAppRootSystemProperty(servletContext);
聽聽聽聽聽聽{
聽聽聽聽聽聽String root = servletContext.getRealPath("/");
聽聽聽聽聽聽String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);
聽聽聽聽聽聽聽String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY);
聽聽聽聽聽聽聽聽System.setProperty(key, root);
聽聽聽聽聽聽//use system property聽to聽deal with ${webapp.root} or聽its聽alias.
聽聽聽聽聽聽//once聽I聽writed careless聽${webapp.root}聽to {webapp.root}聽,and聽look up聽the error for聽much time.
聽聽聽聽聽聽聽聽聽聽}
聽聽聽聽聽聽String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
聽聽聽聽聽聽Log4jConfigurer.initLogging(location);
聽聽聽聽聽聽{
聽聽聽聽聽聽聽聽聽//distinguish the log4j.xml聽and聽log4j.properties
聽聽聽聽聽聽聽聽聽if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
聽聽聽聽聽聽聽聽聽聽聽聽DOMConfigurator.configure(url);
聽聽聽聽聽聽聽聽}
聽聽聽聽聽else {
聽聽聽聽聽聽聽聽聽PropertyConfigurator.configure(url);
聽聽聽聽聽}
聽聽聽聽聽聽}
}
use DOMConfigurator.configure("log4j.xml"); to init config ,then LogFactory can work. the "log4j.xml "
may be any name .DOMConfigurator may use cache mechanism聽as聽in LogFactory class .cache machanism is
another way to implement "single" design pattern.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2銆塛EB-INF/classes涓嬮潰
閲囧彇榪欑鏂瑰紡錛屽畠鐨勬枃浠禷ppender鐨勭浉瀵硅礬寰勬繪槸鎸囧悜${TOMCAT_HOM},涔熷氨鏄痶omcat鐨勫畨瑁呯洰褰?font color="#ff0000">銆?lt;param name="File" value="demo.log" /> 浼氭妸demo.log 淇濆瓨鍒?/font>${TOMCAT_HOM}/demo.log 錛?br />閲囩敤緇濆璺緞鍒欏彲浠ヤ換鎰忚緗?br />
涓轟簡浣跨敤鐩稿璺緞錛屾垜浠妸project鏀懼埌${TOMCAT_HOMe}/webapps涓媎eploy銆?br />濡俻roject鍚嶄負demo錛宭og瑕佷繚瀛樺湪demo/log/demo.log鏂囦歡閲岋紝鍒欏彲浠ヨ涓猴細
<param name="File" value="webapps\\demo\\log\\framefile.log" />
---------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------
娉ㄦ剰鈥淺" 瑕佺敤杞箟瀛楃"\\",濡傛灉娌″姞,tomcat鍚姩灞忎腑鐨勮礬寰勪細鍙樹負涔辯爜.
tomcat涓技涔庨噰鍙栦簡鏌愮瀹夊叏絳栫暐,<param name="Append" value="false" />涓嶈搗浣滅敤銆?br />
鏈嶅姟鍣ㄩ噸璧峰悗灝變細鏂板緩涓涓猯og鏂囦歡.
Appender - 鏃ュ織鐩殑鍦幫紝鎶婃牸寮忓寲濂界殑鏃ュ織淇℃伅杈撳嚭鍒版寚瀹氱殑鍦版柟鍘?
ConsoleAppender - 鐩殑鍦頒負鎺у埗鍙扮殑Appender
FileAppender - 鐩殑鍦頒負鏂囦歡鐨凙ppender
RollingFileAppender - 鐩殑鍦頒負澶у皬鍙楅檺鐨勬枃浠剁殑Appender
Layout - 鏃ュ織鏍煎紡鍖栧櫒錛岀敤鏉ユ妸紼嬪簭鍛樼殑logging request鏍煎紡鍖栨垚瀛楃涓?
PatternLayout - 鐢ㄦ寚瀹氱殑pattern鏍煎紡鍖杔ogging request鐨凩ayout
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=warn, stdout #鎵鏈夐厤緗戶鎵挎閰嶇疆(鍦ㄦ鍩虹澧炲姞),鍙笉瑕?BR>#鍙畾涔夎嚜宸辯殑綰у埆:
log4j.logger.test=info
#log4j.logger蹇呴渶;鍏跺悗鍙姞package name or class name;
浣跨敤:
package test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author herald
*
* TODO 瑕佹洿鏀規鐢熸垚鐨勭被鍨嬫敞閲婄殑妯℃澘錛岃杞嚦 紿楀彛 錛?棣栭夐」 錛?Java 錛?浠g爜鏍峰紡 錛?浠g爜妯℃澘
*/
public class Test {
public static void main(String[] args) {
Log log = LogFactory.getLog("test"); 鍏跺鏋滃瓨鍦?test",涓嶉噸鏂板緩绔媗og
log.info("aa");
log.error("bbbbbb");
}
}
婧愮爜:
CategoryKey key = new CategoryKey(name);
// Synchronize to prevent write conflicts. Read conflicts (in
// getChainedLevel method) are possible only if variable
// assignments are non-atomic.
Logger logger;
synchronized (ht) {
Object o = ht.get(key);
if (o == null) {
logger = factory.makeNewLoggerInstance(name);
logger.setHierarchy(this);
ht.put(key, logger);
updateParents(logger);
return logger;
} else if (o instanceof Logger) {
return (Logger) o;
} else if (o instanceof ProvisionNode) {
//System.out.println("("+name+") ht.get(this) returned
// ProvisionNode");
logger = factory.makeNewLoggerInstance(name);
logger.setHierarchy(this);
ht.put(key, logger);
updateChildren((ProvisionNode) o, logger);
updateParents(logger);
return logger;
} else {
// It should be impossible to arrive here
return null; // but let's keep the compiler happy.
}
}
}
LogFactory
ImplementationFrom an application perspective, the first requirement is to retrieve an object reference to the LogFactory
instance that will be used to create Log
instances for this application. This is normally accomplished by calling the static getFactory()
method. This method implements the following discovery algorithm to select the name of the LogFactory
implementation class this application wants to use:
org.apache.commons.logging.LogFactory
.
META-INF/services/org.apache.commons.logging.LogFactory
whose first line is assumed to contain the desired class name.
commons-logging.properties
visible in the application class path, with a property named org.apache.commons.logging.LogFactory
defining the desired implementation class name.
If a commons-logging.properties
file is found, all of the properties defined there are also used to set configuration attributes on the instantiated LogFactory
instance.
浣跨敤蹇呴』:
commons-logging-1.0.4.jar
log4j-1.2.9.jar
log4j.properties
Logger瀵硅薄鏄敤鏉ュ彇浠?TT>System.out鎴栬?TT>System.err鐨勬棩蹇楀啓鍑哄櫒錛岀敤鏉ヤ緵紼嬪簭鍛樿緭鍑烘棩蹇椾俊鎭?/P>
Logger鐨勮緭鍑烘柟娉?/B> |
Logger綾誨璞℃彁渚涗竴緋誨垪鏂規硶渚涚▼搴忓憳杈撳嚭鏃ュ織淇℃伅銆?/P>
|
Logger鐨勫懡鍚嶈鍒?/B> |
Logger鐢變竴涓猄tring綾葷殑鍚嶅瓧璇嗗埆錛宭ogger鐨勫悕瀛楁槸澶у皬鍐欐晱鎰熺殑錛屼笖鍚嶅瓧涔嬮棿鍏鋒湁緇ф壙鐨勫叧緋伙紝瀛愬悕鏈夌埗鍚嶄綔涓哄墠緙錛岀敤鐐瑰彿.鍒嗛殧銆傚錛?TT>x.y鏄?TT>x.y.z鐨勭埗浜層?/P> 鏍筶ogger (root logger)鏄墍鏈塴ogger鐨勭鍏堬紝瀹冨叿鏈夊涓嬪睘鎬э細1) 瀹冩繪槸瀛樺湪鐨勶紱2) 瀹冧笉鍙互閫氳繃鍚嶅瓧鑾峰緱銆?/P> 閫氳繃璋冪敤public static Logger Logger.getRootLogger()鑾峰緱root logger錛涢氳繃璋冪敤public static Logger Logger.getLogger(String name)鎴栬?TT>public static Logger Logger.getLogger(Class clazz)鑾峰緱錛堟垨鑰呭垱寤猴級涓涓?TT>named logger銆傚悗鑰呯浉褰撲簬璋冪敤Logger.getLogger(clazz.getName())銆?/P> 鍦ㄦ煇瀵硅薄涓紝鐢ㄨ瀵硅薄鎵灞炵殑綾諱負鍙傛暟錛岃皟鐢?TT>Logger.getLogger(Class clazz)浠ヨ幏寰條ogger琚涓烘槸鐩墠鎵鐭ョ殑鏈鐞嗘櫤鐨勫懡鍚峫ogger鐨勬柟娉曘?/P> |
Log level |
姣忎釜logger閮借鍒嗛厤浜嗕竴涓棩蹇楃駭鍒?(log level)錛岀敤鏉ユ帶鍒舵棩蹇椾俊鎭殑杈撳嚭銆傛湭琚垎閰峫evel鐨刲ogger灝嗙戶鎵垮畠鏈榪戠殑鐖秎ogger鐨刲evel銆?/P> 姣忔潯杈撳嚭鍒發ogger鐨勬棩蹇楄姹?logging request)涔熼兘鏈変竴涓猯evel錛屽鏋滆request鐨刲evel澶т簬絳変簬璇ogger鐨刲evel錛屽垯璇equest灝嗚澶勭悊錛堢О涓篹nabled錛夛紱鍚﹀垯璇equest灝嗚蹇界暐銆傛晠鍙緱鐭ワ細
Level綾諱腑棰勫畾涔変簡浜斾釜level錛屽畠浠殑澶у皬鍏崇郴濡備笅錛?/P>
|
紺轟緥浠g爜 |
浠ヤ笅浠g爜灝嗙敤鑷繁鎵灞炵殑綾諱負鍙傛暟錛屽垱寤轟竴涓猯ogger錛屽惎鐢ㄩ粯璁ら厤緗紝璁劇疆鍏秎evel騫跺悜鍏惰緭鍑鴻嫢騫瞝ogging request銆?/P>
|
鍏充簬logger鐨勪袱鐐硅鏄?/B> |
|
Appender錛氭棩蹇楃洰鐨勫湴 | ||||||
姣忎釜logger閮藉彲浠ユ嫢鏈変竴涓垨鑰呭涓猘ppender錛屾瘡涓猘ppender琛ㄧず涓涓棩蹇楃殑杈撳嚭鐩殑鍦幫紝姣斿console鎴栬呮煇涓枃浠躲傚彲浠ヤ嬌鐢?TT>Logger.addAppender(Appender app)涓簂ogger澧炲姞涓涓猘ppender錛涘彲浠ヤ嬌鐢?TT>Logger.removeAppender(Appender app)涓簂ogger縐婚櫎涓涓猘ppender銆?/P> 榛樿鎯呭喌涓嬶紝logger鐨刟dditive鏍囧織琚緗負true錛岃〃紺哄瓙logger灝嗙戶鎵跨埗logger鐨勬墍鏈塧ppenders銆傝閫夐」鍙互琚噸鏂拌緗紝琛ㄧず瀛恖ogger灝嗕笉鍐嶇戶鎵跨埗logger鐨刟ppenders銆?/P> root logger鎷ユ湁鐩爣涓?TT>system.out鐨?TT>consoleAppender錛屾晠榛樿鎯呭喌涓嬶紝鎵鏈夌殑logger閮藉皢緇ф壙璇ppender銆?/P>
|
Layout錛氭棩蹇楁牸寮忓寲鍣?/B> | ||||
姣忎釜appender閮藉拰涓涓猯ayout鐩歌仈緋伙紱layout鐨勪換鍔℃槸鏍煎紡鍖栫敤鎴風殑logging request錛宎ppender鐨勪換鍔℃槸鎶妉ayout鏍煎紡鍖栧ソ鐨勮緭鍑哄唴瀹歸佸線鎸囧畾鐨勭洰鐨勫湴銆?/P>
|
Configuration錛氶厤緗?/B> | ||||||||||||||||||||||||||||||||||||||
瀵筶og4j鐜鐨勯厤緗氨鏄root logger鐨勯厤緗紝鍖呮嫭鎶妑oot logger璁劇疆涓哄摢涓駭鍒?level)錛涗負瀹冨鍔犲摢浜沘ppender錛岀瓑絳夈傝繖浜涘彲浠ラ氳繃璁劇疆緋葷粺灞炴х殑鏂規硶鏉ラ殣寮忓湴瀹屾垚錛屼篃鍙互鍦ㄧ▼搴忛噷璋冪敤XXXConfigurator.configure()鏂規硶鏉ユ樉寮忓湴瀹屾垚銆?/P>
|
Log4j鐨勭紪鐮佷範鎯?/B> |
|