1 19 20 package org.apache.excalibur.instrument.manager.impl; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.InputStream ; 26 import java.io.IOException ; 27 import java.io.OutputStream ; 28 import java.io.OutputStreamWriter ; 29 import java.io.PrintWriter ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Comparator ; 33 import java.util.HashMap ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Map ; 37 38 import org.apache.avalon.framework.activity.Disposable; 39 import org.apache.avalon.framework.activity.Initializable; 40 import org.apache.avalon.framework.configuration.Configurable; 41 import org.apache.avalon.framework.configuration.Configuration; 42 import org.apache.avalon.framework.configuration.ConfigurationException; 43 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 44 import org.apache.avalon.framework.container.ContainerUtil; 45 import org.apache.avalon.framework.logger.AbstractLogEnabled; 46 import org.apache.avalon.framework.logger.Logger; 47 import org.apache.avalon.framework.service.ServiceException; 48 49 import org.apache.excalibur.instrument.AbstractInstrument; 50 import org.apache.excalibur.instrument.CounterInstrument; 51 import org.apache.excalibur.instrument.Instrument; 52 import org.apache.excalibur.instrument.InstrumentManager; 53 import org.apache.excalibur.instrument.Instrumentable; 54 import org.apache.excalibur.instrument.ValueInstrument; 55 56 import org.apache.excalibur.instrument.manager.DefaultInstrumentManager; 57 import org.apache.excalibur.instrument.manager.DefaultInstrumentManagerConnector; 58 import org.apache.excalibur.instrument.manager.InstrumentableDescriptor; 59 import org.apache.excalibur.instrument.manager.InstrumentDescriptor; 60 import org.apache.excalibur.instrument.manager.InstrumentSampleDescriptor; 61 import org.apache.excalibur.instrument.manager.InstrumentSampleUtils; 62 import org.apache.excalibur.instrument.manager.NoSuchInstrumentException; 63 import org.apache.excalibur.instrument.manager.NoSuchInstrumentSampleException; 64 import org.apache.excalibur.instrument.manager.NoSuchInstrumentableException; 65 66 72 public class DefaultInstrumentManagerImpl 73 extends AbstractLogEnabled 74 implements Configurable, Initializable, Disposable, DefaultInstrumentManager, 75 Instrumentable, Runnable 76 { 77 78 private String m_name; 79 80 81 private String m_description; 82 83 85 private int m_maxLeasedSamples; 86 87 89 private int m_maxLeasedSampleSize; 90 91 93 private long m_maxLeasedSampleLease; 94 95 96 private List m_connectors = new ArrayList (); 97 98 99 private File m_stateFile; 100 101 102 private long m_stateInterval; 103 104 105 private long m_lastStateSave; 106 107 108 private Object m_semaphore = new Object (); 109 110 111 private Map m_instrumentableProxies = new HashMap (); 112 113 114 private InstrumentableProxy[] m_instrumentableProxyArray; 115 116 117 private InstrumentableDescriptor[] m_instrumentableDescriptorArray; 118 119 120 private List m_leasedInstrumentSamples = new ArrayList (); 121 122 123 private InstrumentSample[] m_leasedInstrumentSampleArray; 124 125 126 private Logger m_translationLogger; 127 128 129 private Map m_nameTranslations = new HashMap (); 130 131 132 private String [][] m_nameTranslationArray; 133 134 138 private Thread m_runner; 139 140 141 private String m_instrumentableName = "instrument-manager"; 142 143 144 private ValueInstrument m_totalMemoryInstrument; 145 146 147 private ValueInstrument m_freeMemoryInstrument; 148 149 150 private ValueInstrument m_memoryInstrument; 151 152 153 private ValueInstrument m_activeThreadCountInstrument; 154 155 156 private CounterInstrument m_registrationsInstrument; 157 158 159 private int m_instrumentableCount; 160 161 162 private ValueInstrument m_instrumentablesInstrument; 163 164 165 private int m_instrumentCount; 166 167 168 private ValueInstrument m_instrumentsInstrument; 169 170 171 private int m_permanentSampleCount; 172 173 174 private int m_leasedSampleCount; 175 176 177 private ValueInstrument m_samplesInstrument; 178 179 180 private ValueInstrument m_leasedSamplesInstrument; 181 182 183 private CounterInstrument m_leaseRequestsInstrument; 184 185 186 private CounterInstrument m_stateSavesInstrument; 187 188 189 private ValueInstrument m_stateSaveTimeInstrument; 190 191 192 private int m_stateVersion; 193 194 197 205 public DefaultInstrumentManagerImpl( String name ) 206 { 207 this(); 208 } 209 210 213 public DefaultInstrumentManagerImpl() 214 { 215 m_totalMemoryInstrument = new ValueInstrument( "total-memory" ); 217 m_freeMemoryInstrument = new ValueInstrument( "free-memory" ); 218 m_memoryInstrument = new ValueInstrument( "memory" ); 219 m_activeThreadCountInstrument = new ValueInstrument( "active-thread-count" ); 220 m_registrationsInstrument = new CounterInstrument( "instrumentable-registrations" ); 221 m_instrumentablesInstrument = new ValueInstrument( "instrumentables" ); 222 m_instrumentsInstrument = new ValueInstrument( "instruments" ); 223 m_samplesInstrument = new ValueInstrument( "samples" ); 224 m_leasedSamplesInstrument = new ValueInstrument( "leased-samples" ); 225 m_leaseRequestsInstrument = new CounterInstrument( "lease-requests" ); 226 m_stateSavesInstrument = new CounterInstrument( "state-saves" ); 227 m_stateSaveTimeInstrument = new ValueInstrument( "state-save-time" ); 228 } 229 230 233 240 public void configure( Configuration configuration ) 241 throws ConfigurationException 242 { 243 m_translationLogger = getLogger().getChildLogger( "translation" ); 244 245 try 249 { 250 registerInstrumentable( this, getInstrumentableName() ); 251 } 252 catch ( Exception e ) 253 { 254 throw new ConfigurationException( 256 "Unable to register the InstrumentManager's own instruments.", e ); 257 } 258 259 synchronized( m_semaphore ) 260 { 261 m_name = configuration.getChild( "name" ).getValue( "instrument-manager" ); 263 m_description = configuration.getChild( "description" ).getValue( m_name ); 264 265 m_maxLeasedSamples = 267 configuration.getChild( "max-leased-samples" ).getValueAsInteger( 256 ); 268 m_maxLeasedSampleSize = 269 configuration.getChild( "max-leased-sample-size" ).getValueAsInteger( 2048 ); 270 m_maxLeasedSampleLease = 1000L * 271 configuration.getChild( "max-leased-sample-lease" ).getValueAsInteger( 86400 ); 272 273 Configuration translationsConf = configuration.getChild( "translations" ); 275 Configuration[] translationConfs = translationsConf.getChildren( "translation" ); 276 for( int i = 0; i < translationConfs.length; i++ ) 277 { 278 Configuration translationConf = translationConfs[i]; 279 String source = translationConf.getAttribute( "source" ); 280 String target = translationConf.getAttribute( "target" ); 281 try 282 { 283 registerNameTranslationInner( source, target ); 284 } 285 catch ( IllegalArgumentException e ) 286 { 287 throw new ConfigurationException( e.getMessage(), translationConf ); 288 } 289 } 290 291 Configuration instrumentablesConf = configuration.getChild( "instrumentables" ); 293 Configuration[] instrumentableConfs = 294 instrumentablesConf.getChildren( "instrumentable" ); 295 for( int i = 0; i < instrumentableConfs.length; i++ ) 296 { 297 Configuration instrumentableConf = instrumentableConfs[ i ]; 298 String instrumentableName = instrumentableConf.getAttribute( "name" ); 299 300 InstrumentableProxy instrumentableProxy = 302 (InstrumentableProxy)m_instrumentableProxies.get( instrumentableName ); 303 if ( instrumentableProxy == null ) 304 { 305 instrumentableProxy = new InstrumentableProxy( 306 this, null, instrumentableName, instrumentableName ); 307 instrumentableProxy.enableLogging( getLogger() ); 308 incrementInstrumentableCount(); 309 m_instrumentableProxies.put( instrumentableName, instrumentableProxy ); 310 311 m_instrumentableProxyArray = null; 313 m_instrumentableDescriptorArray = null; 314 } 315 instrumentableProxy.configure( instrumentableConf ); 317 } 318 319 Configuration stateFileConf = configuration.getChild( "state-file" ); 321 m_stateInterval = stateFileConf.getAttributeAsLong( "interval", 60000 ); 322 323 String stateFile = stateFileConf.getValue( null ); 324 if( stateFile != null ) 325 { 326 m_stateFile = new File ( stateFile ); 327 if( m_stateFile.exists() ) 328 { 329 try 330 { 331 loadStateFromFile( m_stateFile ); 332 } 333 catch( Exception e ) 334 { 335 String msg = "Unable to load the instrument manager state. The " 336 + "configuration may have been corrupted. A backup may have been " 337 + "made in the same directory when it was saved."; 338 339 if ( getLogger().isDebugEnabled() ) 340 { 341 getLogger().error( msg, e ); 342 } 343 else 344 { 345 getLogger().error( msg + " : " + e.toString() ); 346 } 347 } 348 } 349 } 350 351 Logger connLogger = getLogger().getChildLogger( "connector" ); 353 354 Configuration connectorsConf = configuration.getChild( "connectors" ); 356 Configuration[] connectorConfs = 357 connectorsConf.getChildren( "connector" ); 358 for( int i = 0; i < connectorConfs.length; i++ ) 359 { 360 Configuration connectorConf = connectorConfs[ i ]; 361 String className = connectorConf.getAttribute( "class" ); 362 if ( className.equals( "http" ) ) 364 { 365 className = "org.apache.excalibur.instrument.manager.http." 368 + "InstrumentManagerHTTPConnector"; 369 } 370 371 try 373 { 374 Class clazz = Class.forName( className ); 375 DefaultInstrumentManagerConnector connector = 376 (DefaultInstrumentManagerConnector)clazz.newInstance(); 377 378 connector.setInstrumentManager( this ); 380 ContainerUtil.enableLogging( connector, connLogger ); 381 ContainerUtil.configure( connector, connectorConf ); 382 ContainerUtil.start( connector ); 383 if ( connector instanceof Instrumentable ) 384 { 385 Instrumentable inst = (Instrumentable)connector; 386 registerInstrumentable( inst, 387 m_instrumentableName + ".connector." + inst.getInstrumentableName() ); 388 } 389 390 m_connectors.add( connector ); 391 } 392 catch ( Exception e ) 393 { 394 String msg = "Unable to create connector because: " + e; 395 396 if ( connectorConf.getAttributeAsBoolean( "optional", true ) ) 398 { 399 getLogger().warn( msg ); 400 } 401 else 402 { 403 throw new ConfigurationException( msg ); 404 } 405 } 406 } 407 } 408 } 409 410 413 418 public void initialize() 419 throws Exception 420 { 421 if( m_runner == null ) 422 { 423 m_runner = new Thread ( this, "InstrumentManagerRunner" ); 424 m_runner.start(); 425 } 426 } 427 428 431 434 public void dispose() 435 { 436 if( m_runner != null ) 437 { 438 m_runner = null; 439 } 440 441 for ( Iterator iter = m_connectors.iterator(); iter.hasNext(); ) 443 { 444 DefaultInstrumentManagerConnector connector = 445 (DefaultInstrumentManagerConnector)iter.next(); 446 try 447 { 448 ContainerUtil.stop( connector ); 449 ContainerUtil.dispose( connector ); 450 } 451 catch ( Exception e ) 452 { 453 getLogger().error( "Encountered an unexpected error shutting down a connector", e ); 454 } 455 } 456 457 saveState(); 458 } 459 460 463 474 public void registerInstrumentable( Instrumentable instrumentable, String instrumentableName ) 475 throws Exception 476 { 477 getLogger().debug( "Registering Instrumentable: " + instrumentableName ); 478 479 m_registrationsInstrument.increment(); 480 481 synchronized( m_semaphore ) 482 { 483 int pos = instrumentableName.indexOf( '.' ); 487 if ( pos >= 0 ) 488 { 489 String parentName = instrumentableName.substring( 0, pos ); 490 String childName = 491 instrumentableName.substring( pos + 1 ); 492 InstrumentableProxy instrumentableProxy = 493 (InstrumentableProxy)m_instrumentableProxies.get( parentName ); 494 if ( instrumentableProxy == null ) 495 { 496 instrumentableProxy = new InstrumentableProxy( 498 this, null, parentName, parentName ); 499 instrumentableProxy.enableLogging( getLogger() ); 500 incrementInstrumentableCount(); 501 m_instrumentableProxies.put( parentName, instrumentableProxy ); 504 505 m_instrumentableProxyArray = null; 507 m_instrumentableDescriptorArray = null; 508 509 registerDummyInstrumentableInner( 511 instrumentable, instrumentableProxy, parentName, childName ); 512 } 513 else 514 { 515 registerDummyInstrumentableInner( 517 instrumentable, instrumentableProxy, parentName, childName ); 518 } 519 } else { 520 InstrumentableProxy instrumentableProxy = 525 (InstrumentableProxy)m_instrumentableProxies.get( instrumentableName ); 526 if( instrumentableProxy == null ) 527 { 528 instrumentableProxy = new InstrumentableProxy( 530 this, null, instrumentableName, instrumentableName ); 531 instrumentableProxy.enableLogging( getLogger() ); 532 incrementInstrumentableCount(); 533 m_instrumentableProxies.put( instrumentableName, instrumentableProxy ); 536 537 m_instrumentableProxyArray = null; 539 m_instrumentableDescriptorArray = null; 540 541 registerInstrumentableInner( 543 instrumentable, instrumentableProxy, instrumentableName ); 544 } 545 else 546 { 547 registerInstrumentableInner( 549 instrumentable, instrumentableProxy, instrumentableName ); 550 } 551 } 552 } 553 554 stateChanged(); 555 } 556 557 560 565 public String getName() 566 { 567 return m_name; 568 } 569 570 575 public String getDescription() 576 { 577 return m_description; 578 } 579 580 601 public void registerNameTranslation( String source, String target ) 602 throws IllegalArgumentException 603 { 604 synchronized( m_semaphore ) 605 { 606 registerNameTranslationInner( source, target ); 607 } 608 } 609 610 621 public InstrumentableDescriptor getInstrumentableDescriptor( String instrumentableName ) 622 throws NoSuchInstrumentableException 623 { 624 InstrumentableProxy proxy = getInstrumentableProxy( instrumentableName ); 625 if( proxy == null ) 626 { 627 throw new NoSuchInstrumentableException( 628 "No instrumentable can be found using name: " + instrumentableName ); 629 } 630 631 return proxy.getDescriptor(); 632 } 633 634 640 public InstrumentableDescriptor[] getInstrumentableDescriptors() 641 { 642 InstrumentableDescriptor[] descriptors = m_instrumentableDescriptorArray; 643 if( descriptors == null ) 644 { 645 descriptors = updateInstrumentableDescriptorArray(); 646 } 647 return descriptors; 648 } 649 650 661 public InstrumentableDescriptor locateInstrumentableDescriptor( String instrumentableName ) 662 throws NoSuchInstrumentableException 663 { 664 InstrumentableProxy instrumentableProxy = 665 locateDeepestInstrumentableProxy( instrumentableName ); 666 if ( instrumentableProxy != null ) 667 { 668 if ( instrumentableProxy.getName().equals( instrumentableName ) ) 669 { 670 return instrumentableProxy.getDescriptor(); 672 } 673 } 674 675 throw new NoSuchInstrumentableException( 677 "No instrumentable can be found with the name: " + instrumentableName ); 678 } 679 680 691 public InstrumentDescriptor locateInstrumentDescriptor( String instrumentName ) 692 throws NoSuchInstrumentException 693 { 694 InstrumentableProxy instrumentableProxy = 695 locateDeepestInstrumentableProxy( instrumentName ); 696 if ( instrumentableProxy != null ) 697 { 698 InstrumentProxy instrumentProxy = 700 instrumentableProxy.getInstrumentProxy( instrumentName ); 701 if ( instrumentProxy != null ) 702 { 703 if ( instrumentProxy.getName().equals( instrumentName ) ) 704 { 705 return instrumentProxy.getDescriptor(); 707 } 708 } 709 } 710 711 throw new NoSuchInstrumentException( 713 "No instrument can be found with the name: " + instrumentName ); 714 } 715 716 727 public InstrumentSampleDescriptor locateInstrumentSampleDescriptor( String sampleName ) 728 throws NoSuchInstrumentSampleException 729 { 730 InstrumentableProxy instrumentableProxy = 731 locateDeepestInstrumentableProxy( sampleName ); 732 if ( instrumentableProxy != null ) 733 { 734 InstrumentProxy instrumentProxy = 736 instrumentableProxy.getInstrumentProxy( sampleName ); 737 if ( instrumentProxy != null ) 738 { 739 InstrumentSample sample = instrumentProxy.getInstrumentSample( sampleName ); 741 if ( sample != null ) 742 { 743 if ( sample.getName().equals( sampleName ) ) 744 { 745 return sample.getDescriptor(); 747 } 748 } 749 } 750 } 751 752 throw new NoSuchInstrumentSampleException( 754 "No instrument sample can be found with the name: " + sampleName ); 755 } 756 757 767 public int getStateVersion() 768 { 769 return m_stateVersion; 770 } 771 772 775 public void invokeGarbageCollection() 776 { 777 System.gc(); 778 } 779 780 785 public int getLeaseSampleCount() 786 { 787 return m_leasedSampleCount; 788 } 789 790 795 public int getMaxLeasedSamples() 796 { 797 return m_maxLeasedSamples; 798 } 799 800 805 public int getMaxLeasedSampleSize() 806 { 807 return m_maxLeasedSampleSize; 808 } 809 810 816 public long getMaxLeasedSampleLease() 817 { 818 return m_maxLeasedSampleLease; 819 } 820 821 824 837 public void setInstrumentableName( String name ) 838 { 839 m_instrumentableName = name; 840 } 841 842 847 public String getInstrumentableName() 848 { 849 return m_instrumentableName; 850 } 851 852 863 public Instrument[] getInstruments() 864 { 865 return new Instrument[] 866 { 867 m_totalMemoryInstrument, 868 m_freeMemoryInstrument, 869 m_memoryInstrument, 870 m_activeThreadCountInstrument, 871 m_registrationsInstrument, 872 m_instrumentablesInstrument, 873 m_instrumentsInstrument, 874 m_samplesInstrument, 875 m_leasedSamplesInstrument, 876 m_leaseRequestsInstrument, 877 m_stateSavesInstrument, 878 m_stateSaveTimeInstrument 879 }; 880 } 881 882 891 public Instrumentable[] getChildInstrumentables() 892 { 893 return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY; 894 } 895 896 899 public void run() 900 { 901 while( m_runner != null ) 902 { 903 try 904 { 905 Thread.sleep( 1000 ); 906 907 memoryInstruments(); 908 threadInstruments(); 909 testInstrumentSampleLeases(); 910 911 long now = System.currentTimeMillis(); 913 if( now - m_lastStateSave >= m_stateInterval ) 914 { 915 saveState(); 916 } 917 } 918 catch( Throwable t ) 919 { 920 getLogger().error( "Encountered an unexpected error.", t ); 921 } 922 } 923 } 924 925 928 935 public void loadStateFromFile( File stateFile ) 936 throws Exception 937 { 938 long now = System.currentTimeMillis(); 939 getLogger().debug( "Loading Instrument Manager state from: " + 940 stateFile.getAbsolutePath() ); 941 942 FileInputStream is = new FileInputStream ( stateFile ); 943 try 944 { 945 loadStateFromStream( is, stateFile.getCanonicalPath() ); 946 } 947 finally 948 { 949 is.close(); 950 } 951 952 getLogger().debug( "Loading Instrument Manager state took " + 953 ( System.currentTimeMillis() - now ) + "ms." ); 954 } 955 956 963 public void loadStateFromStream( InputStream is ) 964 throws Exception 965 { 966 loadStateFromStream( is, null ); 967 } 968 969 978 private void loadStateFromStream( InputStream is, String location ) 979 throws Exception 980 { 981 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 983 Configuration stateConfig; 984 if ( location == null ) 985 { 986 stateConfig = builder.build( is ); 987 } 988 else 989 { 990 stateConfig = builder.build( is, location ); 991 } 992 993 loadStateFromConfiguration( stateConfig ); 994 } 995 996 1004 public void loadStateFromConfiguration( Configuration state ) 1005 throws ConfigurationException 1006 { 1007 loadStateFromConfiguration( state, null ); 1008 } 1009 1010 private void loadStateFromConfiguration( Configuration state, String parentName ) 1011 throws ConfigurationException 1012 { 1013 1017 Configuration[] instrumentableConfs = state.getChildren( "instrumentable" ); 1021 for( int i = 0; i < instrumentableConfs.length; i++ ) 1022 { 1023 loadStateFromConfiguration( 1024 instrumentableConfs[i], instrumentableConfs[i].getAttribute( "name", null ) ); 1025 } 1026 Configuration[] instrumentConfs = state.getChildren( "instrument" ); 1027 for( int i = 0; i < instrumentConfs.length; i++ ) 1028 { 1029 loadStateFromConfiguration( 1030 instrumentConfs[i], instrumentConfs[i].getAttribute( "name", null ) ); 1031 } 1032 1033 Configuration[] sampleConfs = state.getChildren( "sample" ); 1035 for( int i = 0; i < sampleConfs.length; i++ ) 1036 { 1037 Configuration sampleConf = sampleConfs[i]; 1038 1039 String sampleName = sampleConf.getAttribute( "name", null ); 1041 if ( sampleName == null ) 1042 { 1043 if ( parentName == null ) 1046 { 1047 throw new ConfigurationException( 1048 "Unable to resolve sample name.", sampleConf ); 1049 } 1050 1051 int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType( 1052 sampleConf.getAttribute( "type" ) ); 1053 long sampleInterval = sampleConf.getAttributeAsLong( "interval" ); 1054 int sampleSize = sampleConf.getAttributeAsInteger( "size" ); 1055 1056 sampleName = InstrumentSampleUtils.generateFullInstrumentSampleName( 1057 parentName, sampleType, sampleInterval, sampleSize ); 1058 } 1059 sampleName = getTranslatedName( sampleName ); 1061 1062 long now = System.currentTimeMillis(); 1064 long leaseExpirationTime = sampleConf.getAttributeAsLong( "lease-expiration", 0 ); 1065 if ( leaseExpirationTime == 0 ) 1066 { 1067 1072 InstrumentProxy instrumentProxy = getInstrumentProxyForSample( sampleName, false ); 1074 if ( instrumentProxy == null ) 1075 { 1076 getLogger().info( 1078 "Skipping old permantent sample from state due to missing instrument: " 1079 + sampleName ); 1080 } 1081 else 1082 { 1083 InstrumentSample sample = instrumentProxy.loadSampleState( sampleConf ); 1086 if ( sample == null ) 1087 { 1088 getLogger().info( 1089 "Skipping old permantent sample from state: " + sampleName ); 1090 } 1091 else 1092 { 1093 if ( getLogger().isDebugEnabled() ) 1094 { 1095 getLogger().debug( "Load permanent sample state: " + sampleName ); 1096 } 1097 } 1098 } 1099 } 1100 else if ( leaseExpirationTime > now ) 1101 { 1102 1107 InstrumentProxy instrumentProxy = getInstrumentProxyForSample( sampleName, true ); 1109 1110 instrumentProxy.loadSampleState( sampleConf ); 1112 1113 if ( getLogger().isDebugEnabled() ) 1114 { 1115 getLogger().debug( "Load leased sample state : " + sampleName ); 1116 } 1117 } 1118 else 1119 { 1120 if ( getLogger().isDebugEnabled() ) 1122 { 1123 getLogger().debug( "Skip expired sample state: " + sampleName ); 1124 } 1125 } 1126 } 1127 1128 } 1130 1131 1140 public void saveStateToFile( File stateFile ) 1141 throws Exception 1142 { 1143 long now = System.currentTimeMillis(); 1144 getLogger().debug( "Saving Instrument Manager state to: " + stateFile.getAbsolutePath() ); 1145 1146 File tempFile = new File ( stateFile.getAbsolutePath() + "." + now + ".temp" ); 1149 boolean success = false; 1150 FileOutputStream fos = new FileOutputStream ( tempFile ); 1151 try 1152 { 1153 saveStateToStream( fos ); 1154 success = true; 1155 } 1156 finally 1157 { 1158 fos.close(); 1159 1160 File renameFile = null; 1161 try 1162 { 1163 if ( success ) 1164 { 1165 if ( stateFile.exists() ) 1167 { 1168 renameFile = 1169 new File ( stateFile.getAbsolutePath() + "." + now + ".backup" ); 1170 if ( !stateFile.renameTo( renameFile ) ) 1171 { 1172 throw new IOException ( 1173 "Unable to rename the old instrument state file from '" 1174 + stateFile.getAbsolutePath() + "' to '" 1175 + renameFile.getAbsolutePath() + "'" ); 1176 } 1177 } 1178 1179 if ( !tempFile.renameTo( stateFile ) ) 1181 { 1182 if ( renameFile != null ) 1183 { 1184 if ( !renameFile.renameTo( stateFile ) ) 1186 { 1187 getLogger().error( 1189 "Unable to save the instrument state. The last known state " 1190 + "file is backed up as: " + renameFile.getAbsolutePath() ); 1191 1192 renameFile = null; 1194 } 1195 } 1196 1197 throw new IOException ( 1198 "Unable to rename the new instrument state file from '" 1199 + tempFile.getAbsolutePath() + "' to '" 1200 + stateFile.getAbsolutePath() + "'" ); 1201 } 1202 else 1203 { 1204 tempFile = null; 1206 } 1207 } 1208 } 1209 finally 1210 { 1211 if ( ( tempFile != null ) && tempFile.exists() ) 1213 { 1214 if ( !tempFile.delete() ) 1215 { 1216 getLogger().warn( "Unable to delete temporary state file: " 1217 + tempFile.getAbsolutePath() ); 1218 } 1219 } 1220 1221 if ( ( renameFile != null ) && renameFile.exists() ) 1223 { 1224 if ( !renameFile.delete() ) 1225 { 1226 getLogger().warn( "Unable to delete temporary state file: " 1227 + renameFile.getAbsolutePath() ); 1228 } 1229 } 1230 } 1231 } 1232 1233 getLogger().debug( "Saving Instrument Manager state took " + 1234 ( System.currentTimeMillis() - now ) + "ms." ); 1235 } 1236 1237 1244 public void saveStateToStream( OutputStream os ) 1245 throws Exception 1246 { 1247 PrintWriter out = new PrintWriter ( new OutputStreamWriter ( os, "UTF-8" ) ); 1254 1255 out.println( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ); 1257 out.println( "<instrument-manager-state>" ); 1258 1259 InstrumentableProxy[] instrumentableProxies = m_instrumentableProxyArray; 1260 if( instrumentableProxies == null ) 1261 { 1262 instrumentableProxies = updateInstrumentableProxyArray(); 1263 } 1264 1265 for( int i = 0; i < instrumentableProxies.length; i++ ) 1266 { 1267 instrumentableProxies[i].writeState( out ); 1268 } 1269 1270 out.println( "</instrument-manager-state>" ); 1272 1273 out.flush(); 1277 } 1278 1279 1282 1288 void registerLeasedInstrumentSample( InstrumentSample instrumentSample ) 1289 { 1290 synchronized( m_leasedInstrumentSamples ) 1291 { 1292 if ( instrumentSample.getLeaseExpirationTime() <= 0 ) 1294 { 1295 throw new IllegalStateException ( "Got an InstrumentSample that was not leased." ); 1296 } 1297 1298 if ( m_leasedInstrumentSamples.indexOf( instrumentSample ) < 0 ) 1300 { 1301 m_leasedInstrumentSamples.add( instrumentSample ); 1302 m_leasedInstrumentSampleArray = null; 1303 } 1304 } 1305 } 1306 1307 1310 void stateChanged() 1311 { 1312 m_stateVersion++; 1313 } 1314 1315 1318 void incrementInstrumentableCount() 1319 { 1320 int count; 1321 synchronized( m_semaphore ) 1322 { 1323 count = ++m_instrumentableCount; 1324 } 1325 m_instrumentablesInstrument.setValue( count ); 1326 } 1327 1328 1331 void incrementInstrumentCount() 1332 { 1333 int count; 1334 synchronized( m_semaphore ) 1335 { 1336 count = ++m_instrumentCount; 1337 } 1338 m_instrumentsInstrument.setValue( count ); 1339 } 1340 1341 1344 void incrementPermanentSampleCount() 1345 { 1346 int count; 1347 synchronized( m_semaphore ) 1348 { 1349 count = ++m_permanentSampleCount + m_leasedSampleCount; 1350 } 1351 m_samplesInstrument.setValue( count ); 1352 } 1353 1354 1357 void incrementLeasedSampleCount() 1358 { 1359 int count; 1360 int leasedCount; 1361 synchronized( m_semaphore ) 1362 { 1363 leasedCount = ++m_leasedSampleCount; 1364 count = m_permanentSampleCount + m_leasedSampleCount; 1365 } 1366 m_samplesInstrument.setValue( count ); 1367 m_leasedSamplesInstrument.setValue( leasedCount ); 1368 } 1369 1370 1373 void decrementLeasedSampleCount() 1374 { 1375 int count; 1376 int leasedCount; 1377 synchronized( m_semaphore ) 1378 { 1379 leasedCount = --m_leasedSampleCount; 1380 count = m_permanentSampleCount + m_leasedSampleCount; 1381 } 1382 m_samplesInstrument.setValue( count ); 1383 m_leasedSamplesInstrument.setValue( leasedCount ); 1384 } 1385 1386 1389 void incrementLeaseRequests() 1390 { 1391 m_leaseRequestsInstrument.increment(); 1392 } 1393 1394 1397 1400 private void saveState() 1401 { 1402 long now = System.currentTimeMillis(); 1403 1404 m_lastStateSave = now; 1406 1407 if( m_stateFile == null ) 1408 { 1409 return; 1410 } 1411 1412 try 1413 { 1414 saveStateToFile( m_stateFile ); 1415 } 1416 catch ( Exception e ) 1417 { 1418 String msg = "Unable to save the Instrument Manager state"; 1419 if ( getLogger().isDebugEnabled() ) 1420 { 1421 getLogger().warn( msg, e ); 1422 } 1423 else 1424 { 1425 getLogger().warn( msg + " : " + e.toString() ); 1426 } 1427 } 1428 1429 m_stateSavesInstrument.increment(); 1430 m_stateSaveTimeInstrument.setValue( (int)( System.currentTimeMillis() - now ) ); 1431 } 1432 1433 1440 private String [][] updateNameTranslationArray() 1441 { 1442 synchronized( m_semaphore ) 1443 { 1444 String [][] nameTranslations = new String [m_nameTranslations.size()][2]; 1445 int i = 0; 1446 for ( Iterator iter = m_nameTranslations.entrySet().iterator(); iter.hasNext(); i++ ) 1447 { 1448 Map.Entry entry = (Map.Entry )iter.next(); 1449 nameTranslations[i][0] = (String )entry.getKey(); 1450 nameTranslations[i][1] = (String )entry.getValue(); 1451 } 1452 1453 m_nameTranslationArray = nameTranslations; 1456 1457 return nameTranslations; 1458 } 1459 } 1460 1461 1470 String getTranslatedName( String name ) 1471 { 1472 String [][] nameTranslations = m_nameTranslationArray; 1473 if( nameTranslations == null ) 1474 { 1475 nameTranslations = updateNameTranslationArray(); 1476 } 1477 1478 for ( int i = 0; i < nameTranslations.length; i++ ) 1479 { 1480 String [] nameTranslation = nameTranslations[i]; 1481 1482 if ( name.startsWith( nameTranslation[0] ) ) 1483 { 1484 if ( name.equals( nameTranslation[0] ) ) 1486 { 1487 String newName = nameTranslation[1]; 1489 1490 if ( m_translationLogger.isDebugEnabled() ) 1491 { 1492 m_translationLogger.debug( 1493 "Translate \"" + name + "\" to \"" + newName + "\"" ); 1494 } 1495 1496 return newName; 1497 } 1498 else if ( nameTranslation[0].endsWith( "." ) ) 1499 { 1500 String newName = 1502 nameTranslation[1] + name.substring( nameTranslation[0].length() ); 1503 1504 if ( m_translationLogger.isDebugEnabled() ) 1505 { 1506 m_translationLogger.debug( 1507 "Translate \"" + name + "\" to \"" + newName + "\"" ); 1508 } 1509 1510 return newName; 1511 } 1512 else 1513 { 1514 } 1517 } 1518 } 1519 1520 return name; 1522 } 1523 1524 1526 private InstrumentableProxy getInstrumentableProxy( String instrumentableName, boolean create ) 1527 { 1528 int pos = instrumentableName.lastIndexOf( '.' ); 1531 if ( pos <= 0 ) 1532 { 1533 InstrumentableProxy instrumentableProxy; 1535 synchronized( m_semaphore ) 1536 { 1537 instrumentableProxy = 1538 (InstrumentableProxy)m_instrumentableProxies.get( instrumentableName ); 1539 1540 if ( ( instrumentableProxy == null ) && create ) 1541 { 1542 instrumentableProxy = new InstrumentableProxy( 1545 this, null, instrumentableName, instrumentableName ); 1546 instrumentableProxy.enableLogging( getLogger() ); 1547 incrementInstrumentableCount(); 1548 m_instrumentableProxies.put( instrumentableName, instrumentableProxy ); 1549 1550 m_instrumentableProxyArray = null; 1552 m_instrumentableDescriptorArray = null; 1553 } 1554 } 1555 1556 return instrumentableProxy; 1558 } 1559 else 1560 { 1561 String parentInstrumentableName = instrumentableName.substring( 0, pos ); 1562 1563 InstrumentableProxy parentInstrumentableProxy = 1565 getInstrumentableProxy( parentInstrumentableName, create ); 1566 if ( parentInstrumentableProxy == null ) 1567 { 1568 return null; 1571 } 1572 1573 return parentInstrumentableProxy.getChildInstrumentableProxy( 1575 instrumentableName, create ); 1576 } 1577 } 1578 1579 1582 private InstrumentProxy getInstrumentProxy( String instrumentName, boolean create ) 1583 throws IllegalArgumentException 1584 { 1585 int pos = instrumentName.lastIndexOf( '.' ); 1588 if ( pos <= 0 ) 1589 { 1590 throw new IllegalArgumentException ( 1591 "\"" + instrumentName + "\" is not a valid instrument name." ); 1592 } 1593 String instrumentableName = instrumentName.substring( 0, pos ); 1594 1595 InstrumentableProxy instrumentableProxy = 1597 getInstrumentableProxy( instrumentableName, create ); 1598 if ( instrumentableProxy == null ) 1599 { 1600 return null; 1603 } 1604 1605 return instrumentableProxy.getInstrumentProxy( instrumentName, create ); 1607 } 1608 1609 1612 private InstrumentProxy getInstrumentProxyForSample( String sampleName, boolean create ) 1613 throws IllegalArgumentException 1614 { 1615 int pos = sampleName.lastIndexOf( '.' ); 1618 if ( pos <= 0 ) 1619 { 1620 throw new IllegalArgumentException ( 1621 "\"" + sampleName + "\" is not a valid instrument sample name." ); 1622 } 1623 String instrumentName = sampleName.substring( 0, pos ); 1624 1625 return getInstrumentProxy( instrumentName, create ); 1627 } 1628 1629 1637 private InstrumentableProxy getInstrumentableProxy( String instrumentableName ) 1638 { 1639 String name = instrumentableName; 1640 while( true ) 1641 { 1642 InstrumentableProxy proxy = (InstrumentableProxy)m_instrumentableProxies.get( name ); 1643 if( proxy != null ) 1644 { 1645 return proxy; 1646 } 1647 1648 int pos = name.lastIndexOf( '.' ); 1650 if( pos > 0 ) 1651 { 1652 name = name.substring( 0, pos ); 1653 } 1654 else 1655 { 1656 return null; 1657 } 1658 } 1659 } 1660 1661 1671 private InstrumentableProxy locateDeepestInstrumentableProxy( String instrumentableName ) 1672 { 1673 InstrumentableProxy deepestProxy = null; 1674 InstrumentableProxy proxy = getInstrumentableProxy( instrumentableName ); 1676 1677 while ( proxy != null ) 1679 { 1680 deepestProxy = proxy; 1681 1682 proxy = deepestProxy.getChildInstrumentableProxy( instrumentableName ); 1683 } 1684 1685 return deepestProxy; 1686 } 1687 1688 1691 private void memoryInstruments() 1692 { 1693 Runtime runtime = null; 1695 long totalMemory = -1; 1696 long freeMemory = -1; 1697 1698 if( m_totalMemoryInstrument.isActive() ) 1700 { 1701 runtime = Runtime.getRuntime(); 1702 totalMemory = runtime.totalMemory(); 1703 m_totalMemoryInstrument.setValue( (int)totalMemory ); 1704 } 1705 1706 if( m_freeMemoryInstrument.isActive() ) 1708 { 1709 if( runtime == null ) 1710 { 1711 runtime = Runtime.getRuntime(); 1712 } 1713 freeMemory = runtime.freeMemory(); 1714 m_freeMemoryInstrument.setValue( (int)freeMemory ); 1715 } 1716 1717 if( m_memoryInstrument.isActive() ) 1719 { 1720 if( runtime == null ) 1721 { 1722 runtime = Runtime.getRuntime(); 1723 } 1724 if( totalMemory < 0 ) 1725 { 1726 totalMemory = runtime.totalMemory(); 1727 } 1728 if( freeMemory < 0 ) 1729 { 1730 freeMemory = runtime.freeMemory(); 1731 } 1732 m_memoryInstrument.setValue( (int)( totalMemory - freeMemory ) ); 1733 } 1734 } 1735 1736 1739 private void threadInstruments() 1740 { 1741 if( m_activeThreadCountInstrument.isActive() ) 1742 { 1743 ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); 1745 ThreadGroup parent; 1746 while( ( parent = threadGroup.getParent() ) != null ) 1747 { 1748 threadGroup = parent; 1749 } 1750 1751 m_activeThreadCountInstrument.setValue( threadGroup.activeCount() ); 1752 } 1753 } 1754 1755 1760 private void testInstrumentSampleLeases() 1761 { 1762 long now = System.currentTimeMillis(); 1763 1764 InstrumentSample[] samples; 1765 synchronized( m_leasedInstrumentSamples ) 1766 { 1767 samples = m_leasedInstrumentSampleArray; 1768 if ( samples == null ) 1769 { 1770 m_leasedInstrumentSampleArray = 1771 new InstrumentSample[ m_leasedInstrumentSamples.size() ]; 1772 m_leasedInstrumentSamples.toArray( m_leasedInstrumentSampleArray ); 1773 samples = m_leasedInstrumentSampleArray; 1774 } 1775 } 1776 1777 for ( int i = 0; i < samples.length; i++ ) 1778 { 1779 InstrumentSample sample = samples[i]; 1780 long expire = sample.getLeaseExpirationTime(); 1781 if ( now >= expire ) 1782 { 1783 InstrumentProxy instrument = sample.getInstrumentProxy(); 1785 instrument.removeInstrumentSample( sample ); 1786 sample.expire(); 1787 1788 m_leasedInstrumentSamples.remove( sample ); 1789 m_leasedInstrumentSampleArray = null; 1790 } 1791 } 1792 } 1793 1794 1800 private InstrumentableProxy[] updateInstrumentableProxyArray() 1801 { 1802 synchronized( m_semaphore ) 1803 { 1804 InstrumentableProxy[] instrumentableProxyArray = 1805 new InstrumentableProxy[ m_instrumentableProxies.size() ]; 1806 m_instrumentableProxies.values().toArray( instrumentableProxyArray ); 1807 1808 Arrays.sort( instrumentableProxyArray, new Comparator () 1812 { 1813 public int compare( Object o1, Object o2 ) 1814 { 1815 return ((InstrumentableProxy)o1).getDescription(). 1816 compareTo( ((InstrumentableProxy)o2).getDescription() ); 1817 } 1818 1819 public boolean equals( Object obj ) 1820 { 1821 return false; 1822 } 1823 } ); 1824 1825 m_instrumentableProxyArray = instrumentableProxyArray; 1828 1829 return instrumentableProxyArray; 1830 } 1831 } 1832 1833 1839 private InstrumentableDescriptor[] updateInstrumentableDescriptorArray() 1840 { 1841 synchronized( m_semaphore ) 1842 { 1843 InstrumentableProxy[] instrumentableProxyArray = m_instrumentableProxyArray; 1847 if ( instrumentableProxyArray == null ) 1848 { 1849 instrumentableProxyArray = updateInstrumentableProxyArray(); 1850 } 1851 1852 InstrumentableDescriptor[] instrumentableDescriptorArray = 1853 new InstrumentableDescriptor[ instrumentableProxyArray.length ]; 1854 for( int i = 0; i < instrumentableProxyArray.length; i++ ) 1855 { 1856 instrumentableDescriptorArray[ i ] = instrumentableProxyArray[ i ].getDescriptor(); 1857 } 1858 1859 m_instrumentableDescriptorArray = instrumentableDescriptorArray; 1862 1863 return instrumentableDescriptorArray; 1864 } 1865 } 1866 1867 1889 private void registerNameTranslationInner( String source, String target ) 1890 throws IllegalArgumentException 1891 { 1892 if ( !source.endsWith( "." ) ) 1893 { 1894 throw new IllegalArgumentException ( "The translation source must end with a '.'." ); 1895 } 1896 if ( !target.endsWith( "." ) ) 1897 { 1898 throw new IllegalArgumentException ( "The translation target must end with a '.'." ); 1899 } 1900 1901 if ( source.startsWith( "." ) || ( source.indexOf( ".." ) >= 0 ) ) 1903 { 1904 throw new IllegalArgumentException ( 1905 "The translation source is invalid: \"" + source + "\"." ); 1906 } 1907 if ( target.startsWith( "." ) || ( target.indexOf( ".." ) >= 0 ) ) 1908 { 1909 throw new IllegalArgumentException ( 1910 "The translation target is invalid: \"" + target + "\"." ); 1911 } 1912 1913 m_nameTranslations.put( source, target ); 1914 m_nameTranslationArray = null; 1915 } 1916 1917 1931 private void registerDummyInstrumentableInner( Instrumentable instrumentable, 1932 InstrumentableProxy instrumentableProxy, 1933 String instrumentableName, 1934 String childName ) 1935 throws Exception 1936 { 1937 int pos = childName.indexOf( '.' ); 1941 if ( pos >= 0 ) 1942 { 1943 String newParentName = childName.substring( 0, pos ); 1944 String newChildName = 1945 childName.substring( pos + 1 ); 1946 1947 String fullChildName = instrumentableName + "." + newParentName; 1948 1949 getLogger().debug( "Registering Child Instrumentable: " + fullChildName ); 1950 1951 InstrumentableProxy proxy = 1953 instrumentableProxy.getChildInstrumentableProxy( fullChildName ); 1954 if( proxy == null ) 1955 { 1956 proxy = new InstrumentableProxy( 1957 this, instrumentableProxy, fullChildName, newParentName ); 1958 proxy.enableLogging( getLogger() ); 1959 incrementInstrumentableCount(); 1960 1961 instrumentableProxy.addChildInstrumentableProxy( proxy ); 1962 } 1963 1964 registerDummyInstrumentableInner( instrumentable, proxy, fullChildName, newChildName ); 1966 } 1967 else 1968 { 1969 String fullChildName = instrumentableName + "." + childName; 1971 1972 getLogger().debug( "Registering Child Instrumentable: " + fullChildName ); 1973 1974 InstrumentableProxy proxy = 1976 instrumentableProxy.getChildInstrumentableProxy( fullChildName ); 1977 if( proxy == null ) 1978 { 1979 proxy = new InstrumentableProxy( 1980 this, instrumentableProxy, fullChildName, childName ); 1981 proxy.enableLogging( getLogger() ); 1982 incrementInstrumentableCount(); 1983 1984 instrumentableProxy.addChildInstrumentableProxy( proxy ); 1985 } 1986 1987 registerInstrumentableInner( instrumentable, proxy, fullChildName ); 1989 } 1990 } 1991 1992 1998 private void registerInstrumentableInner( Instrumentable instrumentable, 1999 InstrumentableProxy instrumentableProxy, 2000 String instrumentableName ) 2001 throws Exception 2002 { 2003 instrumentableProxy.setRegistered(); 2005 2006 Instrument[] instruments = instrumentable.getInstruments(); 2008 for( int i = 0; i < instruments.length; i++ ) 2009 { 2010 Instrument instrument = instruments[ i ]; 2011 String instrumentName = instrument.getInstrumentName(); 2012 String fullInstrumentName = instrumentableName + "." + instrumentName; 2013 2014 getLogger().debug( "Registering Instrument: " + fullInstrumentName ); 2015 2016 InstrumentProxy proxy = instrumentableProxy.getInstrumentProxy( fullInstrumentName ); 2018 if( proxy == null ) 2019 { 2020 proxy = new InstrumentProxy( 2021 instrumentableProxy, fullInstrumentName, instrumentName ); 2022 proxy.enableLogging( getLogger() ); 2023 incrementInstrumentCount(); 2024 2025 if( instrument instanceof CounterInstrument ) 2028 { 2029 proxy.setType( DefaultInstrumentManager.INSTRUMENT_TYPE_COUNTER ); 2030 } 2031 else if( instrument instanceof ValueInstrument ) 2032 { 2033 proxy.setType( DefaultInstrumentManager.INSTRUMENT_TYPE_VALUE ); 2034 } 2035 else 2036 { 2037 throw new ServiceException( fullInstrumentName, "Encountered an unknown " 2038 + "Instrument type for the Instrument with key, " 2039 + fullInstrumentName + ": " + instrument.getClass().getName() ); 2040 } 2041 2042 proxy.setRegistered(); 2044 2045 ( (AbstractInstrument)instrument ).setInstrumentProxy( proxy ); 2047 2048 instrumentableProxy.addInstrumentProxy( proxy ); 2049 } 2050 else 2051 { 2052 if( instrument instanceof CounterInstrument ) 2055 { 2056 switch( proxy.getType() ) 2057 { 2058 case DefaultInstrumentManager.INSTRUMENT_TYPE_COUNTER: 2059 ( (AbstractInstrument)instrument ).setInstrumentProxy( proxy ); 2062 break; 2063 2064 case DefaultInstrumentManager.INSTRUMENT_TYPE_NONE: 2065 proxy.setType( DefaultInstrumentManager.INSTRUMENT_TYPE_COUNTER ); 2067 2068 ( (AbstractInstrument)instrument ).setInstrumentProxy( proxy ); 2070 break; 2071 2072 default: 2073 throw new ServiceException( instrumentName, 2074 "Instruments of more than one type are assigned to name: " 2075 + instrumentName ); 2076 } 2077 } 2078 else if( instrument instanceof ValueInstrument ) 2079 { 2080 switch( proxy.getType() ) 2081 { 2082 case DefaultInstrumentManager.INSTRUMENT_TYPE_VALUE: 2083 ( (AbstractInstrument)instrument ).setInstrumentProxy( proxy ); 2086 break; 2087 2088 case DefaultInstrumentManager.INSTRUMENT_TYPE_NONE: 2089 proxy.setType( DefaultInstrumentManager.INSTRUMENT_TYPE_VALUE ); 2091 2092 ( (AbstractInstrument)instrument ).setInstrumentProxy( proxy ); 2094 break; 2095 2096 default: 2097 throw new ServiceException( instrumentName, 2098 "Instruments of more than one type are assigned to name: " 2099 + instrumentName ); 2100 } 2101 } 2102 else 2103 { 2104 throw new ServiceException( instrumentName, "Encountered an unknown Instrument " 2105 + "type for the Instrument with name, " + instrumentName + ": " 2106 + instrument.getClass().getName() ); 2107 } 2108 2109 proxy.setRegistered(); 2111 } 2112 } 2113 2114 Instrumentable[] children = instrumentable.getChildInstrumentables(); 2116 for ( int i = 0; i < children.length; i++ ) 2117 { 2118 Instrumentable child = children[i]; 2119 2120 String childName = child.getInstrumentableName(); 2122 if( childName == null ) 2123 { 2124 String msg = "The getInstrumentableName() method of a child Instrumentable of " + 2125 instrumentableName + " returned null. Child class: " + 2126 child.getClass().getName(); 2127 getLogger().debug( msg ); 2128 throw new ServiceException( instrumentable.getClass().getName(), msg ); 2129 } 2130 2131 String fullChildName = instrumentableName + "." + childName; 2132 2133 getLogger().debug( "Registering Child Instrumentable: " + fullChildName ); 2134 2135 InstrumentableProxy proxy = 2137 instrumentableProxy.getChildInstrumentableProxy( fullChildName ); 2138 if( proxy == null ) 2139 { 2140 proxy = new InstrumentableProxy( 2141 this, instrumentableProxy, fullChildName, childName ); 2142 proxy.enableLogging( getLogger() ); 2143 incrementInstrumentableCount(); 2144 2145 instrumentableProxy.addChildInstrumentableProxy( proxy ); 2146 } 2147 2148 registerInstrumentableInner( child, proxy, fullChildName ); 2150 } 2151 } 2152} 2153 2154 | Popular Tags |