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) { |