我是靠谱客的博主 热心康乃馨,这篇文章主要介绍Log4j2与JNDI结合,现在分享给大家,希望可以做个参考。

在Log4j和JNDI结合一文中介绍了在Web应用中如何通过JNDI和log4j结合来指定配置文件地址和日志文件日志。
这里介绍Web应用中log4j2如何和JNDI结合达到相同的目的。
这里也要分2个部分:
第一步是指定配置文件地址,同样要定制自己的listener来初始化log4j2
JndiLog4j2ConfigListener实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
... 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配置

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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指定日志文件地址

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
@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); } }

配置文件:

复制代码
1
2
3
4
5
6
7
<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的代码,以后再看看,有知道的也请指教。

最后

以上就是热心康乃馨最近收集整理的关于Log4j2与JNDI结合的全部内容,更多相关Log4j2与JNDI结合内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部