📄 logwriter.java
字号:
}
}
/**
* Write the log record on the log stream.
*/
public synchronized void write(LogRecord lr) {
if (isActive(lr.channel)) {
if (timestamp) {
writer.print(formatter.format(new Date(lr.date)));
}
if (logChannel && lr.channel!=null) {
writer.print(m_channelStart);
writer.print(lr.channel);
writer.print(m_channelEnd);
}
writer.print(m_channelSeperator);
if (lr.message != null) {
writer.println(lr.message);
}
if (lr.t != null) {
lr.t.printStackTrace(writer);
}
writer.flush();
}
}
/**
* Flush the log record queue.
*/
public void flush() {
// Double locking to prevent the NullPointerException starting
// to happen quite a lot as the priorities grow.
while (!logQueue.isEmpty()) {
LogRecord next = (LogRecord) logQueue.get();
if (next != null) write(next);
}
}
}
/**
* Constructs this class with the output stream to encapsulate.
* The log identifier is used to discriminate between configuration
* parameters.
*
* @param output the output stream to encapsulate.
* @param identifier the identifier for this log writer.
* @param configurations the configurations needed at initialization.
*/
public LogWriter (OutputStream output, String identifier, Configurations configurations) throws IOException {
this(new BufferedWriter(new OutputStreamWriter(output)), identifier, configurations);
}
/**
* Constructs this class with the output stream to encapsulate using
* default identifier.
*
* @param output the output stream to encapsulate.
* @param configurations the configurations needed at initialization.
*/
public LogWriter (OutputStream output, Configurations configurations) throws IOException {
this(new BufferedWriter(new OutputStreamWriter(output)), DEFAULT_IDENTIFIER, configurations);
}
/**
* Constructs this class with the output writer to encapsulate.
* The log identifier is used to discriminate between configuration
* parameters.
*
* @param output the output writer to encapsulate.
* @param identifier the identifier for this log writer.
* @param configurations the configurations needed at initialization.
*/
public LogWriter (Writer output, String identifier, Configurations configurations) throws IOException {
if (configurations == null) {
return;
} else {
this.configurations = configurations;
}
if (identifier == null) {
this.identifier = DEFAULT_IDENTIFIER;
} else {
this.identifier = identifier;
}
this.active = configurations.getBoolean(identifier, false);
this.logChannel = configurations.getBoolean(identifier+"."+KEYWORD_CHANNEL, false);
this.m_channelSeperator = configurations.getString(identifier + "." + C_KEYWORD_SEPERATOR, C_DEFAULT_SEPERATOR);
if (m_channelSeperator == null) m_channelSeperator = "";
String channelStamp = configurations.getString(identifier + "." + C_KEYWORD_CHANNELFORMAT, C_DEFAULT_CHANNELFORMAT);
int pos;
if ((pos = channelStamp.indexOf(C_TOKEN_CHANNELFORMAT)) < 0) {
// Invalid channel stamp, replace with default
channelStamp = C_DEFAULT_CHANNELFORMAT;
pos = channelStamp.indexOf(C_TOKEN_CHANNELFORMAT);
}
m_channelStart = m_channelSeperator + channelStamp.substring(0, pos);
m_channelEnd = channelStamp.substring(pos + C_TOKEN_CHANNELFORMAT.length());
if (active) {
if ((output == null)) {
String logFileName = configurations.getString(identifier + "." + KEYWORD_FILE);
if (logFileName == null) {
throw new IOException("Log is active, but log file ("
+ identifier + "." + KEYWORD_FILE
+ ") is not specified");
}
File file = new File(logFileName);
if (file.exists()) {
// make sure the file it's writable so the reason is obvious
// instead of FileNotFoundException
if (!file.canWrite()) {
throw new IOException("Not writable: " + file.getAbsolutePath());
}
} else {
try {
// make sure the directory in which this file is located
// is writable.
File parent = new File(file.getParent());
if (!parent.canWrite()) {
throw new IOException("Directory not writable: "
+ parent.getAbsolutePath() );
}
} catch (NullPointerException e) {
// This means that the file doesn't have a parent.
}
}
this.writer = new PrintWriter(new FileWriter(file.getAbsolutePath(), true));
} else {
this.writer = new PrintWriter(output);
}
this.timestamp = configurations.getBoolean(identifier + "." + KEYWORD_TIMESTAMP, false);
if (timestamp) {
String dateFormat = configurations.getString(identifier + "." + KEYWORD_DATEFORMAT, DEFAULT_DATEFORMAT);
formatter = new SimpleDateFormat(dateFormat);
/*
* This is a workaround for the bug in SimpleDateFormat that
* doesn't use TimeZone.getDefault() when constructing
* its format. They use an hard coded PST.
*/
formatter.setTimeZone(TimeZone.getDefault());
}
this.memory = configurations.getBoolean(identifier + "." + KEYWORD_MEMORY, false);
this.queue_maxage = configurations.getInteger(KEYWORD_QUEUE_MAXAGE, 5000);
this.queue_maxsize = configurations.getInteger(KEYWORD_QUEUE_MAXSIZE, 10000);
this.logDaemon = new Agent();
this.logDaemon.setDaemon(true);
this.logDaemon.start();
}
}
/**
* Constructs this class with the output writer to encapsulate using
* default identifier.
*
* @param output the output writer to encapsulate.
* @param configurations the configurations needed at initialization.
*/
public LogWriter (Writer output, Configurations configurations) throws IOException {
this(output, DEFAULT_IDENTIFIER, configurations);
}
/**
* Constructs this class using identifier to discriminate between
* configuration parameters and gets output file from configurations.
*
* @param identifier the identifier for this log writer.
* @param configurations the configurations needed at initialization.
*/
public LogWriter (String identifier, Configurations configurations) throws IOException {
this((Writer) null, identifier, configurations);
}
/**
* Constructs this class and gets output file from configurations.
*
* @param configurations the configurations needed at initialization.
*/
public LogWriter (Configurations configurations) throws IOException {
this((Writer) null, DEFAULT_IDENTIFIER, configurations);
}
/**
* Flush the log.
*
* Write any pending messages into the log media.
*/
public void flush() {
if (logDaemon != null) {
// It would be a very bad idea to make the unfortunate thread
// which triggered the queue overflow condition suffer, so
// instead I create another high priority thread which is going
// to take care about stuff.
Runnable plumber = new Runnable() {
public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
logDaemon.flush();
}
};
(new Thread(plumber)).start();
}
}
public String getMem()
{
long total=Runtime.getRuntime().totalMemory()/1024;
long free=Runtime.getRuntime().freeMemory()/1024;
return ("["+total
+"/"+free
+"/"+(total-free)+"]");
}
/**
* Tells if it is active.
*/
public boolean isActive() { return active; }
/**
* Tells if the given channel is active.
*
* @param channel the channel to test.
*/
public boolean isActive(String channel) {
return ((channel != null) && (configurations.getBoolean(identifier + "." + KEYWORD_CHANNEL + "." + channel, false)));
}
/**
* Prints the log message on the right channel.
* <p>
* A "channel" is a virtual log that may be enabled or disabled by
* setting the property "identifier".channel.???=true where ??? is the
* channel identifier that must be passed with the message.
* If a channel is not recognized or its property is set to false
* the message is not written.
*
* @param channel the channel to put the message on.
* @param name the message to log.
*/
public void log(String channel, String message) {
if (active) {
String mem = "";
if (memory) {
mem = getMem();
}
this.logQueue.put(new LogRecord(channel,mem+message, null));
if (this.logQueue.size() > queue_maxsize) {
this.logQueue.put(new LogRecord(CH_QUEUE_STATUS, "Log queue size limit exceeded", null));
flush();
}
}
}
/**
* Prints the error message and stack trace if channel enabled.
*
* @param t the error thrown.
*/
public void log(String channel, Throwable t) {
if (active) {
this.logQueue.put(new LogRecord(channel == null? CH_EXCEPTION_TRACING : channel, null, t));
if ( this.logQueue.size() > queue_maxsize ) {
this.logQueue.put(new LogRecord(CH_QUEUE_STATUS, "Log queue size limit exceeded", null));
flush();
}
}
}
/**
* @deprecated
*/
public void log(Throwable t) {
log(null, t);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -