001: /**
002: * Copyright (C) 2003 Manfred Andres
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: * Created on 05.10.2003
019: */package freecs.util.logger;
020:
021: import java.io.IOException;
022: import java.nio.ByteBuffer;
023: import java.nio.charset.Charset;
024: import java.util.Calendar;
025: import java.util.HashMap;
026:
027: import freecs.Server;
028: import freecs.util.ObjectBuffer;
029:
030: /**
031: * @author Manfred Andres
032: *
033: * freecs.util
034: */
035: public class LogWriter extends Thread {
036: public static LogWriter instance = new LogWriter();
037: private HashMap logDestinations = new HashMap();
038: public ObjectBuffer logQueue = new ObjectBuffer(1000);
039: private Charset cs = Charset.forName(System.getProperty(
040: "file.encoding", "iso-8859-1"));
041:
042: private boolean stopped = false;
043: Calendar cal = Calendar.getInstance();
044:
045: private LogWriter() {
046: this .setPriority(Thread.MAX_PRIORITY);
047: this .start();
048: }
049:
050: /**
051: * retrieve a logDestination to write to
052: * @param path the path to the logfile
053: * @return the LogDestination object
054: */
055: LogDestination getLogDestination(String path) {
056: LogDestination ld = (LogDestination) logDestinations.get(path);
057: if (ld == null) {
058: // TODO: check for file, socket,..) and construct the correct LogDestination
059: ld = new LogFile(path);
060: logDestinations.put(path, ld);
061: }
062: return ld;
063: }
064:
065: /**
066: * this method is used to write messages to a logdestination
067: * @param path the path for this logdestination
068: * @param message the message to be logged
069: */
070: public void addLogMessage(String path, String message) {
071: LogDestination ld = getLogDestination(path);
072: StringBuffer sb = new StringBuffer(Server
073: .formatDefaultTimeStamp(System.currentTimeMillis()));
074: sb.append(": ");
075: sb.append(message);
076: sb.append(System.getProperty("line.separator", "\r\n"));
077: LogEntry le = new LogEntry(ld, cs.encode(sb.toString()));
078: addLogElement(le);
079: }
080:
081: /**
082: *
083: * @param type
084: * @param message
085: */
086: public void addLogMessage(int type, String message) {
087: LogDestination ld = getLogDestination(Server.LOGFILE[type]);
088: LogEntry le = new LogEntry(ld, cs.encode(message));
089: addLogElement(le);
090: }
091:
092: /**
093: * Add the constructed LogEntry to the LogWriter.instance's log Queue
094: * @param le the LogEntry
095: */
096: private void addLogElement(LogEntry le) {
097: int cntr = 0;
098: boolean success = false;
099: while (!success) {
100: synchronized (this ) {
101: success = logQueue.put(le);
102: this .notifyAll();
103: }
104: cntr++;
105: if (cntr > 5) {
106: System.out.print("LQ-full: ");
107: System.out.print(le.toString());
108: }
109: }
110: }
111:
112: public void stopLogging() {
113: stopped = true;
114: }
115:
116: public void run() {
117: LogEntry le = null;
118: long lastMessage = 0;
119: while (!stopped)
120: try {
121: ObjectBuffer workingCopy;
122: synchronized (this ) {
123: while (logQueue.isEmpty())
124: try {
125: this .wait(33);
126: } catch (InterruptedException ie) {
127: }
128: workingCopy = logQueue;
129: logQueue = new ObjectBuffer(1000);
130: this .notifyAll();
131: }
132: while (!workingCopy.isEmpty()) {
133: le = (LogEntry) workingCopy.get();
134: if (writeToChannel(le))
135: workingCopy.pop();
136: }
137: } catch (Exception e) {
138: StringBuffer sb = new StringBuffer(this .toString());
139: sb.append("run:");
140: sb.append(e.getMessage());
141: sb.append("(");
142: sb.append(e.getCause());
143: sb.append(") StackTraceElements: ");
144: StackTraceElement[] st = e.getStackTrace();
145: sb.append(st.length);
146: sb.append("\r\n");
147: for (int i = 0; i < st.length; i++) {
148: sb.append("at ");
149: sb.append(st[i].getClassName());
150: sb.append(" ");
151: sb.append(st[i].getMethodName());
152: sb.append("(");
153: sb.append(st[i].getLineNumber());
154: sb.append(")\r\n");
155: }
156: System.out.println(sb.toString());
157: if (le != null)
158: System.out.println(le.toString());
159: e.printStackTrace();
160: } finally {
161: try {
162: Thread.sleep(33);
163: } catch (InterruptedException ie) {
164: }
165: }
166: }
167:
168: private boolean writeToChannel(LogEntry le) {
169: try {
170: int written = le.ld.getChannel().write(le.buf);
171: if (!le.buf.hasRemaining())
172: return true;
173: } catch (IOException ioe) {
174: Server.debug(this , "writeToFile: ", ioe, Server.MSG_ERROR,
175: Server.LVL_MAJOR);
176: return true;
177: } catch (Exception e) {
178: Server.debug(this , "writeToFile: ", e, Server.MSG_ERROR,
179: Server.LVL_MAJOR);
180: return true;
181: }
182: return false;
183: }
184:
185: private class LogEntry {
186: final LogDestination ld;
187: final ByteBuffer buf;
188:
189: LogEntry(LogDestination ld, ByteBuffer buf) {
190: this.ld = ld;
191: this.buf = buf;
192: }
193: }
194: }
|