History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/util/logging/PlatformLogger.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/util/logging/PlatformLogger.java+571−0
@@ -0,0 +1,571 @@
1/*
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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
27package sun.util.logging;
28
29import java.lang.ref.WeakReference;
30import java.lang.reflect.InvocationTargetException;
31import java.lang.reflect.Method;
32import java.io.PrintStream;
33import java.io.PrintWriter;
34import java.io.StringWriter;
35import java.security.AccessController;
36import java.security.PrivilegedAction;
37import java.text.MessageFormat;
38import java.util.Date;
39import java.util.HashMap;
40import java.util.Map;
41import sun.misc.JavaLangAccess;
42import sun.misc.SharedSecrets;
43
44/**
45 * Platform logger provides an API for the JRE components to log
46 * messages. This enables the runtime components to eliminate the
47 * static dependency of the logging facility and also defers the
48 * java.util.logging initialization until it is enabled.
49 * In addition, the PlatformLogger API can be used if the logging
50 * module does not exist.
51 *
52 * If the logging facility is not enabled, the platform loggers
53 * will output log messages per the default logging configuration
54 * (see below). In this implementation, it does not log the
55 * the stack frame information issuing the log message.
56 *
57 * When the logging facility is enabled (at startup or runtime),
58 * the java.util.logging.Logger will be created for each platform
59 * logger and all log messages will be forwarded to the Logger
60 * to handle.
61 *
62 * Logging facility is "enabled" when one of the following
63 * conditions is met:
64 * 1) a system property "java.util.logging.config.class" or
65 * "java.util.logging.config.file" is set
66 * 2) java.util.logging.LogManager or java.util.logging.Logger
67 * is referenced that will trigger the logging initialization.
68 *
69 * Default logging configuration:
70 * global logging level = INFO
71 * handlers = java.util.logging.ConsoleHandler
72 * java.util.logging.ConsoleHandler.level = INFO
73 * java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
74 *
75 * Limitation:
76 * <JAVA_HOME>/lib/logging.properties is the system-wide logging
77 * configuration defined in the specification and read in the
78 * default case to configure any java.util.logging.Logger instances.
79 * Platform loggers will not detect if <JAVA_HOME>/lib/logging.properties
80 * is modified. In other words, unless the java.util.logging API
81 * is used at runtime or the logging system properties is set,
82 * the platform loggers will use the default setting described above.
83 * The platform loggers are designed for JDK developers use and
84 * this limitation can be workaround with setting
85 * -Djava.util.logging.config.file system property.
86 *
87 * @since 1.7
88 */
89public class PlatformLogger {
90 // Same values as java.util.logging.Level for easy mapping
91 public static final int OFF = Integer.MAX_VALUE;
92 public static final int SEVERE = 1000;
93 public static final int WARNING = 900;
94 public static final int INFO = 800;
95 public static final int CONFIG = 700;
96 public static final int FINE = 500;
97 public static final int FINER = 400;
98 public static final int FINEST = 300;
99 public static final int ALL = Integer.MIN_VALUE;
100
101 private static final int defaultLevel = INFO;
102 private static boolean loggingEnabled;
103 static {
104 loggingEnabled = AccessController.doPrivileged(
105 new PrivilegedAction<Boolean>() {
106 public Boolean run() {
107 String cname = System.getProperty("java.util.logging.config.class");
108 String fname = System.getProperty("java.util.logging.config.file");
109 return (cname != null || fname != null);
110 }
111 });
112 }
113
114 // Table of known loggers. Maps names to PlatformLoggers.
115 private static Map<String,WeakReference<PlatformLogger>> loggers =
116 new HashMap<>();
117
118 /**
119 * Returns a PlatformLogger of a given name.
120 */
121 public static synchronized PlatformLogger getLogger(String name) {
122 PlatformLogger log = null;
123 WeakReference<PlatformLogger> ref = loggers.get(name);
124 if (ref != null) {
125 log = ref.get();
126 }
127 if (log == null) {
128 log = new PlatformLogger(name);
129 loggers.put(name, new WeakReference<>(log));
130 }
131 return log;
132 }
133
134 /**
135 * Initialize java.util.logging.Logger objects for all platform loggers.
136 * This method is called from LogManager.readPrimordialConfiguration().
137 */
138 public static synchronized void redirectPlatformLoggers() {
139 if (loggingEnabled || !LoggingSupport.isAvailable()) return;
140
141 loggingEnabled = true;
142 for (Map.Entry<String, WeakReference<PlatformLogger>> entry : loggers.entrySet()) {
143 WeakReference<PlatformLogger> ref = entry.getValue();
144 PlatformLogger plog = ref.get();
145 if (plog != null) {
146 plog.newJavaLogger();
147 }
148 }
149 }
150
151 /**
152 * Creates a new JavaLogger that the platform logger uses
153 */
154 private void newJavaLogger() {
155 logger = new JavaLogger(logger.name, logger.effectiveLevel);
156 }
157
158 // logger may be replaced with a JavaLogger object
159 // when the logging facility is enabled
160 private volatile LoggerProxy logger;
161
162 private PlatformLogger(String name) {
163 if (loggingEnabled) {
164 this.logger = new JavaLogger(name);
165 } else {
166 this.logger = new LoggerProxy(name);
167 }
168 }
169
170 /**
171 * A convenience method to test if the logger is turned off.
172 * (i.e. its level is OFF).
173 */
174 public boolean isEnabled() {
175 return logger.isEnabled();
176 }
177
178 /**
179 * Gets the name for this platform logger.
180 */
181 public String getName() {
182 return logger.name;
183 }
184
185 /**
186 * Returns true if a message of the given level would actually
187 * be logged by this logger.
188 */
189 public boolean isLoggable(int level) {
190 return logger.isLoggable(level);
191 }
192
193 /**
194 * Gets the current log level. Returns 0 if the current effective level
195 * is not set (equivalent to Logger.getLevel() returns null).
196 */
197 public int getLevel() {
198 return logger.getLevel();
199 }
200
201 /**
202 * Sets the log level.
203 */
204 public void setLevel(int newLevel) {
205 logger.setLevel(newLevel);
206 }
207
208 /**
209 * Logs a SEVERE message.
210 */
211 public void severe(String msg) {
212 logger.doLog(SEVERE, msg);
213 }
214
215 public void severe(String msg, Throwable t) {
216 logger.doLog(SEVERE, msg, t);
217 }
218
219 public void severe(String msg, Object... params) {
220 logger.doLog(SEVERE, msg, params);
221 }
222
223 /**
224 * Logs a WARNING message.
225 */
226 public void warning(String msg) {
227 logger.doLog(WARNING, msg);
228 }
229
230 public void warning(String msg, Throwable t) {
231 logger.doLog(WARNING, msg, t);
232 }
233
234 public void warning(String msg, Object... params) {
235 logger.doLog(WARNING, msg, params);
236 }
237
238 /**
239 * Logs an INFO message.
240 */
241 public void info(String msg) {
242 logger.doLog(INFO, msg);
243 }
244
245 public void info(String msg, Throwable t) {
246 logger.doLog(INFO, msg, t);
247 }
248
249 public void info(String msg, Object... params) {
250 logger.doLog(INFO, msg, params);
251 }
252
253 /**
254 * Logs a CONFIG message.
255 */
256 public void config(String msg) {
257 logger.doLog(CONFIG, msg);
258 }
259
260 public void config(String msg, Throwable t) {
261 logger.doLog(CONFIG, msg, t);
262 }
263
264 public void config(String msg, Object... params) {
265 logger.doLog(CONFIG, msg, params);
266 }
267
268 /**
269 * Logs a FINE message.
270 */
271 public void fine(String msg) {
272 logger.doLog(FINE, msg);
273 }
274
275 public void fine(String msg, Throwable t) {
276 logger.doLog(FINE, msg, t);
277 }
278
279 public void fine(String msg, Object... params) {
280 logger.doLog(FINE, msg, params);
281 }
282
283 /**
284 * Logs a FINER message.
285 */
286 public void finer(String msg) {
287 logger.doLog(FINER, msg);
288 }
289
290 public void finer(String msg, Throwable t) {
291 logger.doLog(FINER, msg, t);
292 }
293
294 public void finer(String msg, Object... params) {
295 logger.doLog(FINER, msg, params);
296 }
297
298 /**
299 * Logs a FINEST message.
300 */
301 public void finest(String msg) {
302 logger.doLog(FINEST, msg);
303 }
304
305 public void finest(String msg, Throwable t) {
306 logger.doLog(FINEST, msg, t);
307 }
308
309 public void finest(String msg, Object... params) {
310 logger.doLog(FINEST, msg, params);
311 }
312
313 /**
314 * Default platform logging support - output messages to
315 * System.err - equivalent to ConsoleHandler with SimpleFormatter.
316 */
317 static class LoggerProxy {
318 private static final PrintStream defaultStream = System.err;
319
320 final String name;
321 volatile int levelValue;
322 volatile int effectiveLevel = 0; // current effective level value
323
324 LoggerProxy(String name) {
325 this(name, defaultLevel);
326 }
327
328 LoggerProxy(String name, int level) {
329 this.name = name;
330 this.levelValue = level == 0 ? defaultLevel : level;
331 }
332
333 boolean isEnabled() {
334 return levelValue != OFF;
335 }
336
337 int getLevel() {
338 return effectiveLevel;
339 }
340
341 void setLevel(int newLevel) {
342 levelValue = newLevel;
343 effectiveLevel = newLevel;
344 }
345
346 void doLog(int level, String msg) {
347 if (level < levelValue || levelValue == OFF) {
348 return;
349 }
350 defaultStream.print(format(level, msg, null));
351 }
352
353 void doLog(int level, String msg, Throwable thrown) {
354 if (level < levelValue || levelValue == OFF) {
355 return;
356 }
357 defaultStream.print(format(level, msg, thrown));
358 }
359
360 void doLog(int level, String msg, Object... params) {
361 if (level < levelValue || levelValue == OFF) {
362 return;
363 }
364 String newMsg = formatMessage(msg, params);
365 defaultStream.print(format(level, newMsg, null));
366 }
367
368 public boolean isLoggable(int level) {
369 if (level < levelValue || levelValue == OFF) {
370 return false;
371 }
372 return true;
373 }
374
375 // Copied from java.util.logging.Formatter.formatMessage
376 private String formatMessage(String format, Object... parameters) {
377 // Do the formatting.
378 try {
379 if (parameters == null || parameters.length == 0) {
380 // No parameters. Just return format string.
381 return format;
382 }
383 // Is it a java.text style format?
384 // Ideally we could match with
385 // Pattern.compile("\\{\\d").matcher(format).find())
386 // However the cost is 14% higher, so we cheaply check for
387 // 1 of the first 4 parameters
388 if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 ||
389 format.indexOf("{2") >=0|| format.indexOf("{3") >=0) {
390 return java.text.MessageFormat.format(format, parameters);
391 }
392 return format;
393 } catch (Exception ex) {
394 // Formatting failed: use format string.
395 return format;
396 }
397 }
398
399 private static final String formatString =
400 LoggingSupport.getSimpleFormat(false); // don't check logging.properties
401
402 // minimize memory allocation
403 private Date date = new Date();
404 private synchronized String format(int level, String msg, Throwable thrown) {
405 date.setTime(System.currentTimeMillis());
406 String throwable = "";
407 if (thrown != null) {
408 StringWriter sw = new StringWriter();
409 PrintWriter pw = new PrintWriter(sw);
410 pw.println();
411 thrown.printStackTrace(pw);
412 pw.close();
413 throwable = sw.toString();
414 }
415
416 return String.format(formatString,
417 date,
418 getCallerInfo(),
419 name,
420 PlatformLogger.getLevelName(level),
421 msg,
422 throwable);
423 }
424
425 // Returns the caller's class and method's name; best effort
426 // if cannot infer, return the logger's name.
427 private String getCallerInfo() {
428 String sourceClassName = null;
429 String sourceMethodName = null;
430
431 JavaLangAccess access = SharedSecrets.getJavaLangAccess();
432 Throwable throwable = new Throwable();
433 int depth = access.getStackTraceDepth(throwable);
434
435 String logClassName = "sun.util.logging.PlatformLogger";
436 boolean lookingForLogger = true;
437 for (int ix = 0; ix < depth; ix++) {
438 // Calling getStackTraceElement directly prevents the VM
439 // from paying the cost of building the entire stack frame.
440 StackTraceElement frame =
441 access.getStackTraceElement(throwable, ix);
442 String cname = frame.getClassName();
443 if (lookingForLogger) {
444 // Skip all frames until we have found the first logger frame.
445 if (cname.equals(logClassName)) {
446 lookingForLogger = false;
447 }
448 } else {
449 if (!cname.equals(logClassName)) {
450 // We've found the relevant frame.
451 sourceClassName = cname;
452 sourceMethodName = frame.getMethodName();
453 break;
454 }
455 }
456 }
457
458 if (sourceClassName != null) {
459 return sourceClassName + " " + sourceMethodName;
460 } else {
461 return name;
462 }
463 }
464 }
465
466 /**
467 * JavaLogger forwards all the calls to its corresponding
468 * java.util.logging.Logger object.
469 */
470 static class JavaLogger extends LoggerProxy {
471 private static final Map<Integer, Object> levelObjects =
472 new HashMap<>();
473
474 static {
475 if (LoggingSupport.isAvailable()) {
476 // initialize the map to Level objects
477 getLevelObjects();
478 }
479 }
480
481 private static void getLevelObjects() {
482 // get all java.util.logging.Level objects
483 int[] levelArray = new int[] {OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL};
484 for (int l : levelArray) {
485 Object level = LoggingSupport.parseLevel(getLevelName(l));
486 levelObjects.put(l, level);
487 }
488 }
489
490 private final Object javaLogger;
491 JavaLogger(String name) {
492 this(name, 0);
493 }
494
495 JavaLogger(String name, int level) {
496 super(name, level);
497 this.javaLogger = LoggingSupport.getLogger(name);
498 if (level != 0) {
499 // level has been updated and so set the Logger's level
500 LoggingSupport.setLevel(javaLogger, levelObjects.get(level));
501 }
502 }
503
504 /**
505 * Let Logger.log() do the filtering since if the level of a
506 * platform logger is altered directly from
507 * java.util.logging.Logger.setLevel(), the levelValue will
508 * not be updated.
509 */
510 void doLog(int level, String msg) {
511 LoggingSupport.log(javaLogger, levelObjects.get(level), msg);
512 }
513
514 void doLog(int level, String msg, Throwable t) {
515 LoggingSupport.log(javaLogger, levelObjects.get(level), msg, t);
516 }
517
518 void doLog(int level, String msg, Object... params) {
519 // only pass String objects to the j.u.l.Logger which may
520 // be created by untrusted code
521 int len = (params != null) ? params.length : 0;
522 Object[] sparams = new String[len];
523 for (int i = 0; i < len; i++) {
524 sparams [i] = String.valueOf(params[i]);
525 }
526 LoggingSupport.log(javaLogger, levelObjects.get(level), msg, sparams);
527 }
528
529 boolean isEnabled() {
530 Object level = LoggingSupport.getLevel(javaLogger);
531 return level == null || level.equals(levelObjects.get(OFF)) == false;
532 }
533
534 int getLevel() {
535 Object level = LoggingSupport.getLevel(javaLogger);
536 if (level != null) {
537 for (Map.Entry<Integer, Object> l : levelObjects.entrySet()) {
538 if (level == l.getValue()) {
539 return l.getKey();
540 }
541 }
542 }
543 return 0;
544 }
545
546 void setLevel(int newLevel) {
547 levelValue = newLevel;
548 LoggingSupport.setLevel(javaLogger, levelObjects.get(newLevel));
549 }
550
551 public boolean isLoggable(int level) {
552 return LoggingSupport.isLoggable(javaLogger, levelObjects.get(level));
553 }
554 }
555
556 private static String getLevelName(int level) {
557 switch (level) {
558 case OFF : return "OFF";
559 case SEVERE : return "SEVERE";
560 case WARNING : return "WARNING";
561 case INFO : return "INFO";
562 case CONFIG : return "CONFIG";
563 case FINE : return "FINE";
564 case FINER : return "FINER";
565 case FINEST : return "FINEST";
566 case ALL : return "ALL";
567 default : return "UNKNOWN";
568 }
569 }
570
571}