Source code: com/lutris/logging/StandardLogChannel.java
1 /*
2 * Enhydra Java Application Server Project
3 *
4 * The contents of this file are subject to the Enhydra Public License
5 * Version 1.1 (the "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy of the License on
7 * the Enhydra web site ( http://www.enhydra.org/ ).
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11 * the License for the specific terms governing rights and limitations
12 * under the License.
13 *
14 * The Initial Developer of the Enhydra Application Server is Lutris
15 * Technologies, Inc. The Enhydra Application Server and portions created
16 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17 * All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * $Id: StandardLogChannel.java,v 1.11.2.1.2.1 2000/10/19 17:58:53 jasona Exp $
22 */
23
24 package com.lutris.logging;
25
26 import java.text.*;
27 import java.util.Date;
28 import java.io.*;
29
30 /**
31 * Standard implementation of a channel associated with a logging
32 * facility. All messages for the facility are written using a channel.
33 * Care is take to avoid synchronization when possible for performance
34 * reasons.
35 *
36 * @author Mark Diekhans
37 * @see com.lutris.logging.LogChannel
38 * @see com.lutris.logging.StandardLogger
39 */
40 public class StandardLogChannel implements LogChannel {
41 /**
42 * Our symbolic name.
43 */
44 private String facility;
45
46 /**
47 * Format for the date.
48 */
49 private static final SimpleDateFormat dateFormatter =
50 new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
51
52 /**
53 * Logger object with which we are associated.
54 */
55 private StandardLogger logger;
56
57
58 /**
59 * Construct a new log channel.
60 *
61 * @param chanFacility The facility that the channel is associate with.
62 * @param loggerObj The logging object that this channel will be associated
63 * with.
64 */
65 protected StandardLogChannel(String chanFacility,
66 StandardLogger loggerObj) {
67 facility = chanFacility;
68 logger = loggerObj;
69
70 }
71
72 /**
73 * @see LogChannel.getLevel
74 */
75 public int getLevel(String level) {
76 return logger.getLevel(level);
77 }
78
79 /**
80 * @see LogChannel.getLogWriter#String
81 */
82 public LogWriter getLogWriter(String level) {
83 return new LogWriter(this, level);
84 }
85
86 /**
87 * @see LogChannel.getLogWriter#int
88 */
89 public LogWriter getLogWriter(int level) {
90 return new LogWriter(this, level);
91 }
92
93 /**
94 * @see LogChannel.isEnabled
95 */
96 public boolean isEnabled(int level) {
97 // Copy to avoid needing to be synchronized.
98 boolean[] enabledLevelFlags = logger.enabledLevelFlags;
99 return (enabledLevelFlags != null)
100 && (level >= 0 && level < enabledLevelFlags.length)
101 && enabledLevelFlags[level];
102 }
103
104 /**
105 * @see LogChannel.isEnabled
106 */
107 public boolean isEnabled(String level) {
108 return isEnabled(logger.getLevel(level));
109 }
110
111 /**
112 * Do the work of writting a log message. It should already be
113 * determined if the channel is enabled; but limited synchronization
114 * is required, as we ignore any error while writing. Handles
115 * multiline messages.
116 *
117 *
118 * @param out Print output stream to write to.
119 * @param date The date to format into the message
120 * @param level Level string for message.
121 */
122 private void doWrite(PrintWriter out, Date date, int level, String msg) {
123 try {
124 // Create prefix for each line.
125 StringBuffer msgBuf = new StringBuffer();
126 dateFormatter.format(date, msgBuf,
127 new FieldPosition(DateFormat.YEAR_FIELD));
128 msgBuf.append(": ");
129 msgBuf.append(facility);
130 msgBuf.append(',');
131
132 msgBuf.append(logger.levelNames[level]);
133
134 // Write as individual lines with the same prefix.
135 int nextIdx = 0;
136 int newlineIdx;
137
138 synchronized (out) {
139 while (nextIdx < msg.length()) {
140 out.print(msgBuf);
141 if (nextIdx == 0) {
142 out.print(": ");
143 } else {
144 out.print("+ ");
145 }
146 newlineIdx = msg.indexOf('\n', nextIdx);
147 if (newlineIdx < 0) {
148 newlineIdx = msg.length();
149 }
150 out.write(msg, nextIdx, (newlineIdx - nextIdx));
151 out.println();
152 nextIdx = newlineIdx + 1;
153 }
154 out.flush();
155 }
156 } catch (Throwable ignore) {
157 // FIXME: Delete eventually or maybe make a fatal exception??
158 System.err.println("StandardLogChannel.doWrite ignored exception:");
159 ignore.printStackTrace();
160 // All errors, including runtime ones, are ignored.
161 }
162 }
163
164
165 /**
166 * @see LogChannel.write
167 */
168 public void write(int level, String msg) {
169 if (isEnabled(level)) {
170 Date date = new Date();
171 if (logger.logFileLevelFlags[level]) {
172 doWrite(logger.logFileStream, date, level, msg);
173 }
174 if (logger.stderrLevelFlags[level]) {
175 doWrite(logger.stderrStream, date, level, msg);
176 }
177 }
178 }
179
180 /**
181 * @see LogChannel.write
182 */
183 public synchronized void write(String level, String msg) {
184 write(getLevel(level), msg);
185 }
186
187 /**
188 * @see LogChannel.write
189 */
190 public synchronized void write(int level, String msg, Throwable throwable) {
191 if (isEnabled(level)) {
192 Date date = new Date();
193 StringWriter stackBuf = new StringWriter();
194 throwable.printStackTrace(new PrintWriter(stackBuf));
195 stackBuf.flush();
196
197 String errMsg = msg + ":" + " " + throwable.getMessage() + '\n'
198 + stackBuf;
199
200 if (logger.logFileLevelFlags[level]) {
201 doWrite(logger.logFileStream, date, level, errMsg);
202 }
203 if (logger.stderrLevelFlags[level]) {
204 doWrite(logger.stderrStream, date, level, errMsg);
205 }
206 }
207 }
208
209 /**
210 * @see LogChannel.write
211 */
212 public synchronized void write(String level, String msg, Throwable throwable) {
213 write(getLevel(level), msg, throwable);
214 }
215 }