Log4j2与JNDI结合
来源:互联网 发布:rxjava 源码 编辑:程序博客网 时间:2024/05/22 06:04
在Log4j和JNDI结合一文中介绍了在Web应用中如何通过JNDI和log4j结合来指定配置文件地址和日志文件日志。
这里介绍Web应用中log4j2如何和JNDI结合达到相同的目的。
这里也要分2个部分:
第一步是指定配置文件地址,同样要定制自己的listener来初始化log4j2
JndiLog4j2ConfigListener实现
...import org.apache.logging.log4j.core.config.Configurator;... public static final String CONFIG_FILE_URL = "log4jConfiguration"; public static final String CONFIG_FILENAME_PARAM = "log4jFilename"; private LoggerContext loggerContext; public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext sc = servletContextEvent.getServletContext(); String location = sc.getInitParameter(CONFIG_FILE_URL); String filename = sc.getInitParameter(CONFIG_FILENAME_PARAM); if(StringUtils.isBlank(location) || StringUtils.isBlank(filename)){ sc.log("invalid config file location or filename, location: " + location + " filename: " + filename); } try{ InitialContext ic = new InitialContext(); URL log4jURL = (URL) context.lookup(location); location = log4jURL.toExternalForm(); location = location + file.separator + filename; String contextName = servletContext.getServletContextName(); Classloader classloader = this.getClass().getClassloader(); loggerContext = Configurator.initialize(contextName, classloader, location); } catch (NamingException ex){ throw new IllegalArgumentException("Invaild log4j config: " + ex.getMessage()); } } public void contextDestroyed(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); servletContext.log("Log4jConfigurationListener - Shutting down log4j"); if (loggerContext != null) Configurator.shutdown(loggerContext); }
Web配置
<context-param> <param-name>log4jConfiguration</param-name> <param-value>jndi:java:/comp/env/config_dir</param-value> </context-param> <context-param> <param-name>log4jFilename</param-name> <param-value>log4j2-demo.xml</param-value> </context-param> <listener> <listener-class>com.demo.JndiLog4j2ConfigListener</listener-class> </listener> <resource-ref> <res-ref-name> config_dir </res-ref-name> <res-type> java.net.URL </res-type> <res-auth> Container </res-auth> </resource-ref>
第二步是
定制自己的appender,这里参考RollingRandomAccessFileAppender来通过JNDI指定日志文件地址
@Plugin(name = "JndiRollingRandomAccessFile", category = "Core", elementType = "appender", printObject = true)public final class JndiRollingRandomAccessFileAppender extends AbstractOutputStreamAppender<JndiRollingRandomAccessFileManager> { private final String fileName; private final String filePattern; private final Object advertisement; private final Advertiser advertiser; private static String LOG_DIR_URL = "java:comp/env/DEFAULT_URL"; private JndiRollingRandomAccessFileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter, final JndiRollingRandomAccessFileManager manager, final String fileName, final String filePattern, final boolean ignoreExceptions, final boolean immediateFlush, final int bufferSize, final Advertiser advertiser) { super(name, layout, filter, ignoreExceptions, immediateFlush, manager); if (advertiser != null) { final Map<String, String> configuration = new HashMap<>(layout.getContentFormat()); configuration.put("contentType", layout.getContentType()); configuration.put("name", name); advertisement = advertiser.advertise(configuration); } else { advertisement = null; } this.fileName = fileName; this.filePattern = filePattern; this.advertiser = advertiser; } @Override public void stop() { super.stop(); if (advertiser != null) { advertiser.unadvertise(advertisement); } } /** * Write the log entry rolling over the file when required. * * @param event The LogEvent. */ @Override public void append(final LogEvent event) { final JndiRollingRandomAccessFileManager manager = getManager(); manager.checkRollover(event); // Leverage the nice batching behaviour of async Loggers/Appenders: // we can signal the file manager that it needs to flush the buffer // to disk at the end of a batch. // From a user's point of view, this means that all log events are // _always_ available in the log file, without incurring the overhead // of immediateFlush=true. manager.setEndOfBatch(event.isEndOfBatch()); // FIXME manager's EndOfBatch threadlocal can be deleted // LOG4J2-1292 utilize gc-free Layout.encode() method: taken care of in superclass super.append(event); } /** * Returns the File name for the Appender. * * @return The file name. */ public String getFileName() { return fileName; } /** * Returns the file pattern used when rolling over. * * @return The file pattern. */ public String getFilePattern() { return filePattern; } /** * Returns the size of the file manager's buffer. * @return the buffer size */ public int getBufferSize() { return getManager().getBufferSize(); } /** * Create a JndiRollingRandomAccessFileAppender. * * @param parent The name of the dir that the file is actively written to. * (required). * @param fileName The name of the file that is actively written to. * (required). * @param filePattern The pattern of the file name to use on rollover. * (required). * @param append If true, events are appended to the file. If false, the * file is overwritten when opened. Defaults to "true" * @param name The name of the Appender (required). * @param immediateFlush When true, events are immediately flushed. Defaults * to "true". * @param bufferSizeStr The buffer size, defaults to {@value JndiRollingRandomAccessFileManager#DEFAULT_BUFFER_SIZE}. * @param policy The triggering policy. (required). * @param strategy The rollover strategy. Defaults to * DefaultRolloverStrategy. * @param layout The layout to use (defaults to the default PatternLayout). * @param filter The Filter or null. * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise * they are propagated to the caller. * @param advertise "true" if the appender configuration should be * advertised, "false" otherwise. * @param advertiseURI The advertised URI which can be used to retrieve the * file contents. * @param config The Configuration. * @return A JndiRollingRandomAccessFileAppender. */ @PluginFactory public static JndiRollingRandomAccessFileAppender createAppender( @PluginAttribute("parent") final String parent, @PluginAttribute("fileName") final String fileName, @PluginAttribute("filePattern") final String filePattern, @PluginAttribute("append") final String append, @PluginAttribute("name") final String name, @PluginAttribute("immediateFlush") final String immediateFlush, @PluginAttribute("bufferSize") final String bufferSizeStr, @PluginElement("Policy") final TriggeringPolicy policy, @PluginElement("Strategy") RolloverStrategy strategy, @PluginElement("Layout") Layout<? extends Serializable> layout, @PluginElement("Filter") final Filter filter, @PluginAttribute("ignoreExceptions") final String ignore, @PluginAttribute("advertise") final String advertise, @PluginAttribute("advertiseURI") final String advertiseURI, @PluginConfiguration final Configuration config) { final boolean isAppend = Booleans.parseBoolean(append, true); final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); final boolean isFlush = Booleans.parseBoolean(immediateFlush, true); final boolean isAdvertise = Boolean.parseBoolean(advertise); final int bufferSize = Integers.parseInt(bufferSizeStr, JndiRollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE); if (name == null) { LOGGER.error("No name provided for FileAppender"); return null; } if (parent == null) { LOGGER.error("No parent folder was provided for FileAppender with name " + name); return null; } if (fileName == null) { LOGGER.error("No filename was provided for FileAppender with name " + name); return null; } String dir = null; try{ InitialContext ic = new InitialContext(); URL log4jURL = (URL) context.lookup(parent); dir = log4jURL.toExternalForm(); } catch (NamingException ex){ LOGGER.error("fail to fetch parent dir for FileAppender with name " + name); return null; } if (filePattern == null) { LOGGER.error("No filename pattern provided for FileAppender with name " + name); return null; } if (policy == null) { LOGGER.error("A TriggeringPolicy must be provided"); return null; } if (strategy == null) { strategy = DefaultRolloverStrategy.createStrategy(null, null, null, String.valueOf(Deflater.DEFAULT_COMPRESSION), null, true, config); } if (layout == null) { layout = PatternLayout.createDefaultLayout(); } final JndiRollingRandomAccessFileManager manager = JndiRollingRandomAccessFileManager.getJndiRollingRandomAccessFileManager( parent + File.separator + fileName, parent + File.separator + filePattern, isAppend, isFlush, bufferSize, policy, strategy, advertiseURI, layout); if (manager == null) { return null; } return new JndiRollingRandomAccessFileAppender(name, layout, filter, manager, parent + File.separator + fileName, parent + File.separator + filePattern, ignoreExceptions, isFlush, bufferSize, isAdvertise ? config.getAdvertiser() : null); }}
配置文件:
<JndiRollingRandomAccessFile name="RollingFile" parent="java:comp/env/DEFAULT_URL" fileName="sample.log" filePattern="$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz" immediateFlush="false" append="true"> <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="50 MB" /> <DefaultRolloverStrategy max="10" /> </JndiRollingRandomAccessFile>
注1:log4j2的基本使用参考
注2:log4j2的配置文件号称可以替换参数来定制路径,我使用失败了,最近没空研究log4j2的代码,以后再看看,有知道的也请指教。
0 0
- Log4j2与JNDI结合
- log4j2单独的配置与使用&log4j2+slf4j的结合的配置与使用
- Log4j2(二)Nutz与Log4j2
- Web应用中Log4j与JNDI结合1 -- JNDI指定配置文件
- Web应用中Log4j与JNDI结合2 -- JNDI指定日志路径
- log4j2 配置与使用
- Log4j2 与 SpringMVC 整合
- Log4j2分析与实践
- log4j与log4j2
- Log4J2的配置与使用
- Spring4与log4j2的集成
- log4j2 与 spring mvc整合
- log4j2 与 spring mvc整合
- log4j2 与 spring mvc整合
- Spring4与log4j2的集成
- Log4j2架构分析与实战
- log4j2 入门学习与总结
- Log4j2 SMTPAppender 配置与使用
- bzoj 2660: [Beijing wc2012]最多的方案 递推
- TS协议解析第二部分(PMT)
- 刷题第七天:南邮NOJ【1014数据的插入与删除】
- Roman to Integer
- apt-get详解
- Log4j2与JNDI结合
- hdu5646(DZY Loves Partition) 划分
- 介绍一个轻量级iOS安全框架:SSKeyChain
- JAVA-WEB开发第三讲[2016-06-04]JAVA环境变量的设置
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
- CentOS安装openvpn
- 电力电子仿真软件---PLECS
- C语言calloc()函数
- iOS开发(OC)——日期选择器