Log.java 11.2 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
6
 * Copyright (C) 2004-2008 Jive Software. All rights reserved.
Matt Tucker's avatar
Matt Tucker committed
7
 *
8 9 10 11 12 13 14 15 16 17 18
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
Matt Tucker's avatar
Matt Tucker committed
19
 */
20

Matt Tucker's avatar
Matt Tucker committed
21 22
package org.jivesoftware.util;

23
import java.io.BufferedWriter;
24
import java.io.File;
25
import java.io.FileWriter;
26 27 28
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
29 30
import java.util.ArrayList;
import java.util.List;
31
import java.util.Map;
Matt Tucker's avatar
Matt Tucker committed
32 33

/**
34 35 36 37 38 39 40 41 42 43 44 45
 * Openfire makes use of a logging facade (slf4j) to manage its log output. The
 * facade is backed up by Log4j by default. This class provides utility methods.
 * <p>
 * Additionally, this class provides methods that can be used to record logging
 * statements. These methods are exact duplicates of the previous Log
 * implementation of Openfire and are kept for backwards-compatibility (the are
 * deprecated). These methods will delegate logging functionality to slf4j.
 * Instead of these methods, slf4j logging functionality should be used
 * directly.
 * 
 * @author Guus der Kinderen, guus.der.kinderen@gmail.com
 * @see <a href="http://www.slf4j.org/">http://www.slf4j.org/</a>
Matt Tucker's avatar
Matt Tucker committed
46 47 48
 */
public class Log {

49
	private static final org.slf4j.Logger Logger = org.slf4j.LoggerFactory.getLogger(Log.class);
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
	public static final String LOG_DEBUG_ENABLED = "log.debug.enabled";
	
	// listen for changes to the log.debug.enabled property
	static {
    	PropertyEventDispatcher.addListener(new PropertyEventListener() {
    		
			public void propertySet(String property, Map<String, Object> params) {
				enableDebugLog(property, Boolean.parseBoolean(params.get("value").toString()));
			}
			
			public void propertyDeleted(String property, Map<String, Object> params) {
				enableDebugLog(property, false);
			}
			
			// ignore these events
			public void xmlPropertySet(String property, Map<String, Object> params) { }
			public void xmlPropertyDeleted(String property, Map<String, Object> params) { }
			
			private void enableDebugLog(String property, boolean enabled) {
				if ((LOG_DEBUG_ENABLED).equals(property)) {
					Log.setDebugEnabled(enabled);
				}
			}
		});
	}
	
76 77 78 79 80

	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#isErrorEnabled()}.
	 *             Functionality of this method is delegated there.
	 */
81
	@Deprecated
Matt Tucker's avatar
Matt Tucker committed
82
    public static boolean isErrorEnabled() {
83
        return Logger.isErrorEnabled();
84 85
    }

86 87 88 89
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#isDebugEnabled()}.
	 *             Functionality of this method is delegated there.
	 */
90 91
    @Deprecated
	public static boolean isDebugEnabled() {
92
        return Logger.isDebugEnabled();
93 94 95
    }

    public static void setDebugEnabled(boolean enabled) {
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
    	final org.apache.log4j.Level newLevel;
    	if (enabled) {
    		newLevel = org.apache.log4j.Level.ALL;
    	} else {
    		newLevel = org.apache.log4j.Level.INFO;
    	}
    		
    	org.apache.log4j.LogManager.getRootLogger().setLevel(newLevel);
    }

	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#isInfoEnabled()}.
	 *             Functionality of this method is delegated there.
	 */
111 112
    @Deprecated
	public static boolean isInfoEnabled() {
113
        return Logger.isInfoEnabled();
Matt Tucker's avatar
Matt Tucker committed
114 115
    }

116 117 118 119
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#isWarnEnabled()}.
	 *             Functionality of this method is delegated there.
	 */
120 121
    @Deprecated
	public static boolean isWarnEnabled() {
122
        return Logger.isWarnEnabled();
Matt Tucker's avatar
Matt Tucker committed
123 124
    }

125 126 127 128
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#debug(String)}.
	 *             Functionality of this method is delegated there.
	 */
129 130
    @Deprecated
	public static void debug(String s) {
131
        if (isDebugEnabled()) {
132
            Logger.debug(s);
133 134 135
        }
    }

136 137 138 139
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
140 141
    @Deprecated
	public static void debug(Throwable throwable) {
142
        if (isDebugEnabled()) {
143
            Logger.debug("", throwable);
144 145 146
        }
    }

147 148 149 150
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
151 152
    @Deprecated
	public static void debug(String s, Throwable throwable) {
153
        if (isDebugEnabled()) {
154
            Logger.debug(s, throwable);
155 156 157
        }
    }

158
    public static void markDebugLogFile(String username) {
159 160
    	String message = getMarkMessage(username);
        debug(message);
161 162 163
    }

    public static void rotateDebugLogFile() {
164 165 166
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
        File logFile = new File(Log.getLogDirectory(), "debug.log");
        emptyFile(logFile);
167 168
    }

169 170 171 172
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#info(String)}.
	 *             Functionality of this method is delegated there.
	 */
173 174
    @Deprecated
	public static void info(String s) {
175
        if (isInfoEnabled()) {
176
            Logger.info(s);
177
        }
Matt Tucker's avatar
Matt Tucker committed
178 179
    }

180 181 182 183
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#info(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
184 185
    @Deprecated
	public static void info(Throwable throwable) {
186
        if (isInfoEnabled()) {
187
            Logger.info("", throwable);
188
        }
Matt Tucker's avatar
Matt Tucker committed
189 190
    }

191 192 193 194
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#info(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
195 196
    @Deprecated
	public static void info(String s, Throwable throwable) {
197
        if (isInfoEnabled()) {
198
            Logger.info(s, throwable);
199 200 201
        }
    }

202
    public static void markInfoLogFile(String username) {
203 204
    	String message = getMarkMessage(username);
        info(message);
205 206 207
    }

    public static void rotateInfoLogFile() {
208 209 210 211 212 213 214 215 216
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
        File logFile = new File(Log.getLogDirectory(), "info.log");
        emptyFile(logFile);
    }
    
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#warn(String)}.
	 *             Functionality of this method is delegated there.
	 */
217 218
    @Deprecated
	public static void warn(String s) {
219
        if (isWarnEnabled()) {
220
            Logger.warn(s);
221
        }
Matt Tucker's avatar
Matt Tucker committed
222 223
    }

224 225 226 227
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#warn(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
228 229
    @Deprecated
	public static void warn(Throwable throwable) {
230
        if (isWarnEnabled()) {
231
            Logger.warn("", throwable);
232
        }
Matt Tucker's avatar
Matt Tucker committed
233 234
    }

235 236 237 238
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
239 240
    @Deprecated
	public static void warn(String s, Throwable throwable) {
241
        if (isWarnEnabled()) {
242
            Logger.warn(s, throwable);
243 244 245
        }
    }

246
    public static void markWarnLogFile(String username) {
247 248
    	String message = getMarkMessage(username);
        warn(message);
249 250 251
    }

    public static void rotateWarnLogFile() {
252 253 254
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
        File logFile = new File(Log.getLogDirectory(), "warn.log");
        emptyFile(logFile);
Matt Tucker's avatar
Matt Tucker committed
255 256
    }

257 258 259 260
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#error(String)}.
	 *             Functionality of this method is delegated there.
	 */
261 262
    @Deprecated
	public static void error(String s) {
263
        if (isErrorEnabled()) {
264
            Logger.error(s);
265 266 267 268
            if (isDebugEnabled()) {
                printToStdErr(s, null);
            }
        }
Matt Tucker's avatar
Matt Tucker committed
269 270
    }

271 272 273 274
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#error(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
275 276
    @Deprecated
	public static void error(Throwable throwable) {
277
        if (isErrorEnabled()) {
278
            Logger.error("", throwable);
279 280 281 282 283 284
            if (isDebugEnabled()) {
                printToStdErr(null, throwable);
            }
        }
    }

285 286 287 288
	/**
	 * @deprecated replaced by {@link org.slf4j.Logger#error(String, Throwable)}.
	 *             Functionality of this method is delegated there.
	 */
289 290
    @Deprecated
	public static void error(String s, Throwable throwable) {
291
        if (isErrorEnabled()) {
292
            Logger.error(s, throwable);
293 294 295 296 297 298
            if (isDebugEnabled()) {
                printToStdErr(s, throwable);
            }
        }
    }

299
    public static void markErrorLogFile(String username) {
300 301
    	String message = getMarkMessage(username);
        error(message);
302 303 304
    }

    public static void rotateErrorLogFile() {
305 306 307
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
        File logFile = new File(Log.getLogDirectory(), "error.log");
        emptyFile(logFile);
Matt Tucker's avatar
Matt Tucker committed
308 309 310
    }

    /**
311 312
     * Returns the directory that log files exist in. The directory name will
     * have a File.separator as the last character in the string.
Matt Tucker's avatar
Matt Tucker committed
313
     *
314
     * @return the directory that log files exist in.
Matt Tucker's avatar
Matt Tucker committed
315
     */
316
    public static String getLogDirectory() {
317 318 319 320 321 322 323 324 325 326 327 328 329
        // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j.
    	final StringBuilder sb = new StringBuilder();
    	sb.append(JiveGlobals.getHomeDirectory());
    	if (!sb.substring(sb.length()-1).startsWith(File.separator)) {
    		sb.append(File.separator);
    	}
    	sb.append("logs");
    	sb.append(File.separator);
    	return sb.toString();
    }

    private static String getMarkMessage(String username) {
        final List<String> args = new ArrayList<String>();
330
        args.add(username);
331
        args.add(JiveGlobals.formatDateTime(new java.util.Date()));
332
        return LocaleUtils.getLocalizedString("log.marker_inserted_by", args);
333
    }
334
    
335 336 337 338 339 340 341 342 343 344 345
    private static void printToStdErr(String s, Throwable throwable) {
        if (s != null) {
            System.err.println(s);
        }
        if (throwable != null) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            throwable.printStackTrace(pw);
            System.err.print(sw.toString());
            System.err.print("\n");
        }
Matt Tucker's avatar
Matt Tucker committed
346
    }
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
    private static void emptyFile(File logFile) {
    	BufferedWriter out = null;
        try {
            out = new BufferedWriter(new FileWriter(logFile));
            out.write("");
        } catch (IOException ex) {
        	Log.warn("Could not empty file " + logFile.getName(), ex);
        } finally {
        	if (out != null) {
        		try {
					out.close();
				} catch (IOException ex) {
					Log.warn("Could not close file.", ex);
				}
        	}
        }
	}
365
}