1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /* ident	"%Z%%M%	%I%	%E% SMI" */
28 
29 package com.sun.solaris.service.logging;
30 
31 import java.io.PrintWriter;
32 import java.io.StringWriter;
33 import java.text.*;
34 import java.util.*;
35 import java.util.logging.Formatter;
36 import java.util.logging.LogRecord;
37 
38 import com.sun.solaris.service.exception.SuccinctStackTraceFormatter;
39 
40 /**
41  * Formats a LogRecord in a human-readable, <code>syslog</code>-like
42  * format, and is intended for use with non-syslog handlers, such as
43  * FileHandler.
44  *
45  * Multi-line messages are automatically indented by four spaces to make
46  * subsequent lines easier to differentiate from new records.
47  */
48 public class SysloglikeFormatter extends Formatter {
49 	/**
50 	 * The date set for each published Record.
51 	 */
52 	private Date date = new Date();
53 
54 	/**
55 	 * Format string for published dates.
56 	 */
57 	private final static String dateFormat =
58 	    "MMM d kk:mm:ss";
59 
60 	/**
61 	 * For published dates, the formatter.
62 	 */
63 	private DateFormat dateFormatter;
64 
65 	/**
66 	 * For published dates, the argument to date formatter.
67 	 */
68 	private Object args[] = { date };
69 
70 	/**
71 	 * Line separator string.
72 	 */
73 	private String lineSeparator = (String)java.security.AccessController
74 	    .doPrivileged(new sun.security.action.GetPropertyAction(
75 	    "line.separator"));
76 
77 	/**
78 	 * Flag to set whether log records should indicate the name of
79 	 * the class generating the record, if possible.  (default
80 	 * false)
81 	 */
82 	private boolean useClassName = false;
83 
84 	/**
85 	 * Flag to set whether log records should indicate the record's
86 	 * logger, if useClassName isn't set and the class name was
87 	 * available.  (default false)
88 	 */
89 	private boolean useLoggerName = false;
90 
91 	/**
92 	 * Flag to set whether log records should indicate the last
93 	 * component of the record's logger name, if useLoggerName isn't
94 	 * set.  (default true)
95 	 */
96 	private boolean useShortLoggerName = true;
97 
98 	/**
99 	 * Flag to set whether log records should indicate the method
100 	 * used to invoke the logger, if available.  (default false)
101 	 */
102 	private boolean useMethodName = false;
103 
104 	/**
105 	 * Flag to set whether each record should be split into two
106 	 * lines such that the severity and message are on a line by
107 	 * themselves.  (default false)
108 	 */
109 	private boolean useTwoLineStyle = false;
110 
111 	/**
112 	 * Format the given LogRecord.
113 	 * @param record the log record to be formatted.
114 	 * @return a formatted log record.
115 	 */
116 	public synchronized String format(LogRecord record)
117 	{
118 		StringBuffer sb = new StringBuffer();
119 
120 		date.setTime(record.getMillis());
121 		StringBuffer text = new StringBuffer();
122 		if (dateFormatter == null)
123 			dateFormatter = new SimpleDateFormat(dateFormat);
124 		sb.append(dateFormatter.format(date));
125 
126 		if (record.getSourceClassName() != null && useClassName) {
127 			sb.append(" ");
128 			sb.append(record.getSourceClassName());
129 		} else if (useLoggerName) {
130 			if (record.getLoggerName() != null) {
131 				sb.append(" ");
132 				sb.append(record.getLoggerName());
133 			}
134 		} else if (useShortLoggerName) {
135 			String loggerName = record.getLoggerName();
136 
137 			if (loggerName != null) {
138 				sb.append(" ");
139 				int lastDot = loggerName.lastIndexOf('.');
140 				if (lastDot >= 0)
141 					loggerName = loggerName.substring(
142 					    lastDot + 1);
143 				sb.append(loggerName);
144 			}
145 		}
146 
147 		if (record.getSourceMethodName() != null && useMethodName) {
148 			sb.append(" ");
149 			sb.append(record.getSourceMethodName());
150 		}
151 		if (useTwoLineStyle)
152 			sb.append(lineSeparator);
153 		else
154 			sb.append(" ");
155 
156 		String message = formatMessage(record);
157 		message = message.replaceAll("\n", lineSeparator + "    ");
158 
159 		sb.append(record.getLevel()).toString();
160 		sb.append(": ");
161 		sb.append(message);
162 		if (record.getThrown() != null) {
163 			sb.append(" ");
164 			sb.append(SuccinctStackTraceFormatter
165 			    .formatWithDescription(record.getThrown(),
166 			    "with tracing information: ").toString());
167 		}
168 		sb.append(lineSeparator);
169 
170 		return sb.toString();
171 	}
172 }
173