| /* |
| * Conditions Of Use |
| * |
| * This software was developed by employees of the National Institute of |
| * Standards and Technology (NIST), an agency of the Federal Government. |
| * Pursuant to title 15 Untied States Code Section 105, works of NIST |
| * employees are not subject to copyright protection in the United States |
| * and are considered to be in the public domain. As a result, a formal |
| * license is not needed to use the software. |
| * |
| * This software is provided by NIST as a service and is expressly |
| * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED |
| * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT |
| * AND DATA ACCURACY. NIST does not warrant or make any representations |
| * regarding the use of the software or the results thereof, including but |
| * not limited to the correctness, accuracy, reliability or usefulness of |
| * the software. |
| * |
| * Permission to use this software is contingent upon your acceptance |
| * of the terms of this agreement |
| * |
| * . |
| * |
| */ |
| /******************************************************************************* |
| * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * |
| ******************************************************************************/ |
| |
| package gov.nist.javax.sip.stack; |
| |
| import gov.nist.core.ServerLogger; |
| import gov.nist.core.StackLogger; |
| import gov.nist.javax.sip.LogRecord; |
| import gov.nist.javax.sip.header.CallID; |
| import gov.nist.javax.sip.message.SIPMessage; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.Properties; |
| |
| import javax.sip.SipStack; |
| import javax.sip.header.TimeStampHeader; |
| |
| // BEGIN android-deleted |
| // import org.apache.log4j.Level; |
| // import org.apache.log4j.Logger; |
| // END android-deleted |
| |
| /** |
| * Log file wrapper class. Log messages into the message trace file and also write the log into |
| * the debug file if needed. This class keeps an XML formatted trace around for later access via |
| * RMI. The trace can be viewed with a trace viewer (see tools.traceviewerapp). |
| * |
| * @version 1.2 $Revision: 1.39 $ $Date: 2009/11/11 14:00:58 $ |
| * |
| * @author M. Ranganathan <br/> |
| * |
| * |
| */ |
| public class ServerLog implements ServerLogger { |
| |
| private boolean logContent; |
| |
| protected StackLogger stackLogger; |
| |
| /** |
| * Name of the log file in which the trace is written out (default is null) |
| */ |
| private String logFileName; |
| |
| /** |
| * Print writer that is used to write out the log file. |
| */ |
| private PrintWriter printWriter; |
| |
| /** |
| * Set auxililary information to log with this trace. |
| */ |
| private String auxInfo; |
| |
| private String description; |
| |
| private String stackIpAddress; |
| |
| private SIPTransactionStack sipStack; |
| |
| private Properties configurationProperties; |
| |
| public ServerLog() { |
| // Debug log file. Whatever gets logged by us also makes its way into debug log. |
| } |
| |
| private void setProperties(Properties configurationProperties) { |
| this.configurationProperties = configurationProperties; |
| // Set a descriptive name for the message trace logger. |
| this.description = configurationProperties.getProperty("javax.sip.STACK_NAME"); |
| this.stackIpAddress = configurationProperties.getProperty("javax.sip.IP_ADDRESS"); |
| this.logFileName = configurationProperties.getProperty("gov.nist.javax.sip.SERVER_LOG"); |
| String logLevel = configurationProperties.getProperty("gov.nist.javax.sip.TRACE_LEVEL"); |
| String logContent = configurationProperties |
| .getProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT"); |
| |
| this.logContent = (logContent != null && logContent.equals("true")); |
| |
| if (logLevel != null) { |
| if (logLevel.equals("LOG4J")) { |
| // if TRACE_LEVEL property is specified as |
| // "LOG4J" then, set the traceLevel based on |
| // the log4j effective log level. |
| |
| // check whether a Log4j logger name has been |
| // specified. if not, use the stack name as the default |
| // logger name. |
| |
| // BEGIN android-deleted |
| /* |
| Logger logger = Logger.getLogger(configurationProperties.getProperty( |
| "gov.nist.javax.sip.LOG4J_LOGGER_NAME", this.description)); |
| Level level = logger.getEffectiveLevel(); |
| if (level == Level.OFF) { |
| this.setTraceLevel(0); |
| } else if (level.isGreaterOrEqual(Level.DEBUG)) { |
| this.setTraceLevel(TRACE_DEBUG); |
| } else if (level.isGreaterOrEqual(Level.INFO)) { |
| this.setTraceLevel(TRACE_MESSAGES); |
| } else if (level.isGreaterOrEqual(Level.WARN)) { |
| this.setTraceLevel(TRACE_EXCEPTION); |
| } |
| */ |
| // END android-deleted |
| } else { |
| try { |
| int ll; |
| if (logLevel.equals("DEBUG")) { |
| ll = TRACE_DEBUG; |
| } else if (logLevel.equals("INFO")) { |
| ll = TRACE_MESSAGES; |
| } else if (logLevel.equals("ERROR")) { |
| ll = TRACE_EXCEPTION; |
| } else if (logLevel.equals("NONE") || logLevel.equals("OFF")) { |
| ll = TRACE_NONE; |
| } else { |
| ll = Integer.parseInt(logLevel); |
| } |
| |
| this.setTraceLevel(ll); |
| } catch (NumberFormatException ex) { |
| System.out.println("ServerLog: WARNING Bad integer " + logLevel); |
| System.out.println("logging dislabled "); |
| this.setTraceLevel(0); |
| } |
| } |
| } |
| checkLogFile(); |
| |
| } |
| |
| public void setStackIpAddress(String ipAddress) { |
| this.stackIpAddress = ipAddress; |
| } |
| |
| // public static boolean isWebTesterCatchException=false; |
| // public static String webTesterLogFile=null; |
| |
| /** |
| * default trace level |
| */ |
| protected int traceLevel = TRACE_MESSAGES; |
| |
| public synchronized void closeLogFile() { |
| if (printWriter != null) { |
| printWriter.close(); |
| printWriter = null; |
| } |
| } |
| |
| public void checkLogFile() { |
| if (logFileName == null || traceLevel < TRACE_MESSAGES) { |
| // Dont create a log file if tracing is |
| // disabled. |
| return; |
| } |
| try { |
| File logFile = new File(logFileName); |
| if (!logFile.exists()) { |
| logFile.createNewFile(); |
| printWriter = null; |
| } |
| // Append buffer to the end of the file unless otherwise specified |
| // by the user. |
| if (printWriter == null) { |
| boolean overwrite = Boolean.valueOf( |
| configurationProperties.getProperty( |
| "gov.nist.javax.sip.SERVER_LOG_OVERWRITE")); |
| |
| FileWriter fw = new FileWriter(logFileName, !overwrite); |
| |
| printWriter = new PrintWriter(fw, true); |
| printWriter.println("<!-- " |
| + "Use the Trace Viewer in src/tools/tracesviewer to" |
| + " view this trace \n" |
| + "Here are the stack configuration properties \n" |
| + "javax.sip.IP_ADDRESS= " |
| + configurationProperties.getProperty("javax.sip.IP_ADDRESS") + "\n" |
| + "javax.sip.STACK_NAME= " |
| + configurationProperties.getProperty("javax.sip.STACK_NAME") + "\n" |
| + "javax.sip.ROUTER_PATH= " |
| + configurationProperties.getProperty("javax.sip.ROUTER_PATH") + "\n" |
| + "javax.sip.OUTBOUND_PROXY= " |
| + configurationProperties.getProperty("javax.sip.OUTBOUND_PROXY") + "\n" |
| + "-->"); |
| printWriter.println("<description\n logDescription=\"" + description |
| + "\"\n name=\"" |
| + configurationProperties.getProperty("javax.sip.STACK_NAME") |
| + "\"\n auxInfo=\"" + auxInfo + "\"/>\n "); |
| if (auxInfo != null) { |
| |
| if (sipStack.isLoggingEnabled()) { |
| stackLogger |
| .logDebug("Here are the stack configuration properties \n" |
| + "javax.sip.IP_ADDRESS= " |
| + configurationProperties |
| .getProperty("javax.sip.IP_ADDRESS") |
| + "\n" |
| + "javax.sip.ROUTER_PATH= " |
| + configurationProperties |
| .getProperty("javax.sip.ROUTER_PATH") |
| + "\n" |
| + "javax.sip.OUTBOUND_PROXY= " |
| + configurationProperties |
| .getProperty("javax.sip.OUTBOUND_PROXY") |
| + "\n" |
| + "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS= " |
| + configurationProperties |
| .getProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS") |
| + "\n" |
| + "gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS= " |
| + configurationProperties |
| .getProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS") |
| + "\n" |
| + "gov.nist.javax.sip.REENTRANT_LISTENER= " |
| + configurationProperties |
| .getProperty("gov.nist.javax.sip.REENTRANT_LISTENER") |
| + "gov.nist.javax.sip.THREAD_POOL_SIZE= " |
| + configurationProperties |
| .getProperty("gov.nist.javax.sip.THREAD_POOL_SIZE") |
| + "\n"); |
| stackLogger.logDebug(" ]]> "); |
| stackLogger.logDebug("</debug>"); |
| stackLogger.logDebug("<description\n logDescription=\"" + description |
| + "\"\n name=\"" + stackIpAddress + "\"\n auxInfo=\"" + auxInfo |
| + "\"/>\n "); |
| stackLogger.logDebug("<debug>"); |
| stackLogger.logDebug("<![CDATA[ "); |
| } |
| } else { |
| |
| if (sipStack.isLoggingEnabled()) { |
| stackLogger.logDebug("Here are the stack configuration properties \n" |
| + configurationProperties + "\n"); |
| stackLogger.logDebug(" ]]>"); |
| stackLogger.logDebug("</debug>"); |
| stackLogger.logDebug("<description\n logDescription=\"" + description |
| + "\"\n name=\"" + stackIpAddress + "\" />\n"); |
| stackLogger.logDebug("<debug>"); |
| stackLogger.logDebug("<![CDATA[ "); |
| } |
| } |
| } |
| } catch (IOException ex) { |
| |
| } |
| } |
| |
| /** |
| * Global check for whether to log or not. To minimize the time return false here. |
| * |
| * @return true -- if logging is globally enabled and false otherwise. |
| * |
| */ |
| public boolean needsLogging() { |
| return logFileName != null; |
| } |
| |
| /** |
| * Set the log file name |
| * |
| * @param name is the name of the log file to set. |
| */ |
| public void setLogFileName(String name) { |
| logFileName = name; |
| } |
| |
| /** |
| * return the name of the log file. |
| */ |
| public String getLogFileName() { |
| return logFileName; |
| } |
| |
| /** |
| * Log a message into the log file. |
| * |
| * @param message message to log into the log file. |
| */ |
| private void logMessage(String message) { |
| // String tname = Thread.currentThread().getName(); |
| checkLogFile(); |
| String logInfo = message; |
| if (printWriter != null) { |
| printWriter.println(logInfo); |
| } |
| if (sipStack.isLoggingEnabled()) { |
| stackLogger.logInfo(logInfo); |
| |
| } |
| } |
| |
| private void logMessage(String message, String from, String to, boolean sender, |
| String callId, String firstLine, String status, String tid, long time, |
| long timestampVal) { |
| |
| LogRecord log = this.sipStack.logRecordFactory.createLogRecord(message, from, to, time, |
| sender, firstLine, tid, callId, timestampVal); |
| if (log != null) |
| logMessage(log.toString()); |
| } |
| |
| /** |
| * Log a message into the log directory. |
| * |
| * @param message a SIPMessage to log |
| * @param from from header of the message to log into the log directory |
| * @param to to header of the message to log into the log directory |
| * @param sender is the server the sender |
| * @param time is the time to associate with the message. |
| */ |
| public void logMessage(SIPMessage message, String from, String to, boolean sender, long time) { |
| checkLogFile(); |
| if (message.getFirstLine() == null) |
| return; |
| CallID cid = (CallID) message.getCallId(); |
| String callId = null; |
| if (cid != null) |
| callId = cid.getCallId(); |
| String firstLine = message.getFirstLine().trim(); |
| String inputText = (logContent ? message.encode() : message.encodeMessage()); |
| String tid = message.getTransactionId(); |
| TimeStampHeader tsHdr = (TimeStampHeader) message.getHeader(TimeStampHeader.NAME); |
| long tsval = tsHdr == null ? 0 : tsHdr.getTime(); |
| logMessage(inputText, from, to, sender, callId, firstLine, null, tid, time, tsval); |
| } |
| |
| /** |
| * Log a message into the log directory. |
| * |
| * @param message a SIPMessage to log |
| * @param from from header of the message to log into the log directory |
| * @param to to header of the message to log into the log directory |
| * @param status the status to log. |
| * @param sender is the server the sender or receiver (true if sender). |
| * @param time is the reception time. |
| */ |
| public void logMessage(SIPMessage message, String from, String to, String status, |
| boolean sender, long time) { |
| checkLogFile(); |
| CallID cid = (CallID) message.getCallId(); |
| String callId = null; |
| if (cid != null) |
| callId = cid.getCallId(); |
| String firstLine = message.getFirstLine().trim(); |
| String encoded = (logContent ? message.encode() : message.encodeMessage()); |
| String tid = message.getTransactionId(); |
| TimeStampHeader tshdr = (TimeStampHeader) message.getHeader(TimeStampHeader.NAME); |
| long tsval = tshdr == null ? 0 : tshdr.getTime(); |
| logMessage(encoded, from, to, sender, callId, firstLine, status, tid, time, tsval); |
| } |
| |
| /** |
| * Log a message into the log directory. Time stamp associated with the message is the current |
| * time. |
| * |
| * @param message a SIPMessage to log |
| * @param from from header of the message to log into the log directory |
| * @param to to header of the message to log into the log directory |
| * @param status the status to log. |
| * @param sender is the server the sender or receiver (true if sender). |
| */ |
| public void logMessage(SIPMessage message, String from, String to, String status, |
| boolean sender) { |
| logMessage(message, from, to, status, sender, System.currentTimeMillis()); |
| } |
| |
| /** |
| * Log an exception stack trace. |
| * |
| * @param ex Exception to log into the log file |
| */ |
| |
| public void logException(Exception ex) { |
| if (traceLevel >= TRACE_EXCEPTION) { |
| checkLogFile(); |
| ex.printStackTrace(); |
| if (printWriter != null) |
| ex.printStackTrace(printWriter); |
| |
| } |
| } |
| |
| /** |
| * Set the trace level for the stack. |
| * |
| * @param level -- the trace level to set. The following trace levels are supported: |
| * <ul> |
| * <li> 0 -- no tracing </li> |
| * |
| * <li> 16 -- trace messages only </li> |
| * |
| * <li> 32 Full tracing including debug messages. </li> |
| * |
| * </ul> |
| */ |
| public void setTraceLevel(int level) { |
| traceLevel = level; |
| } |
| |
| /** |
| * Get the trace level for the stack. |
| * |
| * @return the trace level |
| */ |
| public int getTraceLevel() { |
| return traceLevel; |
| } |
| |
| /** |
| * Set aux information. Auxiliary information may be associated with the log file. This is |
| * useful for remote logs. |
| * |
| * @param auxInfo -- auxiliary information. |
| */ |
| public void setAuxInfo(String auxInfo) { |
| this.auxInfo = auxInfo; |
| } |
| |
| public void setSipStack(SipStack sipStack) { |
| if(sipStack instanceof SIPTransactionStack) { |
| this.sipStack = (SIPTransactionStack)sipStack; |
| this.stackLogger = this.sipStack.getStackLogger(); |
| } |
| else |
| throw new IllegalArgumentException("sipStack must be a SIPTransactionStack"); |
| } |
| |
| public void setStackProperties(Properties stackProperties) { |
| setProperties(stackProperties); |
| } |
| |
| public void setLevel(int jsipLoggingLevel) { |
| |
| } |
| |
| } |