jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java
changeset 29117 7956b5dc0eac
parent 29094 a4fd2b5e49f8
child 32834 e1dca5fe4de3
equal deleted inserted replaced
29116:9918719cfcc0 29117:7956b5dc0eac
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.util.logging;
    26 package java.util.logging;
       
    27 import java.time.Instant;
    27 import java.util.*;
    28 import java.util.*;
    28 import java.util.concurrent.atomic.AtomicInteger;
    29 import java.util.concurrent.atomic.AtomicInteger;
    29 import java.util.concurrent.atomic.AtomicLong;
    30 import java.util.concurrent.atomic.AtomicLong;
    30 import java.io.*;
    31 import java.io.*;
       
    32 import java.time.Clock;
    31 
    33 
    32 import sun.misc.JavaLangAccess;
    34 import sun.misc.JavaLangAccess;
    33 import sun.misc.SharedSecrets;
    35 import sun.misc.SharedSecrets;
    34 
    36 
    35 /**
    37 /**
    86         = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
    88         = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
    87 
    89 
    88     private static final ThreadLocal<Integer> threadIds = new ThreadLocal<>();
    90     private static final ThreadLocal<Integer> threadIds = new ThreadLocal<>();
    89 
    91 
    90     /**
    92     /**
    91      * @serial Logging message level
    93      * Logging message level
    92      */
    94      */
    93     private Level level;
    95     private Level level;
    94 
    96 
    95     /**
    97     /**
    96      * @serial Sequence number
    98      * Sequence number
    97      */
    99      */
    98     private long sequenceNumber;
   100     private long sequenceNumber;
    99 
   101 
   100     /**
   102     /**
   101      * @serial Class that issued logging call
   103      * Class that issued logging call
   102      */
   104      */
   103     private String sourceClassName;
   105     private String sourceClassName;
   104 
   106 
   105     /**
   107     /**
   106      * @serial Method that issued logging call
   108      * Method that issued logging call
   107      */
   109      */
   108     private String sourceMethodName;
   110     private String sourceMethodName;
   109 
   111 
   110     /**
   112     /**
   111      * @serial Non-localized raw message text
   113      * Non-localized raw message text
   112      */
   114      */
   113     private String message;
   115     private String message;
   114 
   116 
   115     /**
   117     /**
   116      * @serial Thread ID for thread that issued logging call.
   118      * Thread ID for thread that issued logging call.
   117      */
   119      */
   118     private int threadID;
   120     private int threadID;
   119 
   121 
   120     /**
   122     /**
   121      * @serial Event time in milliseconds since 1970
   123      * The Throwable (if any) associated with log message
   122      */
       
   123     private long millis;
       
   124 
       
   125     /**
       
   126      * @serial The Throwable (if any) associated with log message
       
   127      */
   124      */
   128     private Throwable thrown;
   125     private Throwable thrown;
   129 
   126 
   130     /**
   127     /**
   131      * @serial Name of the source Logger.
   128      * Name of the source Logger.
   132      */
   129      */
   133     private String loggerName;
   130     private String loggerName;
   134 
   131 
   135     /**
   132     /**
   136      * @serial Resource bundle name to localized log message.
   133      * Resource bundle name to localized log message.
   137      */
   134      */
   138     private String resourceBundleName;
   135     private String resourceBundleName;
       
   136 
       
   137     /**
       
   138      * Event time.
       
   139      * @since 1.9
       
   140      */
       
   141     private Instant instant;
       
   142 
       
   143     /**
       
   144      * @serialField level Level Logging message level
       
   145      * @serialField sequenceNumber long Sequence number
       
   146      * @serialField sourceClassName String Class that issued logging call
       
   147      * @serialField sourceMethodName String Method that issued logging call
       
   148      * @serialField message String Non-localized raw message text
       
   149      * @serialField threadID int Thread ID for thread that issued logging call
       
   150      * @serialField millis long Truncated event time in milliseconds since 1970
       
   151      *              - calculated as getInstant().toEpochMilli().
       
   152      *               The event time instant can be reconstructed using
       
   153      * <code>Instant.ofEpochSecond(millis/1000, (millis % 1000) * 1000_000 + nanoAdjustment)</code>
       
   154      * @serialField nanoAdjustment int Nanoseconds adjustment to the millisecond of
       
   155      *              event time - calculated as getInstant().getNano() % 1000_000
       
   156      *               The event time instant can be reconstructed using
       
   157      * <code>Instant.ofEpochSecond(millis/1000, (millis % 1000) * 1000_000 + nanoAdjustment)</code>
       
   158      *              <p>
       
   159      *              Since: 1.9
       
   160      * @serialField thrown Throwable The Throwable (if any) associated with log
       
   161      *              message
       
   162      * @serialField loggerName String Name of the source Logger
       
   163      * @serialField resourceBundleName String Resource bundle name to localized
       
   164      *              log message
       
   165      */
       
   166     private static final ObjectStreamField[] serialPersistentFields =
       
   167         new ObjectStreamField[] {
       
   168             new ObjectStreamField("level", Level.class),
       
   169             new ObjectStreamField("sequenceNumber", long.class),
       
   170             new ObjectStreamField("sourceClassName", String.class),
       
   171             new ObjectStreamField("sourceMethodName", String.class),
       
   172             new ObjectStreamField("message", String.class),
       
   173             new ObjectStreamField("threadID", int.class),
       
   174             new ObjectStreamField("millis", long.class),
       
   175             new ObjectStreamField("nanoAdjustment", int.class),
       
   176             new ObjectStreamField("thrown", Throwable.class),
       
   177             new ObjectStreamField("loggerName", String.class),
       
   178             new ObjectStreamField("resourceBundleName", String.class),
       
   179         };
   139 
   180 
   140     private transient boolean needToInferCaller;
   181     private transient boolean needToInferCaller;
   141     private transient Object parameters[];
   182     private transient Object parameters[];
   142     private transient ResourceBundle resourceBundle;
   183     private transient ResourceBundle resourceBundle;
   143 
   184 
   162      * Construct a LogRecord with the given level and message values.
   203      * Construct a LogRecord with the given level and message values.
   163      * <p>
   204      * <p>
   164      * The sequence property will be initialized with a new unique value.
   205      * The sequence property will be initialized with a new unique value.
   165      * These sequence values are allocated in increasing order within a VM.
   206      * These sequence values are allocated in increasing order within a VM.
   166      * <p>
   207      * <p>
   167      * The millis property will be initialized to the current time.
   208      * Since JDK 1.9, the event time is represented by an {@link Instant}.
       
   209      * The instant property will be initialized to the {@linkplain
       
   210      * Instant#now() current instant}, using the best available
       
   211      * {@linkplain Clock#systemUTC() clock} on the system.
   168      * <p>
   212      * <p>
   169      * The thread ID property will be initialized with a unique ID for
   213      * The thread ID property will be initialized with a unique ID for
   170      * the current thread.
   214      * the current thread.
   171      * <p>
   215      * <p>
   172      * All other properties will be initialized to "null".
   216      * All other properties will be initialized to "null".
   173      *
   217      *
   174      * @param level  a logging level value
   218      * @param level  a logging level value
   175      * @param msg  the raw non-localized logging message (may be null)
   219      * @param msg  the raw non-localized logging message (may be null)
       
   220      * @see java.time.Clock#systemUTC()
   176      */
   221      */
   177     public LogRecord(Level level, String msg) {
   222     public LogRecord(Level level, String msg) {
   178         this.level = Objects.requireNonNull(level);
   223         this.level = Objects.requireNonNull(level);
   179         message = msg;
   224         message = msg;
   180         // Assign a thread ID and a unique sequence number.
   225         // Assign a thread ID and a unique sequence number.
   181         sequenceNumber = globalSequenceNumber.getAndIncrement();
   226         sequenceNumber = globalSequenceNumber.getAndIncrement();
   182         threadID = defaultThreadID();
   227         threadID = defaultThreadID();
   183         millis = System.currentTimeMillis();
   228         instant = Instant.now();
   184         needToInferCaller = true;
   229         needToInferCaller = true;
   185    }
   230    }
   186 
   231 
   187     /**
   232     /**
   188      * Get the source Logger's name.
   233      * Get the source Logger's name.
   414     public void setThreadID(int threadID) {
   459     public void setThreadID(int threadID) {
   415         this.threadID = threadID;
   460         this.threadID = threadID;
   416     }
   461     }
   417 
   462 
   418     /**
   463     /**
   419      * Get event time in milliseconds since 1970.
   464      * Get truncated event time in milliseconds since 1970.
   420      *
   465      *
   421      * @return event time in millis since 1970
   466      * @return truncated event time in millis since 1970
   422      */
   467      *
       
   468      * @implSpec This is equivalent to calling
       
   469      *      {@link #getInstant() getInstant().toEpochMilli()}.
       
   470      *
       
   471      * @deprecated To get the full nanosecond resolution event time,
       
   472      *             use {@link #getInstant()}.
       
   473      *
       
   474      * @see #getInstant()
       
   475      */
       
   476     @Deprecated
   423     public long getMillis() {
   477     public long getMillis() {
   424         return millis;
   478         return instant.toEpochMilli();
   425     }
   479     }
   426 
   480 
   427     /**
   481     /**
   428      * Set event time.
   482      * Set event time.
   429      *
   483      *
   430      * @param millis event time in millis since 1970
   484      * @param millis event time in millis since 1970.
   431      */
   485      *
       
   486      * @implSpec This is equivalent to calling
       
   487      *      {@link #setInstant(java.time.Instant)
       
   488      *      setInstant(Instant.ofEpochMilli(millis))}.
       
   489      *
       
   490      * @deprecated To set event time with nanosecond resolution,
       
   491      *             use {@link #setInstant(java.time.Instant)}.
       
   492      *
       
   493      * @see #setInstant(java.time.Instant)
       
   494      */
       
   495     @Deprecated
   432     public void setMillis(long millis) {
   496     public void setMillis(long millis) {
   433         this.millis = millis;
   497         this.instant = Instant.ofEpochMilli(millis);
       
   498     }
       
   499 
       
   500     /**
       
   501      * Gets the instant that the event occurred.
       
   502      *
       
   503      * @return the instant that the event occurred.
       
   504      *
       
   505      * @since 1.9
       
   506      */
       
   507     public Instant getInstant() {
       
   508         return instant;
       
   509     }
       
   510 
       
   511     /**
       
   512      * Sets the instant that the event occurred.
       
   513      *
       
   514      * @param instant the instant that the event occurred.
       
   515      *
       
   516      * @throws NullPointerException if {@code instant} is null.
       
   517      * @since 1.9
       
   518      */
       
   519     public void setInstant(Instant instant) {
       
   520         this.instant = Objects.requireNonNull(instant);
   434     }
   521     }
   435 
   522 
   436     /**
   523     /**
   437      * Get any throwable associated with the log record.
   524      * Get any throwable associated with the log record.
   438      * <p>
   525      * <p>
   455     }
   542     }
   456 
   543 
   457     private static final long serialVersionUID = 5372048053134512534L;
   544     private static final long serialVersionUID = 5372048053134512534L;
   458 
   545 
   459     /**
   546     /**
   460      * @serialData Default fields, followed by a two byte version number
   547      * @serialData Serialized fields, followed by a two byte version number
   461      * (major byte, followed by minor byte), followed by information on
   548      * (major byte, followed by minor byte), followed by information on
   462      * the log record parameter array.  If there is no parameter array,
   549      * the log record parameter array.  If there is no parameter array,
   463      * then -1 is written.  If there is a parameter array (possible of zero
   550      * then -1 is written.  If there is a parameter array (possible of zero
   464      * length) then the array length is written as an integer, followed
   551      * length) then the array length is written as an integer, followed
   465      * by String values for each parameter.  If a parameter is null, then
   552      * by String values for each parameter.  If a parameter is null, then
   466      * a null String is written.  Otherwise the output of Object.toString()
   553      * a null String is written.  Otherwise the output of Object.toString()
   467      * is written.
   554      * is written.
   468      */
   555      */
   469     private void writeObject(ObjectOutputStream out) throws IOException {
   556     private void writeObject(ObjectOutputStream out) throws IOException {
   470         // We have to call defaultWriteObject first.
   557         // We have to write serialized fields first.
   471         out.defaultWriteObject();
   558         ObjectOutputStream.PutField pf = out.putFields();
       
   559         pf.put("level", level);
       
   560         pf.put("sequenceNumber", sequenceNumber);
       
   561         pf.put("sourceClassName", sourceClassName);
       
   562         pf.put("sourceMethodName", sourceMethodName);
       
   563         pf.put("message", message);
       
   564         pf.put("threadID", threadID);
       
   565         pf.put("millis", instant.toEpochMilli());
       
   566         pf.put("nanoAdjustment", instant.getNano() % 1000_000);
       
   567         pf.put("thrown", thrown);
       
   568         pf.put("loggerName", loggerName);
       
   569         pf.put("resourceBundleName", resourceBundleName);
       
   570         out.writeFields();
   472 
   571 
   473         // Write our version number.
   572         // Write our version number.
   474         out.writeByte(1);
   573         out.writeByte(1);
   475         out.writeByte(0);
   574         out.writeByte(0);
   476         if (parameters == null) {
   575         if (parameters == null) {
   484         }
   583         }
   485     }
   584     }
   486 
   585 
   487     private void readObject(ObjectInputStream in)
   586     private void readObject(ObjectInputStream in)
   488                         throws IOException, ClassNotFoundException {
   587                         throws IOException, ClassNotFoundException {
   489         // We have to call defaultReadObject first.
   588         // We have to read serialized fields first.
   490         in.defaultReadObject();
   589         ObjectInputStream.GetField gf = in.readFields();
       
   590         level = (Level) gf.get("level", null);
       
   591         sequenceNumber = gf.get("sequenceNumber", 0L);
       
   592         sourceClassName = (String) gf.get("sourceClassName", null);
       
   593         sourceMethodName = (String) gf.get("sourceMethodName", null);
       
   594         message = (String) gf.get("message", null);
       
   595         threadID = gf.get("threadID", 0);
       
   596         long millis = gf.get("millis", 0L);
       
   597         int nanoOfMilli = gf.get("nanoAdjustment", 0);
       
   598         instant = Instant.ofEpochSecond(
       
   599             millis / 1000L, (millis % 1000L) * 1000_000L + nanoOfMilli);
       
   600         thrown = (Throwable) gf.get("thrown", null);
       
   601         loggerName = (String) gf.get("loggerName", null);
       
   602         resourceBundleName = (String) gf.get("resourceBundleName", null);
   491 
   603 
   492         // Read version number.
   604         // Read version number.
   493         byte major = in.readByte();
   605         byte major = in.readByte();
   494         byte minor = in.readByte();
   606         byte minor = in.readByte();
   495         if (major != 1) {
   607         if (major != 1) {