1 5 package com.tc.object.logging; 6 7 import com.tc.logging.CustomerLogging; 8 import com.tc.logging.TCLogger; 9 import com.tc.logging.TCLogging; 10 import com.tc.object.TCObject; 11 import com.tc.object.bytecode.ByteCodeUtil; 12 import com.tc.object.config.DSOClientConfigHelper; 13 import com.tc.object.config.schema.DSORuntimeLoggingOptions; 14 import com.tc.object.config.schema.DSORuntimeOutputOptions; 15 import com.tc.object.lockmanager.api.LockLevel; 16 import com.tc.object.tx.WaitInvocation; 17 import com.tc.util.Util; 18 19 public class RuntimeLoggerImpl implements RuntimeLogger { 20 private static final TCLogger internalLogger = TCLogging.getLogger(RuntimeLoggerImpl.class); 21 22 private final DSORuntimeLoggingOptions configuration; 23 private final DSORuntimeOutputOptions options; 24 private final TCLogger logger; 25 26 public RuntimeLoggerImpl(DSOClientConfigHelper configHelper) { 27 this.options = configHelper.runtimeOutputOptions(); 28 this.logger = CustomerLogging.getDSORuntimeLogger(); 29 this.configuration = configHelper.runtimeLoggingOptions(); 30 } 31 32 public boolean lockDebug() { 33 return this.configuration.logLockDebug().getBoolean(); 34 } 35 36 public boolean fieldChangeDebug() { 37 return this.configuration.logFieldChangeDebug().getBoolean(); 38 } 39 40 public boolean arrayChangeDebug() { 41 return this.configuration.logFieldChangeDebug().getBoolean(); 42 } 43 44 public boolean newManagedObjectDebug() { 45 return this.configuration.logNewObjectDebug().getBoolean(); 46 } 47 48 public boolean waitNotifyDebug() { 49 return this.configuration.logWaitNotifyDebug().getBoolean(); 50 } 51 52 public boolean distributedMethodDebug() { 53 return this.configuration.logDistributedMethodDebug().getBoolean(); 54 } 55 56 public boolean nonPortableDump() { 57 return this.configuration.logNonPortableDump().getBoolean(); 58 } 59 60 public void lockAcquired(String lockName, int level, Object instance, TCObject tcObject) { 61 boolean isAutoLock = ByteCodeUtil.isAutolockName(lockName); 62 63 if (isAutoLock) { 64 autoLockAcquired(lockName, level, instance, tcObject); 65 } else { 66 namedLockAcquired(lockName, level); 67 } 68 } 69 70 private void namedLockAcquired(String lockName, int level) { 71 StringBuffer message = new StringBuffer ("Named lock [").append(lockName).append("] acquired with level ") 72 .append(LockLevel.toString(level)); 73 appendCall(message); 74 logger.info(message); 75 } 76 77 private void autoLockAcquired(String lockName, int level, Object instance, TCObject tcObject) { 78 StringBuffer message = new StringBuffer ("Autolock [").append(lockName).append("] acquired with level ") 79 .append(LockLevel.toString(level)); 80 81 if (options.doAutoLockDetails().getBoolean() && (instance != null)) { 82 message.append("\n type: ").append(instance.getClass().getName()); 83 message.append(", identityHashCode: 0x").append(Integer.toHexString(System.identityHashCode(instance))); 84 } 85 86 appendCall(message); 87 88 logger.info(message); 89 } 90 91 private void appendCall(StringBuffer message) { 92 boolean fullStack = options.doFullStack().getBoolean(); 93 boolean callOnly = options.doCaller().getBoolean(); 94 95 if (fullStack || callOnly) { 96 StackTraceElement [] stack = getTrimmedStack(); 97 if (stack != null) { 98 message.append("\n"); 99 if (fullStack) { 100 for (int i = 0; i < stack.length; i++) { 101 message.append(" at ").append(stack[i].toString()); 102 103 if (i < (stack.length - 1)) { 104 message.append("\n"); 105 } 106 } 107 } else { 108 message.append(" call: ").append(stack[0].toString()); 109 } 110 } 111 } 112 113 } 114 115 public void literalValueChanged(TCObject source, Object newValue) { 116 StringBuffer message = new StringBuffer ("DSO object literal value changed\n"); 117 if (newValue != null) { 118 message.append("\n newValue type: ").append(newValue.getClass().getName()); 119 message.append(", identityHashCode: 0x").append(Integer.toHexString(System.identityHashCode(newValue))); 120 } else { 121 message.append("\n newValue: null"); 122 } 123 124 logger.info(message.toString()); 125 } 126 127 public void fieldChanged(TCObject source, String classname, String fieldName, Object newValue, int index) { 128 StringBuffer message = new StringBuffer ("DSO object field changed\n"); 129 message.append(" class: ").append(classname).append(", field: ").append(fieldName); 130 if (index >= 0) { 131 message.append(", index: ").append(index); 132 } 133 if (newValue != null) { 134 message.append("\n newValue type: ").append(newValue.getClass().getName()); 135 message.append(", identityHashCode: 0x").append(Integer.toHexString(System.identityHashCode(newValue))); 136 } else { 137 message.append("\n newValue: null"); 138 } 139 140 logger.info(message.toString()); 141 } 142 143 public void arrayChanged(TCObject source, int startPos, Object array) { 144 StringBuffer message = new StringBuffer ("DSO array changed\n"); 145 message.append("\n startPos: ").append(startPos); 146 message.append("\n subset component types: \n").append(array.getClass().getComponentType()); 147 148 logger.info(message.toString()); 149 } 150 151 public void newManagedObject(TCObject object) { 152 StringBuffer message = new StringBuffer ("New DSO Object instance created\n"); 153 message.append(" instance: ").append(baseToString(object.getPeerObject())).append("\n"); 154 message.append(" object ID: ").append(object.getObjectID()); 155 appendCall(message); 156 logger.info(message.toString()); 157 } 158 159 public void objectNotify(boolean all, Object obj, TCObject tcObject) { 160 StringBuffer message = new StringBuffer ("notify").append(all ? "All()" : "()"); 161 message.append(" called on ").append(baseToString(obj)).append(", ObjectID: ").append( 162 tcObject.getObjectID() 163 .toLong()); 164 logger.info(message.toString()); 165 } 166 167 public void objectWait(WaitInvocation call, Object obj, TCObject tcObject) { 168 StringBuffer message = new StringBuffer (call.toString()).append(" called on "); 169 message.append(baseToString(obj)).append(", ObjectID: ").append(tcObject.getObjectID().toLong()); 170 logger.info(message.toString()); 171 } 172 173 public void distributedMethodCall(String receiverName, String methodName, String params) { 174 StringBuffer message = new StringBuffer ("Distributed method invoked\n"); 175 message.append(" receiver class: ").append(receiverName).append("\n"); 176 message.append(" methodName: ").append(methodName).append("\n"); 177 message.append(" params: ").append(params).append("\n"); 178 179 appendCall(message); 180 logger.info(message.toString()); 181 } 182 183 public void distributedMethodCallError(String receiverClassName, String methodName, String params, Throwable error) { 184 StringBuffer message = new StringBuffer ("Unhandled execption occurred in distributed method call\n"); 185 message.append(" receiver class: ").append(receiverClassName).append("\n"); 186 message.append(" methodName: ").append(methodName).append("\n"); 187 message.append(" params: ").append(params).append("\n"); 188 189 logger.warn(message.toString(), error); 190 } 191 192 private static String baseToString(Object obj) { 193 if (obj == null) { return null; } 194 return obj.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(obj)); 195 } 196 197 private static StackTraceElement [] getTrimmedStack() { 198 StackTraceElement [] stack = new Throwable ().getStackTrace(); 199 if ((stack == null) || (stack.length <= 1)) { 200 internalLogger.warn("funny stack returned: " + Util.enumerateArray(stack)); 201 return null; 202 } 203 204 int index = 0; 205 while (index < stack.length) { 206 String className = stack[index].getClassName(); 207 208 if (className.equals("com.tc.object.bytecode.ManagerUtil")) { 209 break; 210 } 211 212 index++; 213 } 214 215 index++; 217 218 if (index < (stack.length - 1)) { 219 StackTraceElement [] rv = new StackTraceElement [stack.length - index]; 220 System.arraycopy(stack, index, rv, 0, rv.length); 221 return rv; 222 } else { 223 internalLogger.warn("could not find proper stack frame: " + Util.enumerateArray(stack)); 224 return null; 225 } 226 227 } 229 230 231 } 232 | Popular Tags |