jdk/src/java.logging/share/classes/java/util/logging/XMLFormatter.java
author dfuchs
Thu, 06 Apr 2017 14:38:15 +0100
changeset 44538 a603c475d649
parent 35782 cce69c0777dc
permissions -rw-r--r--
8178139: Minor typo in API documentation of java.util.logging.Logger Reviewed-by: lancea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
     2
 * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package java.util.logging;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.nio.charset.Charset;
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    30
import java.time.Instant;
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    31
import java.time.format.DateTimeFormatter;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * Format a LogRecord into a standard XML format.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * The DTD specification is provided as Appendix A to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * Java Logging APIs specification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * The XMLFormatter can be used with arbitrary character encodings,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * but it is recommended that it normally be used with UTF-8.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * character encoding can be set on the output Handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *
35782
cce69c0777dc 8149601: Update references from "1.9" to "9"
iris
parents: 29117
diff changeset
    44
 * @implSpec Since JDK 9, instances of {@linkplain LogRecord} contain
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    45
 * an {@link LogRecord#getInstant() Instant} which can have nanoseconds below
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    46
 * the millisecond resolution.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    47
 * The DTD specification has been updated to allow for an optional
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    48
 * {@code <nanos>} element. By default, the XMLFormatter will compute the
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    49
 * nanosecond adjustment below the millisecond resolution (using
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    50
 * {@code LogRecord.getInstant().getNano() % 1000_000}) - and if this is not 0,
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    51
 * this adjustment value will be printed in the new {@code <nanos>} element.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    52
 * The event instant can then be reconstructed using
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    53
 * {@code Instant.ofEpochSecond(millis/1000L, (millis % 1000L) * 1000_000L + nanos)}
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    54
 * where {@code millis} and {@code nanos} represent the numbers serialized in
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    55
 * the {@code <millis>} and {@code <nanos>} elements, respectively.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    56
 * <br>
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    57
 * The {@code <date>} element will now contain the whole instant as formatted
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    58
 * by the {@link DateTimeFormatter#ISO_INSTANT DateTimeFormatter.ISO_INSTANT}
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    59
 * formatter.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    60
 * <p>
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    61
 * For compatibility with old parsers, XMLFormatters can
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    62
 * be configured to revert to the old format by specifying a
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    63
 * {@code <xml-formatter-fully-qualified-class-name>.useInstant = false}
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    64
 * {@linkplain LogManager#getProperty(java.lang.String) property} in the
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    65
 * logging configuration. When {@code useInstant} is {@code false}, the old
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    66
 * formatting will be preserved. When {@code useInstant} is {@code true}
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    67
 * (the default), the {@code <nanos>} element will be printed and the
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    68
 * {@code <date>} element will contain the {@linkplain
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    69
 * DateTimeFormatter#ISO_INSTANT formatted} instant.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    70
 * <p>
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    71
 * For instance, in order to configure plain instances of XMLFormatter to omit
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    72
 * the new {@code <nano>} element,
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    73
 * {@code java.util.logging.XMLFormatter.useInstant = false} can be specified
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    74
 * in the logging configuration.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    75
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
public class XMLFormatter extends Formatter {
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    80
    private final LogManager manager = LogManager.getLogManager();
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    81
    private final boolean useInstant;
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    82
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    83
    /**
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    84
     * Creates a new instance of XMLFormatter.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    85
     *
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    86
     * @implSpec
35782
cce69c0777dc 8149601: Update references from "1.9" to "9"
iris
parents: 29117
diff changeset
    87
     *    Since JDK 9, the XMLFormatter will print out the record {@linkplain
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    88
     *    LogRecord#getInstant() event time} as an Instant. This instant
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    89
     *    has the best resolution available on the system. The {@code <date>}
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    90
     *    element will contain the instant as formatted by the {@link
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    91
     *    DateTimeFormatter#ISO_INSTANT}.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    92
     *    In addition, an optional {@code <nanos>} element containing a
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    93
     *    nanosecond adjustment will be printed if the instant contains some
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    94
     *    nanoseconds below the millisecond resolution.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    95
     *    <p>
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    96
     *    This new behavior can be turned off, and the old formatting restored,
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    97
     *    by specifying a property in the {@linkplain
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    98
     *    LogManager#getProperty(java.lang.String) logging configuration}.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
    99
     *    If {@code LogManager.getLogManager().getProperty(
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   100
     *    this.getClass().getName()+".useInstant")} is {@code "false"} or
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   101
     *    {@code "0"}, the old formatting will be restored.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   102
     */
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   103
    public XMLFormatter() {
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   104
        useInstant = (manager == null)
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   105
            || manager.getBooleanProperty(
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   106
                    this.getClass().getName()+".useInstant", true);
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   107
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // Append a two digit number.
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   110
    private void a2(StringBuilder sb, int x) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        if (x < 10) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            sb.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        sb.append(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // Append the time and date in ISO 8601 format
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   118
    private void appendISO8601(StringBuilder sb, long millis) {
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   119
        GregorianCalendar cal = new GregorianCalendar();
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   120
        cal.setTimeInMillis(millis);
21823
2100a5feec29 8028185: XMLFormatter.format emits incorrect year
dfuchs
parents: 19224
diff changeset
   121
        sb.append(cal.get(Calendar.YEAR));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        sb.append('-');
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   123
        a2(sb, cal.get(Calendar.MONTH) + 1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        sb.append('-');
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   125
        a2(sb, cal.get(Calendar.DAY_OF_MONTH));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        sb.append('T');
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   127
        a2(sb, cal.get(Calendar.HOUR_OF_DAY));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        sb.append(':');
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   129
        a2(sb, cal.get(Calendar.MINUTE));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        sb.append(':');
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   131
        a2(sb, cal.get(Calendar.SECOND));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   134
    // Append to the given StringBuilder an escaped version of the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    // given text string where XML special characters have been escaped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    // For a null string we append "<null>"
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   137
    private void escape(StringBuilder sb, String text) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        if (text == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            text = "<null>";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        for (int i = 0; i < text.length(); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            char ch = text.charAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            if (ch == '<') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                sb.append("&lt;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            } else if (ch == '>') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                sb.append("&gt;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            } else if (ch == '&') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                sb.append("&amp;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                sb.append(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * Format the given message to XML.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * This method can be overridden in a subclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * It is recommended to use the {@link Formatter#formatMessage}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * convenience method to localize and format the message field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * @param record the log record to be formatted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * @return a formatted log record
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     */
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   165
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    public String format(LogRecord record) {
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   167
        StringBuilder sb = new StringBuilder(500);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        sb.append("<record>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   170
        final Instant instant = record.getInstant();
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   171
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        sb.append("  <date>");
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   173
        if (useInstant) {
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   174
            // If useInstant is true - we will print the instant in the
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   175
            // date field, using the ISO_INSTANT formatter.
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   176
            DateTimeFormatter.ISO_INSTANT.formatTo(instant, sb);
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   177
        } else {
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   178
            // If useInstant is false - we will keep the 'old' formating
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   179
            appendISO8601(sb, instant.toEpochMilli());
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   180
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        sb.append("</date>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        sb.append("  <millis>");
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   184
        sb.append(instant.toEpochMilli());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        sb.append("</millis>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   187
        final int nanoAdjustment = instant.getNano() % 1000_000;
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   188
        if (useInstant && nanoAdjustment != 0) {
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   189
            sb.append("  <nanos>");
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   190
            sb.append(nanoAdjustment);
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   191
            sb.append("</nanos>\n");
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   192
        }
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   193
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        sb.append("  <sequence>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        sb.append(record.getSequenceNumber());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        sb.append("</sequence>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        String name = record.getLoggerName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        if (name != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            sb.append("  <logger>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            escape(sb, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            sb.append("</logger>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        sb.append("  <level>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        escape(sb, record.getLevel().toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        sb.append("</level>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (record.getSourceClassName() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            sb.append("  <class>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            escape(sb, record.getSourceClassName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            sb.append("</class>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        if (record.getSourceMethodName() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            sb.append("  <method>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            escape(sb, record.getSourceMethodName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            sb.append("</method>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        sb.append("  <thread>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        sb.append(record.getThreadID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        sb.append("</thread>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        if (record.getMessage() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            // Format the message string and its accompanying parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            String message = formatMessage(record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            sb.append("  <message>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            escape(sb, message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            sb.append("</message>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            sb.append("\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        // If the message is being localized, output the key, resource
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        // bundle name, and params.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        ResourceBundle bundle = record.getResourceBundle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            if (bundle != null && bundle.getString(record.getMessage()) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                sb.append("  <key>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                escape(sb, record.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                sb.append("</key>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                sb.append("  <catalog>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                escape(sb, record.getResourceBundleName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                sb.append("</catalog>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        } catch (Exception ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            // The message is not in the catalog.  Drop through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        Object parameters[] = record.getParameters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        //  Check to see if the parameter was not a messagetext format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        //  or was not null or empty
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21823
diff changeset
   253
        if (parameters != null && parameters.length != 0
24685
215fa91e1b4c 8044461: Cleanup new Boolean and single character strings
rriggs
parents: 23010
diff changeset
   254
                && record.getMessage().indexOf('{') == -1 ) {
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21823
diff changeset
   255
            for (Object parameter : parameters) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                sb.append("  <param>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                try {
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21823
diff changeset
   258
                    escape(sb, parameter.toString());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                } catch (Exception ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                    sb.append("???");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                sb.append("</param>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        if (record.getThrown() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            // Report on the state of the throwable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            Throwable th = record.getThrown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            sb.append("  <exception>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            sb.append("    <message>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            escape(sb, th.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            sb.append("</message>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            StackTraceElement trace[] = th.getStackTrace();
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21823
diff changeset
   274
            for (StackTraceElement frame : trace) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                sb.append("    <frame>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                sb.append("      <class>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                escape(sb, frame.getClassName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                sb.append("</class>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                sb.append("      <method>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                escape(sb, frame.getMethodName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                sb.append("</method>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                // Check for a line number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                if (frame.getLineNumber() >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                    sb.append("      <line>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                    sb.append(frame.getLineNumber());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                    sb.append("</line>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                sb.append("    </frame>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            sb.append("  </exception>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        sb.append("</record>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * Return the header string for a set of XML formatted records.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * @param   h  The target handler (can be null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * @return  a valid XML string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     */
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   303
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    public String getHead(Handler h) {
19224
a4283c67519d 8022454: Fixed various serializations and deprecation warnings in java.util, java.net and sun.tools
lagergren
parents: 5506
diff changeset
   305
        StringBuilder sb = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        String encoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        sb.append("<?xml version=\"1.0\"");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        if (h != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            encoding = h.getEncoding();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            encoding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        if (encoding == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            // Figure out the default encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            encoding = java.nio.charset.Charset.defaultCharset().name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        // Try to map the encoding name to a canonical name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            Charset cs = Charset.forName(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            encoding = cs.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        } catch (Exception ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            // We hit problems finding a canonical name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            // Just use the raw encoding name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        sb.append(" encoding=\"");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        sb.append(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        sb.append("\"");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        sb.append(" standalone=\"no\"?>\n");
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   332
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        sb.append("<!DOCTYPE log SYSTEM \"logger.dtd\">\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        sb.append("<log>\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * Return the tail string for a set of XML formatted records.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * @param   h  The target handler (can be null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * @return  a valid XML string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     */
29117
7956b5dc0eac 8072645: java.util.logging should use java.time to get more precise time stamps
dfuchs
parents: 25859
diff changeset
   344
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    public String getTail(Handler h) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return "</log>\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
}