启动Geoserver后,我们可以查看Geoserver服务器的状态。点击这个按钮呈现下面的界面。这里是一个tab选项卡,有状态、模型、系统状态信息。在状态信息界面我们可以看到JVM版本、内存使用情况、可用字体。
而在模块界面我们可以看到对应了Geoserver相应源码提供模块。每个模块对应有一个模块的ID。相应有一个可用性。
最后一个是系统(机子)对应的状态。
从上面提供的信息来看,我们可以利用java获取和硬件相关的信息。来看源代码实现。首先是一个StatusPage类,该类非常简单。
public class StatusPage extends AbstractStatusPage {
/** serialVersionUID */
private static final long serialVersionUID = -5811282543852926742L;
public void StatusNewPage() {
initUI();
}
protected void initUI() {
super.initUI();
}
}
对应的html界面则如下图所示。是不是非常简单。
java代码功能主要是通过其父类AbstractStatusPage类来实现。
public abstract class AbstractStatusPage extends ServerAdminPage {
/** serialVersionUID */
private static final long serialVersionUID = -6228795354577370186L;
protected AjaxTabbedPanel tabbedPanel;
public AbstractStatusPage() {
initUI();
}
protected void initUI() {
List tabs = new ArrayList();
PanelCachingTab statusTab =
new PanelCachingTab(
new AbstractTab(new Model("Status")) {
private static final long serialVersionUID = 9062803783143908814L;
public Panel getPanel(String id) {
return new StatusPanel(id, AbstractStatusPage.this);
}
});
PanelCachingTab moduleStatusTab =
new PanelCachingTab(
new AbstractTab(new Model("Modules")) {
private static final long serialVersionUID = -5301288750339244612L;
public Panel getPanel(String id) {
return new ModuleStatusPanel(id, AbstractStatusPage.this);
}
});
PanelCachingTab systemStatusTab =
new PanelCachingTab(
new AbstractTab(new StringResourceModel("MonitoringPanel.title")) {
private static final long serialVersionUID = -5301288750339244612L;
public Panel getPanel(String id) {
return new SystemStatusMonitorPanel(id);
}
});
tabs.add(statusTab);
tabs.add(moduleStatusTab);
tabs.add(systemStatusTab);
// extension point for adding extra tabs that will be ordered using the extension priority
GeoServerExtensions.extensions(StatusPage.TabDefinition.class)
.forEach(
tabDefinition -> {
// create the new extra panel using the tab definition title
String title =
new ResourceModel(tabDefinition.getTitleKey()).getObject();
PanelCachingTab tab =
new PanelCachingTab(
new AbstractTab(new Model<>(title)) {
private static final long serialVersionUID =
-5301288750339244612L;
// create the extra tab panel passing down the
// container id
public Panel getPanel(String panelId) {
return tabDefinition.createPanel(
panelId, AbstractStatusPage.this);
}
});
tabs.add(tab);
});
AjaxTabbedPanel tabbedPanel = new AjaxTabbedPanel<>("tabs", tabs);
tabbedPanel
.get("panel")
.add(
new Behavior() {
@Override
public boolean getStatelessHint(Component component) {
// this will force canCallListenerInterfaceAfterExpiry to be false
// when a pending Ajax request
// is processed for expired tabs, we can't predict the Ajax events
// that will be used
return false;
}
});
add(tabbedPanel);
}
// Make sure child tabs can see this
@Override
protected boolean isAuthenticatedAsAdmin() {
return super.isAuthenticatedAsAdmin();
}
@Override
protected Catalog getCatalog() {
return super.getCatalog();
}
@Override
protected GeoServerApplication getGeoServerApplication() {
return super.getGeoServerApplication();
}
@Override
protected GeoServer getGeoServer() {
return super.getGeoServerApplication().getGeoServer();
}
/**
* Extensions that implement this interface will be able to contribute a new tabs to GeoServer
* status page, interface {@link org.geoserver.platform.ExtensionPriority} should be used to
* define the tab priority.
*/
public interface TabDefinition {
// title of the tab
String getTitleKey();
// content of the tab, the created panel should use the provided id
Panel createPanel(String panelId, Page containerPage);
}
}
在这里我们看到了三个选项卡tab的实现。分别是StatusPanel、ModuleStatusPanel、SystemStatusMonitorPanel
PanelCachingTab statusTab =
new PanelCachingTab(
new AbstractTab(new Model("Status")) {
private static final long serialVersionUID = 9062803783143908814L;
public Panel getPanel(String id) {
return new StatusPanel(id, AbstractStatusPage.this);
}
});
PanelCachingTab moduleStatusTab =
new PanelCachingTab(
new AbstractTab(new Model("Modules")) {
private static final long serialVersionUID = -5301288750339244612L;
public Panel getPanel(String id) {
return new ModuleStatusPanel(id, AbstractStatusPage.this);
}
});
PanelCachingTab systemStatusTab =
new PanelCachingTab(
new AbstractTab(new StringResourceModel("MonitoringPanel.title")) {
private static final long serialVersionUID = -5301288750339244612L;
public Panel getPanel(String id) {
return new SystemStatusMonitorPanel(id);
}
});
注意这里有StatusPanel,其源码如下所示。
public class StatusPanel extends Panel {
private static final long serialVersionUID = 7732030199323990637L;
/** The map used as the model source so the label contents are updated */
private Map values;
private static final String KEY_DATA_DIR = "dataDir";
private static final String KEY_LOCKS = "locks";
private static final String KEY_CONNECTIONS = "connections";
private static final String KEY_MEMORY = "memory";
private static final String KEY_JVM_VERSION = "jvm_version";
private static final String KEY_JAI_AVAILABLE = "jai_available";
private static final String KEY_JAI_IMAGEIO_AVAILABLE = "jai_imageio_available";
private static final String KEY_JAI_MAX_MEM = "jai_max_mem";
private static final String KEY_JAI_MEM_USAGE = "jai_mem_usage";
private static final String KEY_JAI_MEM_THRESHOLD = "jai_mem_threshold";
private static final String KEY_JAI_TILE_THREADS = "jai_tile_threads";
private static final String KEY_JAI_TILE_THREAD_PRIORITY = "jai_tile_thread_priority";
private static final String KEY_COVERAGEACCESS_CORE_POOL_SIZE = "coverage_thread_corepoolsize";
private static final String KEY_COVERAGEACCESS_MAX_POOL_SIZE = "coverage_thread_maxpoolsize";
private static final String KEY_COVERAGEACCESS_KEEP_ALIVE_TIME =
"coverage_thread_keepalivetime";
private static final String KEY_UPDATE_SEQUENCE = "update_sequence";
private static final String KEY_JAVA_RENDERER = "renderer";
private static final Logger LOGGER = Logging.getLogger(StatusPanel.class);
private AbstractStatusPage parent;
public StatusPanel(String id, AbstractStatusPage parent) {
super(id);
this.parent = parent;
initUI();
}
public void initUI() {
values = new HashMap();
updateModel();
// TODO: if we just provide the values directly as the models they won't
// be refreshed on a page reload (ugh).
add(new Label("dataDir", new MapModel(values, KEY_DATA_DIR)));
add(new Label("locks", new MapModel(values, KEY_LOCKS)));
add(new Label("connections", new MapModel(values, KEY_CONNECTIONS)));
add(new Label("memory", new MapModel(values, KEY_MEMORY)));
add(new Label("jvm.version", new MapModel(values, KEY_JVM_VERSION)));
add(new Label("jai.available", new MapModel(values, KEY_JAI_AVAILABLE)));
add(new Label("jai.imageio.available", new MapModel(values, KEY_JAI_IMAGEIO_AVAILABLE)));
add(new Label("jai.memory.available", new MapModel(values, KEY_JAI_MAX_MEM)));
add(new Label("jai.memory.used", new MapModel(values, KEY_JAI_MEM_USAGE)));
add(new Label("jai.memory.threshold", new MapModel(values, KEY_JAI_MEM_THRESHOLD)));
add(new Label("jai.tile.threads", new MapModel(values, KEY_JAI_TILE_THREADS)));
add(new Label("jai.tile.priority", new MapModel(values, KEY_JAI_TILE_THREAD_PRIORITY)));
add(
new Label(
"coverage.corepoolsize",
new MapModel(values, KEY_COVERAGEACCESS_CORE_POOL_SIZE)));
add(
new Label(
"coverage.maxpoolsize",
new MapModel(values, KEY_COVERAGEACCESS_MAX_POOL_SIZE)));
add(
new Label(
"coverage.keepalivetime",
new MapModel(values, KEY_COVERAGEACCESS_KEEP_ALIVE_TIME)));
add(new Label("updateSequence", new MapModel(values, KEY_UPDATE_SEQUENCE)));
add(new Label("renderer", new MapModel(values, KEY_JAVA_RENDERER)));
// serialization error here
add(
new Link("free.locks") {
private static final long serialVersionUID = -2889353495319211391L;
public void onClick() {
// TODO: see GEOS-2130
updateModel();
}
});
add(
new Link("free.memory") {
private static final long serialVersionUID = 3695369177295089346L;
public void onClick() {
System.gc();
System.runFinalization();
updateModel();
}
});
add(
new Link("free.memory.jai") {
private static final long serialVersionUID = -3556725607958589003L;
public void onClick() {
TileCache jaiCache =
parent.getGeoServer().getGlobal().getJAI().getTileCache();
final long capacityBefore = jaiCache.getMemoryCapacity();
jaiCache.flush();
jaiCache.setMemoryCapacity(0); // to be sure we realease all tiles
System.gc();
System.runFinalization();
jaiCache.setMemoryCapacity(capacityBefore);
updateModel();
}
});
int fontCount = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts().length;
add(
new Label(
"fontCount",
new ParamResourceModel("StatusPage.fontCount", this, fontCount)));
add(new BookmarkablePageLink("show.fonts", JVMFontsPage.class));
add(
new AjaxLink("clear.resourceCache") {
private static final long serialVersionUID = 2663650174059497376L;
@Override
public void onClick(AjaxRequestTarget target) {
try {
parent.getGeoServer().reset();
info(
getLocalizer()
.getString("resourceCacheClearedSuccessfully", this));
} catch (Throwable t) {
LOGGER.log(Level.SEVERE, "Error resetting resource caches", t);
error(t);
}
parent.addFeedbackPanels(target);
}
});
add(
new AjaxLink("reload.catalogConfig") {
private static final long serialVersionUID = -7476556423889306321L;
@Override
public void onClick(AjaxRequestTarget target) {
try {
parent.getGeoServer().reload();
info(
getLocalizer()
.getString(
"catalogConfigReloadedSuccessfully",
StatusPanel.this));
} catch (Throwable t) {
LOGGER.log(
Level.SEVERE,
"An error occurred while reloading the catalog",
t);
error(t);
}
parent.addFeedbackPanels(target);
}
});
}
private void updateModel() {
values.put(KEY_DATA_DIR, getDataDirectory());
values.put(KEY_LOCKS, Long.toString(getLockCount()));
values.put(KEY_CONNECTIONS, Long.toString(getConnectionCount()));
values.put(KEY_MEMORY, formatUsedMemory());
values.put(
KEY_JVM_VERSION,
System.getProperty("java.vendor")
+ ": "
+ System.getProperty("java.version")
+ " ("
+ System.getProperty("java.vm.name")
+ ")");
values.put(KEY_JAI_AVAILABLE, Boolean.toString(isNativeJAIAvailable()));
values.put(KEY_JAI_IMAGEIO_AVAILABLE, Boolean.toString(PackageUtil.isCodecLibAvailable()));
GeoServerInfo geoServerInfo = parent.getGeoServer().getGlobal();
JAIInfo jaiInfo = geoServerInfo.getJAI();
JAI jai = jaiInfo.getJAI();
CoverageAccessInfo coverageAccess = geoServerInfo.getCoverageAccess();
TileCache jaiCache = jaiInfo.getTileCache();
values.put(KEY_JAI_MAX_MEM, formatMemory(jaiCache.getMemoryCapacity()));
if (jaiCache instanceof CacheDiagnostics) {
values.put(
KEY_JAI_MEM_USAGE,
formatMemory(((CacheDiagnostics) jaiCache).getCacheMemoryUsed()));
} else {
values.put(KEY_JAI_MEM_USAGE, "-");
}
values.put(
KEY_JAI_MEM_THRESHOLD,
Integer.toString((int) (100.0f * jaiCache.getMemoryThreshold())) + "%");
values.put(KEY_JAI_TILE_THREADS, Integer.toString(jai.getTileScheduler().getParallelism()));
values.put(
KEY_JAI_TILE_THREAD_PRIORITY,
Integer.toString(jai.getTileScheduler().getPriority()));
values.put(
KEY_COVERAGEACCESS_CORE_POOL_SIZE,
Integer.toString(coverageAccess.getCorePoolSize()));
values.put(
KEY_COVERAGEACCESS_MAX_POOL_SIZE,
Integer.toString(coverageAccess.getMaxPoolSize()));
values.put(
KEY_COVERAGEACCESS_KEEP_ALIVE_TIME,
Integer.toString(coverageAccess.getKeepAliveTime()));
values.put(KEY_UPDATE_SEQUENCE, Long.toString(geoServerInfo.getUpdateSequence()));
values.put(KEY_JAVA_RENDERER, checkRenderer());
}
/** Retrieves the GeoServer data directory */
private String getDataDirectory() {
GeoServerDataDirectory dd =
parent.getGeoServerApplication().getBeanOfType(GeoServerDataDirectory.class);
return dd.root().getAbsolutePath();
}
private String checkRenderer() {
try {
// static access to sun.java2d.pipe.RenderingEngine gives a warning that cannot be
// suppressed
String renderer =
Class.forName("sun.java2d.pipe.RenderingEngine")
.getMethod("getInstance")
.invoke(null)
.getClass()
.getName();
return renderer;
} catch (Throwable e) {
return "Unknown";
}
}
boolean isNativeJAIAvailable() {
// we directly access the Mlib Image class, if in the classpath it will tell us if
// the native extensions are available, if not, an Error will be thrown
try {
Class> image = Class.forName("com.sun.medialib.mlib.Image");
return (Boolean) image.getMethod("isAvailable").invoke(null);
} catch (Throwable e) {
return false;
}
}
/** @return a human friendly string for the VM used memory */
private String formatUsedMemory() {
final Runtime runtime = Runtime.getRuntime();
final long usedBytes = runtime.totalMemory() - runtime.freeMemory();
String formattedUsedMemory = formatMemory(usedBytes);
String formattedMaxMemory = formatMemory(runtime.maxMemory());
return formattedUsedMemory + " / " + formattedMaxMemory;
}
private String formatMemory(final long bytes) {
final long KB = 1024;
final long MB = KB * KB;
final long GB = KB * MB;
final NumberFormat formatter = NumberFormat.getInstance();
formatter.setMaximumFractionDigits(2);
String formattedUsedMemory;
if (bytes > GB) {
formattedUsedMemory = formatter.format((float) bytes / GB) + " GB";
} else if (bytes > MB) {
formattedUsedMemory = formatter.format(bytes / MB) + " MB";
} else {
formattedUsedMemory = formatter.format(bytes / KB) + " KB";
}
return formattedUsedMemory;
}
private synchronized int getLockCount() {
int count = 0;
CloseableIterator i = getDataStores();
try {
while (i.hasNext()) {
DataStoreInfo meta = (DataStoreInfo) i.next();
if (!meta.isEnabled()) {
// Don't count locks from disabled datastores.
continue;
}
// try {
// DataAccess store = meta.getDataStore(null);
// if (store instanceof DataStore) {
// LockingManager lockingManager = ((DataStore) store).getLockingManager();
// if (lockingManager != null) {
// // we can't actually *count* locks right now?
// count += lockingManager.getLockSet().size();
// }
// }
// } catch (IllegalStateException notAvailable) {
// continue;
// } catch (Throwable huh) {
// continue;
// }
}
} finally {
i.close();
}
return count;
}
private synchronized int getConnectionCount() {
int count = 0;
CloseableIterator i = getDataStores();
try {
while (i.hasNext()) {
DataStoreInfo meta = i.next();
if (!meta.isEnabled()) {
// Don't count connections from disabled datastores.
continue;
}
try {
meta.getDataStore(null);
} catch (Throwable notAvailable) {
// TODO: Logging.
continue;
}
count += 1;
}
} finally {
i.close();
}
return count;
}
private CloseableIterator getDataStores() {
Catalog catalog = parent.getGeoServer().getCatalog();
Filter filter = Predicates.acceptAll();
CloseableIterator stores = catalog.list(DataStoreInfo.class, filter);
return stores;
}
}
那么这里应用到GeoServerExtensions来获取数据路径。
/** Retrieves the GeoServer data directory */
private String getDataDirectory() {
GeoServerDataDirectory dd =
parent.getGeoServerApplication().getBeanOfType(GeoServerDataDirectory.class);
return dd.root().getAbsolutePath();
}
通过Catalog来获得数据存储,依此来计算锁的数量、
private CloseableIterator getDataStores() {
Catalog catalog = parent.getGeoServer().getCatalog();
Filter filter = Predicates.acceptAll();
CloseableIterator stores = catalog.list(DataStoreInfo.class, filter);
return stores;
}
以及使用java相关的函数获取相关信息。比如jvm
private void updateModel() {
values.put(KEY_DATA_DIR, getDataDirectory());
values.put(KEY_LOCKS, Long.toString(getLockCount()));
values.put(KEY_CONNECTIONS, Long.toString(getConnectionCount()));
values.put(KEY_MEMORY, formatUsedMemory());
values.put(
KEY_JVM_VERSION,
System.getProperty("java.vendor")
+ ": "
+ System.getProperty("java.version")
+ " ("
+ System.getProperty("java.vm.name")
+ ")");
values.put(KEY_JAI_AVAILABLE, Boolean.toString(isNativeJAIAvailable()));
values.put(KEY_JAI_IMAGEIO_AVAILABLE, Boolean.toString(PackageUtil.isCodecLibAvailable()));
GeoServerInfo geoServerInfo = parent.getGeoServer().getGlobal();
JAIInfo jaiInfo = geoServerInfo.getJAI();
JAI jai = jaiInfo.getJAI();
CoverageAccessInfo coverageAccess = geoServerInfo.getCoverageAccess();
TileCache jaiCache = jaiInfo.getTileCache();
values.put(KEY_JAI_MAX_MEM, formatMemory(jaiCache.getMemoryCapacity()));
if (jaiCache instanceof CacheDiagnostics) {
values.put(
KEY_JAI_MEM_USAGE,
formatMemory(((CacheDiagnostics) jaiCache).getCacheMemoryUsed()));
} else {
values.put(KEY_JAI_MEM_USAGE, "-");
}
values.put(
KEY_JAI_MEM_THRESHOLD,
Integer.toString((int) (100.0f * jaiCache.getMemoryThreshold())) + "%");
values.put(KEY_JAI_TILE_THREADS, Integer.toString(jai.getTileScheduler().getParallelism()));
values.put(
KEY_JAI_TILE_THREAD_PRIORITY,
Integer.toString(jai.getTileScheduler().getPriority()));
values.put(
KEY_COVERAGEACCESS_CORE_POOL_SIZE,
Integer.toString(coverageAccess.getCorePoolSize()));
values.put(
KEY_COVERAGEACCESS_MAX_POOL_SIZE,
Integer.toString(coverageAccess.getMaxPoolSize()));
values.put(
KEY_COVERAGEACCESS_KEEP_ALIVE_TIME,
Integer.toString(coverageAccess.getKeepAliveTime()));
values.put(KEY_UPDATE_SEQUENCE, Long.toString(geoServerInfo.getUpdateSequence()));
values.put(KEY_JAVA_RENDERER, checkRenderer());
}
那么接下来是模型状态的选项卡。
public class ModuleStatusPanel extends Panel {
private static final long serialVersionUID = 3892224318224575781L;
final CatalogIconFactory icons = CatalogIconFactory.get();
ModalWindow popup;
AjaxLink msgLink;
public ModuleStatusPanel(String id, AbstractStatusPage parent) {
super(id);
initUI();
}
public void initUI() {
final WebMarkupContainer wmc = new WebMarkupContainer("listViewContainer");
wmc.setOutputMarkupId(true);
this.add(wmc);
popup = new ModalWindow("popup");
add(popup);
// get the list of ModuleStatuses
List applicationStatus =
GeoServerExtensions.extensions(ModuleStatus.class)
.stream()
.filter(status -> !status.getModule().matches("\\A[system-](.*)"))
.map(ModuleStatusImpl::new)
.sorted(Comparator.comparing(ModuleStatus::getModule))
.collect(Collectors.toList());
final ListView moduleView =
new ListView("modules", applicationStatus) {
private static final long serialVersionUID = 235576083712961710L;
@Override
protected void populateItem(ListItem item) {
item.add(new Label("module", new PropertyModel(item.getModel(), "module")));
item.add(getIcons("available", item.getModelObject().isAvailable()));
item.add(getIcons("enabled", item.getModelObject().isEnabled()));
item.add(
new Label(
"component",
new Model(
item.getModelObject().getComponent().orElse(""))));
item.add(
new Label(
"version",
new Model(item.getModelObject().getVersion().orElse(""))));
msgLink =
new AjaxLink("msg") {
@Override
public void onClick(AjaxRequestTarget target) {
popup.setInitialHeight(325);
popup.setInitialWidth(525);
popup.setContent(
new MessagePanel(popup.getContentId(), item));
popup.setTitle("Module Info");
popup.show(target);
}
};
msgLink.setEnabled(true);
msgLink.add(
new Label("nameLink", new PropertyModel(item.getModel(), "name")));
item.add(msgLink);
}
};
wmc.add(moduleView);
}
final Fragment getIcons(String id, boolean status) {
PackageResourceReference icon = status ? icons.getEnabledIcon() : icons.getDisabledIcon();
Fragment f = new Fragment(id, "iconFragment", this);
f.add(new Image("statusIcon", icon));
return f;
};
class MessagePanel extends Panel {
private static final long serialVersionUID = -3200098674603724915L;
public MessagePanel(String id, ListItem item) {
super(id);
Label name = new Label("name", new PropertyModel(item.getModel(), "name"));
Label module = new Label("module", new PropertyModel(item.getModel(), "module"));
Label component =
new Label(
"component",
new Model(item.getModelObject().getComponent().orElse("")));
Label version =
new Label("version", new Model(item.getModelObject().getVersion().orElse("")));
MultiLineLabel msgLabel =
new MultiLineLabel("msg", item.getModelObject().getMessage().orElse(""));
add(name);
add(module);
add(component);
add(version);
add(msgLabel);
}
}
}
模型清单通过下面的函数语句来获得。
// get the list of ModuleStatuses
List applicationStatus =
GeoServerExtensions.extensions(ModuleStatus.class)
.stream()
.filter(status -> !status.getModule().matches("\\A[system-](.*)"))
.map(ModuleStatusImpl::new)
.sorted(Comparator.comparing(ModuleStatus::getModule))
.collect(Collectors.toList());
最后一个是系统信息tab选项卡。
public class RefreshedPanel extends Panel {
private static final long serialVersionUID = -5616622546856772557L;
public static final String datePattern = "yyyy-MM-dd HH:mm:ss.SSS";
public RefreshedPanel(String id) {
super(id);
/*
* Configure panel
*/
final SystemInfoCollector systemInfoCollector =
GeoServerExtensions.bean(SystemInfoCollector.class);
final IModel timeMdl = Model.of(new Date());
final IModel> metricMdl = Model.ofList(Collections.emptyList());
Label time = DateLabel.forDatePattern("time", timeMdl, datePattern);
time.setOutputMarkupId(true);
add(time);
ListView list =
new ListView("metrics", metricMdl) {
private static final long serialVersionUID = -5654700538264617274L;
private int counter;
@Override
protected void onBeforeRender() {
super.onBeforeRender();
counter = 0;
}
@Override
protected void populateItem(ListItem item) {
item.add(
new Label(
"info",
new PropertyModel(
new MetricValueI18nDescriptionWrapper(
item.getModel().getObject(), this),
"description")),
new Label(
"value",
new PropertyModel(
item.getModel(), "valueUnit")));
if (counter % 2 == 0) {
item.add(new AttributeModifier("class", "odd"));
} else {
item.add(new AttributeModifier("class", "even"));
}
counter++;
}
};
list.setOutputMarkupId(true);
add(list);
/*
* Refresh every seconds
*/
this.add(
new AjaxSelfUpdatingTimerBehavior(Duration.seconds(1)) {
private static final long serialVersionUID = -7009847252782601466L;
@Override
public void onConfigure(Component component) {
Metrics metrics = systemInfoCollector.retrieveAllSystemInfo();
metricMdl.setObject(metrics.getMetrics());
timeMdl.setObject(new Date());
}
});
}
/** An internal wrapper for getting optional localization string on description values. */
private static class MetricValueI18nDescriptionWrapper implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER =
Logging.getLogger(MetricValueI18nDescriptionWrapper.class);
private final MetricValue value;
private final Component component;
public MetricValueI18nDescriptionWrapper(MetricValue value, Component component) {
super();
this.value = value;
this.component = component;
}
public String getDescription() {
String keyValue = formatKeyValue(value);
LOGGER.log(
Level.FINE,
"Getting localized name for {0} -> {1}",
new Object[] {keyValue, value.getDescription()});
final String localizedValue =
component.getString(keyValue, null, value.getDescription());
return localizedValue;
}
private String formatKeyValue(MetricValue value) {
StringBuilder keyBuilder = new StringBuilder();
keyBuilder.append(scapeKeyString(value.getName().toLowerCase()));
keyBuilder.append("-");
keyBuilder.append(scapeKeyString(value.getIdentifier().toLowerCase()));
return keyBuilder.toString();
}
private String scapeKeyString(String value) {
return value.replace(" ", "_").replace(":", "_").replace("=", "_");
}
}
}
同样该类主要是通过下面的语句将系统信息列举出来。
final SystemInfoCollector systemInfoCollector =
GeoServerExtensions.bean(SystemInfoCollector.class);