4747
4848import org .exist .start .CompatibleJavaVersionCheck ;
4949import org .exist .start .StartException ;
50+ import org .exist .util .FileUtils ;
5051import org .exist .util .OSUtil ;
5152import org .exist .util .SystemExitCodes ;
5253import se .softhouse .jargo .Argument ;
5354import se .softhouse .jargo .ArgumentException ;
5455import se .softhouse .jargo .CommandLineParser ;
5556import se .softhouse .jargo .ParsedArguments ;
5657
58+ import javax .annotation .Nullable ;
5759import javax .management .Attribute ;
5860import javax .management .AttributeList ;
5961import javax .management .AttributeNotFoundException ;
6466import javax .management .ObjectName ;
6567import javax .management .ReflectionException ;
6668import javax .management .openmbean .CompositeData ;
69+ import javax .management .openmbean .CompositeDataSupport ;
6770import javax .management .openmbean .TabularData ;
6871import javax .management .remote .JMXConnector ;
6972import javax .management .remote .JMXConnectorFactory ;
@@ -103,9 +106,9 @@ public void memoryStats() {
103106 final CompositeData composite = (CompositeData ) connection .getAttribute (name , "HeapMemoryUsage" );
104107 if (composite != null ) {
105108 echo ("\n MEMORY:" );
106- echo (String .format ("Current heap: %,12d k Committed memory: %,12d k " ,
107- ((Long )composite .get ("used" )) / 1024 , ((Long )composite .get ("committed" )) / 1024 ));
108- echo (String .format ("Max memory: %,12d k " , ((Long )composite .get ("max" )) / 1024 ));
109+ echo (String .format ("Current heap: %12s Committed memory: %12s " ,
110+ FileUtils . humanSize ((Long )composite .get ("used" )), FileUtils . humanSize ((Long )composite .get ("committed" ))));
111+ echo (String .format ("Max memory: %12s " , FileUtils . humanSize ((Long )composite .get ("max" ))));
109112 }
110113 } catch (final Exception e ) {
111114 error (e );
@@ -116,23 +119,24 @@ public void instanceStats() {
116119 try {
117120 echo ("\n INSTANCE:" );
118121 final ObjectName name = new ObjectName ("org.exist.management." + instance + ":type=Database" );
122+ echo (String .format ("%25s: %10s" , "Name" , instance ));
119123 final Long memReserved = (Long ) connection .getAttribute (name , "ReservedMem" );
120- echo (String .format ("%25s: %10d k " , "Reserved memory" , memReserved / 1024 ));
124+ echo (String .format ("%25s: %10s " , "Reserved memory" , FileUtils . humanSize ( memReserved ) ));
121125 final Long memCache = (Long ) connection .getAttribute (name , "CacheMem" );
122- echo (String .format ("%25s: %10d k " , "Cache memory" , memCache / 1024 ));
126+ echo (String .format ("%25s: %10s " , "Cache memory" , FileUtils . humanSize ( memCache ) ));
123127 final Long memCollCache = (Long ) connection .getAttribute (name , "CollectionCacheMem" );
124- echo (String .format ("%25s: %10d k " , "Collection cache memory" , memCollCache / 1024 ));
128+ echo (String .format ("%25s: %10s " , "Collection cache memory" , FileUtils . humanSize ( memCollCache ) ));
125129
126- final String cols [] = { "MaxBrokers" , "AvailableBrokers" , "ActiveBrokers" };
130+ final String [] cols = { "MaxBrokers" , "AvailableBrokers" , "ActiveBrokers" };
127131 echo (String .format ("\n %17s %17s %17s" , cols [0 ], cols [1 ], cols [2 ]));
128132 final AttributeList attrs = connection .getAttributes (name , cols );
129- final Object values [] = getValues (attrs );
130- echo (String .format ("%17d %17d %17d" , values [0 ], values [1 ], values [2 ]));
133+ final Object [] values = getValues (attrs );
134+ echo (String .format ("%17d %17d %17d" , ( Integer ) values [0 ], ( Integer ) values [1 ], ( Integer ) values [2 ]));
131135
132136 final TabularData table = (TabularData ) connection .getAttribute (name , "ActiveBrokersMap" );
133- if (table .size () > 0 ) {
137+ // if (table.size() > 0) {
134138 echo ("\n Currently active threads:" );
135- }
139+ // }
136140
137141 for (Object o : table .values ()) {
138142 final CompositeData data = (CompositeData ) o ;
@@ -146,59 +150,100 @@ public void instanceStats() {
146150 public void cacheStats () {
147151 try {
148152 ObjectName name = new ObjectName ("org.exist.management." + instance + ":type=CacheManager" );
149- String cols [] = { "MaxTotal" , "CurrentSize" };
153+ String [] cols = { "MaxTotal" , "CurrentSize" };
150154 AttributeList attrs = connection .getAttributes (name , cols );
151- Object values [] = getValues (attrs );
155+ Object [] values = getValues (attrs );
152156 echo (String .format ("\n CACHE [%8d pages max. / %8d pages allocated]" , values [0 ], values [1 ]));
153157
154158 final Set <ObjectName > beans = connection .queryNames (new ObjectName ("org.exist.management." + instance + ":type=CacheManager.Cache,*" ), null );
155- cols = new String [] {"Type" , "FileName " , "Size" , "Used" , "Hits" , "Fails" };
159+ cols = new String [] {"Type" , "CacheName " , "Size" , "Used" , "Hits" , "Fails" };
156160 echo (String .format ("%10s %20s %10s %10s %10s %10s" , cols [0 ], cols [1 ], cols [2 ], cols [3 ], cols [4 ], cols [5 ]));
157- for (ObjectName bean : beans ) {
161+ for (final ObjectName bean : beans ) {
158162 name = bean ;
159163 attrs = connection .getAttributes (name , cols );
160164 values = getValues (attrs );
161165 echo (String .format ("%10s %20s %,10d %,10d %,10d %,10d" , values [0 ], values [1 ], values [2 ], values [3 ], values [4 ], values [5 ]));
162166 }
163-
167+
164168 echo ("" );
165- name = new ObjectName ("org.exist.management." + instance + ":type=CollectionCacheManager " );
166- cols = new String [] { "MaxTotal " , "CurrentSize " };
169+ name = new ObjectName ("org.exist.management." + instance + ":type=CollectionCache " );
170+ cols = new String [] { "MaxCacheSize " , "Statistics " };
167171 attrs = connection .getAttributes (name , cols );
168172 values = getValues (attrs );
169- echo (String .format ("Collection Cache: %10d k max / %10d k allocated" ,
170- ((Long )values [0 ] / 1024 ), ((Long )values [1 ] / 1024 )));
173+
174+
175+ echo (String .format ("COLLECTION CACHE: [%10s max]" , FileUtils .humanSize ((Integer )values [0 ])));
176+
177+ cols = new String [] {"Hit Count" , "Miss Count" , "Load Success Count" , "Load Failure Count" , "Total Load Time" , "Eviction Count" , "Eviction Weight" };
178+ echo (String .format ("%10s %20s %20s %20s %20s %20s %20s" , cols [0 ], cols [1 ], cols [2 ], cols [3 ], cols [4 ], cols [5 ], cols [6 ]));
179+ final CompositeDataSupport statistics = (CompositeDataSupport ) values [1 ];
180+ echo (String .format ("%10d %20d %20d %20d %20d %20d %20d" , (Long )statistics .get ("hitCount" ), (Long )statistics .get ("missCount" ), (Long )statistics .get ("loadSuccessCount" ), (Long )statistics .get ("loadFailureCount" ), (Long )statistics .get ("totalLoadTime" ), (Long )statistics .get ("evictionCount" ), (Long )statistics .get ("evictionWeight" )));
181+
171182 } catch (final Exception e ) {
172183 error (e );
173184 }
174185 }
175186
176187 public void lockTable () {
177- echo ("\n List of threads currently waiting for a lock:" );
188+ echo ("\n List of threads attempting to acquire a lock:" );
178189 echo ("-----------------------------------------------" );
179190 try {
180- final TabularData table = (TabularData ) connection .getAttribute (new ObjectName ("org.exist.management:type=LockManager" ), "WaitingThreads" );
181- for (Object o : table .values ()) {
182- final CompositeData data = (CompositeData ) o ;
183- echo ("Thread " + data .get ("waitingThread" ));
184- echo (String .format ("%20s: %s" , "Lock type" , data .get ("lockType" )));
185- echo (String .format ("%20s: %s" , "Lock mode" , data .get ("lockMode" )));
186- echo (String .format ("%20s: %s" , "Lock id" , data .get ("id" )));
187- echo (String .format ("%20s: %s" , "Held by" , Arrays .toString ((String []) data .get ("owner" ))));
188- final String [] readers = (String []) data .get ("waitingForRead" );
189- if (readers .length > 0 ) {
190- echo (String .format ("%20s: %s" , "Wait for read" , Arrays .toString (readers )));
191- }
192- final String [] writers = (String []) data .get ("waitingForWrite" );
193- if (writers .length > 0 ) {
194- echo (String .format ("%20s: %s" , "Wait for write" , Arrays .toString (writers )));
195- }
196- }
191+ final TabularData table = (TabularData ) connection .getAttribute (new ObjectName ("org.exist.management." + instance + ":type=LockTable" ), "Attempting" );
192+ printLockTable (table );
193+ } catch (final MBeanException | AttributeNotFoundException | InstanceNotFoundException | ReflectionException | IOException | MalformedObjectNameException e ) {
194+ error (e );
195+ }
196+
197+ echo ("" );
198+
199+ echo ("\n List of threads holding a lock:" );
200+ echo ("-----------------------------------------------" );
201+ try {
202+ final TabularData table = (TabularData ) connection .getAttribute (new ObjectName ("org.exist.management." + instance + ":type=LockTable" ), "Acquired" );
203+ printLockTable (table );
197204 } catch (final MBeanException | AttributeNotFoundException | InstanceNotFoundException | ReflectionException | IOException | MalformedObjectNameException e ) {
198205 error (e );
199206 }
200207 }
201208
209+ private void printLockTable (final TabularData table ) {
210+ for (final Object tv : table .values ()) {
211+ final CompositeData data = (CompositeData ) tv ;
212+
213+ final String resourceUri = (String ) data .get ("key" );
214+ echo ("URI: " + resourceUri );
215+
216+ final TabularData valueData = (TabularData ) data .get ("value" );
217+ for (final Object vdv : valueData .values ()) {
218+ final CompositeData cvdv = (CompositeData ) vdv ;
219+ final String resourceType = (String ) cvdv .get ("key" );
220+ echo (String .format ("%20s: %s" , "Lock type" , resourceType ));
221+
222+ final TabularData resourceData = (TabularData ) cvdv .get ("value" );
223+
224+ for (final Object rvdv : resourceData .values ()) {
225+ final CompositeData crvdv = (CompositeData ) rvdv ;
226+ final String lockMode = (String ) crvdv .get ("key" );
227+ echo (String .format ("%20s: %s" , "Lock type" , lockMode ));
228+
229+ final TabularData lockData = (TabularData ) crvdv .get ("value" );
230+
231+ for (final Object lrvdv : lockData .values ()) {
232+ final CompositeData clrvdv = (CompositeData ) lrvdv ;
233+ final String owner = (String ) clrvdv .get ("key" );
234+ echo (String .format ("%20s: %s" , "Held by" , owner ));
235+
236+ final CompositeData ownerData = (CompositeData ) clrvdv .get ("value" );
237+
238+ final Integer holdCount = (Integer ) ownerData .get ("count" );
239+ echo (String .format ("%20s: %d" , "Hold count" , holdCount ));
240+ }
241+ }
242+
243+ }
244+ }
245+ }
246+
202247 public void sanityReport () {
203248 echo ("\n Sanity report" );
204249 echo ("-----------------------------------------------" );
@@ -213,12 +258,27 @@ public void sanityReport() {
213258 if (lastCheckStart != null && lastCheckEnd != null )
214259 {echo (String .format ("%22s: %dms" , "Check took" , (lastCheckEnd .getTime () - lastCheckStart .getTime ())));}
215260
216- final TabularData table = (TabularData )
217- connection .getAttribute (name , "Errors" );
218- for (Object o : table .values ()) {
219- final CompositeData data = (CompositeData ) o ;
220- echo (String .format ("%22s: %s" , "Error code" , data .get ("errcode" )));
221- echo (String .format ("%22s: %s" , "Description" , data .get ("description" )));
261+ @ Nullable final Object result = connection .getAttribute (name , "Errors" );
262+ if (result != null ) {
263+ @ Nullable final CompositeData table ;
264+ if (result .getClass ().isArray ()) {
265+ final CompositeData [] tables = ((CompositeData []) result );
266+ if (tables .length > 0 ) {
267+ table = tables [0 ];
268+ } else {
269+ table = null ;
270+ }
271+ } else {
272+ table = (CompositeData ) result ;
273+ }
274+
275+ if (table != null ) {
276+ for (final Object o : table .values ()) {
277+ final CompositeData data = (CompositeData ) o ;
278+ echo (String .format ("%22s: %s" , "Error code" , data .get ("errcode" )));
279+ echo (String .format ("%22s: %s" , "Description" , data .get ("description" )));
280+ }
281+ }
222282 }
223283 } catch (final MBeanException | AttributeNotFoundException | InstanceNotFoundException | ReflectionException | IOException | MalformedObjectNameException e ) {
224284 error (e );
@@ -255,10 +315,10 @@ public void jobReport() {
255315 }
256316 }
257317
258- private Object [] getValues (AttributeList attribs ) {
318+ private Object [] getValues (final AttributeList attribs ) {
259319 final Object [] v = new Object [attribs .size ()];
260320 for (int i = 0 ; i < attribs .size (); i ++) {
261- v [i ] = ((Attribute )attribs .get (i )).getValue ();
321+ v [i ] = ((Attribute ) attribs .get (i )).getValue ();
262322 }
263323 return v ;
264324 }
0 commit comments