001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014-2016 ForgeRock AS. 015 */ 016package org.opends.server.loggers; 017 018import java.io.PrintStream; 019import java.util.logging.ErrorManager; 020import java.util.logging.Formatter; 021import java.util.logging.Handler; 022import java.util.logging.Level; 023import java.util.logging.LogManager; 024import java.util.logging.LogRecord; 025import java.util.logging.Logger; 026import java.util.logging.SimpleFormatter; 027 028/** Utility class for java.util.logging support. */ 029public class JDKLogging 030{ 031 /** Root packages that contains all OpenDJ related classes. */ 032 private static final String[] LOGGING_ROOTS = new String[] { "org.opends", "org.forgerock.opendj"}; 033 034 /** Disable java.util.logging. */ 035 public static void disableLogging() 036 { 037 LogManager.getLogManager().reset(); 038 Logger.getLogger("").setLevel(Level.OFF); 039 } 040 041 /** 042 * Enable JDK logging to stderr at provided level for OpenDJ classes. 043 * <p> 044 * Error and warning messages will be printed on stderr, other messages will be printed on stdout. 045 */ 046 public static void enableVerboseConsoleLoggingForOpenDJ() 047 { 048 enableConsoleLoggingForOpenDJ(Level.ALL, System.out, System.err); 049 } 050 051 /** 052 * Enable JDK logging for OpenDJ tool. 053 * <p> 054 * Error and warning messages will be printed on stderr, other messages will be printed on stdout. 055 * This method should only be used by external tool classes. 056 */ 057 public static void enableConsoleLoggingForOpenDJTool() 058 { 059 enableConsoleLoggingForOpenDJ(Level.FINE, System.out, System.err); 060 } 061 062 /** 063 * Enable JDK logging in provided {@link PrintStream} for OpenDJ tool. 064 * <p> 065 * All messages will be printed on the provided {@link PrintStream}. 066 * This method should only be used by external tool classes. 067 * 068 * @param stream 069 * The stream to use to print messages. 070 */ 071 public static void enableLoggingForOpenDJTool(final PrintStream stream) 072 { 073 enableConsoleLoggingForOpenDJ(Level.FINE, stream, stream); 074 } 075 076 /** 077 * Enable JDK logging at provided {@link Level} in provided {@link PrintStream} for OpenDJ classes. 078 * 079 * @param level 080 * The level to log. 081 * @param out 082 * The stream to use to print messages from {@link Level#FINEST} and {@link Level#INFO} included. 083 * @param err 084 * The stream to use to print {@link Level#SEVERE} and {@link Level#WARNING} messages. 085 */ 086 private static void enableConsoleLoggingForOpenDJ(final Level level, final PrintStream out, final PrintStream err) 087 { 088 LogManager.getLogManager().reset(); 089 Handler handler = new OpenDJHandler(out, err); 090 handler.setFormatter(getFormatter()); 091 handler.setLevel(level); 092 for (String loggingRoot : LOGGING_ROOTS) 093 { 094 Logger logger = Logger.getLogger(loggingRoot); 095 logger.setLevel(level); 096 logger.addHandler(handler); 097 } 098 } 099 100 /** Custom handler to log to either stdout or stderr depending on the log level. */ 101 private static final class OpenDJHandler extends Handler 102 { 103 private final PrintStream out; 104 private final PrintStream err; 105 106 private OpenDJHandler(final PrintStream out, final PrintStream err) 107 { 108 this.out = out; 109 this.err = err; 110 } 111 112 @Override 113 public void publish(LogRecord record) 114 { 115 if (getFormatter() == null) 116 { 117 setFormatter(new SimpleFormatter()); 118 } 119 120 try 121 { 122 String message = getFormatter().format(record); 123 if (record.getLevel().intValue() >= Level.WARNING.intValue()) 124 { 125 err.write(message.getBytes()); 126 } 127 else 128 { 129 out.write(message.getBytes()); 130 } 131 } 132 catch (Exception exception) 133 { 134 reportError(null, exception, ErrorManager.FORMAT_FAILURE); 135 return; 136 } 137 } 138 139 @Override 140 public void close() throws SecurityException 141 { 142 } 143 144 @Override 145 public void flush() 146 { 147 System.out.flush(); 148 System.err.flush(); 149 } 150 } 151 152 /** 153 * Get a formatter. 154 * 155 * @return a formatter for loggers 156 */ 157 public static Formatter getFormatter() 158 { 159 return new JDKLoggingFormater(); 160 } 161 162 /** 163 * Returns the packages to be used as root for logging. 164 * <p> 165 * This package covers all OpenDJ classes. 166 * 167 * @return the root packages to log 168 */ 169 public static String[] getOpendDJLoggingRoots() { 170 return LOGGING_ROOTS; 171 } 172 173}