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 package org.opends.server.api; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.HashMap; 033 import java.util.List; 034 import java.util.Map; 035 import java.util.TreeMap; 036 037 import com.sleepycat.je.Transaction; 038 import com.sleepycat.je.Database; 039 import com.sleepycat.je.DatabaseEntry; 040 import com.sleepycat.je.OperationStatus; 041 042 import org.opends.server.admin.std.server.DebugLogPublisherCfg; 043 import org.opends.server.config.ConfigException; 044 import org.opends.server.loggers.LogLevel; 045 import org.opends.server.loggers.debug.TraceSettings; 046 import org.opends.server.types.DebugLogLevel; 047 import org.opends.server.types.InitializationException; 048 import org.opends.server.types.DN; 049 050 051 052 /** 053 * This class defines the set of methods and structures that must be 054 * implemented for a Directory Server debug log publisher. 055 * 056 * @param <T> The type of debug log publisher configuration handled 057 * by this log publisher implementation. 058 */ 059 @org.opends.server.types.PublicAPI( 060 stability=org.opends.server.types.StabilityLevel.VOLATILE, 061 mayInstantiate=false, 062 mayExtend=true, 063 mayInvoke=false) 064 public abstract class DebugLogPublisher 065 <T extends DebugLogPublisherCfg> 066 { 067 //The default global settings key. 068 private static final String GLOBAL= "_global"; 069 070 //The map of class names to their trace settings. 071 private Map<String,TraceSettings> classTraceSettings; 072 073 //The map of class names to their method trace settings. 074 private Map<String,Map<String,TraceSettings>> methodTraceSettings; 075 076 077 078 /** 079 * Construct a default configuration where the global scope will 080 * only log at the ERROR level. 081 */ 082 protected DebugLogPublisher() 083 { 084 classTraceSettings = null; 085 methodTraceSettings = null; 086 087 //Set the global settings so that only errors are logged. 088 addTraceSettings(null, new TraceSettings(DebugLogLevel.ERROR)); 089 } 090 091 092 093 /** 094 * Initializes this debug publisher provider based on the 095 * information in the provided debug publisher configuration. 096 * 097 * @param config The debug publisher configuration that contains 098 * the information to use to initialize this debug 099 * publisher. 100 * 101 * @throws ConfigException If an unrecoverable problem arises in 102 * the process of performing the 103 * initialization as a result of the 104 * server configuration. 105 * 106 * @throws InitializationException If a problem occurs during 107 * initialization that is not 108 * related to the server 109 * configuration. 110 */ 111 public abstract void initializeDebugLogPublisher(T config) 112 throws ConfigException, InitializationException; 113 114 115 116 /** 117 * Indicates whether the provided configuration is acceptable for 118 * this debug log publisher. It should be possible to call this 119 * method on an uninitialized debug log publisher instance in 120 * order to determine whether the debug log publisher would be able 121 * to use the provided configuration. 122 * <BR><BR> 123 * Note that implementations which use a subclass of the provided 124 * configuration class will likely need to cast the configuration 125 * to the appropriate subclass type. 126 * 127 * @param configuration The debug log publisher 128 * configuration for which to make the 129 * determination. 130 * @param unacceptableReasons A list that may be used to hold the 131 * reasons that the provided 132 * configuration is not acceptable. 133 * 134 * @return {@code true} if the provided configuration is acceptable 135 * for this debug log publisher, or {@code false} if not. 136 */ 137 public boolean isConfigurationAcceptable( 138 DebugLogPublisherCfg configuration, 139 List<Message> unacceptableReasons) 140 { 141 // This default implementation does not perform any special 142 // validation. It should be overridden by debug log publisher 143 // implementations that wish to perform more detailed validation. 144 return true; 145 } 146 147 148 149 /** 150 * Gets the method trace levels for a specified class. 151 * 152 * @param className The fully-qualified name of the class for 153 * which to get the trace levels. 154 * 155 *@return An unmodifiable map of trace levels keyed by method name, 156 * or {@code null} if no method-level tracing is configured 157 * for the scope. 158 */ 159 public final Map<String,TraceSettings> getMethodSettings( 160 String className) 161 { 162 if(methodTraceSettings == null) 163 { 164 return null; 165 } 166 else 167 { 168 return methodTraceSettings.get(className); 169 } 170 } 171 172 173 174 /** 175 * Get the trace settings for a specified class. 176 * 177 * @param className The fully-qualified name of the class for 178 * which to get the trace levels. 179 * 180 * @return The current trace settings for the class. 181 */ 182 public final TraceSettings getClassSettings(String className) 183 { 184 TraceSettings settings = TraceSettings.DISABLED; 185 186 // If we're not enabled, trace level is DISABLED. 187 if (classTraceSettings != null) { 188 // Find most specific trace setting which covers this 189 // fully qualified class name 190 // Search up the hierarchy for a match. 191 String searchName= className; 192 Object value= null; 193 value= classTraceSettings.get(searchName); 194 while (value == null && searchName != null) { 195 int clipPoint= searchName.lastIndexOf('$'); 196 if (clipPoint == -1) clipPoint= searchName.lastIndexOf('.'); 197 if (clipPoint != -1) { 198 searchName= searchName.substring(0, clipPoint); 199 value= classTraceSettings.get(searchName); 200 } 201 else { 202 searchName= null; 203 } 204 } 205 206 // Use global settings, if nothing more specific was found. 207 if (value == null) value= classTraceSettings.get(GLOBAL); 208 209 if (value != null) { 210 settings= (TraceSettings)value; 211 } 212 } 213 return settings; 214 } 215 216 217 218 /** 219 * Adds a trace settings to the current set for a specified scope. 220 * If a scope is not specified, the settings will be set for the 221 * global scope. The global scope settings are used when no other 222 * scope matches. 223 * 224 * @param scope The scope for which to set the trace settings. 225 * This should be a fully-qualified class name, or 226 * {@code null} to set the trace settings for the 227 * global scope. 228 * @param settings The trace settings for the specified scope. 229 */ 230 public final void addTraceSettings(String scope, 231 TraceSettings settings) 232 { 233 if (scope == null) { 234 setClassSettings(GLOBAL, settings); 235 } 236 else { 237 int methodPt= scope.lastIndexOf('#'); 238 if (methodPt != -1) { 239 String methodName= scope.substring(methodPt+1); 240 scope= scope.substring(0, methodPt); 241 setMethodSettings(scope, methodName, settings); 242 } 243 else { 244 setClassSettings(scope, settings); 245 } 246 } 247 } 248 249 250 251 /** 252 * Determine whether a trace setting is already defined for a 253 * particular scope. 254 * 255 * @param scope The scope for which to make the determination. 256 * This should be a fully-qualified class name, or 257 * {@code null} to make the determination for the 258 * global scope. 259 * 260 * @return The trace settings for the specified scope, or 261 * {@code null} if no trace setting is defined for that 262 * scope. 263 */ 264 public final TraceSettings getTraceSettings(String scope) 265 { 266 if (scope == null) { 267 if(classTraceSettings != null) 268 { 269 return classTraceSettings.get(GLOBAL); 270 } 271 return null; 272 } 273 else { 274 int methodPt= scope.lastIndexOf('#'); 275 if (methodPt != -1) { 276 String methodName= scope.substring(methodPt+1); 277 scope= scope.substring(0, methodPt); 278 if(methodTraceSettings != null) 279 { 280 Map<String, TraceSettings> methodLevels = 281 methodTraceSettings.get(scope); 282 if(methodLevels != null) 283 { 284 return methodLevels.get(methodName); 285 } 286 return null; 287 } 288 return null; 289 } 290 else { 291 if(classTraceSettings != null) 292 { 293 return classTraceSettings.get(scope); 294 } 295 return null; 296 } 297 } 298 } 299 300 301 302 /** 303 * Remove a trace setting by scope. 304 * 305 * @param scope The scope for which to remove the trace setting. 306 * This should be a fully-qualified class name, or 307 * {@code null} to remove the trace setting for the 308 * global scope. 309 * 310 * @return The trace settings for the specified scope, or 311 * {@code null} if no trace setting is defined for that 312 * scope. 313 */ 314 public final TraceSettings removeTraceSettings(String scope) 315 { 316 TraceSettings removedSettings = null; 317 if (scope == null) { 318 if(classTraceSettings != null) 319 { 320 removedSettings = classTraceSettings.remove(GLOBAL); 321 } 322 } 323 else { 324 int methodPt= scope.lastIndexOf('#'); 325 if (methodPt != -1) { 326 String methodName= scope.substring(methodPt+1); 327 scope= scope.substring(0, methodPt); 328 if(methodTraceSettings != null) 329 { 330 Map<String, TraceSettings> methodLevels = 331 methodTraceSettings.get(scope); 332 if(methodLevels != null) 333 { 334 removedSettings = methodLevels.remove(methodName); 335 if(methodLevels.isEmpty()) 336 { 337 methodTraceSettings.remove(scope); 338 } 339 } 340 } 341 } 342 else { 343 if(classTraceSettings != null) 344 { 345 removedSettings = classTraceSettings.remove(scope); 346 } 347 } 348 } 349 350 return removedSettings; 351 } 352 353 354 355 /** 356 * Set the trace settings for a class. 357 * 358 * @param className The class name. 359 * @param settings The trace settings for the class. 360 */ 361 private synchronized final void setClassSettings(String className, 362 TraceSettings settings) 363 { 364 if(classTraceSettings == null) classTraceSettings = 365 new HashMap<String, TraceSettings>(); 366 367 classTraceSettings.put(className, settings); 368 } 369 370 371 372 /** 373 * Set the method settings for a particular method in a class. 374 * 375 * @param className The class name. 376 * @param methodName The method name. 377 * @param settings The trace settings for the method. 378 */ 379 private synchronized final void setMethodSettings(String className, 380 String methodName, 381 TraceSettings settings) 382 { 383 if (methodTraceSettings == null) methodTraceSettings = 384 new HashMap<String, Map<String, TraceSettings>>(); 385 Map<String, TraceSettings> methodLevels= 386 methodTraceSettings.get(className); 387 if (methodLevels == null) { 388 methodLevels= new TreeMap<String, TraceSettings>(); 389 methodTraceSettings.put(className, methodLevels); 390 } 391 392 methodLevels.put(methodName, settings); 393 } 394 395 396 397 /** 398 * Log a constructor entry. 399 * 400 * @param level The log level for the message. 401 * @param settings The current trace settings in effect. 402 * @param signature The constuctor signature. 403 * @param sourceLocation The location of the method in the source. 404 * @param args The parameters provided to the 405 * constructor. 406 * @param stackTrace The stack trace at the time the 407 * constructor is executed or null if its 408 * not available. 409 */ 410 public abstract void traceConstructor(LogLevel level, 411 TraceSettings settings, 412 String signature, 413 String sourceLocation, 414 Object[] args, 415 StackTraceElement[] stackTrace); 416 417 418 419 /** 420 * Log a non-static method entry. 421 * 422 * @param level The log level for the message. 423 * @param settings The current trace settings in effect. 424 * @param signature The method signature. 425 * @param sourceLocation The location of the method in the source. 426 * @param obj The object instance on which the method 427 * has been invoked. 428 * @param args The parameters provided to the method. 429 * @param stackTrace The stack trace at the time the method 430 * is executed or null if its not available. 431 */ 432 public abstract void traceMethodEntry(LogLevel level, 433 TraceSettings settings, 434 String signature, 435 String sourceLocation, 436 Object obj, 437 Object[] args, 438 StackTraceElement[] stackTrace); 439 440 441 442 /** 443 * Log a static method entry. 444 * 445 * @param level The log level for the message. 446 * @param settings The current trace settings in effect. 447 * @param signature The method signature. 448 * @param sourceLocation The location of the method in the source. 449 * @param args The parameters provided to the method. 450 * @param stackTrace The stack trace at the time the method 451 * is executed or null if its not available. 452 */ 453 public abstract void traceStaticMethodEntry(LogLevel level, 454 TraceSettings settings, 455 String signature, 456 String sourceLocation, 457 Object[] args, 458 StackTraceElement[] stackTrace); 459 460 461 462 /** 463 * Log a method return. 464 * 465 * @param level The log level for the message. 466 * @param settings The current trace settings in effect. 467 * @param signature The method signature. 468 * @param sourceLocation The location of the method in the source. 469 * @param ret The return value for the method. 470 * @param stackTrace The stack trace at the time the method 471 * is returned or null if its not available. 472 */ 473 public abstract void traceReturn(LogLevel level, 474 TraceSettings settings, 475 String signature, 476 String sourceLocation, 477 Object ret, 478 StackTraceElement[] stackTrace); 479 480 481 482 /** 483 * Log an arbitrary event in a method. 484 * 485 * @param level The log level for the message. 486 * @param settings The current trace settings in effect. 487 * @param signature The method signature. 488 * @param sourceLocation The location of the method in the source. 489 * @param msg The message to be logged. 490 * @param stackTrace The stack trace at the time the message 491 * is logged or null if its not available. 492 */ 493 public abstract void traceMessage(LogLevel level, 494 TraceSettings settings, 495 String signature, 496 String sourceLocation, 497 String msg, 498 StackTraceElement[] stackTrace); 499 500 501 502 /** 503 * Log a thrown exception in a method. 504 * 505 * @param level The log level for the message. 506 * @param settings The current trace settings in effect. 507 * @param signature The method signature. 508 * @param sourceLocation The location of the method in the source. 509 * @param ex The exception that was thrown. 510 * @param stackTrace The stack trace at the time the exception 511 * is thrown or null if its not available. 512 */ 513 public abstract void traceThrown(LogLevel level, 514 TraceSettings settings, 515 String signature, 516 String sourceLocation, 517 Throwable ex, 518 StackTraceElement[] stackTrace); 519 520 521 522 /** 523 * Log a caught exception in a method. 524 * 525 * @param level The log level for the message. 526 * @param settings The current trace settings in effect. 527 * @param signature The method signature. 528 * @param sourceLocation The location of the method in the source. 529 * @param ex The exception that was caught. 530 * @param stackTrace The stack trace at the time the exception 531 * is caught or null if its not available. 532 */ 533 public abstract void traceCaught(LogLevel level, 534 TraceSettings settings, 535 String signature, 536 String sourceLocation, 537 Throwable ex, 538 StackTraceElement[] stackTrace); 539 540 541 542 /** 543 * Log an JE database access in a method. 544 * 545 * @param level The log level for the message. 546 * @param settings The current trace settings in effect. 547 * @param signature The method signature. 548 * @param sourceLocation The location of the method in the source. 549 * @param status The status of the JE operation. 550 * @param database The database handle. 551 * @param txn The transaction handle (may be 552 * {@code null}). 553 * @param key The key to dump. 554 * @param data The data to dump. 555 * @param stackTrace The stack trace at the time the access 556 * occurred or null if its not available. 557 */ 558 public abstract void traceJEAccess(LogLevel level, 559 TraceSettings settings, 560 String signature, 561 String sourceLocation, 562 OperationStatus status, 563 Database database, 564 Transaction txn, 565 DatabaseEntry key, 566 DatabaseEntry data, 567 StackTraceElement[] stackTrace); 568 569 570 571 /** 572 * Log raw data in a method. 573 * 574 * @param level The log level for the message. 575 * @param settings The current trace settings in effect. 576 * @param signature The method signature. 577 * @param sourceLocation The location of the method in the source. 578 * @param data The data to dump. 579 * @param stackTrace The stack trace at the time the data 580 * is logged or null if its not available. 581 */ 582 public abstract void traceData(LogLevel level, 583 TraceSettings settings, 584 String signature, 585 String sourceLocation, 586 byte[] data, 587 StackTraceElement[] stackTrace); 588 589 590 591 /** 592 * Log a protocol element in a method. 593 * 594 * @param level The log level for the message. 595 * @param settings The current trace settings in effect. 596 * @param signature The method signature. 597 * @param sourceLocation The location of the method in the source. 598 * @param element The protocol element to dump. 599 * @param stackTrace The stack trace at the time the protocol 600 * element is logged or null if its not 601 * available. 602 */ 603 public abstract void traceProtocolElement(LogLevel level, 604 TraceSettings settings, 605 String signature, 606 String sourceLocation, 607 ProtocolElement element, 608 StackTraceElement[] stackTrace); 609 610 /** 611 * Close this publisher. 612 */ 613 public abstract void close(); 614 615 /** 616 * Gets the DN of the configuration entry for this debug log 617 * publisher. 618 * 619 * @return The configuration entry DN. 620 */ 621 public abstract DN getDN(); 622 } 623