[MRM-1580] system status page display caches.

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1299683 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Olivier Lamy 2012-03-12 14:29:17 +00:00
parent 3a90a3b357
commit fac85e0b4b
6 changed files with 217 additions and 4 deletions

View File

@ -0,0 +1,119 @@
package org.apache.archiva.rest.api.model;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
/**
* @author Olivier Lamy
* @since 1.4-M3
*/
@XmlRootElement( name = "cacheEntry" )
public class CacheEntry
implements Serializable
{
private String key;
private long size;
private long cacheHits;
private long cacheMiss;
private String cacheHitRate;
public CacheEntry()
{
// no op
}
public CacheEntry( String key, long size, long cacheHits, long cacheMiss, String cacheHitRate )
{
this.key = key;
this.size = size;
this.cacheHits = cacheHits;
this.cacheMiss = cacheMiss;
this.cacheHitRate = cacheHitRate;
}
public String getKey()
{
return key;
}
public void setKey( String key )
{
this.key = key;
}
public long getSize()
{
return size;
}
public void setSize( long size )
{
this.size = size;
}
public long getCacheHits()
{
return cacheHits;
}
public void setCacheHits( long cacheHits )
{
this.cacheHits = cacheHits;
}
public long getCacheMiss()
{
return cacheMiss;
}
public void setCacheMiss( long cacheMiss )
{
this.cacheMiss = cacheMiss;
}
public String getCacheHitRate()
{
return cacheHitRate;
}
public void setCacheHitRate( String cacheHitRate )
{
this.cacheHitRate = cacheHitRate;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "CacheEntry" );
sb.append( "{key='" ).append( key ).append( '\'' );
sb.append( ", size=" ).append( size );
sb.append( ", cacheHits=" ).append( cacheHits );
sb.append( ", cacheMiss=" ).append( cacheMiss );
sb.append( ", cacheHitRate=" ).append( cacheHitRate );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -18,6 +18,7 @@ package org.apache.archiva.rest.api.services;
* under the License. * under the License.
*/ */
import org.apache.archiva.rest.api.model.CacheEntry;
import org.apache.archiva.rest.api.model.QueueEntry; import org.apache.archiva.rest.api.model.QueueEntry;
import org.apache.archiva.security.common.ArchivaRoleConstants; import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.codehaus.plexus.redback.authorization.RedbackAuthorization; import org.codehaus.plexus.redback.authorization.RedbackAuthorization;
@ -57,4 +58,11 @@ public interface SystemStatusService
List<QueueEntry> getQueueEntries() List<QueueEntry> getQueueEntries()
throws ArchivaRestServiceException; throws ArchivaRestServiceException;
@Path( "cacheEntries" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
List<CacheEntry> getCacheEntries()
throws ArchivaRestServiceException;
} }

View File

@ -18,9 +18,12 @@ package org.apache.archiva.rest.services;
* under the License. * under the License.
*/ */
import org.apache.archiva.rest.api.model.CacheEntry;
import org.apache.archiva.rest.api.model.QueueEntry; import org.apache.archiva.rest.api.model.QueueEntry;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.SystemStatusService; import org.apache.archiva.rest.api.services.SystemStatusService;
import org.codehaus.plexus.cache.Cache;
import org.codehaus.plexus.cache.CacheStatistics;
import org.codehaus.plexus.taskqueue.TaskQueue; import org.codehaus.plexus.taskqueue.TaskQueue;
import org.codehaus.plexus.taskqueue.TaskQueueException; import org.codehaus.plexus.taskqueue.TaskQueueException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -28,6 +31,7 @@ import org.springframework.stereotype.Service;
import javax.inject.Inject; import javax.inject.Inject;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -47,13 +51,19 @@ public class DefaultSystemStatusService
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
Map<String, TaskQueue> queues = null; private Map<String, TaskQueue> queues = null;
Map<String, Cache> caches = null;
@Inject @Inject
public DefaultSystemStatusService( ApplicationContext applicationContext ) public DefaultSystemStatusService( ApplicationContext applicationContext )
{ {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
queues = getBeansOfType( applicationContext, TaskQueue.class ); queues = getBeansOfType( applicationContext, TaskQueue.class );
caches = getBeansOfType( applicationContext, Cache.class );
} }
public String getMemoryStatus() public String getMemoryStatus()
@ -99,4 +109,21 @@ public class DefaultSystemStatusService
Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() ); Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
} }
} }
public List<CacheEntry> getCacheEntries()
throws ArchivaRestServiceException
{
List<CacheEntry> cacheEntries = new ArrayList<CacheEntry>( caches.size() );
DecimalFormat decimalFormat = new DecimalFormat( "#%" );
for ( Map.Entry<String, Cache> entry : caches.entrySet() )
{
CacheStatistics cacheStatistics = entry.getValue().getStatistics();
cacheEntries.add( new CacheEntry( entry.getKey(), cacheStatistics.getSize(), cacheStatistics.getCacheHits(),
cacheStatistics.getCacheMiss(),
decimalFormat.format( cacheStatistics.getCacheHitRate() ).toString() ) );
}
return cacheEntries;
}
} }

View File

@ -297,6 +297,7 @@ system-status.header.scanning=Repository Scans Currently in Progress
system-status.header.scanning.inprogress.none=No scans in progress. system-status.header.scanning.inprogress.none=No scans in progress.
system-status.queues.grid.header.key=Queue system-status.queues.grid.header.key=Queue
system-status.queues.grid.header.number=Size system-status.queues.grid.header.number=Size
system-status.header.main=System Status

View File

@ -573,9 +573,35 @@ $(function() {
return new QueueEntry(item.key,item.entriesNumber); return new QueueEntry(item.key,item.entriesNumber);
}) })
} }
return null; return [];
} }
CacheEntry=function(key,size,cacheHits,cacheMiss,cacheHitRate){
this.key=key;
this.size=size;
this.cacheHits=cacheHits;
this.cacheMiss=cacheMiss;
this.cacheHitRate=cacheHitRate;
}
mapCacheEntries=function(data){
if(data!=null){
return $.map(data,function(item){
return new CacheEntry(item.key,item.size,item.cacheHits,item.cacheMiss,item.cacheHitRate);
})
}
return [];
}
displayCacheEntries=function(){
$.ajax("restServices/archivaServices/systemStatusService/cacheEntries", {
type: "GET",
success: function(data){
var cacheEntries=mapCacheEntries(data);
$("#main-content #status_caches").html($("#status_caches_tmpl" ).tmpl({cacheEntries: cacheEntries}));
}
});
}
displaySystemStatus=function(){ displaySystemStatus=function(){
screenChange(); screenChange();
@ -613,6 +639,9 @@ $(function() {
} }
}); });
displayCacheEntries();
} }
}); });

View File

@ -310,6 +310,10 @@
</script> </script>
<script id="system-status-main" type="text/html"> <script id="system-status-main" type="text/html">
<div class="page-header">
<h3>${$.i18n.prop('system-status.header.main')}</h3>
</div>
<div class="page-header"> <div class="page-header">
<h4>${$.i18n.prop('system-status.header.queues')}</h4> <h4>${$.i18n.prop('system-status.header.queues')}</h4>
</div> </div>
@ -354,12 +358,38 @@
</script> </script>
<script id="status_caches_tmpl" type="text/html">
<table class="table table-condensed">
<thead>
<tr>
<th>${$.i18n.prop('system-status.caches.grid.header.key')}</th>
<th>${$.i18n.prop('system-status.caches.grid.header.size')}</th>
<th>${$.i18n.prop('system-status.caches.grid.header.cacheHits')}</th>
<th>${$.i18n.prop('system-status.caches.grid.header.cacheMiss')}</th>
<th>${$.i18n.prop('system-status.caches.grid.header.cacheHitRate')}</th>
</tr>
</thead>
<tbody>
{{each(i,cacheEntry) cacheEntries}}
<tr>
<td>${cacheEntry.key}</td>
<td>${cacheEntry.size}</td>
<td>${cacheEntry.cacheHits}</td>
<td>${cacheEntry.cacheMiss}</td>
<td>${cacheEntry.cacheHitRate}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
<script id="status_queues_tmpl" type="text/html"> <script id="status_queues_tmpl" type="text/html">
<table class="table table-condensed"> <table class="table table-condensed">
<thead> <thead>
<tr> <tr>
<th>${$.i18n.prop('system-status.queues.grid.header.key')}</th> <th>${$.i18n.prop('system-status.queues.grid.header.key')}</th>
<th>${$.i18n.prop('system-status.queues.grid.header.number')}</th> <th>${$.i18n.prop('system-status.queues.grid.header.size')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -375,4 +405,3 @@