001: /**
002: * Copyright 2004 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */package com.sun.portal.log.common;
013:
014: import java.io.PrintWriter;
015: import java.io.StringWriter;
016: import java.text.FieldPosition;
017: import java.text.SimpleDateFormat;
018: import java.util.Date;
019: import java.util.ResourceBundle;
020: import java.util.logging.Formatter;
021: import java.util.logging.LogRecord;
022:
023: /**
024: * PortalLogFormatter conforms to the logging format defined by the
025: * Log Working Group in Java Webservices Org.
026: * The specified format is
027: * "[#|DATETIME|LOG_LEVEL|PRODUCT_ID|LOGGER NAME|OPTIONAL KEY VALUE PAIRS|MESSAGE|#]\n"
028: * Message also includes the stacktrace only if it is set on the PortalLogFormatter.
029: * By default it is not displayed. For any other formatter this feature is not available.
030: * It needs to be handled by the formatter itself.
031: */
032: public class PortalLogFormatter extends Formatter {
033:
034: private boolean printStackTrace = false;
035: private ResourceBundle resourceBundle;
036: private String resourceBundleName;
037:
038: // A Dummy Container Date Object is used to format the date
039: private Date date = new Date();
040:
041: // This is temporary. The product version should be got from elsewhere...
042: private static final String PRODUCT_VERSION = "SJS Portal Server";
043:
044: public static final String LINE_SEPARATOR = (String) java.security.AccessController
045: .doPrivileged(new sun.security.action.GetPropertyAction(
046: "line.separator"));
047:
048: public static final String RECORD_BEGIN_MARKER = "[#|";
049: public static final String RECORD_END_MARKER = "|#]";
050: public static final String FIELD_SEPARATOR = "|";
051: private static final String NV_PAIRS_SEPARATOR = "; ";
052:
053: public static final char DATE_TIME_DELIMITER = 'T';
054: public static final String DATE_FORMAT = "yyyy-MM-dd";
055: public static final String TIME_FORMAT = "HH:mm:ss.SSSZ";
056:
057: // "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
058: public static final String RFC_3339_DATE_FORMAT = DATE_FORMAT + "'"
059: + DATE_TIME_DELIMITER + "'" + TIME_FORMAT;
060:
061: private static final SimpleDateFormat dateFormatter = new SimpleDateFormat(
062: RFC_3339_DATE_FORMAT);
063:
064: void setResourceBundle(ResourceBundle resourceBundle) {
065: this .resourceBundle = resourceBundle;
066: }
067:
068: ResourceBundle getResourceBundle() {
069: return this .resourceBundle;
070: }
071:
072: void setResourceBundleName(String resourceBundleName) {
073: this .resourceBundleName = resourceBundleName;
074: }
075:
076: String getResourceBundleName() {
077: return this .resourceBundleName;
078: }
079:
080: /**
081: * Format the given LogRecord.
082: *
083: * @param record the log record to be formatted.
084: * @return a formatted log record
085: */
086: public synchronized String format(LogRecord record) {
087:
088: // Check whether the log record has resource bundle.
089: // If not, set it.
090: if (record.getResourceBundle() == null) {
091: record.setResourceBundleName(getResourceBundleName());
092: record.setResourceBundle(getResourceBundle());
093: }
094:
095: StringBuffer recordBuffer = new StringBuffer(
096: RECORD_BEGIN_MARKER);
097: // The following operations are to format the date and time in a
098: // human readable format.
099: date.setTime(record.getMillis());
100: dateFormatter.format(date, recordBuffer, new FieldPosition(0));
101: recordBuffer.append(FIELD_SEPARATOR);
102: recordBuffer.append(record.getLevel().getLocalizedName());
103: recordBuffer.append(FIELD_SEPARATOR);
104: recordBuffer.append(getProductId(record));
105: recordBuffer.append(FIELD_SEPARATOR);
106: recordBuffer.append(record.getLoggerName());
107: recordBuffer.append(FIELD_SEPARATOR);
108: recordBuffer.append(getNameValuePairs(record));
109: recordBuffer.append(FIELD_SEPARATOR);
110: recordBuffer.append(getMessage(record));
111: recordBuffer.append(RECORD_END_MARKER);
112: recordBuffer.append(LINE_SEPARATOR);
113: recordBuffer.append(LINE_SEPARATOR);
114:
115: return recordBuffer.toString();
116: }
117:
118: public synchronized void setPrintStackTrace(boolean value) {
119: this .printStackTrace = value;
120: }
121:
122: public synchronized boolean getPrintStackTrace() {
123: return this .printStackTrace;
124: }
125:
126: /**
127: * Customers can override to specify their product version
128: */
129: protected String getProductId(LogRecord record) {
130: return PRODUCT_VERSION;
131: }
132:
133: protected String getNameValuePairs(LogRecord record) {
134:
135: // Construct and return the key-value pair string
136: StringBuffer nvpairsBuffer = new StringBuffer("");
137:
138: nvpairsBuffer.append("ThreadID=" + record.getThreadID());
139: nvpairsBuffer.append(NV_PAIRS_SEPARATOR);
140: if (record.getSourceClassName() != null) {
141: nvpairsBuffer.append("ClassName="
142: + record.getSourceClassName());
143: nvpairsBuffer.append(NV_PAIRS_SEPARATOR);
144: }
145: if (record.getSourceMethodName() != null) {
146: nvpairsBuffer.append("MethodName="
147: + record.getSourceMethodName());
148: nvpairsBuffer.append(NV_PAIRS_SEPARATOR);
149: }
150: return nvpairsBuffer.toString();
151: }
152:
153: protected String getMessage(LogRecord record) {
154: String message = formatMessage(record);
155: StringBuffer messageBuffer = new StringBuffer(message);
156: Throwable throwable = record.getThrown();
157: if (throwable != null && getPrintStackTrace()) {
158: try {
159: messageBuffer.append(LINE_SEPARATOR);
160: StringWriter sw = new StringWriter();
161: PrintWriter pw = new PrintWriter(sw);
162: throwable.printStackTrace(pw);
163: pw.close();
164: messageBuffer.append(sw.toString());
165: } catch (Exception ex) {
166: }
167: }
168: return messageBuffer.toString();
169: }
170: }
|