Home | History | Annotate | Download | only in stack
      1 /*
      2  * Conditions Of Use
      3  *
      4  * This software was developed by employees of the National Institute of
      5  * Standards and Technology (NIST), an agency of the Federal Government.
      6  * Pursuant to title 15 Untied States Code Section 105, works of NIST
      7  * employees are not subject to copyright protection in the United States
      8  * and are considered to be in the public domain.  As a result, a formal
      9  * license is not needed to use the software.
     10  *
     11  * This software is provided by NIST as a service and is expressly
     12  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
     13  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
     14  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
     15  * AND DATA ACCURACY.  NIST does not warrant or make any representations
     16  * regarding the use of the software or the results thereof, including but
     17  * not limited to the correctness, accuracy, reliability or usefulness of
     18  * the software.
     19  *
     20  * Permission to use this software is contingent upon your acceptance
     21  * of the terms of this agreement
     22  *
     23  * .
     24  *
     25  */
     26 /*******************************************************************************
     27  * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).       *
     28  ******************************************************************************/
     29 
     30 package gov.nist.javax.sip.stack;
     31 
     32 import gov.nist.core.ServerLogger;
     33 import gov.nist.core.StackLogger;
     34 import gov.nist.javax.sip.LogRecord;
     35 import gov.nist.javax.sip.header.CallID;
     36 import gov.nist.javax.sip.message.SIPMessage;
     37 
     38 import java.io.File;
     39 import java.io.FileWriter;
     40 import java.io.IOException;
     41 import java.io.PrintWriter;
     42 import java.util.Properties;
     43 
     44 import javax.sip.SipStack;
     45 import javax.sip.header.TimeStampHeader;
     46 
     47 // BEGIN android-deleted
     48 // import org.apache.log4j.Level;
     49 // import org.apache.log4j.Logger;
     50 // END android-deleted
     51 
     52 /**
     53  * Log file wrapper class. Log messages into the message trace file and also write the log into
     54  * the debug file if needed. This class keeps an XML formatted trace around for later access via
     55  * RMI. The trace can be viewed with a trace viewer (see tools.traceviewerapp).
     56  *
     57  * @version 1.2 $Revision: 1.39 $ $Date: 2009/11/11 14:00:58 $
     58  *
     59  * @author M. Ranganathan <br/>
     60  *
     61  *
     62  */
     63 public class ServerLog implements ServerLogger {
     64 
     65     private boolean logContent;
     66 
     67     protected StackLogger stackLogger;
     68 
     69     /**
     70      * Name of the log file in which the trace is written out (default is null)
     71      */
     72     private String logFileName;
     73 
     74     /**
     75      * Print writer that is used to write out the log file.
     76      */
     77     private PrintWriter printWriter;
     78 
     79     /**
     80      * Set auxililary information to log with this trace.
     81      */
     82     private String auxInfo;
     83 
     84     private String description;
     85 
     86     private String stackIpAddress;
     87 
     88     private SIPTransactionStack sipStack;
     89 
     90     private Properties configurationProperties;
     91 
     92     public ServerLog() {
     93         // Debug log file. Whatever gets logged by us also makes its way into debug log.
     94     }
     95 
     96     private void setProperties(Properties configurationProperties) {
     97         this.configurationProperties = configurationProperties;
     98         // Set a descriptive name for the message trace logger.
     99         this.description = configurationProperties.getProperty("javax.sip.STACK_NAME");
    100         this.stackIpAddress = configurationProperties.getProperty("javax.sip.IP_ADDRESS");
    101         this.logFileName = configurationProperties.getProperty("gov.nist.javax.sip.SERVER_LOG");
    102         String logLevel = configurationProperties.getProperty("gov.nist.javax.sip.TRACE_LEVEL");
    103         String logContent = configurationProperties
    104                 .getProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT");
    105 
    106         this.logContent = (logContent != null && logContent.equals("true"));
    107 
    108         if (logLevel != null) {
    109             if (logLevel.equals("LOG4J")) {
    110                 // if TRACE_LEVEL property is specified as
    111                 // "LOG4J" then, set the traceLevel based on
    112                 // the log4j effective log level.
    113 
    114                 // check whether a Log4j logger name has been
    115                 // specified. if not, use the stack name as the default
    116                 // logger name.
    117 
    118                 // BEGIN android-deleted
    119                 /*
    120                 Logger logger = Logger.getLogger(configurationProperties.getProperty(
    121                         "gov.nist.javax.sip.LOG4J_LOGGER_NAME", this.description));
    122                 Level level = logger.getEffectiveLevel();
    123                 if (level == Level.OFF) {
    124                     this.setTraceLevel(0);
    125                 } else if (level.isGreaterOrEqual(Level.DEBUG)) {
    126                     this.setTraceLevel(TRACE_DEBUG);
    127                 } else if (level.isGreaterOrEqual(Level.INFO)) {
    128                     this.setTraceLevel(TRACE_MESSAGES);
    129                 } else if (level.isGreaterOrEqual(Level.WARN)) {
    130                     this.setTraceLevel(TRACE_EXCEPTION);
    131                 }
    132                 */
    133                 // END android-deleted
    134             } else {
    135                 try {
    136                     int ll;
    137                     if (logLevel.equals("DEBUG")) {
    138                         ll = TRACE_DEBUG;
    139                     } else if (logLevel.equals("INFO")) {
    140                         ll = TRACE_MESSAGES;
    141                     } else if (logLevel.equals("ERROR")) {
    142                         ll = TRACE_EXCEPTION;
    143                     } else if (logLevel.equals("NONE") || logLevel.equals("OFF")) {
    144                         ll = TRACE_NONE;
    145                     } else {
    146                         ll = Integer.parseInt(logLevel);
    147                     }
    148 
    149                     this.setTraceLevel(ll);
    150                 } catch (NumberFormatException ex) {
    151                     System.out.println("ServerLog: WARNING Bad integer " + logLevel);
    152                     System.out.println("logging dislabled ");
    153                     this.setTraceLevel(0);
    154                 }
    155             }
    156         }
    157         checkLogFile();
    158 
    159     }
    160 
    161     public void setStackIpAddress(String ipAddress) {
    162         this.stackIpAddress = ipAddress;
    163     }
    164 
    165     // public static boolean isWebTesterCatchException=false;
    166     // public static String webTesterLogFile=null;
    167 
    168     /**
    169      * default trace level
    170      */
    171     protected int traceLevel = TRACE_MESSAGES;
    172 
    173     public synchronized void closeLogFile() {
    174         if (printWriter != null) {
    175             printWriter.close();
    176             printWriter = null;
    177         }
    178     }
    179 
    180     public void checkLogFile() {
    181         if (logFileName == null || traceLevel < TRACE_MESSAGES) {
    182             // Dont create a log file if tracing is
    183             // disabled.
    184             return;
    185         }
    186         try {
    187             File logFile = new File(logFileName);
    188             if (!logFile.exists()) {
    189                 logFile.createNewFile();
    190                 printWriter = null;
    191             }
    192             // Append buffer to the end of the file unless otherwise specified
    193             // by the user.
    194             if (printWriter == null) {
    195                 boolean overwrite = Boolean.valueOf(
    196                     configurationProperties.getProperty(
    197                         "gov.nist.javax.sip.SERVER_LOG_OVERWRITE"));
    198 
    199                 FileWriter fw = new FileWriter(logFileName, !overwrite);
    200 
    201                 printWriter = new PrintWriter(fw, true);
    202                 printWriter.println("<!-- "
    203                         + "Use the  Trace Viewer in src/tools/tracesviewer to"
    204                         + " view this  trace  \n"
    205                         + "Here are the stack configuration properties \n"
    206                         + "javax.sip.IP_ADDRESS= "
    207                         + configurationProperties.getProperty("javax.sip.IP_ADDRESS") + "\n"
    208                         + "javax.sip.STACK_NAME= "
    209                         + configurationProperties.getProperty("javax.sip.STACK_NAME") + "\n"
    210                         + "javax.sip.ROUTER_PATH= "
    211                         + configurationProperties.getProperty("javax.sip.ROUTER_PATH") + "\n"
    212                         + "javax.sip.OUTBOUND_PROXY= "
    213                         + configurationProperties.getProperty("javax.sip.OUTBOUND_PROXY") + "\n"
    214                         + "-->");
    215                 printWriter.println("<description\n logDescription=\"" + description
    216                         + "\"\n name=\""
    217                         + configurationProperties.getProperty("javax.sip.STACK_NAME")
    218                         + "\"\n auxInfo=\"" + auxInfo + "\"/>\n ");
    219                 if (auxInfo != null) {
    220 
    221                     if (sipStack.isLoggingEnabled()) {
    222                         stackLogger
    223                                 .logDebug("Here are the stack configuration properties \n"
    224                                         + "javax.sip.IP_ADDRESS= "
    225                                         + configurationProperties
    226                                                 .getProperty("javax.sip.IP_ADDRESS")
    227                                         + "\n"
    228                                         + "javax.sip.ROUTER_PATH= "
    229                                         + configurationProperties
    230                                                 .getProperty("javax.sip.ROUTER_PATH")
    231                                         + "\n"
    232                                         + "javax.sip.OUTBOUND_PROXY= "
    233                                         + configurationProperties
    234                                                 .getProperty("javax.sip.OUTBOUND_PROXY")
    235                                         + "\n"
    236                                         + "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS= "
    237                                         + configurationProperties
    238                                                 .getProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS")
    239                                         + "\n"
    240                                         + "gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS= "
    241                                         + configurationProperties
    242                                                 .getProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS")
    243                                         + "\n"
    244                                         + "gov.nist.javax.sip.REENTRANT_LISTENER= "
    245                                         + configurationProperties
    246                                                 .getProperty("gov.nist.javax.sip.REENTRANT_LISTENER")
    247                                         + "gov.nist.javax.sip.THREAD_POOL_SIZE= "
    248                                         + configurationProperties
    249                                                 .getProperty("gov.nist.javax.sip.THREAD_POOL_SIZE")
    250                                         + "\n");
    251                         stackLogger.logDebug(" ]]> ");
    252                         stackLogger.logDebug("</debug>");
    253                         stackLogger.logDebug("<description\n logDescription=\"" + description
    254                                 + "\"\n name=\"" + stackIpAddress + "\"\n auxInfo=\"" + auxInfo
    255                                 + "\"/>\n ");
    256                         stackLogger.logDebug("<debug>");
    257                         stackLogger.logDebug("<![CDATA[ ");
    258                     }
    259                 } else {
    260 
    261                     if (sipStack.isLoggingEnabled()) {
    262                         stackLogger.logDebug("Here are the stack configuration properties \n"
    263                                 + configurationProperties + "\n");
    264                         stackLogger.logDebug(" ]]>");
    265                         stackLogger.logDebug("</debug>");
    266                         stackLogger.logDebug("<description\n logDescription=\"" + description
    267                                 + "\"\n name=\"" + stackIpAddress + "\" />\n");
    268                         stackLogger.logDebug("<debug>");
    269                         stackLogger.logDebug("<![CDATA[ ");
    270                     }
    271                 }
    272             }
    273         } catch (IOException ex) {
    274 
    275         }
    276     }
    277 
    278     /**
    279      * Global check for whether to log or not. To minimize the time return false here.
    280      *
    281      * @return true -- if logging is globally enabled and false otherwise.
    282      *
    283      */
    284     public boolean needsLogging() {
    285         return logFileName != null;
    286     }
    287 
    288     /**
    289      * Set the log file name
    290      *
    291      * @param name is the name of the log file to set.
    292      */
    293     public void setLogFileName(String name) {
    294         logFileName = name;
    295     }
    296 
    297     /**
    298      * return the name of the log file.
    299      */
    300     public String getLogFileName() {
    301         return logFileName;
    302     }
    303 
    304     /**
    305      * Log a message into the log file.
    306      *
    307      * @param message message to log into the log file.
    308      */
    309     private void logMessage(String message) {
    310         // String tname = Thread.currentThread().getName();
    311         checkLogFile();
    312         String logInfo = message;
    313         if (printWriter != null) {
    314             printWriter.println(logInfo);
    315         }
    316         if (sipStack.isLoggingEnabled()) {
    317             stackLogger.logInfo(logInfo);
    318 
    319         }
    320     }
    321 
    322     private void logMessage(String message, String from, String to, boolean sender,
    323             String callId, String firstLine, String status, String tid, long time,
    324             long timestampVal) {
    325 
    326         LogRecord log = this.sipStack.logRecordFactory.createLogRecord(message, from, to, time,
    327                 sender, firstLine, tid, callId, timestampVal);
    328         if (log != null)
    329             logMessage(log.toString());
    330     }
    331 
    332     /**
    333      * Log a message into the log directory.
    334      *
    335      * @param message a SIPMessage to log
    336      * @param from from header of the message to log into the log directory
    337      * @param to to header of the message to log into the log directory
    338      * @param sender is the server the sender
    339      * @param time is the time to associate with the message.
    340      */
    341     public void logMessage(SIPMessage message, String from, String to, boolean sender, long time) {
    342         checkLogFile();
    343         if (message.getFirstLine() == null)
    344             return;
    345         CallID cid = (CallID) message.getCallId();
    346         String callId = null;
    347         if (cid != null)
    348             callId = cid.getCallId();
    349         String firstLine = message.getFirstLine().trim();
    350         String inputText = (logContent ? message.encode() : message.encodeMessage());
    351         String tid = message.getTransactionId();
    352         TimeStampHeader tsHdr = (TimeStampHeader) message.getHeader(TimeStampHeader.NAME);
    353         long tsval = tsHdr == null ? 0 : tsHdr.getTime();
    354         logMessage(inputText, from, to, sender, callId, firstLine, null, tid, time, tsval);
    355     }
    356 
    357     /**
    358      * Log a message into the log directory.
    359      *
    360      * @param message a SIPMessage to log
    361      * @param from from header of the message to log into the log directory
    362      * @param to to header of the message to log into the log directory
    363      * @param status the status to log.
    364      * @param sender is the server the sender or receiver (true if sender).
    365      * @param time is the reception time.
    366      */
    367     public void logMessage(SIPMessage message, String from, String to, String status,
    368             boolean sender, long time) {
    369         checkLogFile();
    370         CallID cid = (CallID) message.getCallId();
    371         String callId = null;
    372         if (cid != null)
    373             callId = cid.getCallId();
    374         String firstLine = message.getFirstLine().trim();
    375         String encoded = (logContent ? message.encode() : message.encodeMessage());
    376         String tid = message.getTransactionId();
    377         TimeStampHeader tshdr = (TimeStampHeader) message.getHeader(TimeStampHeader.NAME);
    378         long tsval = tshdr == null ? 0 : tshdr.getTime();
    379         logMessage(encoded, from, to, sender, callId, firstLine, status, tid, time, tsval);
    380     }
    381 
    382     /**
    383      * Log a message into the log directory. Time stamp associated with the message is the current
    384      * time.
    385      *
    386      * @param message a SIPMessage to log
    387      * @param from from header of the message to log into the log directory
    388      * @param to to header of the message to log into the log directory
    389      * @param status the status to log.
    390      * @param sender is the server the sender or receiver (true if sender).
    391      */
    392     public void logMessage(SIPMessage message, String from, String to, String status,
    393             boolean sender) {
    394         logMessage(message, from, to, status, sender, System.currentTimeMillis());
    395     }
    396 
    397     /**
    398      * Log an exception stack trace.
    399      *
    400      * @param ex Exception to log into the log file
    401      */
    402 
    403     public void logException(Exception ex) {
    404         if (traceLevel >= TRACE_EXCEPTION) {
    405             checkLogFile();
    406             ex.printStackTrace();
    407             if (printWriter != null)
    408                 ex.printStackTrace(printWriter);
    409 
    410         }
    411     }
    412 
    413     /**
    414      * Set the trace level for the stack.
    415      *
    416      * @param level -- the trace level to set. The following trace levels are supported:
    417      *        <ul>
    418      *        <li> 0 -- no tracing </li>
    419      *
    420      * <li> 16 -- trace messages only </li>
    421      *
    422      * <li> 32 Full tracing including debug messages. </li>
    423      *
    424      * </ul>
    425      */
    426     public void setTraceLevel(int level) {
    427         traceLevel = level;
    428     }
    429 
    430     /**
    431      * Get the trace level for the stack.
    432      *
    433      * @return the trace level
    434      */
    435     public int getTraceLevel() {
    436         return traceLevel;
    437     }
    438 
    439     /**
    440      * Set aux information. Auxiliary information may be associated with the log file. This is
    441      * useful for remote logs.
    442      *
    443      * @param auxInfo -- auxiliary information.
    444      */
    445     public void setAuxInfo(String auxInfo) {
    446         this.auxInfo = auxInfo;
    447     }
    448 
    449 	public void setSipStack(SipStack sipStack) {
    450 		if(sipStack instanceof SIPTransactionStack) {
    451 			this.sipStack = (SIPTransactionStack)sipStack;
    452 	        this.stackLogger = this.sipStack.getStackLogger();
    453 		}
    454 		else
    455 			throw new IllegalArgumentException("sipStack must be a SIPTransactionStack");
    456 	}
    457 
    458 	public void setStackProperties(Properties stackProperties) {
    459 		setProperties(stackProperties);
    460 	}
    461 
    462 	public void setLevel(int jsipLoggingLevel) {
    463 
    464 	}
    465 
    466 }
    467