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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.loggers.debug; 028 029 import org.opends.server.api.DebugLogPublisher; 030 import org.opends.server.api.ProtocolElement; 031 import org.opends.server.types.DebugLogCategory; 032 import org.opends.server.types.DebugLogLevel; 033 import org.opends.server.loggers.LogLevel; 034 import org.opends.server.loggers.LogCategory; 035 036 import java.util.Map; 037 import java.nio.ByteBuffer; 038 039 import com.sleepycat.je.OperationStatus; 040 import com.sleepycat.je.Transaction; 041 import com.sleepycat.je.DatabaseEntry; 042 import com.sleepycat.je.Database; 043 044 /** 045 * Class for source-code tracing at the method level. 046 * 047 * One DebugTracer instance exists for each Java class using tracing. 048 * Tracer must be registered with the DebugLogger. 049 * 050 * Logging is always done at a level basis, with debug log messages 051 * exceeding the trace threshold being traced, others being discarded. 052 */ 053 054 public class DebugTracer 055 { 056 // The class this aspect traces. 057 private String className; 058 059 /** 060 * A class that represents a settings cache entry. 061 */ 062 private class PublisherSettings 063 { 064 DebugLogPublisher debugPublisher; 065 TraceSettings classSettings; 066 Map<String, TraceSettings> methodSettings; 067 } 068 069 PublisherSettings[] publisherSettings; 070 071 /** 072 * Construct a new DebugTracer object with cached settings obtained from 073 * the provided array of publishers. 074 * 075 * @param publishers The array of publishers to obtain the settings from. 076 */ 077 @SuppressWarnings("unchecked") 078 DebugTracer(DebugLogPublisher[] publishers) 079 { 080 // Trim off the debug logging and non OpenDS frames. 081 StackTraceElement callerFrame = 082 getCallerFrame(Thread.currentThread().getStackTrace()); 083 084 // TODO: What if this is null or 0 length? 085 if(callerFrame != null) 086 { 087 // The caller should be the first item on the stack. 088 className = callerFrame.getClassName(); 089 } 090 091 publisherSettings = new PublisherSettings[publishers.length]; 092 093 // Get the settings from all publishers. 094 for(int i = 0; i < publishers.length; i++) 095 { 096 DebugLogPublisher publisher = publishers[i]; 097 PublisherSettings settings = new PublisherSettings(); 098 099 settings.debugPublisher = publisher; 100 settings.classSettings = publisher.getClassSettings(className); 101 102 // For some reason, the compiler doesn't see that 103 // debugLogPublihser.getMethodSettings returns a parameterized Map. 104 // This problem goes away if a parameterized verson of DebugLogPublisher 105 // is used. However, we can't not use reflection to instantiate a generic 106 // DebugLogPublisher<? extends DebugLogPublisherCfg> type. The only thing 107 // we can do is to just supress the compiler warnings. 108 settings.methodSettings = publisher.getMethodSettings(className); 109 110 publisherSettings[i] = settings; 111 } 112 } 113 114 /** 115 * Log an constructor execution event. 116 * 117 * @param level The level of the message being logged. 118 * @param args The arguments passed to the constructor. 119 */ 120 public void debugConstructor(LogLevel level, Object... args) 121 { 122 if(DebugLogger.debugEnabled()) 123 { 124 StackTraceElement[] stackTrace = null; 125 StackTraceElement[] filteredStackTrace = null; 126 StackTraceElement callerFrame = null; 127 for (PublisherSettings settings : publisherSettings) 128 { 129 TraceSettings activeSettings = settings.classSettings; 130 Map<String, TraceSettings> methodSettings = settings.methodSettings; 131 132 if (shouldLog(level, DebugLogCategory.CONSTRUCTOR, 133 activeSettings) || methodSettings != null) 134 { 135 if(stackTrace == null) 136 { 137 stackTrace = Thread.currentThread().getStackTrace(); 138 } 139 if (callerFrame == null) 140 { 141 callerFrame = getCallerFrame(stackTrace); 142 } 143 144 String signature = callerFrame.getMethodName(); 145 146 // Specific method settings still could exist. Try getting 147 // the settings for this method. 148 if(methodSettings != null) 149 { 150 TraceSettings mSettings = methodSettings.get(signature); 151 152 if (mSettings == null) 153 { 154 // Try looking for an undecorated method name 155 int idx = signature.indexOf('('); 156 if (idx != -1) 157 { 158 mSettings = 159 methodSettings.get(signature.substring(0, idx)); 160 } 161 } 162 163 // If this method does have a specific setting and it is not 164 // suppose to be logged, continue. 165 if (mSettings != null) 166 { 167 if(!shouldLog(level, DebugLogCategory.CONSTRUCTOR, 168 mSettings)) 169 { 170 continue; 171 } 172 else 173 { 174 activeSettings = mSettings; 175 } 176 } 177 } 178 179 String sl = callerFrame.getFileName() + ":" + 180 callerFrame.getLineNumber(); 181 182 if (activeSettings.noArgs) 183 { 184 args = null; 185 } 186 187 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 188 { 189 filteredStackTrace = 190 DebugStackTraceFormatter.SMART_FRAME_FILTER. 191 getFilteredStackTrace(stackTrace); 192 } 193 194 settings.debugPublisher.traceConstructor(level, 195 activeSettings, signature, 196 sl, args, 197 filteredStackTrace); 198 } 199 } 200 } 201 } 202 203 /** 204 * Log an non static method entry event. 205 * 206 * @param level The level of the message being logged. 207 * @param obj The object type instance the method is a member of. 208 * @param args The arguments passed to the method. 209 */ 210 public void debugMethodEntry(LogLevel level, Object obj, Object... args) 211 { 212 if(DebugLogger.debugEnabled()) 213 { 214 StackTraceElement[] stackTrace = null; 215 StackTraceElement[] filteredStackTrace = null; 216 StackTraceElement callerFrame = null; 217 for (PublisherSettings settings : publisherSettings) 218 { 219 TraceSettings activeSettings = settings.classSettings; 220 Map<String, TraceSettings> methodSettings = settings.methodSettings; 221 222 if (shouldLog(level, DebugLogCategory.ENTER, 223 activeSettings) || methodSettings != null) 224 { 225 if(stackTrace == null) 226 { 227 stackTrace = Thread.currentThread().getStackTrace(); 228 } 229 if (callerFrame == null) 230 { 231 callerFrame = getCallerFrame(stackTrace); 232 } 233 234 String signature = callerFrame.getMethodName(); 235 236 // Specific method settings still could exist. Try getting 237 // the settings for this method. 238 if(methodSettings != null) 239 { 240 TraceSettings mSettings = methodSettings.get(signature); 241 242 if (mSettings == null) 243 { 244 // Try looking for an undecorated method name 245 int idx = signature.indexOf('('); 246 if (idx != -1) 247 { 248 mSettings = 249 methodSettings.get(signature.substring(0, idx)); 250 } 251 } 252 253 // If this method does have a specific setting and it is not 254 // suppose to be logged, continue. 255 if (mSettings != null) 256 { 257 if(!shouldLog(level, DebugLogCategory.ENTER, 258 mSettings)) 259 { 260 continue; 261 } 262 else 263 { 264 activeSettings = mSettings; 265 } 266 } 267 } 268 269 String sl = callerFrame.getFileName() + ":" + 270 callerFrame.getLineNumber(); 271 272 if (activeSettings.noArgs) 273 { 274 args = null; 275 } 276 277 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 278 { 279 filteredStackTrace = 280 DebugStackTraceFormatter.SMART_FRAME_FILTER. 281 getFilteredStackTrace(stackTrace); 282 } 283 284 settings.debugPublisher.traceMethodEntry(level, 285 activeSettings, signature, 286 sl, obj, args, 287 filteredStackTrace); 288 } 289 } 290 } 291 } 292 293 /** 294 * Log an static method entry event. 295 * 296 * @param level The level of the message being logged. 297 * @param args The arguments passed to the method. 298 */ 299 public void debugStaticMethodEntry(LogLevel level, Object... args) 300 { 301 if(DebugLogger.debugEnabled()) 302 { 303 StackTraceElement[] stackTrace = null; 304 StackTraceElement[] filteredStackTrace = null; 305 StackTraceElement callerFrame = null; 306 for (PublisherSettings settings : publisherSettings) 307 { 308 TraceSettings activeSettings = settings.classSettings; 309 Map<String, TraceSettings> methodSettings = settings.methodSettings; 310 311 if (shouldLog(level, DebugLogCategory.ENTER, 312 activeSettings) || methodSettings != null) 313 { 314 if(stackTrace == null) 315 { 316 stackTrace = Thread.currentThread().getStackTrace(); 317 } 318 if (callerFrame == null) 319 { 320 callerFrame = getCallerFrame(stackTrace); 321 } 322 323 String signature = callerFrame.getMethodName(); 324 325 // Specific method settings still could exist. Try getting 326 // the settings for this method. 327 if(methodSettings != null) 328 { 329 TraceSettings mSettings = methodSettings.get(signature); 330 331 if (mSettings == null) 332 { 333 // Try looking for an undecorated method name 334 int idx = signature.indexOf('('); 335 if (idx != -1) 336 { 337 mSettings = 338 methodSettings.get(signature.substring(0, idx)); 339 } 340 } 341 342 // If this method does have a specific setting and it is not 343 // suppose to be logged, continue. 344 if (mSettings != null) 345 { 346 if(!shouldLog(level, DebugLogCategory.ENTER, 347 mSettings)) 348 { 349 continue; 350 } 351 else 352 { 353 activeSettings = mSettings; 354 } 355 } 356 } 357 358 String sl = callerFrame.getFileName() + ":" + 359 callerFrame.getLineNumber(); 360 361 if (activeSettings.noArgs) 362 { 363 args = null; 364 } 365 366 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 367 { 368 filteredStackTrace = 369 DebugStackTraceFormatter.SMART_FRAME_FILTER. 370 getFilteredStackTrace(stackTrace); 371 } 372 373 settings.debugPublisher.traceStaticMethodEntry(level, 374 activeSettings, 375 signature, sl, args, 376 filteredStackTrace); 377 } 378 } 379 } 380 } 381 382 /** 383 * Log a return from a method call event. 384 * 385 * @param level The level of the message being logged. 386 * @param ret The value being returned from the method. 387 */ 388 public void debugReturn(LogLevel level, Object ret) 389 { 390 if(DebugLogger.debugEnabled()) 391 { 392 StackTraceElement[] stackTrace = null; 393 StackTraceElement[] filteredStackTrace = null; 394 StackTraceElement callerFrame = null; 395 for (PublisherSettings settings : publisherSettings) 396 { 397 TraceSettings activeSettings = settings.classSettings; 398 Map<String, TraceSettings> methodSettings = settings.methodSettings; 399 400 if (shouldLog(level, DebugLogCategory.ENTER, 401 activeSettings) || methodSettings != null) 402 { 403 if(stackTrace == null) 404 { 405 stackTrace = Thread.currentThread().getStackTrace(); 406 } 407 if (callerFrame == null) 408 { 409 callerFrame = getCallerFrame(stackTrace); 410 } 411 412 String signature = callerFrame.getMethodName(); 413 414 // Specific method settings still could exist. Try getting 415 // the settings for this method. 416 if(methodSettings != null) 417 { 418 TraceSettings mSettings = methodSettings.get(signature); 419 420 if (mSettings == null) 421 { 422 // Try looking for an undecorated method name 423 int idx = signature.indexOf('('); 424 if (idx != -1) 425 { 426 mSettings = 427 methodSettings.get(signature.substring(0, idx)); 428 } 429 } 430 431 // If this method does have a specific setting and it is not 432 // suppose to be logged, continue. 433 if (mSettings != null) 434 { 435 if(!shouldLog(level, DebugLogCategory.ENTER, 436 mSettings)) 437 { 438 continue; 439 } 440 else 441 { 442 activeSettings = mSettings; 443 } 444 } 445 } 446 447 String sl = callerFrame.getFileName() + ":" + 448 callerFrame.getLineNumber(); 449 450 if (activeSettings.noRetVal) 451 { 452 ret = null; 453 } 454 455 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 456 { 457 filteredStackTrace = 458 DebugStackTraceFormatter.SMART_FRAME_FILTER. 459 getFilteredStackTrace(stackTrace); 460 } 461 462 settings.debugPublisher.traceReturn(level, 463 activeSettings, signature, 464 sl, ret, 465 filteredStackTrace); 466 } 467 } 468 } 469 } 470 471 /** 472 * Log an exception thrown from a method. 473 * 474 * @param level The level of the message being logged. 475 * @param ex The exception being thrown. 476 */ 477 public void debugThrown(LogLevel level, Throwable ex) 478 { 479 if(DebugLogger.debugEnabled()) 480 { 481 StackTraceElement[] stackTrace = null; 482 StackTraceElement[] filteredStackTrace = null; 483 StackTraceElement callerFrame = null; 484 for (PublisherSettings settings : publisherSettings) 485 { 486 TraceSettings activeSettings = settings.classSettings; 487 Map<String, TraceSettings> methodSettings = settings.methodSettings; 488 489 if (shouldLog(level, DebugLogCategory.THROWN, 490 activeSettings) || methodSettings != null) 491 { 492 if(stackTrace == null) 493 { 494 stackTrace = Thread.currentThread().getStackTrace(); 495 } 496 if (callerFrame == null) 497 { 498 callerFrame = getCallerFrame(stackTrace); 499 } 500 501 String signature = callerFrame.getMethodName(); 502 503 // Specific method settings still could exist. Try getting 504 // the settings for this method. 505 if(methodSettings != null) 506 { 507 TraceSettings mSettings = methodSettings.get(signature); 508 509 if (mSettings == null) 510 { 511 // Try looking for an undecorated method name 512 int idx = signature.indexOf('('); 513 if (idx != -1) 514 { 515 mSettings = 516 methodSettings.get(signature.substring(0, idx)); 517 } 518 } 519 520 // If this method does have a specific setting and it is not 521 // suppose to be logged, continue. 522 if (mSettings != null) 523 { 524 if(!shouldLog(level, DebugLogCategory.THROWN, 525 mSettings)) 526 { 527 continue; 528 } 529 else 530 { 531 activeSettings = mSettings; 532 } 533 } 534 } 535 536 String sl = callerFrame.getFileName() + ":" + 537 callerFrame.getLineNumber(); 538 539 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 540 { 541 filteredStackTrace = 542 DebugStackTraceFormatter.SMART_FRAME_FILTER. 543 getFilteredStackTrace(ex.getStackTrace()); 544 } 545 546 settings.debugPublisher.traceThrown(level, activeSettings, signature, 547 sl, ex, filteredStackTrace); 548 } 549 } 550 } 551 } 552 553 /** 554 * Log an arbitrary event at the verbose level. 555 * Same as debugMessage(DebugLogLevel.ERROR, msg) 556 * 557 * @param msg message to format and log. 558 */ 559 public void debugVerbose(String msg) 560 { 561 debugMessage(DebugLogLevel.VERBOSE, msg, new Object[]{}); 562 } 563 564 /** 565 * Log an arbitrary event at the verbose level. 566 * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) 567 * 568 * @param msg message to format and log. 569 * @param msgArgs arguments to place into the format string. 570 */ 571 public void debugVerbose(String msg, Object... msgArgs) 572 { 573 debugMessage(DebugLogLevel.VERBOSE, msg, msgArgs); 574 } 575 576 /** 577 * Log an arbitrary event at the info level. 578 * Same as debugMessage(DebugLogLevel.ERROR, msg) 579 * 580 * @param msg message to format and log. 581 */ 582 public void debugInfo(String msg) 583 { 584 debugMessage(DebugLogLevel.INFO, msg, new Object[]{}); 585 } 586 587 /** 588 * Log an arbitrary event at the info level. 589 * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) 590 * 591 * @param msg message to format and log. 592 * @param msgArgs arguments to place into the format string. 593 */ 594 public void debugInfo(String msg, Object... msgArgs) 595 { 596 debugMessage(DebugLogLevel.INFO, msg, msgArgs); 597 } 598 599 /** 600 * Log an arbitrary event at the warning level. 601 * Same as debugMessage(DebugLogLevel.ERROR, msg) 602 * 603 * @param msg message to format and log. 604 */ 605 public void debugWarning(String msg) 606 607 { 608 debugMessage(DebugLogLevel.WARNING, msg, new Object[]{}); 609 } 610 611 /** 612 * Log an arbitrary event at the warning level. 613 * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) 614 * 615 * @param msg message to format and log. 616 * @param msgArgs arguments to place into the format string. 617 */ 618 public void debugWarning(String msg, Object... msgArgs) 619 { 620 debugMessage(DebugLogLevel.WARNING, msg, msgArgs); 621 } 622 623 /** 624 * Log an arbitrary event at the error level. 625 * Same as debugMessage(DebugLogLevel.ERROR, msg) 626 * 627 * @param msg message to format and log. 628 */ 629 public void debugError(String msg) 630 631 { 632 debugMessage(DebugLogLevel.ERROR, msg, new Object[]{}); 633 } 634 635 /** 636 * Log an arbitrary event at the error level. 637 * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) 638 * 639 * @param msg message to format and log. 640 * @param msgArgs arguments to place into the format string. 641 */ 642 public void debugError(String msg, Object... msgArgs) 643 { 644 debugMessage(DebugLogLevel.ERROR, msg, msgArgs); 645 } 646 647 /** 648 * Log an arbitrary event. 649 * 650 * @param level the level of the log message. 651 * @param msg message to format and log. 652 */ 653 public void debugMessage(LogLevel level, String msg) 654 { 655 debugMessage(level, msg, new Object[]{}); 656 } 657 658 /** 659 * Log an arbitrary event. 660 * 661 * @param level the level of the log message. 662 * @param msg message to format and log. 663 * @param msgArgs arguments to place into the format string. 664 */ 665 public void debugMessage(LogLevel level, String msg, Object... msgArgs) 666 { 667 if(DebugLogger.debugEnabled()) 668 { 669 StackTraceElement[] stackTrace = null; 670 StackTraceElement[] filteredStackTrace = null; 671 StackTraceElement callerFrame = null; 672 for (PublisherSettings settings : publisherSettings) 673 { 674 TraceSettings activeSettings = settings.classSettings; 675 Map<String, TraceSettings> methodSettings = settings.methodSettings; 676 677 if (shouldLog(level, DebugLogCategory.MESSAGE, 678 activeSettings) || methodSettings != null) 679 { 680 if(stackTrace == null) 681 { 682 stackTrace = Thread.currentThread().getStackTrace(); 683 } 684 if (callerFrame == null) 685 { 686 callerFrame = getCallerFrame(stackTrace); 687 } 688 689 String signature = callerFrame.getMethodName(); 690 691 // Specific method settings still could exist. Try getting 692 // the settings for this method. 693 if(methodSettings != null) 694 { 695 TraceSettings mSettings = methodSettings.get(signature); 696 697 if (mSettings == null) 698 { 699 // Try looking for an undecorated method name 700 int idx = signature.indexOf('('); 701 if (idx != -1) 702 { 703 mSettings = 704 methodSettings.get(signature.substring(0, idx)); 705 } 706 } 707 708 // If this method does have a specific setting and it is not 709 // suppose to be logged, continue. 710 if (mSettings != null) 711 { 712 if(!shouldLog(level, DebugLogCategory.MESSAGE, 713 mSettings)) 714 { 715 continue; 716 } 717 else 718 { 719 activeSettings = mSettings; 720 } 721 } 722 } 723 724 String sl = callerFrame.getFileName() + ":" + 725 callerFrame.getLineNumber(); 726 727 if(msgArgs != null && msgArgs.length > 0) 728 { 729 msg = String.format(msg, msgArgs); 730 } 731 732 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 733 { 734 filteredStackTrace = 735 DebugStackTraceFormatter.SMART_FRAME_FILTER. 736 getFilteredStackTrace(stackTrace); 737 } 738 739 settings.debugPublisher.traceMessage(level, activeSettings, signature, 740 sl, msg, filteredStackTrace); 741 } 742 } 743 } 744 } 745 746 /** 747 * Log an cought exception. 748 * 749 * @param level the level of the log message. 750 * @param ex the exception caught. 751 */ 752 public void debugCaught(LogLevel level, Throwable ex) 753 { 754 if(DebugLogger.debugEnabled()) 755 { 756 StackTraceElement[] stackTrace = null; 757 StackTraceElement[] filteredStackTrace = null; 758 StackTraceElement callerFrame = null; 759 for (PublisherSettings settings : publisherSettings) 760 { 761 TraceSettings activeSettings = settings.classSettings; 762 Map<String, TraceSettings> methodSettings = settings.methodSettings; 763 764 if (shouldLog(level, DebugLogCategory.CAUGHT, 765 activeSettings) || methodSettings != null) 766 { 767 if(stackTrace == null) 768 { 769 stackTrace = Thread.currentThread().getStackTrace(); 770 } 771 if (callerFrame == null) 772 { 773 callerFrame = getCallerFrame(stackTrace); 774 } 775 776 String signature = callerFrame.getMethodName(); 777 778 // Specific method settings still could exist. Try getting 779 // the settings for this method. 780 if(methodSettings != null) 781 { 782 TraceSettings mSettings = methodSettings.get(signature); 783 784 if (mSettings == null) 785 { 786 // Try looking for an undecorated method name 787 int idx = signature.indexOf('('); 788 if (idx != -1) 789 { 790 mSettings = 791 methodSettings.get(signature.substring(0, idx)); 792 } 793 } 794 795 // If this method does have a specific setting and it is not 796 // suppose to be logged, continue. 797 if (mSettings != null) 798 { 799 if(!shouldLog(level, DebugLogCategory.CAUGHT, 800 mSettings)) 801 { 802 continue; 803 } 804 else 805 { 806 activeSettings = mSettings; 807 } 808 } 809 } 810 811 String sl = callerFrame.getFileName() + ":" + 812 callerFrame.getLineNumber(); 813 814 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 815 { 816 filteredStackTrace = 817 DebugStackTraceFormatter.SMART_FRAME_FILTER. 818 getFilteredStackTrace(ex.getStackTrace()); 819 } 820 821 settings.debugPublisher.traceCaught(level, activeSettings, signature, 822 sl, ex, filteredStackTrace); 823 } 824 } 825 } 826 } 827 828 /** 829 * Log a JE database access event. 830 * 831 * @param level the level of the log message. 832 * @param status status of the JE operation. 833 * @param database the database handle. 834 * @param txn transaction handle (may be null). 835 * @param key the key to dump. 836 * @param data the data to dump. 837 */ 838 public void debugJEAccess(LogLevel level, OperationStatus status, 839 Database database, Transaction txn, 840 DatabaseEntry key, DatabaseEntry data) 841 { 842 if(DebugLogger.debugEnabled()) 843 { 844 StackTraceElement[] stackTrace = null; 845 StackTraceElement[] filteredStackTrace = null; 846 StackTraceElement callerFrame = null; 847 for (PublisherSettings settings : publisherSettings) 848 { 849 TraceSettings activeSettings = settings.classSettings; 850 Map<String, TraceSettings> methodSettings = settings.methodSettings; 851 852 if (shouldLog(level, DebugLogCategory.DATABASE_ACCESS, 853 activeSettings) || methodSettings != null) 854 { 855 if(stackTrace == null) 856 { 857 stackTrace = Thread.currentThread().getStackTrace(); 858 } 859 if (callerFrame == null) 860 { 861 callerFrame = getCallerFrame(stackTrace); 862 } 863 864 String signature = callerFrame.getMethodName(); 865 866 // Specific method settings still could exist. Try getting 867 // the settings for this method. 868 if(methodSettings != null) 869 { 870 TraceSettings mSettings = methodSettings.get(signature); 871 872 if (mSettings == null) 873 { 874 // Try looking for an undecorated method name 875 int idx = signature.indexOf('('); 876 if (idx != -1) 877 { 878 mSettings = 879 methodSettings.get(signature.substring(0, idx)); 880 } 881 } 882 883 // If this method does have a specific setting and it is not 884 // suppose to be logged, continue. 885 if (mSettings != null) 886 { 887 if(!shouldLog(level, DebugLogCategory.DATABASE_ACCESS, 888 mSettings)) 889 { 890 continue; 891 } 892 else 893 { 894 activeSettings = mSettings; 895 } 896 } 897 } 898 899 String sl = callerFrame.getFileName() + ":" + 900 callerFrame.getLineNumber(); 901 902 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 903 { 904 filteredStackTrace = 905 DebugStackTraceFormatter.SMART_FRAME_FILTER. 906 getFilteredStackTrace(stackTrace); 907 } 908 909 settings.debugPublisher.traceJEAccess(level, activeSettings, 910 signature, sl, status, database, 911 txn, key, data, 912 filteredStackTrace); 913 } 914 } 915 } 916 } 917 918 /** 919 * Log raw data in the form of a byte array. 920 * 921 * @param level the level of the log message. 922 * @param data the data to dump. 923 */ 924 public void debugData(LogLevel level, byte[] data) 925 { 926 if(DebugLogger.debugEnabled() && data != null) 927 { 928 StackTraceElement[] stackTrace = null; 929 StackTraceElement[] filteredStackTrace = null; 930 StackTraceElement callerFrame = null; 931 for (PublisherSettings settings : publisherSettings) 932 { 933 TraceSettings activeSettings = settings.classSettings; 934 Map<String, TraceSettings> methodSettings = settings.methodSettings; 935 936 if (shouldLog(level, DebugLogCategory.DATA, 937 activeSettings) || methodSettings != null) 938 { 939 if(stackTrace == null) 940 { 941 stackTrace = Thread.currentThread().getStackTrace(); 942 } 943 if (callerFrame == null) 944 { 945 callerFrame = getCallerFrame(stackTrace); 946 } 947 948 String signature = callerFrame.getMethodName(); 949 950 // Specific method settings still could exist. Try getting 951 // the settings for this method. 952 if(methodSettings != null) 953 { 954 TraceSettings mSettings = methodSettings.get(signature); 955 956 if (mSettings == null) 957 { 958 // Try looking for an undecorated method name 959 int idx = signature.indexOf('('); 960 if (idx != -1) 961 { 962 mSettings = 963 methodSettings.get(signature.substring(0, idx)); 964 } 965 } 966 967 // If this method does have a specific setting and it is not 968 // suppose to be logged, continue. 969 if (mSettings != null) 970 { 971 if(!shouldLog(level, DebugLogCategory.DATA, 972 mSettings)) 973 { 974 continue; 975 } 976 else 977 { 978 activeSettings = mSettings; 979 } 980 } 981 } 982 983 String sl = callerFrame.getFileName() + ":" + 984 callerFrame.getLineNumber(); 985 986 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 987 { 988 filteredStackTrace = 989 DebugStackTraceFormatter.SMART_FRAME_FILTER. 990 getFilteredStackTrace(stackTrace); 991 } 992 993 settings.debugPublisher.traceData(level, activeSettings, signature, 994 sl, data, filteredStackTrace); 995 } 996 } 997 } 998 } 999 1000 /** 1001 * Log a protocol element. 1002 * 1003 * @param level the level of the log message. 1004 * @param element the protocol element to dump. 1005 */ 1006 public void debugProtocolElement(LogLevel level, ProtocolElement element) 1007 { 1008 if(DebugLogger.debugEnabled() && element != null) 1009 { 1010 StackTraceElement[] stackTrace = null; 1011 StackTraceElement[] filteredStackTrace = null; 1012 StackTraceElement callerFrame = null; 1013 for (PublisherSettings settings : publisherSettings) 1014 { 1015 TraceSettings activeSettings = settings.classSettings; 1016 Map<String, TraceSettings> methodSettings = settings.methodSettings; 1017 1018 if (shouldLog(level, DebugLogCategory.PROTOCOL, 1019 activeSettings) || methodSettings != null) 1020 { 1021 if(stackTrace == null) 1022 { 1023 stackTrace = Thread.currentThread().getStackTrace(); 1024 } 1025 if (callerFrame == null) 1026 { 1027 callerFrame = getCallerFrame(stackTrace); 1028 } 1029 1030 String signature = callerFrame.getMethodName(); 1031 1032 // Specific method settings still could exist. Try getting 1033 // the settings for this method. 1034 if(methodSettings != null) 1035 { 1036 TraceSettings mSettings = methodSettings.get(signature); 1037 1038 if (mSettings == null) 1039 { 1040 // Try looking for an undecorated method name 1041 int idx = signature.indexOf('('); 1042 if (idx != -1) 1043 { 1044 mSettings = 1045 methodSettings.get(signature.substring(0, idx)); 1046 } 1047 } 1048 1049 // If this method does have a specific setting and it is not 1050 // suppose to be logged, continue. 1051 if (mSettings != null) 1052 { 1053 if(!shouldLog(level, DebugLogCategory.PROTOCOL, 1054 mSettings)) 1055 { 1056 continue; 1057 } 1058 else 1059 { 1060 activeSettings = mSettings; 1061 } 1062 } 1063 } 1064 1065 String sl = callerFrame.getFileName() + ":" + 1066 callerFrame.getLineNumber(); 1067 1068 if (filteredStackTrace == null && activeSettings.stackDepth > 0) 1069 { 1070 filteredStackTrace = 1071 DebugStackTraceFormatter.SMART_FRAME_FILTER. 1072 getFilteredStackTrace(stackTrace); 1073 } 1074 1075 settings.debugPublisher.traceProtocolElement(level, activeSettings, 1076 signature, sl, element, 1077 filteredStackTrace); 1078 } 1079 } 1080 } 1081 } 1082 1083 /** 1084 * Log raw data in the form of a ByteBuffer. 1085 * 1086 * @param level the level of the log message. 1087 * @param buffer the data to dump. 1088 */ 1089 public void debugData(LogLevel level, ByteBuffer buffer) 1090 { 1091 debugData(level, buffer.array()); 1092 } 1093 1094 /** 1095 * Gets the name of the class this tracer traces. 1096 * 1097 * @return The name of the class this tracer traces. 1098 */ 1099 public String getTracedClassName() 1100 { 1101 return className; 1102 } 1103 1104 /** 1105 * Update the cached settings of the tracer with the settings from the 1106 * provided publishers. 1107 * 1108 * @param publishers The array of publishers to obtain the settings from. 1109 */ 1110 @SuppressWarnings("unchecked") 1111 void updateSettings(DebugLogPublisher[] publishers) 1112 { 1113 PublisherSettings[] newSettings = 1114 new PublisherSettings[publishers.length]; 1115 1116 // Get the settings from all publishers. 1117 for(int i = 0; i < publishers.length; i++) 1118 { 1119 DebugLogPublisher publisher = publishers[i]; 1120 PublisherSettings settings = new PublisherSettings(); 1121 1122 settings.debugPublisher = publisher; 1123 settings.classSettings = publisher.getClassSettings(className); 1124 1125 // For some reason, the compiler doesn't see that 1126 // debugLogPublihser.getMethodSettings returns a parameterized Map. 1127 // This problem goes away if a parameterized verson of DebugLogPublisher 1128 // is used. However, we can't not use reflection to instantiate a generic 1129 // DebugLogPublisher<? extends DebugLogPublisherCfg> type. The only thing 1130 // we can do is to just supress the compiler warnings. 1131 settings.methodSettings = publisher.getMethodSettings(className); 1132 1133 newSettings[i] = settings; 1134 } 1135 1136 publisherSettings = newSettings; 1137 } 1138 1139 /** 1140 * Return the caller stack frame. 1141 * 1142 * @param stackTrace The entrie stack trace frames. 1143 * @return the caller stack frame or null if none is found on the 1144 * stack trace. 1145 */ 1146 private StackTraceElement getCallerFrame(StackTraceElement[] stackTrace) 1147 { 1148 if (stackTrace != null && stackTrace.length > 0) 1149 { 1150 // Skip leading frames debug logging classes and getStackTrace 1151 // method call frame if any. 1152 for (int i = 0; i < stackTrace.length; i++) 1153 { 1154 StackTraceElement aStackTrace = stackTrace[i]; 1155 if(aStackTrace.getClassName().startsWith("java.lang.Thread")) 1156 { 1157 continue; 1158 } 1159 1160 if (!aStackTrace.getClassName().startsWith( 1161 "org.opends.server.loggers.debug")) 1162 { 1163 return aStackTrace; 1164 } 1165 } 1166 } 1167 1168 return null; 1169 } 1170 1171 private boolean shouldLog(LogLevel messageLevel, LogCategory messageCategory, 1172 TraceSettings activeSettings) 1173 { 1174 return !(activeSettings.includeCategories != null && 1175 !activeSettings.includeCategories.contains(messageCategory)) && 1176 messageLevel.intValue() >= activeSettings.level.intValue(); 1177 1178 } 1179 }