001
014
015 package com.liferay.util.log4j;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.log.LogFactory;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.kernel.util.PropsUtil;
023 import com.liferay.portal.kernel.util.ServerDetector;
024 import com.liferay.portal.kernel.util.StreamUtil;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027
028 import java.io.IOException;
029 import java.io.InputStream;
030
031 import java.net.URL;
032
033 import java.util.Enumeration;
034 import java.util.HashMap;
035 import java.util.List;
036 import java.util.Map;
037 import java.util.concurrent.ConcurrentHashMap;
038
039 import org.apache.log4j.Level;
040 import org.apache.log4j.LogManager;
041 import org.apache.log4j.Logger;
042 import org.apache.log4j.xml.DOMConfigurator;
043
044 import org.dom4j.Document;
045 import org.dom4j.Element;
046 import org.dom4j.io.SAXReader;
047
048 import org.xml.sax.EntityResolver;
049 import org.xml.sax.InputSource;
050
051
055 public class Log4JUtil {
056
057 public static void configureLog4J(ClassLoader classLoader) {
058 configureLog4J(classLoader.getResource("META-INF/portal-log4j.xml"));
059
060 try {
061 Enumeration<URL> enu = classLoader.getResources(
062 "META-INF/portal-log4j-ext.xml");
063
064 while (enu.hasMoreElements()) {
065 configureLog4J(enu.nextElement());
066 }
067 }
068 catch (IOException ioe) {
069 java.util.logging.Logger logger =
070 java.util.logging.Logger.getLogger(Log4JUtil.class.getName());
071
072 logger.log(
073 java.util.logging.Level.WARNING,
074 "Unable to load portal-log4j-ext.xml", ioe);
075 }
076 }
077
078 public static void configureLog4J(URL url) {
079 if (url == null) {
080 return;
081 }
082
083 String urlContent = _getURLContent(url);
084
085 if (urlContent == null) {
086 return;
087 }
088
089
090
091 DOMConfigurator domConfigurator = new DOMConfigurator();
092
093 domConfigurator.doConfigure(
094 new UnsyncStringReader(urlContent),
095 LogManager.getLoggerRepository());
096
097 try {
098 SAXReader saxReader = new SAXReader();
099
100 saxReader.setEntityResolver(
101 new EntityResolver() {
102
103 @Override
104 public InputSource resolveEntity(
105 String publicId, String systemId) {
106
107 if (systemId.endsWith("log4j.dtd")) {
108 return new InputSource(
109 DOMConfigurator.class.getResourceAsStream(
110 "log4j.dtd"));
111 }
112
113 return null;
114 }
115
116 });
117
118 Document document = saxReader.read(
119 new UnsyncStringReader(urlContent), url.toExternalForm());
120
121 Element rootElement = document.getRootElement();
122
123 List<Element> categoryElements = rootElement.elements("category");
124
125 for (Element categoryElement : categoryElements) {
126 String name = categoryElement.attributeValue("name");
127
128 Element priorityElement = categoryElement.element("priority");
129
130 String priority = priorityElement.attributeValue("value");
131
132 java.util.logging.Logger jdkLogger =
133 java.util.logging.Logger.getLogger(name);
134
135 jdkLogger.setLevel(_getJdkLevel(priority));
136 }
137 }
138 catch (Exception e) {
139 _logger.error(e, e);
140 }
141 }
142
143 public static Map<String, String> getCustomLogSettings() {
144 return new HashMap<>(_customLogSettings);
145 }
146
147 public static String getOriginalLevel(String className) {
148 Level level = Level.ALL;
149
150 Enumeration<Logger> enu = LogManager.getCurrentLoggers();
151
152 while (enu.hasMoreElements()) {
153 Logger logger = enu.nextElement();
154
155 if (className.equals(logger.getName())) {
156 level = logger.getLevel();
157
158 break;
159 }
160 }
161
162 return level.toString();
163 }
164
165 public static void initLog4J(
166 String serverId, String liferayHome, ClassLoader classLoader,
167 LogFactory logFactory, Map<String, String> customLogSettings) {
168
169 ServerDetector.init(serverId);
170
171 _liferayHome = liferayHome;
172
173 configureLog4J(classLoader);
174
175 try {
176 LogFactoryUtil.setLogFactory(logFactory);
177 }
178 catch (Exception e) {
179 _logger.error(e, e);
180 }
181
182 for (String name : customLogSettings.keySet()) {
183 String priority = customLogSettings.get(name);
184
185 setLevel(name, priority, false);
186 }
187 }
188
189 public static void setLevel(String name, String priority, boolean custom) {
190 Logger logger = Logger.getLogger(name);
191
192 logger.setLevel(Level.toLevel(priority));
193
194 java.util.logging.Logger jdkLogger = java.util.logging.Logger.getLogger(
195 name);
196
197 jdkLogger.setLevel(_getJdkLevel(priority));
198
199 if (custom) {
200 _customLogSettings.put(name, priority);
201 }
202 }
203
204
207 private static byte[] _getBytes(InputStream inputStream)
208 throws IOException {
209
210 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
211 new UnsyncByteArrayOutputStream();
212
213 StreamUtil.transfer(inputStream, unsyncByteArrayOutputStream, -1, true);
214
215 return unsyncByteArrayOutputStream.toByteArray();
216 }
217
218 private static java.util.logging.Level _getJdkLevel(String priority) {
219 if (StringUtil.equalsIgnoreCase(priority, Level.DEBUG.toString())) {
220 return java.util.logging.Level.FINE;
221 }
222 else if (StringUtil.equalsIgnoreCase(
223 priority, Level.ERROR.toString())) {
224
225 return java.util.logging.Level.SEVERE;
226 }
227 else if (StringUtil.equalsIgnoreCase(priority, Level.WARN.toString())) {
228 return java.util.logging.Level.WARNING;
229 }
230 else {
231 return java.util.logging.Level.INFO;
232 }
233 }
234
235 private static String _getLiferayHome() {
236 if (_liferayHome == null) {
237 _liferayHome = PropsUtil.get(PropsKeys.LIFERAY_HOME);
238 }
239
240 return _liferayHome;
241 }
242
243 private static String _getURLContent(URL url) {
244 Map<String, String> variables = new HashMap<>();
245
246 variables.put("@liferay.home@", _getLiferayHome());
247
248 String spiId = System.getProperty("spi.id");
249
250 if (spiId == null) {
251 spiId = StringPool.BLANK;
252 }
253
254 variables.put("@spi.id@", spiId);
255
256 String urlContent = null;
257
258 InputStream inputStream = null;
259
260 try {
261 inputStream = url.openStream();
262
263 byte[] bytes = _getBytes(inputStream);
264
265 urlContent = new String(bytes, StringPool.UTF8);
266 }
267 catch (Exception e) {
268 _logger.error(e, e);
269
270 return null;
271 }
272 finally {
273 StreamUtil.cleanUp(inputStream);
274 }
275
276 for (Map.Entry<String, String> variable : variables.entrySet()) {
277 urlContent = StringUtil.replace(
278 urlContent, variable.getKey(), variable.getValue());
279 }
280
281 if (ServerDetector.getServerId() != null) {
282 return urlContent;
283 }
284
285 urlContent = _removeAppender(urlContent, "TEXT_FILE");
286
287 return _removeAppender(urlContent, "XML_FILE");
288 }
289
290 private static String _removeAppender(String content, String appenderName) {
291 int x = content.indexOf("<appender name=\"" + appenderName + "\"");
292
293 int y = content.indexOf("</appender>", x);
294
295 if (y != -1) {
296 y = content.indexOf("<", y + 1);
297 }
298
299 if ((x != -1) && (y != -1)) {
300 content = content.substring(0, x) + content.substring(y);
301 }
302
303 return StringUtil.replace(
304 content, "<appender-ref ref=\"" + appenderName + "\" />",
305 StringPool.BLANK);
306 }
307
308 private static final Logger _logger = Logger.getRootLogger();
309
310 private static final Map<String, String> _customLogSettings =
311 new ConcurrentHashMap<>();
312 private static String _liferayHome;
313
314 }