package mykeynote.server;
import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
import java.io.BufferedWriter;
import mykeynote.exceptions.report.ReportFileCreationException;
import mykeynote.misc.FormatConstants;
import mykeynote.misc.TimeAndDate;
import mykeynote.server.configuration.Configuration;
public class Report {
private BufferedWriter writeDebug, writeVerbouse, writeServer, writeError;
private File fileDebugLog, fileVerbouseLog, fileServerLog, fileErrorLog;
private int buffSize = 8192; // 8kB
private Object debugMon = new Object(), verbouseMon = new Object(),
serverMon = new Object(), errorMon = new Object();
//the name of the file
private static final String debug = "debug", verbouse = "verbouse",
server = "server", error = "error";
private Configuration config;
/**
* Generates the needed report files
* @param logDir The directory where the logs reside
* @param logFormat A file name consists normally of the name and the file
* extension, for example <b>example.txt</b> has the name <b>example</b>
* and the extension <b>txt</b>, which denotes a text file. The log format
* specifies such an extension, which is going to be used for the log files.<br>
* Default is <b>.log</b>. Please note that the starting dot is not needed, as
* the method adds it if necessary.
* @throws ReportFileCreationException This exception is thrown, when a report file
* does not exist, yet we were unable to create such one.
*/
public Report(File logDir, String logFormat, Configuration config) throws ReportFileCreationException {
this.config = config;
if(!logFormat.startsWith("."))
logFormat = "." + logFormat;
fileDebugLog = new File(logDir, debug + logFormat);
fileVerbouseLog = new File(logDir, verbouse + logFormat);
fileServerLog = new File(logDir, server + logFormat);
fileErrorLog = new File(logDir, error + logFormat);
try{
if(!fileErrorLog.exists()){
if(!fileErrorLog.createNewFile()){
if(config.isDemonizied()){
System.err.println("Unable to create the error log file.");
}
throw new ReportFileCreationException("Unable to create the " +
fileErrorLog.getAbsolutePath() + ".");
}
}
writeError = new BufferedWriter(new FileWriter(fileErrorLog, true));
if(config.getDebugLog()){
if(!fileDebugLog.exists()){
if(!fileDebugLog.createNewFile()){
reportErrorLog("localhost", "Unable to create the debug log file");
throw new ReportFileCreationException("Unable to create the " +
fileDebugLog.getAbsolutePath() + ".");
}
}
writeDebug = new BufferedWriter(new FileWriter(fileDebugLog, true), buffSize);
}
if(config.getVerbouseLog()){
if(!fileVerbouseLog.exists()){
if(!fileVerbouseLog.createNewFile()){
reportErrorLog("localhost", "Unable to create the verbouse log file");
throw new ReportFileCreationException("Unable to create the " +
fileVerbouseLog.getAbsolutePath() + ".");
}
}
writeVerbouse = new BufferedWriter(new FileWriter(fileVerbouseLog, true));
}
if(!fileServerLog.exists()){
if(!fileServerLog.createNewFile()){
reportErrorLog("localhost", "Unable to create the server log file");
throw new ReportFileCreationException("Unable to create the " +
fileServerLog.getAbsolutePath() + ".");
}
}
writeServer = new BufferedWriter(new FileWriter(fileServerLog, true));
} catch(IOException e){
System.err.printf("IOException hit while creating temp file:\n%s\nExiting", e.toString());
}
}
/**
* Reports if anything at debug level has happened to the debug log file
*
* @param message The message, that should be reported
*/
private void reportDebugLog(String message) {
synchronized(debugMon){
if(writeDebug == null){
//well, we are finished, nothing to report
return;
}
try{
//writeDebug.write(TimeAndDate.getTime());
writeDebug.write(message);
//if (config.getReportToConsole()) synchronized (System.out) {
// System.out.print(message);
//}
}catch (IOException e){
reportErrorLog("localhost", "IO Exception while reporting to the Debug log.");
}
}
}
/**
* This is the new standard way for logging in the debug log.
* @param unique Unique is the unique identifier of the client,<br> if there is no unique,
* please use <b>localhost</b> for a localhost connection or <b>ip:port</b> for any other entity
* @param error This is the <b>error message</b> that should be reported,<br>
* there is <b>no need</b> for a trailing newline, as it will be put automatically by the program
*/
public void reportDebugLog(String unique, String error){
String message = TimeAndDate.getTime() + ", " + unique + ", \"" + error + "\"" + FormatConstants.NEWLINE;
synchronized(debugMon){
if(writeDebug == null){
//well, we are finished, nothing to report
return;
}
try{
writeDebug.write(message);
}catch (IOException e){
reportErrorLog("localhost", "IO Exception while reporting to the Debug log.");
}
}
if (config.getReportToConsole()) synchronized (System.out) {
System.out.print(message);
}
}
/**
* Reports if anything at more level has happened to the more log file
*
* @param message The message, that should be reported
* @deprecated depreciated, please use reportVerbouseLog(String unique, String error)
* as it will report it according to the log format!
*/
@Deprecated
public void reportVerbouseLog(String message) {
synchronized(verbouseMon){
if(writeDebug == null){
//well, we are finished, nothing to report
return;
}
try{
writeVerbouse.write(message);
writeVerbouse.write(FormatConstants.NEWLINE);
if (config.getReportToConsole()) synchronized (System.out) {
System.out.println(message);
}
} catch (IOException e){
reportErrorLog("localhost", "IO Exception while reporting to the Verbouse log.");
}
}
}
/**
* This is the new standard way for logging in the debug log.
* @param unique Unique is the unique identifier of the client,<br> if there is no unique,
* please use <b>localhost</b> for a localhost connection or <b>ip:port</b> for any other entity
* @param message This is the <b>message</b> that was sent and should be reported<br>
* there is <b>no need</b> for a trailing newline, as it will be put automatically by the program
*/
public void reportVerbouseLog(String unique, String message){
message = TimeAndDate.getTime() + ", " + unique + ", \"" + message + "\"" + FormatConstants.NEWLINE;
synchronized(verbouseMon){
if(writeVerbouse == null){
//well, we are finished, nothing to report
return;
}
try{
writeVerbouse.write(message);
}catch (IOException e){
reportErrorLog("localhost", "IO Exception while reporting to the Verbouse log.");
}
}
if (config.getReportToConsole()) synchronized (System.out) {
System.out.print(message);
}
}
/**
* Reports if anything at server level has happen to the server log file
*
* @param message
* The message, that should be reported
*/
public void reportServerLog(String message){
message = TimeAndDate.getDate() + "@" + TimeAndDate.getTime() + " " + message + FormatConstants.NEWLINE;
synchronized(serverMon){
if(writeServer == null){
//well, we are finished, nothing to report
return;
}
try{
writeServer.write(message);
if (config.getReportToConsole()) synchronized (System.out) {
System.out.print(message);
}
} catch(IOException e) {
reportErrorLog("localhost", "IO Exception while reporting to the Server log.");
}
}
if(writeDebug != null){
reportDebugLog("server, " + message);
}
}
/**
* Reports if an error has been encountered to the error log file
*
* @param message The error message, that should be reported
* @deprecated Depreciated, please use reportDebugLog(String unique, String error)
* as it will report it according to the log format!
*/
@Deprecated
public void reportErrorLog(String message){
synchronized(errorMon){
if(writeDebug == null){
//well, we are finished, nothing to report
return;
}
try{
writeError.write(message);
writeError.write(FormatConstants.NEWLINE);
if (config.getReportToConsole()) synchronized (System.err) {
System.err.println(message);
}
} catch (IOException e){
System.err.println("There was an IO Exception while trying to report an Error\n" +
"Original error is: " + message + "\nSecond error is: " + e.getCause());
}
}
}
/**
* This is the new standard way for logging in the error log.
* @param unique Unique is the unique identifier of the client,<br> if there is no unique,
* please use <b>localhost</b> for a localhost connection or <b>ip:port</b> for any other entity
* @param error This is the <b>error message</b> that should be reported,<br>
* there is <b>no need</b> for a trailing newline, as it will be put automatically by the program
*/
public void reportErrorLog(String unique, String error){
String message = TimeAndDate.getTime() + ", " + unique + ", \"" + error + "\"" + FormatConstants.NEWLINE;
synchronized(debugMon){
if(writeDebug == null){
//well, we are finished, nothing to report
return;
}
try{
writeDebug.write(message);
}catch (IOException e){
System.err.println("IO Exception while reporting to the Error log.");
}
}
if (config.getReportToConsole()) synchronized (System.out) {
System.out.print(message);
}
if(writeDebug != null){
reportDebugLog(message);
}
}
public File getFileDebugLogFile() {
return fileDebugLog;
}
public File getFileVerbouseLogFile() {
return fileVerbouseLog;
}
public File getFileServerLogFile() {
return fileServerLog;
}
public File getFileErrorLogFile() {
return fileErrorLog;
}
public void finish() throws IOException{
synchronized(serverMon){
writeServer.flush();
writeServer.close();
writeServer = null;}
if(config.getVerbouseLog()){
synchronized(verbouseMon){
writeVerbouse.flush();
writeVerbouse.close();
writeVerbouse = null;}
}
if(config.getDebugLog()){
synchronized(debugMon){
writeDebug.flush();
writeDebug.close();
writeDebug = null;}
}
synchronized(errorMon){
writeError.flush();
writeError.close();
writeError = null;}
}
}