Skip to content
Snippets Groups Projects
DefaultTAPLog.java 6.24 KiB
Newer Older
  • Learn to ignore specific revisions
  • package tap.log;
    
    /*
     * This file is part of TAPLibrary.
     * 
     * TAPLibrary is free software: you can redistribute it and/or modify
     * it under the terms of the GNU Lesser General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     * 
     * TAPLibrary is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Lesser General Public License for more details.
     * 
     * You should have received a copy of the GNU Lesser General Public License
     * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
     * 
    
     * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
    
     *                       Astronomisches Rechen Institut (ARI)
    
     */
    
    import java.io.OutputStream;
    import java.io.PrintWriter;
    
    import tap.TAPExecutionReport;
    
    import tap.db.DBConnection;
    
    import tap.parameters.TAPParameters;
    
    import uws.service.file.UWSFileManager;
    
    import uws.service.log.DefaultUWSLog;
    
    /**
     * Default implementation of the {@link TAPLog} interface which lets logging any message about a TAP service.
     * 
    
     * @author Gr&eacute;gory Mantelet (CDS;ARI)
    
     * 
     * @see DefaultUWSLog
     */
    public class DefaultTAPLog extends DefaultUWSLog implements TAPLog {
    
    
    	/**
    	 * <p>Builds a {@link TAPLog} which will use the given file
    
    	 * manager to get the log output (see {@link UWSFileManager#getLogOutput(LogLevel, String)}).</p>
    
    	 * 
    	 * <p><i><u>note 1</u>: This constructor is particularly useful if the way of managing log output may change in the given file manager.
    	 * Indeed, the output may change in function of the type of message to log ({@link LogLevel}).</i></p>
    	 * 
    	 * <p><i><u>note 2</u> If no output can be found in the file manager the standard error output ({@link System#err})
    	 * will be chosen automatically for all log messages.</i></p>
    	 * 
    	 * @param fm	A TAP file manager.
    	 * 
    
    	 * @see DefaultUWSLog#DefaultUWSLog(UWSFileManager)
    
    	public DefaultTAPLog(final UWSFileManager fm){
    
    	/**
    	 * <p>Builds a {@link TAPLog} which will print all its
    	 * messages into the given stream.</p>
    	 * 
    	 * <p><i><u>note</u>: the given output will be used whatever is the type of message to log ({@link LogLevel}).</i></p>
    	 * 
    	 * @param output	An output stream.
    	 * 
    	 * @see DefaultUWSLog#DefaultUWSLog(OutputStream)
    	 */
    	public DefaultTAPLog(final OutputStream output){
    
    	/**
    	 * <p>Builds a {@link TAPLog} which will print all its
    	 * messages into the given stream.</p>
    	 * 
    	 * <p><i><u>note</u>: the given output will be used whatever is the type of message to log ({@link LogLevel}).</i></p>
    	 * 
    	 * @param writer	A print writer.
    	 * 
    	 * @see DefaultUWSLog#DefaultUWSLog(PrintWriter)
    	 */
    	public DefaultTAPLog(final PrintWriter writer){
    
    	@Override
    	protected void printException(Throwable error, final PrintWriter out){
    		if (error != null){
    			if (error instanceof UWSException || error instanceof TAPException || error.getClass().getPackage().getName().startsWith("adql.")){
    				if (error.getCause() != null)
    					printException(error.getCause(), out);
    				else{
    
    					out.println("Caused by a " + error.getClass().getName() + " " + getExceptionOrigin(error));
    
    					if (error.getMessage() != null)
    						out.println("\t" + error.getMessage());
    				}
    			}else if (error instanceof SQLException){
    
    				out.println("Caused by a " + error.getClass().getName() + " " + getExceptionOrigin(error));
    
    				out.print("\t");
    				do{
    					out.println(error.getMessage());
    					error = ((SQLException)error).getNextException();
    					if (error != null)
    						out.print("\t=> ");
    				}while(error != null);
    			}else{
    				out.print("Caused by a ");
    				error.printStackTrace(out);
    			}
    		}
    	}
    
    
    	public void logDB(LogLevel level, final DBConnection connection, final String event, final String message, final Throwable error){
    		// If the type is missing:
    		if (level == null)
    			level = (error != null) ? LogLevel.ERROR : LogLevel.INFO;
    
    		// Log or not?
    		if (!canLog(level))
    			return;
    
    
    		log(level, "DB", event, (connection != null ? connection.getID() : null), message, null, error);
    
    
    		/* Some SQL exceptions (like BatchUpdateException) have a next exception which provides more information.
    		 * Here, the stack trace of the next exception is also logged:
    		 */
    		if (error != null && error instanceof SQLException && ((SQLException)error).getNextException() != null){
    			PrintWriter out = getOutput(level, "DB");
    			out.println("[NEXT EXCEPTION]");
    			((SQLException)error).getNextException().printStackTrace(out);
    			out.flush();
    		}
    
    	public void logTAP(LogLevel level, final Object obj, final String event, final String message, final Throwable error){
    		// If the type is missing:
    		if (level == null)
    			level = (error != null) ? LogLevel.ERROR : LogLevel.INFO;
    
    		// Log or not?
    		if (!canLog(level))
    			return;
    
    
    		// Get more information (when known event and available object):
    		String jobId = null, msgAppend = null;
    		try{
    			if (event != null && obj != null){
    				if (event.equals("SYNC_INIT"))
    
    					msgAppend = "QUERY=" + ((TAPParameters)obj).getQuery();
    				else if (obj instanceof TAPSyncJob){
    					log(level, "JOB", event, ((TAPSyncJob)obj).getID(), message, null, error);
    					return;
    				}else if (obj instanceof TAPExecutionReport){
    
    					TAPExecutionReport report = (TAPExecutionReport)obj;
    					jobId = report.jobID;
    					msgAppend = (report.synchronous ? "SYNC" : "ASYNC") + ",duration=" + report.getTotalDuration() + "ms (upload=" + report.getUploadDuration() + ",parse=" + report.getParsingDuration() + ",exec=" + report.getExecutionDuration() + ",format[" + report.parameters.getFormat() + "]=" + report.getFormattingDuration() + ")";
    
    				}else if (event.equalsIgnoreCase("WRITING_ERROR"))
    					jobId = obj.toString();
    
    			}
    		}catch(Throwable t){
    			error("Error while preparing a log message in logTAP(...)! The message will be logger but without additional information such as the job ID.", t);
    		}
    
    		log(level, "TAP", event, jobId, message, msgAppend, error);