• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ServerLog()92     public ServerLog() {
93         // Debug log file. Whatever gets logged by us also makes its way into debug log.
94     }
95 
setProperties(Properties configurationProperties)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 
setStackIpAddress(String ipAddress)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 
closeLogFile()173     public synchronized void closeLogFile() {
174         if (printWriter != null) {
175             printWriter.close();
176             printWriter = null;
177         }
178     }
179 
checkLogFile()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      */
needsLogging()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      */
setLogFileName(String name)293     public void setLogFileName(String name) {
294         logFileName = name;
295     }
296 
297     /**
298      * return the name of the log file.
299      */
getLogFileName()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      */
logMessage(String message)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 
logMessage(String message, String from, String to, boolean sender, String callId, String firstLine, String status, String tid, long time, long timestampVal)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      */
logMessage(SIPMessage message, String from, String to, boolean sender, long time)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      */
logMessage(SIPMessage message, String from, String to, String status, boolean sender, long time)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      */
logMessage(SIPMessage message, String from, String to, String status, boolean sender)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 
logException(Exception ex)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      */
setTraceLevel(int level)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      */
getTraceLevel()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      */
setAuxInfo(String auxInfo)445     public void setAuxInfo(String auxInfo) {
446         this.auxInfo = auxInfo;
447     }
448 
setSipStack(SipStack sipStack)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 
setStackProperties(Properties stackProperties)458 	public void setStackProperties(Properties stackProperties) {
459 		setProperties(stackProperties);
460 	}
461 
setLevel(int jsipLoggingLevel)462 	public void setLevel(int jsipLoggingLevel) {
463 
464 	}
465 
466 }
467