14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.logger;
27
28 import java.io.PrintStream;
29 import java.io.PrintWriter;
30 import java.io.StringWriter;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.time.ZonedDateTime;
34 import java.util.Optional;
35 import java.util.ResourceBundle;
36 import java.util.function.Function;
37 import java.lang.System.Logger;
38 import java.util.function.Predicate;
39 import java.util.function.Supplier;
40 import sun.util.logging.PlatformLogger;
41 import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
42
43 /**
44 * A simple console logger to emulate the behavior of JUL loggers when
45 * in the default configuration. SimpleConsoleLoggers are also used when
46 * JUL is not present and no DefaultLoggerFinder is installed.
47 */
48 public class SimpleConsoleLogger extends LoggerConfiguration
49 implements Logger, PlatformLogger.Bridge, PlatformLogger.ConfigurableBridge {
50
51 static final PlatformLogger.Level DEFAULT_LEVEL = PlatformLogger.Level.INFO;
52
53 final String name;
54 volatile PlatformLogger.Level level;
55 final boolean usePlatformLevel;
56 SimpleConsoleLogger(String name, boolean usePlatformLevel) {
57 this.name = name;
58 this.usePlatformLevel = usePlatformLevel;
59 }
151 public void setPlatformLevel(PlatformLogger.Level newLevel) {
152 level = newLevel;
153 }
154
155 @Override
156 public LoggerConfiguration getLoggerConfiguration() {
157 return this;
158 }
159
160 /**
161 * Default platform logging support - output messages to System.err -
162 * equivalent to ConsoleHandler with SimpleFormatter.
163 */
164 static PrintStream outputStream() {
165 return System.err;
166 }
167
168 // Returns the caller's class and method's name; best effort
169 // if cannot infer, return the logger's name.
170 private String getCallerInfo() {
171 Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
172 if (frame.isPresent()) {
173 return frame.get().getClassName() + " " + frame.get().getMethodName();
174 } else {
175 return name;
176 }
177 }
178
179 /*
180 * CallerFinder is a stateful predicate.
181 */
182 static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
183 static final StackWalker WALKER = StackWalker.getInstance();
184
185 /**
186 * Returns StackFrame of the caller's frame.
187 * @return StackFrame of the caller's frame.
188 */
189 Optional<StackWalker.StackFrame> get() {
190 return WALKER.walk((s) -> s.filter(this).findFirst());
191 }
192
193 private boolean lookingForLogger = true;
194 /**
195 * Returns true if we have found the caller's frame, false if the frame
196 * must be skipped.
197 *
198 * @param t The frame info.
199 * @return true if we have found the caller's frame, false if the frame
200 * must be skipped.
201 */
202 @Override
203 public boolean test(StackWalker.StackFrame t) {
204 final String cname = t.getClassName();
205 // We should skip all frames until we have found the logger,
206 // because these frames could be frames introduced by e.g. custom
207 // sub classes of Handler.
208 if (lookingForLogger) {
209 // Skip all frames until we have found the first logger frame.
210 lookingForLogger = !isLoggerImplFrame(cname);
211 return false;
212 }
213 // We've found the relevant frame.
214 return !skipLoggingFrame(cname) && !isLoggerImplFrame(cname);
215 }
216
217 private boolean isLoggerImplFrame(String cname) {
218 return (cname.equals("sun.util.logging.PlatformLogger") ||
219 cname.equals("jdk.internal.logger.SimpleConsoleLogger"));
220 }
221 }
222
223 private String getCallerInfo(String sourceClassName, String sourceMethodName) {
224 if (sourceClassName == null) return name;
225 if (sourceMethodName == null) return sourceClassName;
226 return sourceClassName + " " + sourceMethodName;
227 }
228
229 private String toString(Throwable thrown) {
230 String throwable = "";
231 if (thrown != null) {
232 StringWriter sw = new StringWriter();
233 PrintWriter pw = new PrintWriter(sw);
234 pw.println();
235 thrown.printStackTrace(pw);
236 pw.close();
237 throwable = sw.toString();
238 }
239 return throwable;
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.logger;
27
28 import java.io.PrintStream;
29 import java.io.PrintWriter;
30 import java.io.StringWriter;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.time.ZonedDateTime;
34 import java.util.ResourceBundle;
35 import java.util.function.Function;
36 import java.lang.System.Logger;
37 import java.lang.System.Logger.Level;
38 import java.util.function.Supplier;
39 import jdk.internal.misc.JavaLangAccess;
40 import jdk.internal.misc.SharedSecrets;
41 import sun.util.logging.PlatformLogger;
42 import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
43
44 /**
45 * A simple console logger to emulate the behavior of JUL loggers when
46 * in the default configuration. SimpleConsoleLoggers are also used when
47 * JUL is not present and no DefaultLoggerFinder is installed.
48 */
49 public class SimpleConsoleLogger extends LoggerConfiguration
50 implements Logger, PlatformLogger.Bridge, PlatformLogger.ConfigurableBridge {
51
52 static final PlatformLogger.Level DEFAULT_LEVEL = PlatformLogger.Level.INFO;
53
54 final String name;
55 volatile PlatformLogger.Level level;
56 final boolean usePlatformLevel;
57 SimpleConsoleLogger(String name, boolean usePlatformLevel) {
58 this.name = name;
59 this.usePlatformLevel = usePlatformLevel;
60 }
152 public void setPlatformLevel(PlatformLogger.Level newLevel) {
153 level = newLevel;
154 }
155
156 @Override
157 public LoggerConfiguration getLoggerConfiguration() {
158 return this;
159 }
160
161 /**
162 * Default platform logging support - output messages to System.err -
163 * equivalent to ConsoleHandler with SimpleFormatter.
164 */
165 static PrintStream outputStream() {
166 return System.err;
167 }
168
169 // Returns the caller's class and method's name; best effort
170 // if cannot infer, return the logger's name.
171 private String getCallerInfo() {
172 String sourceClassName = null;
173 String sourceMethodName = null;
174
175 JavaLangAccess access = SharedSecrets.getJavaLangAccess();
176 Throwable throwable = new Throwable();
177 int depth = access.getStackTraceDepth(throwable);
178
179 String logClassName = "sun.util.logging.PlatformLogger";
180 String simpleLoggerClassName = "jdk.internal.logger.SimpleConsoleLogger";
181 boolean lookingForLogger = true;
182 for (int ix = 0; ix < depth; ix++) {
183 // Calling getStackTraceElement directly prevents the VM
184 // from paying the cost of building the entire stack frame.
185 final StackTraceElement frame =
186 access.getStackTraceElement(throwable, ix);
187 final String cname = frame.getClassName();
188 if (lookingForLogger) {
189 // Skip all frames until we have found the first logger frame.
190 if (cname.equals(logClassName) || cname.equals(simpleLoggerClassName)) {
191 lookingForLogger = false;
192 }
193 } else {
194 if (skipLoggingFrame(cname)) continue;
195 if (!cname.equals(logClassName) && !cname.equals(simpleLoggerClassName)) {
196 // We've found the relevant frame.
197 sourceClassName = cname;
198 sourceMethodName = frame.getMethodName();
199 break;
200 }
201 }
202 }
203
204 if (sourceClassName != null) {
205 return sourceClassName + " " + sourceMethodName;
206 } else {
207 return name;
208 }
209 }
210
211 private String getCallerInfo(String sourceClassName, String sourceMethodName) {
212 if (sourceClassName == null) return name;
213 if (sourceMethodName == null) return sourceClassName;
214 return sourceClassName + " " + sourceMethodName;
215 }
216
217 private String toString(Throwable thrown) {
218 String throwable = "";
219 if (thrown != null) {
220 StringWriter sw = new StringWriter();
221 PrintWriter pw = new PrintWriter(sw);
222 pw.println();
223 thrown.printStackTrace(pw);
224 pw.close();
225 throwable = sw.toString();
226 }
227 return throwable;
|