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 }