001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.tools;
029
030 import org.opends.server.protocols.ldap.LDAPMessage;
031 import org.opends.server.protocols.ldap.LDAPConstants;
032 import org.opends.server.protocols.asn1.ASN1Element;
033 import org.opends.server.util.ServerConstants;
034
035 import java.io.PrintStream;
036 import java.text.DateFormat;
037 import java.text.SimpleDateFormat;
038 import java.util.Date;
039
040 /**
041 * A utility class for the LDAP client tools that performs verbose tracing of
042 * LDAP and ASN.1 messages.
043 */
044 public class VerboseTracer
045 {
046 /**
047 * Indicates whether verbose mode is on or off.
048 */
049 private boolean verbose;
050
051 /**
052 * The print stream where tracing will be sent.
053 */
054 private PrintStream err;
055
056 /**
057 * The time in milliseconds of the first message traced.
058 */
059 private long firstMessageTimestamp = 0;
060
061 /**
062 * The time in millseconds of the previous message traced.
063 */
064 private long lastMessageTimestamp = 0;
065
066 /**
067 * The format used for trace timestamps.
068 */
069 private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
070
071 /**
072 * Constructs a tracer with a specified verbosity and print stream.
073 * @param verbose Indicates whether verbose mode is on or off.
074 * @param err The print stream where tracing will be sent.
075 */
076 public VerboseTracer(boolean verbose, PrintStream err)
077 {
078 this.verbose = verbose;
079 this.err = err;
080 }
081
082 /**
083 * Trace an incoming or outgoing message.
084 * @param messageDirection Use "C>S" to indicate outgoing client to server.
085 * Use "S>C" to indicate incoming server to client.
086 * @param message The LDAP message to be traced.
087 * @param element The ASN.1 element of the message.
088 */
089 private synchronized void traceMessage(String messageDirection,
090 LDAPMessage message,
091 ASN1Element element)
092 {
093 StringBuilder header = new StringBuilder();
094 StringBuilder builder = new StringBuilder();
095
096 long timestamp = System.currentTimeMillis();
097 long timeSinceLast;
098
099 if (firstMessageTimestamp == 0)
100 {
101 firstMessageTimestamp = timestamp;
102 }
103
104 if (lastMessageTimestamp == 0)
105 {
106 lastMessageTimestamp = timestamp;
107 }
108
109 timeSinceLast = timestamp - lastMessageTimestamp;
110 if (timeSinceLast < 0)
111 {
112 timeSinceLast = 0;
113 }
114
115 String timestampString = dateFormat.format(new Date(timestamp));
116
117 header.append(messageDirection);
118 header.append(' ');
119 header.append(timestampString);
120
121 // Include the number of milliseconds since the previous traced message.
122 header.append(" (");
123 header.append(timeSinceLast);
124 header.append("ms) ");
125
126
127 builder.append("LDAP: ");
128 builder.append(header);
129 builder.append(message);
130 builder.append(ServerConstants.EOL);
131
132 builder.append("ASN1: ");
133 builder.append(header);
134 element.toString(builder, 0);
135
136 err.print(builder);
137
138 if (timestamp > lastMessageTimestamp)
139 {
140 lastMessageTimestamp = timestamp;
141 }
142 }
143
144 /**
145 * Trace an incoming message.
146 * @param message The LDAP message to be traced.
147 * @param element The ASN.1 element of the message.
148 */
149 public void traceIncomingMessage(LDAPMessage message,
150 ASN1Element element)
151 {
152 if (verbose)
153 {
154 if (message.getProtocolOpType() !=
155 LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY)
156 {
157 traceMessage("S>C", message, element);
158 }
159 }
160 }
161
162
163 /**
164 * Trace an outgoing message.
165 * @param message The LDAP message to be traced.
166 * @param element The ASN.1 element of the message.
167 */
168 public void traceOutgoingMessage(LDAPMessage message,
169 ASN1Element element)
170 {
171 if (verbose)
172 {
173 if (message.getProtocolOpType() !=
174 LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY)
175 {
176 traceMessage("C>S", message, element);
177 }
178 }
179 }
180
181 }