📄 tracesystem.java
字号:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.message;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.util.FileUtils;
import org.h2.util.SmallLRUCache;
/**
* The trace mechanism is the logging facility of this database. There is
* usually one trace system per database. It is called 'trace' because the term
* 'log' is already used in the database domain and means 'transaction log'. It
* is possible to write after close was called, but that means for each write
* the log file will be opened and closed again (which is slower).
*/
public class TraceSystem {
public static final int OFF = 0, ERROR = 1, INFO = 2, DEBUG = 3;
// TODO log total and free memory from time to time
// max file size is currently 64 MB,
// and then there could be a .old file of the same size
private static final int DEFAULT_MAX_FILE_SIZE = 64 * 1024 * 1024;
public static final int DEFAULT_TRACE_LEVEL_SYSTEM_OUT = OFF;
public static final int DEFAULT_TRACE_LEVEL_FILE = ERROR;
private static final int CHECK_FILE_TIME = 4000;
private int levelSystemOut = DEFAULT_TRACE_LEVEL_SYSTEM_OUT;
private int levelFile = DEFAULT_TRACE_LEVEL_FILE;
private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
private String fileName;
private long lastCheck;
private SmallLRUCache traces;
private SimpleDateFormat dateFormat;
private Writer fileWriter;
private PrintWriter printWriter;
private static final int CHECK_SIZE_EACH_WRITES = 128;
private int checkSize;
private boolean closed;
private boolean manualEnabling = true;
private boolean writingErrorLogged;
public static void traceThrowable(Throwable e) {
PrintWriter writer = DriverManager.getLogWriter();
if (writer != null) {
e.printStackTrace(writer);
}
}
public void setManualEnabling(boolean value) {
this.manualEnabling = value;
}
public TraceSystem(String fileName, boolean init) {
this.fileName = fileName;
traces = new SmallLRUCache(100);
dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss ");
if (fileName != null && init) {
try {
openWriter();
} catch (Exception e) {
logWritingError(e);
}
}
}
public Trace getTrace(String module) {
Trace t = (Trace) traces.get(module);
if (t == null) {
t = new Trace(this, module);
traces.put(module, t);
}
return t;
}
public boolean isEnabled(int level) {
int max = Math.max(levelSystemOut, levelFile);
return level <= max;
}
public void setFileName(String name) {
this.fileName = name;
}
public void setMaxFileSize(int max) {
this.maxFileSize = max;
}
public int getMaxFileSize() {
return maxFileSize;
}
public void setLevelSystemOut(int l) {
levelSystemOut = l;
}
public int getLevelFile() {
return levelFile;
}
public int getLevelSystemOut() {
return levelSystemOut;
}
public void setLevelFile(int l) {
levelFile = l;
}
private String format(String module, String s) {
synchronized (dateFormat) {
return dateFormat.format(new Date()) + module + ": " + s;
}
}
void write(int l, String module, String s, Throwable t) {
if (l <= levelSystemOut) {
System.out.println(format(module, s));
if (t != null && levelSystemOut == DEBUG) {
t.printStackTrace();
}
}
if (fileName != null) {
if (l > levelFile) {
enableIfRequired();
}
if (l <= levelFile) {
writeFile(format(module, s), t);
}
}
}
private void enableIfRequired() {
if (!manualEnabling) {
return;
}
long time = System.currentTimeMillis();
if (time > lastCheck + CHECK_FILE_TIME) {
String checkFile = fileName + Constants.SUFFIX_TRACE_START_FILE;
lastCheck = time;
if (FileUtils.exists(checkFile)) {
levelFile = DEBUG;
try {
FileUtils.delete(checkFile);
} catch (Exception e) {
// the file may be read only
}
}
}
}
private synchronized void writeFile(String s, Throwable t) {
try {
if (checkSize++ >= CHECK_SIZE_EACH_WRITES) {
checkSize = 0;
closeWriter();
if (maxFileSize > 0 && FileUtils.length(fileName) > maxFileSize) {
String old = fileName + ".old";
if (FileUtils.exists(old)) {
FileUtils.delete(old);
}
FileUtils.rename(fileName, old);
}
}
if (!openWriter()) {
return;
}
printWriter.println(s);
if (t != null) {
t.printStackTrace(printWriter);
}
printWriter.flush();
if (closed) {
closeWriter();
}
} catch (Exception e) {
logWritingError(e);
}
}
private void logWritingError(Exception e) {
if (writingErrorLogged) {
return;
}
writingErrorLogged = true;
// TODO translate trace messages
SQLException se = Message.getSQLException(ErrorCode.TRACE_FILE_ERROR_2, new String[] { fileName, e.toString() },
e);
// print this error only once
fileName = null;
System.out.println(se);
se.printStackTrace();
}
private boolean openWriter() {
if (printWriter == null) {
try {
FileUtils.createDirs(fileName);
if (FileUtils.exists(fileName) && FileUtils.isReadOnly(fileName)) {
// read only database: don't log error if the trace file
// can't be opened
return false;
}
fileWriter = FileUtils.openFileWriter(fileName, true);
printWriter = new PrintWriter(fileWriter, true);
} catch (Exception e) {
logWritingError(e);
return false;
}
}
return true;
}
private synchronized void closeWriter() {
if (printWriter != null) {
printWriter.flush();
printWriter.close();
printWriter = null;
}
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
// ignore
}
fileWriter = null;
}
try {
if (fileName != null && FileUtils.length(fileName) == 0) {
FileUtils.delete(fileName);
}
} catch (SQLException e) {
// ignore
}
}
public void close() {
closeWriter();
closed = true;
}
protected void finalize() {
if (!SysProperties.runFinalize) {
return;
}
close();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -