IDEMPIERE-4072 iDempiere Monitor: Implement server and cache details for cluster node
This commit is contained in:
parent
62a8e4efaa
commit
97bb8d9b83
|
@ -319,5 +319,12 @@ public class MSession extends X_AD_Session
|
||||||
return null;
|
return null;
|
||||||
} // changeLog
|
} // changeLog
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return number of cached sessions
|
||||||
|
*/
|
||||||
|
public static int getCachedSessionCount() {
|
||||||
|
return s_sessions.size()-1;
|
||||||
|
}
|
||||||
} // MSession
|
} // MSession
|
||||||
|
|
||||||
|
|
|
@ -427,4 +427,8 @@ public class CCache<K,V> implements CacheInterface, Map<K, V>, Serializable
|
||||||
public int getMaxSize() {
|
public int getMaxSize() {
|
||||||
return m_maxSize;
|
return m_maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDistributed() {
|
||||||
|
return m_distributed;
|
||||||
|
}
|
||||||
} // CCache
|
} // CCache
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.compiere.util;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.adempiere.base.IServiceHolder;
|
||||||
|
import org.adempiere.base.Service;
|
||||||
|
import org.idempiere.distributed.IClusterMember;
|
||||||
|
import org.idempiere.distributed.IClusterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CacheInfo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -9069013908523249394L;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String tableName;
|
||||||
|
private int size;
|
||||||
|
private int expireMinutes;
|
||||||
|
private int maxSize;
|
||||||
|
private boolean distributed;
|
||||||
|
private InetAddress nodeAddress;
|
||||||
|
private String nodeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public CacheInfo(CCache<?, ?> cache) {
|
||||||
|
name = cache.getName();
|
||||||
|
tableName = cache.getTableName();
|
||||||
|
size = cache.size();
|
||||||
|
expireMinutes = cache.getExpireMinutes();
|
||||||
|
maxSize = cache.getMaxSize();
|
||||||
|
distributed = cache.isDistributed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tableName
|
||||||
|
*/
|
||||||
|
public String getTableName() {
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the size
|
||||||
|
*/
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the expireMinutes
|
||||||
|
*/
|
||||||
|
public int getExpireMinutes() {
|
||||||
|
return expireMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxSize
|
||||||
|
*/
|
||||||
|
public int getMaxSize() {
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the distributed
|
||||||
|
*/
|
||||||
|
public boolean isDistributed() {
|
||||||
|
return distributed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the nodeAddress
|
||||||
|
*/
|
||||||
|
public InetAddress getNodeAddress() {
|
||||||
|
return nodeAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the nodeId
|
||||||
|
*/
|
||||||
|
public String getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sortByName
|
||||||
|
* @return cache infos
|
||||||
|
*/
|
||||||
|
public static List<CacheInfo> getCacheInfos(boolean sortByName) {
|
||||||
|
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
||||||
|
IClusterService service = holder != null ? holder.getService() : null;
|
||||||
|
if (service != null && service.getMembers().size() > 1) {
|
||||||
|
List<CacheInfo> instances = new ArrayList<>();
|
||||||
|
GetCacheInfoCallable callable = new GetCacheInfoCallable();
|
||||||
|
Map<IClusterMember, Future<List<CacheInfo>>> futureMap = service.execute(callable, service.getMembers());
|
||||||
|
if (futureMap != null) {
|
||||||
|
try {
|
||||||
|
Set<Entry<IClusterMember, Future<List<CacheInfo>>>> results = futureMap.entrySet();
|
||||||
|
for(Entry<IClusterMember, Future<List<CacheInfo>>> f : results) {
|
||||||
|
List<CacheInfo> response = f.getValue().get();
|
||||||
|
if (response != null && response.size() > 0) {
|
||||||
|
response.forEach(e -> {
|
||||||
|
e.setNodeId(f.getKey().getId());
|
||||||
|
e.setNodeAddress(f.getKey().getAddress());
|
||||||
|
instances.add(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortByName) {
|
||||||
|
Collections.sort(instances, new Comparator<CacheInfo>() {
|
||||||
|
@Override
|
||||||
|
public int compare(CacheInfo o1, CacheInfo o2) {
|
||||||
|
return o1.getName().compareTo(o2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return instances;
|
||||||
|
} else {
|
||||||
|
List<CacheInfo> instances = CacheMgt.get().getCacheInfos();
|
||||||
|
if (sortByName) {
|
||||||
|
Collections.sort(instances, new Comparator<CacheInfo>() {
|
||||||
|
@Override
|
||||||
|
public int compare(CacheInfo o1, CacheInfo o2) {
|
||||||
|
return o1.getName().compareTo(o2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return instances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setNodeAddress(InetAddress address) {
|
||||||
|
nodeAddress = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setNodeId(String id) {
|
||||||
|
nodeId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -385,6 +386,21 @@ public class CacheMgt
|
||||||
clusterNewRecord(tableName, recordId);
|
clusterNewRecord(tableName, recordId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return cache infos
|
||||||
|
*/
|
||||||
|
public List<CacheInfo> getCacheInfos() {
|
||||||
|
List<CacheInfo> infos = new ArrayList<>();
|
||||||
|
CacheInterface[] instances = getInstancesAsArray();
|
||||||
|
for(CacheInterface ci : instances) {
|
||||||
|
if (ci instanceof CCache<?, ?>) {
|
||||||
|
infos.add(new CacheInfo((CCache<?, ?>) ci));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
private static class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> {
|
private static class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||||
/**
|
/**
|
||||||
* generated serial id
|
* generated serial id
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.compiere.util;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetCacheInfoCallable implements Callable<List<CacheInfo>>, Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 6444040776576577718L;
|
||||||
|
|
||||||
|
public GetCacheInfoCallable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CacheInfo> call() throws Exception {
|
||||||
|
List<CacheInfo> instances = CacheMgt.get().getCacheInfos();
|
||||||
|
return instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public class ResetCacheCallable implements Callable<Integer>, Serializable
|
||||||
private String tableName;
|
private String tableName;
|
||||||
private int Record_ID;
|
private int Record_ID;
|
||||||
|
|
||||||
protected ResetCacheCallable(String tableName, int Record_ID)
|
public ResetCacheCallable(String tableName, int Record_ID)
|
||||||
{
|
{
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
this.Record_ID = Record_ID;
|
this.Record_ID = Record_ID;
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.compiere.util.Env;
|
||||||
import org.idempiere.distributed.ICacheService;
|
import org.idempiere.distributed.ICacheService;
|
||||||
import org.idempiere.distributed.IClusterMember;
|
import org.idempiere.distributed.IClusterMember;
|
||||||
import org.idempiere.distributed.IClusterService;
|
import org.idempiere.distributed.IClusterService;
|
||||||
|
import org.idempiere.server.cluster.ClusterServerMgr;
|
||||||
import org.osgi.framework.BundleEvent;
|
import org.osgi.framework.BundleEvent;
|
||||||
import org.osgi.framework.BundleListener;
|
import org.osgi.framework.BundleListener;
|
||||||
import org.osgi.framework.ServiceReference;
|
import org.osgi.framework.ServiceReference;
|
||||||
|
@ -840,14 +841,8 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IClusterService getClusterService() {
|
|
||||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
|
||||||
IClusterService service = holder != null ? holder.getService() : null;
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getClusterMemberId() {
|
private String getClusterMemberId() {
|
||||||
IClusterService service = getClusterService();
|
IClusterService service = ClusterServerMgr.getClusterService();
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
IClusterMember local = service.getLocalMember();
|
IClusterMember local = service.getLocalMember();
|
||||||
if (local != null)
|
if (local != null)
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.compiere.server;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LogFileInfo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -5841677623091843473L;
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
private long fileSize;
|
||||||
|
|
||||||
|
|
||||||
|
private LogFileInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return LogFileInfo[]
|
||||||
|
*/
|
||||||
|
public static LogFileInfo[] getLogFileInfos() {
|
||||||
|
List<LogFileInfo> list = new ArrayList<>();
|
||||||
|
CLogFile fileHandler = CLogFile.get (true, null, false);
|
||||||
|
File logDir = fileHandler.getLogDirectory();
|
||||||
|
if (logDir != null && logDir.isDirectory())
|
||||||
|
{
|
||||||
|
File[] logs = logDir.listFiles();
|
||||||
|
for (int i = 0; i < logs.length; i++)
|
||||||
|
{
|
||||||
|
// Skip if is not a file - teo_sarca [ 1726066 ]
|
||||||
|
if (!logs[i].isFile())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LogFileInfo lfi = new LogFileInfo();
|
||||||
|
lfi.fileName = logs[i].getAbsolutePath();
|
||||||
|
lfi.fileSize = logs[i].length();
|
||||||
|
list.add(lfi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.toArray(new LogFileInfo[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return current log file name
|
||||||
|
*/
|
||||||
|
public static String getCurrentLogFile() {
|
||||||
|
CLogFile fileHandler = CLogFile.get (true, null, false);
|
||||||
|
return fileHandler.getFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileName
|
||||||
|
*/
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileSize
|
||||||
|
*/
|
||||||
|
public long getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,360 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.compiere.server;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.MemoryMXBean;
|
||||||
|
import java.lang.management.OperatingSystemMXBean;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.lang.management.ThreadMXBean;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.db.AdempiereDatabase;
|
||||||
|
import org.compiere.db.CConnection;
|
||||||
|
import org.compiere.model.MSession;
|
||||||
|
import org.compiere.util.CLogMgt;
|
||||||
|
import org.compiere.util.CMemoryUsage;
|
||||||
|
import org.idempiere.distributed.IClusterMember;
|
||||||
|
import org.idempiere.distributed.IClusterService;
|
||||||
|
import org.idempiere.server.cluster.ClusterServerMgr;
|
||||||
|
import org.idempiere.server.cluster.callable.GetSystemInfoCallable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SystemInfo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -4451616690416295597L;
|
||||||
|
|
||||||
|
private String operatingSystem;
|
||||||
|
private String javaVM;
|
||||||
|
private String databaseDescription;
|
||||||
|
private String databaseConnectionURL;
|
||||||
|
private String databaseStatus;
|
||||||
|
private String memoryUsage;
|
||||||
|
private String heapMemoryUsage;
|
||||||
|
private String runtimeName;
|
||||||
|
private long runtimeUpTime;
|
||||||
|
private int threadCount;
|
||||||
|
private int peakThreadCount;
|
||||||
|
private int daemonThreadCount;
|
||||||
|
private long totalStartedThreadCount;
|
||||||
|
private TrxInfo[] trxInfos;
|
||||||
|
private Level logLevel;
|
||||||
|
private String currentLogFile;
|
||||||
|
private LogFileInfo[] logFileInfos;
|
||||||
|
private long garbageCollectionTime;
|
||||||
|
private long garbageCollectionCount;
|
||||||
|
private int availableProcessors;
|
||||||
|
private double averageSystemLoad;
|
||||||
|
|
||||||
|
private int sessionCount;
|
||||||
|
|
||||||
|
private InetAddress address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private SystemInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the operatingSystem
|
||||||
|
*/
|
||||||
|
public String getOperatingSystem() {
|
||||||
|
return operatingSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the javaVM
|
||||||
|
*/
|
||||||
|
public String getJavaVM() {
|
||||||
|
return javaVM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the databaseDescription
|
||||||
|
*/
|
||||||
|
public String getDatabaseDescription() {
|
||||||
|
return databaseDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the databaseConnectionURL
|
||||||
|
*/
|
||||||
|
public String getDatabaseConnectionURL() {
|
||||||
|
return databaseConnectionURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the databaseStatus
|
||||||
|
*/
|
||||||
|
public String getDatabaseStatus() {
|
||||||
|
return databaseStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the memoryUsage
|
||||||
|
*/
|
||||||
|
public String getMemoryUsage() {
|
||||||
|
return memoryUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the heapMemoryUsage
|
||||||
|
*/
|
||||||
|
public String getHeapMemoryUsage() {
|
||||||
|
return heapMemoryUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the runtimeName
|
||||||
|
*/
|
||||||
|
public String getRuntimeName() {
|
||||||
|
return runtimeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the runtimeUpTime
|
||||||
|
*/
|
||||||
|
public long getRuntimeUpTime() {
|
||||||
|
return runtimeUpTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the threadCount
|
||||||
|
*/
|
||||||
|
public int getThreadCount() {
|
||||||
|
return threadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the peakThreadCount
|
||||||
|
*/
|
||||||
|
public int getPeakThreadCount() {
|
||||||
|
return peakThreadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the daemonThreadCount
|
||||||
|
*/
|
||||||
|
public int getDaemonThreadCount() {
|
||||||
|
return daemonThreadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the totalStartedThreadCount
|
||||||
|
*/
|
||||||
|
public long getTotalStartedThreadCount() {
|
||||||
|
return totalStartedThreadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the trxInfos
|
||||||
|
*/
|
||||||
|
public TrxInfo[] getTrxInfos() {
|
||||||
|
return trxInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the logLevel
|
||||||
|
*/
|
||||||
|
public Level getLogLevel() {
|
||||||
|
return logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the currentLogFile
|
||||||
|
*/
|
||||||
|
public String getCurrentLogFile() {
|
||||||
|
return currentLogFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the logFileInfos
|
||||||
|
*/
|
||||||
|
public LogFileInfo[] getLogFileInfos() {
|
||||||
|
return logFileInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the garbageCollectionTime
|
||||||
|
*/
|
||||||
|
public long getGarbageCollectionTime() {
|
||||||
|
return garbageCollectionTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SystemInfo getLocalSystemInfo() {
|
||||||
|
SystemInfo si = new SystemInfo();
|
||||||
|
OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
|
||||||
|
String osInfo = os.getName() + " " + os.getVersion();
|
||||||
|
osInfo += " (" + os.getArch() + ")";
|
||||||
|
si.operatingSystem = osInfo;
|
||||||
|
si.availableProcessors = os.getAvailableProcessors();
|
||||||
|
if (os instanceof com.sun.management.OperatingSystemMXBean) {
|
||||||
|
com.sun.management.OperatingSystemMXBean extInfo = (com.sun.management.OperatingSystemMXBean) os;
|
||||||
|
si.averageSystemLoad = extInfo.getSystemCpuLoad() * 100;
|
||||||
|
} else {
|
||||||
|
si.averageSystemLoad = (os.getSystemLoadAverage() / si.availableProcessors) * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
String vm = System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version");
|
||||||
|
si.javaVM = vm;
|
||||||
|
CConnection cc = CConnection.get();
|
||||||
|
AdempiereDatabase db = cc.getDatabase();
|
||||||
|
si.databaseDescription = db.getDescription();
|
||||||
|
si.databaseConnectionURL = cc.getConnectionURL();
|
||||||
|
si.databaseStatus = cc.getDatabase().getStatus();
|
||||||
|
MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
|
||||||
|
si.memoryUsage = new CMemoryUsage(memory.getNonHeapMemoryUsage()).toString();
|
||||||
|
si.heapMemoryUsage = new CMemoryUsage(memory.getHeapMemoryUsage()).toString();
|
||||||
|
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
|
||||||
|
si.runtimeName = rt.getName();
|
||||||
|
si.runtimeUpTime = rt.getUptime();
|
||||||
|
ThreadMXBean th = ManagementFactory.getThreadMXBean();
|
||||||
|
si.threadCount = th.getThreadCount();
|
||||||
|
si.peakThreadCount = th.getPeakThreadCount();
|
||||||
|
si.daemonThreadCount = th.getDaemonThreadCount();
|
||||||
|
si.totalStartedThreadCount = th.getTotalStartedThreadCount();
|
||||||
|
si.trxInfos = TrxInfo.getActiveTransactions();
|
||||||
|
si.logLevel = CLogMgt.getLevel();
|
||||||
|
si.currentLogFile = LogFileInfo.getCurrentLogFile();
|
||||||
|
si.logFileInfos = LogFileInfo.getLogFileInfos();
|
||||||
|
si.garbageCollectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();
|
||||||
|
si.garbageCollectionCount = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionCount()).sum();
|
||||||
|
si.sessionCount = MSession.getCachedSessionCount();
|
||||||
|
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the serialversionuid
|
||||||
|
*/
|
||||||
|
public static long getSerialversionuid() {
|
||||||
|
return serialVersionUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the garbageCollectionCount
|
||||||
|
*/
|
||||||
|
public long getGarbageCollectionCount() {
|
||||||
|
return garbageCollectionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the availableProcessors
|
||||||
|
*/
|
||||||
|
public int getAvailableProcessors() {
|
||||||
|
return availableProcessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the averageSystemLoad
|
||||||
|
*/
|
||||||
|
public double getAverageSystemLoad() {
|
||||||
|
return averageSystemLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sessionCount
|
||||||
|
*/
|
||||||
|
public int getSessionCount() {
|
||||||
|
return sessionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the address
|
||||||
|
*/
|
||||||
|
public InetAddress getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeId
|
||||||
|
* @return systeminfo for cluster node
|
||||||
|
*/
|
||||||
|
public static SystemInfo getClusterNodeInfo(String nodeId) {
|
||||||
|
SystemInfo si = null;
|
||||||
|
|
||||||
|
IClusterMember member = ClusterServerMgr.getClusterMember(nodeId);
|
||||||
|
if (member != null) {
|
||||||
|
GetSystemInfoCallable callable = new GetSystemInfoCallable();
|
||||||
|
Future<SystemInfo> future = ClusterServerMgr.getClusterService().execute(callable, member);
|
||||||
|
if (future != null) {
|
||||||
|
try {
|
||||||
|
si = future.get();
|
||||||
|
si.address = member.getAddress();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param member
|
||||||
|
* @return session count for cluster node
|
||||||
|
*/
|
||||||
|
public static int getClusterSessionCount(IClusterMember member) {
|
||||||
|
IClusterService service = ClusterServerMgr.getClusterService();
|
||||||
|
if (service != null) {
|
||||||
|
GetSessionCountCallable callable = new GetSessionCountCallable();
|
||||||
|
Future<Integer> future = service.execute(callable, member);
|
||||||
|
if (future != null) {
|
||||||
|
try {
|
||||||
|
return future.get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GetSessionCountCallable implements Callable<Integer>, Serializable {
|
||||||
|
private static final long serialVersionUID = -7793108679625240698L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
return MSession.getCachedSessionCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.compiere.server;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.compiere.util.Trx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TrxInfo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -4002703843474813148L;
|
||||||
|
|
||||||
|
private String displayName;
|
||||||
|
private Date startTime;
|
||||||
|
private String stackTrace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private TrxInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TrxInfo[] getActiveTransactions() {
|
||||||
|
List<TrxInfo> list = new ArrayList<>();
|
||||||
|
Trx[] trxs = Trx.getActiveTransactions();
|
||||||
|
for (Trx trx : trxs) {
|
||||||
|
if (trx != null && trx.isActive()) {
|
||||||
|
TrxInfo ti = new TrxInfo();
|
||||||
|
ti.displayName = trx.getDisplayName();
|
||||||
|
ti.startTime = trx.getStartTime();
|
||||||
|
ti.stackTrace = trx.getStrackTrace();
|
||||||
|
list.add(ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list.toArray(new TrxInfo[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayName
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the startTime
|
||||||
|
*/
|
||||||
|
public Date getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the stackTrace
|
||||||
|
*/
|
||||||
|
public String getStackTrace() {
|
||||||
|
return stackTrace;
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,12 +79,33 @@ public class ClusterServerMgr implements IServerManager {
|
||||||
private ClusterServerMgr() {
|
private ClusterServerMgr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IClusterService getClusterService() {
|
/**
|
||||||
|
*
|
||||||
|
* @return cluster service
|
||||||
|
*/
|
||||||
|
public static IClusterService getClusterService() {
|
||||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
||||||
IClusterService service = holder != null ? holder.getService() : null;
|
IClusterService service = holder != null ? holder.getService() : null;
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeId
|
||||||
|
* @return cluster member node
|
||||||
|
*/
|
||||||
|
public static IClusterMember getClusterMember(String nodeId) {
|
||||||
|
IClusterService service = getClusterService();
|
||||||
|
if (service != null) {
|
||||||
|
Collection<IClusterMember> members = service.getMembers();
|
||||||
|
for(IClusterMember member : members) {
|
||||||
|
if (member.getId().equals(nodeId))
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerInstance getServerInstance(String serverId) {
|
public ServerInstance getServerInstance(String serverId) {
|
||||||
IClusterService service = getClusterService();
|
IClusterService service = getClusterService();
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.server.cluster.callable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.adempiere.util.LogAuthFailure;
|
||||||
|
import org.compiere.util.CLogFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DeleteLogsCallable implements Callable<Boolean>, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -5830938669376247267L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DeleteLogsCallable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
CLogFile fileHandler = CLogFile.get (false, null, false);
|
||||||
|
//
|
||||||
|
File logDir = fileHandler.getLogDirectory();
|
||||||
|
if (logDir != null && logDir.isDirectory())
|
||||||
|
{
|
||||||
|
File[] logs = logDir.listFiles();
|
||||||
|
for (int i = 0; i < logs.length; i++)
|
||||||
|
{
|
||||||
|
String fileName = logs[i].getAbsolutePath();
|
||||||
|
if (fileName.equals(fileHandler.getFileName()))
|
||||||
|
continue;
|
||||||
|
if (fileName.endsWith(LogAuthFailure.authFailureFilename)) // Do not delete login failure
|
||||||
|
continue;
|
||||||
|
logs[i].delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.server.cluster.callable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.compiere.server.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetSystemInfoCallable implements Callable<SystemInfo>, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 3496041492358893501L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
|
public GetSystemInfoCallable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SystemInfo call() throws Exception {
|
||||||
|
return SystemInfo.getLocalSystemInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.server.cluster.callable;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.Adempiere;
|
||||||
|
import org.compiere.util.CLogFile;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ReadLogCallable implements Callable<byte[]>, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 33969865104073117L;
|
||||||
|
private static final String s_dirAccessFileName = "dirAccess.txt";
|
||||||
|
private static CLogger log = CLogger.getCLogger(ReadLogCallable.class);
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
|
public ReadLogCallable(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] call() throws Exception {
|
||||||
|
CLogFile fileHandler = CLogFile.get(false, null, false);
|
||||||
|
//
|
||||||
|
// Display current log File
|
||||||
|
if (fileHandler != null && fileHandler.getFileName().equals(fileName))
|
||||||
|
fileHandler.flush();
|
||||||
|
|
||||||
|
File file = new File(fileName);
|
||||||
|
if (!file.exists() || !file.canRead()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (file.length() == 0) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
ArrayList<File> dirAccessList = getDirAcessList();
|
||||||
|
|
||||||
|
for (File dir : dirAccessList) {
|
||||||
|
if (file.getCanonicalPath().startsWith(dir.getAbsolutePath())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
log.warning("Couldn't find file in directories that allowed to access");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stream Log
|
||||||
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
|
int bufferSize = 2048; // 2k Buffer
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
//
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(bufferSize);
|
||||||
|
//
|
||||||
|
int read = 0;
|
||||||
|
while ((read = fis.read(buffer)) > 0)
|
||||||
|
baos.write(buffer, 0, read);
|
||||||
|
return baos.toByteArray();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.log(Level.SEVERE, "stream" + ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<File> getDirAcessList() {
|
||||||
|
final ArrayList<File> dirAccessList = new ArrayList<File>();
|
||||||
|
|
||||||
|
// by default has access to log directory
|
||||||
|
CLogFile fileHandler = CLogFile.get(true, null, false);
|
||||||
|
File logDir = fileHandler.getLogDirectory();
|
||||||
|
dirAccessList.add(logDir);
|
||||||
|
|
||||||
|
// load from dirAccess.properties file
|
||||||
|
String dirAccessPathName = Adempiere.getAdempiereHome() + File.separator + s_dirAccessFileName;
|
||||||
|
File dirAccessFile = new File(dirAccessPathName);
|
||||||
|
if (dirAccessFile.exists()) {
|
||||||
|
try {
|
||||||
|
BufferedReader br = new BufferedReader(new FileReader(dirAccessFile));
|
||||||
|
while (true) {
|
||||||
|
String pathName = br.readLine();
|
||||||
|
if (pathName == null)
|
||||||
|
break;
|
||||||
|
File pathDir = new File(pathName);
|
||||||
|
if (pathDir.exists() && !dirAccessList.contains(pathDir))
|
||||||
|
dirAccessList.add(pathDir);
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, dirAccessPathName + " - " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirAccessList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.server.cluster.callable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RotateLogCallable implements Callable<Boolean>, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 33969865104073117L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
|
public RotateLogCallable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
CLogFile fileHandler = CLogFile.get (false, null, false);
|
||||||
|
//
|
||||||
|
if (fileHandler != null) {
|
||||||
|
fileHandler.rotateLog();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Trek Global Corporation *
|
||||||
|
* - Heng Sin Low *
|
||||||
|
**********************************************************************/
|
||||||
|
package org.idempiere.server.cluster.callable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogMgt;
|
||||||
|
import org.compiere.util.Ini;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SetTraceLevelCallable implements Callable<Boolean>, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated serial idd
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 6699443869769763231L;
|
||||||
|
|
||||||
|
private String traceLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public SetTraceLevelCallable(String traceLevel) {
|
||||||
|
this.traceLevel = traceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
CLogMgt.setLevel(traceLevel);
|
||||||
|
Ini.setProperty(Ini.P_TRACELEVEL, traceLevel);
|
||||||
|
Ini.saveProperties(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,13 +22,10 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.MemoryMXBean;
|
|
||||||
import java.lang.management.RuntimeMXBean;
|
|
||||||
import java.lang.management.ThreadMXBean;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -40,9 +37,6 @@ import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.adempiere.base.IServiceHolder;
|
|
||||||
import org.adempiere.base.Service;
|
|
||||||
import org.adempiere.util.LogAuthFailure;
|
|
||||||
import org.apache.ecs.HtmlColor;
|
import org.apache.ecs.HtmlColor;
|
||||||
import org.apache.ecs.xhtml.a;
|
import org.apache.ecs.xhtml.a;
|
||||||
import org.apache.ecs.xhtml.b;
|
import org.apache.ecs.xhtml.b;
|
||||||
|
@ -63,8 +57,6 @@ import org.apache.ecs.xhtml.td;
|
||||||
import org.apache.ecs.xhtml.th;
|
import org.apache.ecs.xhtml.th;
|
||||||
import org.apache.ecs.xhtml.tr;
|
import org.apache.ecs.xhtml.tr;
|
||||||
import org.compiere.Adempiere;
|
import org.compiere.Adempiere;
|
||||||
import org.compiere.db.AdempiereDatabase;
|
|
||||||
import org.compiere.db.CConnection;
|
|
||||||
import org.compiere.model.AdempiereProcessorLog;
|
import org.compiere.model.AdempiereProcessorLog;
|
||||||
import org.compiere.model.MClient;
|
import org.compiere.model.MClient;
|
||||||
import org.compiere.model.MSession;
|
import org.compiere.model.MSession;
|
||||||
|
@ -75,24 +67,30 @@ import org.compiere.model.Query;
|
||||||
import org.compiere.server.AdempiereServerGroup;
|
import org.compiere.server.AdempiereServerGroup;
|
||||||
import org.compiere.server.AdempiereServerMgr;
|
import org.compiere.server.AdempiereServerMgr;
|
||||||
import org.compiere.server.IServerManager;
|
import org.compiere.server.IServerManager;
|
||||||
|
import org.compiere.server.LogFileInfo;
|
||||||
import org.compiere.server.ServerCount;
|
import org.compiere.server.ServerCount;
|
||||||
import org.compiere.server.ServerInstance;
|
import org.compiere.server.ServerInstance;
|
||||||
|
import org.compiere.server.SystemInfo;
|
||||||
|
import org.compiere.server.TrxInfo;
|
||||||
import org.compiere.util.CLogFile;
|
import org.compiere.util.CLogFile;
|
||||||
import org.compiere.util.CLogMgt;
|
import org.compiere.util.CLogMgt;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.CMemoryUsage;
|
import org.compiere.util.CacheInfo;
|
||||||
import org.compiere.util.CacheMgt;
|
import org.compiere.util.CacheMgt;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Ini;
|
|
||||||
import org.compiere.util.TimeUtil;
|
import org.compiere.util.TimeUtil;
|
||||||
import org.compiere.util.Trx;
|
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
import org.compiere.util.WebDoc;
|
import org.compiere.util.WebDoc;
|
||||||
import org.compiere.util.WebEnv;
|
import org.compiere.util.WebEnv;
|
||||||
import org.compiere.util.WebUtil;
|
import org.compiere.util.WebUtil;
|
||||||
|
import org.idempiere.distributed.IClusterMember;
|
||||||
import org.idempiere.distributed.IClusterService;
|
import org.idempiere.distributed.IClusterService;
|
||||||
import org.idempiere.server.cluster.ClusterServerMgr;
|
import org.idempiere.server.cluster.ClusterServerMgr;
|
||||||
|
import org.idempiere.server.cluster.callable.DeleteLogsCallable;
|
||||||
|
import org.idempiere.server.cluster.callable.ReadLogCallable;
|
||||||
|
import org.idempiere.server.cluster.callable.RotateLogCallable;
|
||||||
|
import org.idempiere.server.cluster.callable.SetTraceLevelCallable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adempiere Server Monitor
|
* Adempiere Server Monitor
|
||||||
|
@ -155,6 +153,12 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
createXMLSummaryPage(request, response);
|
createXMLSummaryPage(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (processNodeInfoPage(request, response))
|
||||||
|
{
|
||||||
|
if (xmlOutput)
|
||||||
|
createXMLSummaryPage(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
if (processRunNowParameter (request))
|
if (processRunNowParameter (request))
|
||||||
;
|
;
|
||||||
|
@ -366,12 +370,26 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
{
|
{
|
||||||
String traceCmd = WebUtil.getParameter (request, "Trace");
|
String traceCmd = WebUtil.getParameter (request, "Trace");
|
||||||
String traceLevel = WebUtil.getParameter (request, "TraceLevel");
|
String traceLevel = WebUtil.getParameter (request, "TraceLevel");
|
||||||
|
String nodeId = WebUtil.getParameter (request, "nodeId");
|
||||||
if (traceLevel != null && traceLevel.length() > 0)
|
if (traceLevel != null && traceLevel.length() > 0)
|
||||||
{
|
{
|
||||||
if (log.isLoggable(Level.INFO)) log.info ("New Level: " + traceLevel);
|
if (log.isLoggable(Level.INFO)) log.info ("New Level: " + traceLevel);
|
||||||
CLogMgt.setLevel(traceLevel);
|
SetTraceLevelCallable callable = new SetTraceLevelCallable(traceLevel);
|
||||||
Ini.setProperty(Ini.P_TRACELEVEL, traceLevel);
|
try
|
||||||
Ini.saveProperties(false);
|
{
|
||||||
|
if (!Util.isEmpty(nodeId, true))
|
||||||
|
{
|
||||||
|
ClusterServerMgr.getClusterService().execute(callable, ClusterServerMgr.getClusterMember(nodeId)).get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callable.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,32 +401,68 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
//
|
//
|
||||||
if (traceCmd.equals("ROTATE"))
|
if (traceCmd.equals("ROTATE"))
|
||||||
{
|
{
|
||||||
if (fileHandler != null)
|
RotateLogCallable callable = new RotateLogCallable();
|
||||||
fileHandler.rotateLog();
|
try
|
||||||
|
{
|
||||||
|
if (!Util.isEmpty(nodeId, true))
|
||||||
|
{
|
||||||
|
ClusterServerMgr.getClusterService().execute(callable, ClusterServerMgr.getClusterMember(nodeId)).get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callable.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
return false; // re-display
|
return false; // re-display
|
||||||
}
|
}
|
||||||
else if (traceCmd.equals("DELETE"))
|
else if (traceCmd.equals("DELETE"))
|
||||||
{
|
{
|
||||||
File logDir = fileHandler.getLogDirectory();
|
DeleteLogsCallable callable = new DeleteLogsCallable();
|
||||||
if (logDir != null && logDir.isDirectory())
|
try
|
||||||
{
|
{
|
||||||
File[] logs = logDir.listFiles();
|
if (!Util.isEmpty(nodeId, true))
|
||||||
for (int i = 0; i < logs.length; i++)
|
|
||||||
{
|
{
|
||||||
String fileName = logs[i].getAbsolutePath();
|
ClusterServerMgr.getClusterService().execute(callable, ClusterServerMgr.getClusterMember(nodeId)).get();
|
||||||
if (fileName.equals(fileHandler.getFileName()))
|
}
|
||||||
continue;
|
else
|
||||||
if (fileName.endsWith(LogAuthFailure.authFailureFilename)) // Do not delete login failure
|
{
|
||||||
continue;
|
callable.call();
|
||||||
if (logs[i].delete())
|
|
||||||
log.warning("Deleted: " + fileName);
|
|
||||||
else
|
|
||||||
log.warning("Not Deleted: " + fileName);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return false; // re-display
|
return false; // re-display
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Util.isEmpty(nodeId, true))
|
||||||
|
{
|
||||||
|
ReadLogCallable callable = new ReadLogCallable(traceCmd);
|
||||||
|
try {
|
||||||
|
byte[] contents = ClusterServerMgr.getClusterService().execute(callable, ClusterServerMgr.getClusterMember(nodeId)).get();
|
||||||
|
if (contents == null || contents.length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try(ServletOutputStream out = response.getOutputStream ())
|
||||||
|
{
|
||||||
|
response.setContentType("text/plain");
|
||||||
|
response.setBufferSize(2048);
|
||||||
|
response.setContentLength(contents.length);
|
||||||
|
out.write(contents);
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.WARNING, e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Display current log File
|
// Display current log File
|
||||||
if (fileHandler != null && fileHandler.getFileName().equals(traceCmd))
|
if (fileHandler != null && fileHandler.getFileName().equals(traceCmd))
|
||||||
fileHandler.flush();
|
fileHandler.flush();
|
||||||
|
@ -538,7 +592,8 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
{
|
{
|
||||||
String cmd = WebUtil.getParameter (request, "CacheReset");
|
String cmd = WebUtil.getParameter (request, "CacheReset");
|
||||||
if (cmd == null || cmd.length() == 0)
|
if (cmd == null || cmd.length() == 0)
|
||||||
return false;
|
return createCacheDetailsPage(request, response);
|
||||||
|
|
||||||
String tableName = WebUtil.getParameter (request, "CacheTableName");
|
String tableName = WebUtil.getParameter (request, "CacheTableName");
|
||||||
String record_ID = WebUtil.getParameter (request, "CacheRecord_ID");
|
String record_ID = WebUtil.getParameter (request, "CacheRecord_ID");
|
||||||
|
|
||||||
|
@ -628,15 +683,56 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
bb.addElement(table);
|
bb.addElement(table);
|
||||||
|
|
||||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
IClusterService service = ClusterServerMgr.getClusterService();
|
||||||
IClusterService service = holder != null ? holder.getService() : null;
|
Collection<IClusterMember> members = null;
|
||||||
if (service != null && service.getLocalMember() != null)
|
IClusterMember local = null;
|
||||||
|
if (service != null)
|
||||||
{
|
{
|
||||||
line = new tr();
|
members = service.getMembers();
|
||||||
line.addElement(new th().addElement("Cluster Node Id"));
|
local = service.getLocalMember();
|
||||||
line.addElement(new td().addElement(WebEnv.getCellContent(service.getLocalMember().getId())));
|
if (members.size() > 1 && local != null)
|
||||||
table.addElement(line);
|
{
|
||||||
bb.addElement(table);
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Cluster Nodes"));
|
||||||
|
p para = new p();
|
||||||
|
StringBuilder nodeBuilder = new StringBuilder(local.getId());
|
||||||
|
InetAddress address = local.getAddress();
|
||||||
|
String ip = address != null ? address.getHostAddress() : null;
|
||||||
|
if (ip != null &&
|
||||||
|
(ip.startsWith("10.") ||
|
||||||
|
ip.startsWith("172.16") ||
|
||||||
|
ip.startsWith("192.168")))
|
||||||
|
{
|
||||||
|
nodeBuilder.append(" (").append(ip).append(")");
|
||||||
|
}
|
||||||
|
para.addElement(nodeBuilder.toString());
|
||||||
|
|
||||||
|
for(IClusterMember member : members)
|
||||||
|
{
|
||||||
|
if (member.getId().equals(local.getId()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
para.addElement(" - ");
|
||||||
|
nodeBuilder = new StringBuilder(member.getId());
|
||||||
|
address = member.getAddress();
|
||||||
|
ip = address != null ? address.getHostAddress() : null;
|
||||||
|
if (ip != null &&
|
||||||
|
(ip.startsWith("10.") ||
|
||||||
|
ip.startsWith("172.16") ||
|
||||||
|
ip.startsWith("192.168")))
|
||||||
|
{
|
||||||
|
nodeBuilder.append(" (").append(ip).append(")");
|
||||||
|
}
|
||||||
|
a link = new a ("idempiereMonitor?NodeInfo="+member.getId(), nodeBuilder.toString());
|
||||||
|
para.addElement(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line.addElement(new td().addElement(para));
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
p para = new p();
|
p para = new p();
|
||||||
|
@ -674,7 +770,7 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
bb.addElement(para);
|
bb.addElement(para);
|
||||||
|
|
||||||
// **** Log Management ****
|
// **** Log Management ****
|
||||||
createLogMgtPage(bb);
|
createLogMgtPage(bb, members, local);
|
||||||
|
|
||||||
// ***** Server Details *****
|
// ***** Server Details *****
|
||||||
bb.removeEndEndModifier();
|
bb.removeEndEndModifier();
|
||||||
|
@ -749,7 +845,7 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
line.addElement(new td().addElement(server.getStatistics()));
|
line.addElement(new td().addElement(server.getStatistics()));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
//
|
//
|
||||||
if (server.getClusterMember() != null)
|
if (server.getClusterMember() != null && members != null && members.size() > 1)
|
||||||
{
|
{
|
||||||
InetAddress address = server.getClusterMember().getAddress();
|
InetAddress address = server.getClusterMember().getAddress();
|
||||||
String ip = address != null ? address.getHostAddress() : null;
|
String ip = address != null ? address.getHostAddress() : null;
|
||||||
|
@ -785,7 +881,7 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
// fini
|
// fini
|
||||||
WebUtil.createResponse (request, response, this, null, doc, false);
|
WebUtil.createResponse (request, response, this, null, doc, false);
|
||||||
} // createSummaryPage
|
} // createSummaryPage
|
||||||
|
|
||||||
private String createServerCountMessage(ServerCount serverCount) {
|
private String createServerCountMessage(ServerCount serverCount) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
@ -904,8 +1000,10 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
/**
|
/**
|
||||||
* Add Log Management to page
|
* Add Log Management to page
|
||||||
* @param bb body
|
* @param bb body
|
||||||
|
* @param members
|
||||||
|
* @param local
|
||||||
*/
|
*/
|
||||||
private void createLogMgtPage (body bb)
|
private void createLogMgtPage (body bb, Collection<IClusterMember> members, IClusterMember local)
|
||||||
{
|
{
|
||||||
bb.addElement(new hr());
|
bb.addElement(new hr());
|
||||||
|
|
||||||
|
@ -917,95 +1015,91 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
//
|
//
|
||||||
Properties ctx = new Properties();
|
Properties ctx = new Properties();
|
||||||
MSystem system = MSystem.get(ctx);
|
MSystem system = MSystem.get(ctx);
|
||||||
|
SystemInfo systemInfo = SystemInfo.getLocalSystemInfo();
|
||||||
tr line = new tr();
|
tr line = new tr();
|
||||||
line.addElement(new th().addElement(system.getDBAddress()));
|
line.addElement(new th().addElement(Adempiere.getURL()));
|
||||||
line.addElement(new td().addElement(Ini.getAdempiereHome()));
|
line.addElement(new td().addElement(Adempiere.getAdempiereHome()));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// OS + Name
|
// OS + Name
|
||||||
line = new tr();
|
line = new tr();
|
||||||
String info = System.getProperty("os.name")
|
line.addElement(new th().addElement(systemInfo.getOperatingSystem()));
|
||||||
+ " " + System.getProperty("os.version");
|
String info = system.getName();
|
||||||
String s = System.getProperty("sun.os.patch.level");
|
|
||||||
if (s != null && s.length() > 0)
|
|
||||||
info += " (" + s + ")";
|
|
||||||
line.addElement(new th().addElement(info));
|
|
||||||
info = system.getName();
|
|
||||||
if (system.getCustomPrefix() != null)
|
if (system.getCustomPrefix() != null)
|
||||||
info += " (" + system.getCustomPrefix() + ")";
|
info += " (" + system.getCustomPrefix() + ")";
|
||||||
line.addElement(new td().addElement(info));
|
line.addElement(new td().addElement(info));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// Java + email
|
// Java + email
|
||||||
line = new tr();
|
line = new tr();
|
||||||
info = System.getProperty("java.vm.name")
|
line.addElement(new th().addElement(systemInfo.getJavaVM()));
|
||||||
+ " " + System.getProperty("java.vm.version");
|
line.addElement(new td().addElement(system.getSupportEMail()));
|
||||||
line.addElement(new th().addElement(info));
|
|
||||||
line.addElement(new td().addElement(system.getUserName()));
|
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// DB + Instance
|
// DB + Instance
|
||||||
line = new tr();
|
line = new tr();
|
||||||
CConnection cc = CConnection.get();
|
line.addElement(new th().addElement(systemInfo.getDatabaseDescription()));
|
||||||
AdempiereDatabase db = cc.getDatabase();
|
line.addElement(new td().addElement(systemInfo.getDatabaseConnectionURL()));
|
||||||
info = db.getDescription();
|
|
||||||
line.addElement(new th().addElement(info));
|
|
||||||
line.addElement(new td().addElement(cc.getConnectionURL()));
|
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
line = new tr();
|
line = new tr();
|
||||||
line.addElement(new th().addElement("DB Connection Pool"));
|
line.addElement(new th().addElement("DB Connection Pool"));
|
||||||
line.addElement(new td().addElement(cc.getDatabase().getStatus()));
|
line.addElement(new td().addElement(systemInfo.getDatabaseStatus()));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// Processors/Support
|
// Processors/Support
|
||||||
line = new tr();
|
line = new tr();
|
||||||
line.addElement(new th().addElement("Processor/Support"));
|
line.addElement(new th().addElement("Processor"));
|
||||||
line.addElement(new td().addElement(system.getNoProcessors() + "/" + system.getSupportUnits()));
|
line.addElement(new td().addElement(systemInfo.getAvailableProcessors()+""));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
|
if (systemInfo.getAverageSystemLoad() >= 0)
|
||||||
|
{
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("System Load"));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getAverageSystemLoad()+"%"));
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
// Memory
|
// Memory
|
||||||
line = new tr();
|
line = new tr();
|
||||||
MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
|
|
||||||
line.addElement(new th().addElement("VM Memory"));
|
line.addElement(new th().addElement("VM Memory"));
|
||||||
line.addElement(new td().addElement(new CMemoryUsage(memory.getNonHeapMemoryUsage()).toString()));
|
line.addElement(new td().addElement(systemInfo.getMemoryUsage()));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
line = new tr();
|
line = new tr();
|
||||||
line.addElement(new th().addElement("Heap Memory"));
|
line.addElement(new th().addElement("Heap Memory"));
|
||||||
line.addElement(new td().addElement(new CMemoryUsage(memory.getHeapMemoryUsage()).toString()));
|
line.addElement(new td().addElement(systemInfo.getHeapMemoryUsage()));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// Runtime
|
// Runtime
|
||||||
line = new tr();
|
line = new tr();
|
||||||
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
|
line.addElement(new th().addElement("Runtime " + systemInfo.getRuntimeName()));
|
||||||
line.addElement(new th().addElement("Runtime " + rt.getName()));
|
line.addElement(new td().addElement(TimeUtil.formatElapsed(systemInfo.getRuntimeUpTime())));
|
||||||
line.addElement(new td().addElement(TimeUtil.formatElapsed(rt.getUptime())));
|
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
// Threads
|
// Threads
|
||||||
line = new tr();
|
line = new tr();
|
||||||
ThreadMXBean th = ManagementFactory.getThreadMXBean();
|
line.addElement(new th().addElement("Threads " + systemInfo.getThreadCount()));
|
||||||
line.addElement(new th().addElement("Threads " + th.getThreadCount()));
|
line.addElement(new td().addElement("Peak=" + systemInfo.getPeakThreadCount()
|
||||||
line.addElement(new td().addElement("Peak=" + th.getPeakThreadCount()
|
+ ", Daemons=" + systemInfo.getDaemonThreadCount()
|
||||||
+ ", Demons=" + th.getDaemonThreadCount()
|
+ ", Total=" + systemInfo.getTotalStartedThreadCount()));
|
||||||
+ ", Total=" + th.getTotalStartedThreadCount()));
|
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
|
|
||||||
//Transactions
|
//Transactions
|
||||||
Trx[] trxs = Trx.getActiveTransactions();
|
TrxInfo[] trxs = systemInfo.getTrxInfos();
|
||||||
for (Trx trx : trxs)
|
for (TrxInfo trx : trxs)
|
||||||
{
|
{
|
||||||
if (trx != null && trx.isActive())
|
line = new tr();
|
||||||
{
|
line.addElement(new th().addElement("Active Transaction "));
|
||||||
line = new tr();
|
td td = new td();
|
||||||
line.addElement(new th().addElement("Active Transaction "));
|
td.setOnClick("var newwindow=window.open('','Popup', 'width=800,height=600');newwindow.document.write('<title>" + escapeEcmaScript(trx.getDisplayName()) +"</title>"
|
||||||
td td = new td();
|
+ "<pre>" + escapeEcmaScript(trx.getStackTrace()) + "</pre>')");
|
||||||
td.setOnClick("var newwindow=window.open('','Popup', 'width=800,height=600');newwindow.document.write('<title>" + escapeEcmaScript(trx.getDisplayName()) +"</title>"
|
td.addElement("Name="+trx.getDisplayName() + ", StartTime=" + trx.getStartTime());
|
||||||
+ "<pre>" + escapeEcmaScript(trx.getStrackTrace()) + "</pre>')");
|
td.setTitle("Click to see stack trace");
|
||||||
td.addElement("Name="+trx.getDisplayName() + ", StartTime=" + trx.getStartTime());
|
td.setStyle("text-decoration: underline; color: blue");
|
||||||
td.setTitle("Click to see stack trace");
|
line.addElement(td);
|
||||||
td.setStyle("text-decoration: underline; color: blue");
|
table.addElement(line);
|
||||||
line.addElement(td);
|
|
||||||
table.addElement(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache Reset
|
// Cache Reset
|
||||||
line = new tr();
|
line = new tr();
|
||||||
line.addElement(new th().addElement(CacheMgt.get().toStringX()));
|
line.addElement(new th().addElement(CacheMgt.get().toStringX()));
|
||||||
line.addElement(new td().addElement(new a ("idempiereMonitor?CacheReset=Yes", "Reset Cache")));
|
p cachePara = new p();
|
||||||
|
cachePara.addElement(new a ("idempiereMonitor?CacheReset=Yes", "Reset Cache"))
|
||||||
|
.addElement(" - ")
|
||||||
|
.addElement(new a ("idempiereMonitor?CacheDetails=Yes", "Cache Details"));
|
||||||
|
line.addElement(new td().addElement(cachePara));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
|
|
||||||
// Trace Level
|
// Trace Level
|
||||||
|
@ -1018,7 +1112,7 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
{
|
{
|
||||||
options[i] = new option(CLogMgt.LEVELS[i].getName());
|
options[i] = new option(CLogMgt.LEVELS[i].getName());
|
||||||
options[i].addElement(CLogMgt.LEVELS[i].getName());
|
options[i].addElement(CLogMgt.LEVELS[i].getName());
|
||||||
if (CLogMgt.LEVELS[i] == CLogMgt.getLevel())
|
if (CLogMgt.LEVELS[i] == systemInfo.getLogLevel())
|
||||||
options[i].setSelected(true);
|
options[i].setSelected(true);
|
||||||
}
|
}
|
||||||
select sel = new select("TraceLevel", options);
|
select sel = new select("TraceLevel", options);
|
||||||
|
@ -1028,14 +1122,17 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
//
|
//
|
||||||
line = new tr();
|
line = new tr();
|
||||||
CLogFile fileHandler = CLogFile.get (true, null, false);
|
|
||||||
line.addElement(new th().addElement("Trace File"));
|
line.addElement(new th().addElement("Trace File"));
|
||||||
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=" + fileHandler.getFileName(), "Current")));
|
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=" + systemInfo.getCurrentLogFile(), "Current")));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
//
|
//
|
||||||
line = new tr();
|
line = new tr();
|
||||||
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=ROTATE", "Rotate Trace Log")));
|
p tlp = new p();
|
||||||
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=DELETE", "Delete all Trace Logs")));
|
tlp.addElement(new a ("idempiereMonitor?Trace=ROTATE", "Rotate Trace Log"))
|
||||||
|
.addElement(" - ")
|
||||||
|
.addElement(new a ("idempiereMonitor?Trace=DELETE", "Delete all Trace Logs"));
|
||||||
|
line.addElement(new th());
|
||||||
|
line.addElement(new td().addElement(tlp));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
//
|
//
|
||||||
bb.addElement(table);
|
bb.addElement(table);
|
||||||
|
@ -1044,28 +1141,20 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
p p = new p();
|
p p = new p();
|
||||||
p.addElement(new b("All Log Files: "));
|
p.addElement(new b("All Log Files: "));
|
||||||
// All in dir
|
// All in dir
|
||||||
File logDir = fileHandler.getLogDirectory();
|
LogFileInfo logFiles[] = systemInfo.getLogFileInfos();
|
||||||
if (logDir != null && logDir.isDirectory())
|
for (LogFileInfo logFile : logFiles)
|
||||||
{
|
{
|
||||||
File[] logs = logDir.listFiles();
|
if (logFile != logFiles[0])
|
||||||
for (int i = 0; i < logs.length; i++)
|
p.addElement(" - ");
|
||||||
{
|
String fileName = logFile.getFileName();
|
||||||
// Skip if is not a file - teo_sarca [ 1726066 ]
|
a link = new a ("idempiereMonitor?Trace=" + fileName, fileName);
|
||||||
if (!logs[i].isFile())
|
p.addElement(link);
|
||||||
continue;
|
int size = (int)(logFile.getFileSize()/1024);
|
||||||
|
if (size < 1024)
|
||||||
if (i != 0)
|
p.addElement(" (" + size + "k)");
|
||||||
p.addElement(" - ");
|
else
|
||||||
String fileName = logs[i].getAbsolutePath();
|
p.addElement(" (" + size/1024 + "M)");
|
||||||
a link = new a ("idempiereMonitor?Trace=" + fileName, fileName);
|
}
|
||||||
p.addElement(link);
|
|
||||||
int size = (int)(logs[i].length()/1024);
|
|
||||||
if (size < 1024)
|
|
||||||
p.addElement(" (" + size + "k)");
|
|
||||||
else
|
|
||||||
p.addElement(" (" + size/1024 + "M)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bb.addElement(p);
|
bb.addElement(p);
|
||||||
|
|
||||||
// Clients and Web Stores
|
// Clients and Web Stores
|
||||||
|
@ -1131,6 +1220,20 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
p.addElement(" ");
|
p.addElement(" ");
|
||||||
line.addElement(new td().addElement(p));
|
line.addElement(new td().addElement(p));
|
||||||
table.addElement(line);
|
table.addElement(line);
|
||||||
|
if (members != null && members.size() > 1) {
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement(""));
|
||||||
|
p = null;
|
||||||
|
for(IClusterMember member : members) {
|
||||||
|
if (p == null)
|
||||||
|
p = new p();
|
||||||
|
else
|
||||||
|
p.addElement(" - ");
|
||||||
|
p.addElement(member.getId() + " : " + ((member.getId().equals(local.getId())) ? systemInfo.getSessionCount() : SystemInfo.getClusterSessionCount(member)));
|
||||||
|
}
|
||||||
|
line.addElement(new td().addElement(p));
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
line = new tr();
|
line = new tr();
|
||||||
|
|
||||||
|
@ -1187,9 +1290,7 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
m_serverMgr = AdempiereServerMgr.get();
|
m_serverMgr = AdempiereServerMgr.get();
|
||||||
|
|
||||||
//switch to cluster manager if cluster service is available
|
//switch to cluster manager if cluster service is available
|
||||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
if (ClusterServerMgr.getClusterService() != null)
|
||||||
IClusterService service = holder != null ? holder.getService() : null;
|
|
||||||
if (service != null)
|
|
||||||
m_serverMgr = ClusterServerMgr.getInstance();
|
m_serverMgr = ClusterServerMgr.getInstance();
|
||||||
|
|
||||||
m_dirAccessList = getDirAcessList();
|
m_dirAccessList = getDirAcessList();
|
||||||
|
@ -1307,4 +1408,257 @@ public class AdempiereMonitor extends HttpServlet
|
||||||
input = input.replace("\t", "\\t");
|
input = input.replace("\t", "\\t");
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return cache details page
|
||||||
|
* @param request request
|
||||||
|
* @param response response
|
||||||
|
* @return true if it was a cache details request
|
||||||
|
* @throws ServletException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private boolean createCacheDetailsPage (HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
String cmd = WebUtil.getParameter (request, "CacheDetails");
|
||||||
|
if (cmd == null || cmd.length() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WebDoc doc = WebDoc.create ("iDempiere Server Cache Details");
|
||||||
|
// Body
|
||||||
|
body b = doc.getBody();
|
||||||
|
//
|
||||||
|
p para = new p();
|
||||||
|
a link = new a ("idempiereMonitor", "Return");
|
||||||
|
para.addElement(link);
|
||||||
|
b.addElement(para);
|
||||||
|
//
|
||||||
|
table table = new table();
|
||||||
|
table.setBorder(1);
|
||||||
|
table.setCellSpacing(2);
|
||||||
|
table.setCellPadding(2);
|
||||||
|
|
||||||
|
// Header
|
||||||
|
tr line = new tr();
|
||||||
|
line.addElement(new th().addElement("Name"));
|
||||||
|
line.addElement(new th().addElement("Table Name"));
|
||||||
|
line.addElement(new th().addElement("Size"));
|
||||||
|
line.addElement(new th().addElement("Expire (Minutes)"));
|
||||||
|
line.addElement(new th().addElement("Max Size"));
|
||||||
|
line.addElement(new th().addElement("Distributed"));
|
||||||
|
table.addElement(line);
|
||||||
|
|
||||||
|
List<CacheInfo> instances = CacheInfo.getCacheInfos(true);
|
||||||
|
if (instances.size() > 0 && instances.get(0).getNodeId() != null)
|
||||||
|
{
|
||||||
|
line.addElement(new th().addElement("Node Id"));
|
||||||
|
}
|
||||||
|
for (CacheInfo ccache : instances)
|
||||||
|
{
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getName())));
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getTableName())));
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getSize())));
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getExpireMinutes())));
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getMaxSize())));
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.isDistributed())));
|
||||||
|
if (ccache.getNodeId() != null)
|
||||||
|
{
|
||||||
|
line.addElement(new td().addElement(WebEnv.getCellContent(ccache.getNodeId())));
|
||||||
|
}
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
b.addElement(table);
|
||||||
|
link = new a ("#top", "Top");
|
||||||
|
b.addElement(link);
|
||||||
|
|
||||||
|
// fini
|
||||||
|
WebUtil.createResponse (request, response, this, null, doc, false);
|
||||||
|
return true;
|
||||||
|
} // processLogParameter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return cache details page
|
||||||
|
* @param request request
|
||||||
|
* @param response response
|
||||||
|
* @return true if it was a cache details request
|
||||||
|
* @throws ServletException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public boolean processNodeInfoPage (HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
String nodeId = WebUtil.getParameter (request, "NodeInfo");
|
||||||
|
if (nodeId == null || nodeId.length() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WebDoc doc = WebDoc.create ("Details for node " + nodeId);
|
||||||
|
// Body
|
||||||
|
body b = doc.getBody();
|
||||||
|
p para = new p();
|
||||||
|
a link = new a ("idempiereMonitor", "Return");
|
||||||
|
para.addElement(link);
|
||||||
|
b.addElement(para);
|
||||||
|
|
||||||
|
createNodeInfoPage(b, nodeId);
|
||||||
|
|
||||||
|
WebUtil.createResponse (request, response, this, null, doc, false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createNodeInfoPage (body bb, String nodeId)
|
||||||
|
{
|
||||||
|
SystemInfo systemInfo = SystemInfo.getClusterNodeInfo(nodeId);
|
||||||
|
if (systemInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bb.addElement(new hr());
|
||||||
|
|
||||||
|
table table = new table();
|
||||||
|
table.setBorder(1);
|
||||||
|
table.setCellSpacing(2);
|
||||||
|
table.setCellPadding(2);
|
||||||
|
|
||||||
|
InetAddress address = systemInfo.getAddress();
|
||||||
|
String ip = address != null ? address.getHostAddress() : null;
|
||||||
|
if (ip != null &&
|
||||||
|
(ip.startsWith("10.") ||
|
||||||
|
ip.startsWith("172.16") ||
|
||||||
|
ip.startsWith("192.168")))
|
||||||
|
{
|
||||||
|
tr line = new tr();
|
||||||
|
line.addElement(new th().addElement("IP Address"));
|
||||||
|
line.addElement(new td().addElement(ip));
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OS + Name
|
||||||
|
tr line = new tr();
|
||||||
|
line.addElement(new th().addElement(systemInfo.getOperatingSystem()));
|
||||||
|
table.addElement(line);
|
||||||
|
// Java + email
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement(systemInfo.getJavaVM()));
|
||||||
|
table.addElement(line);
|
||||||
|
// DB + Instance
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement(systemInfo.getDatabaseDescription()));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getDatabaseConnectionURL()));
|
||||||
|
table.addElement(line);
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("DB Connection Pool"));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getDatabaseStatus()));
|
||||||
|
table.addElement(line);
|
||||||
|
// Processors/Support
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Processor (Average System Load)"));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getAvailableProcessors() + " ("
|
||||||
|
+ systemInfo.getAverageSystemLoad() + ") "));
|
||||||
|
table.addElement(line);
|
||||||
|
// Memory
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("VM Memory"));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getMemoryUsage()));
|
||||||
|
table.addElement(line);
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Heap Memory"));
|
||||||
|
line.addElement(new td().addElement(systemInfo.getHeapMemoryUsage()));
|
||||||
|
table.addElement(line);
|
||||||
|
// Runtime
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Runtime " + systemInfo.getRuntimeName()));
|
||||||
|
line.addElement(new td().addElement(TimeUtil.formatElapsed(systemInfo.getRuntimeUpTime())));
|
||||||
|
table.addElement(line);
|
||||||
|
// Threads
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Threads " + systemInfo.getThreadCount()));
|
||||||
|
line.addElement(new td().addElement("Peak=" + systemInfo.getPeakThreadCount()
|
||||||
|
+ ", Daemons=" + systemInfo.getDaemonThreadCount()
|
||||||
|
+ ", Total=" + systemInfo.getTotalStartedThreadCount()));
|
||||||
|
table.addElement(line);
|
||||||
|
|
||||||
|
//Transactions
|
||||||
|
TrxInfo[] trxs = systemInfo.getTrxInfos();
|
||||||
|
for (TrxInfo trx : trxs)
|
||||||
|
{
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Active Transaction "));
|
||||||
|
td td = new td();
|
||||||
|
td.setOnClick("var newwindow=window.open('','Popup', 'width=800,height=600');newwindow.document.write('<title>" + escapeEcmaScript(trx.getDisplayName()) +"</title>"
|
||||||
|
+ "<pre>" + escapeEcmaScript(trx.getStackTrace()) + "</pre>')");
|
||||||
|
td.addElement("Name="+trx.getDisplayName() + ", StartTime=" + trx.getStartTime());
|
||||||
|
td.setTitle("Click to see stack trace");
|
||||||
|
td.setStyle("text-decoration: underline; color: blue");
|
||||||
|
line.addElement(td);
|
||||||
|
table.addElement(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace Level
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement(new label("TraceLevel").addElement("Trace Log Level")));
|
||||||
|
form myForm = new form("idempiereMonitor", form.METHOD_POST, form.ENC_DEFAULT);
|
||||||
|
// LogLevel Selection
|
||||||
|
option[] options = new option[CLogMgt.LEVELS.length];
|
||||||
|
for (int i = 0; i < options.length; i++)
|
||||||
|
{
|
||||||
|
options[i] = new option(CLogMgt.LEVELS[i].getName());
|
||||||
|
options[i].addElement(CLogMgt.LEVELS[i].getName());
|
||||||
|
if (CLogMgt.LEVELS[i] == systemInfo.getLogLevel())
|
||||||
|
options[i].setSelected(true);
|
||||||
|
}
|
||||||
|
select sel = new select("TraceLevel", options);
|
||||||
|
myForm.addElement(sel);
|
||||||
|
myForm.addElement(new input(input.TYPE_HIDDEN, "nodeId", nodeId));
|
||||||
|
myForm.addElement(new input(input.TYPE_SUBMIT, "Set", "Set"));
|
||||||
|
line.addElement(new td().addElement(myForm));
|
||||||
|
table.addElement(line);
|
||||||
|
//
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Trace File"));
|
||||||
|
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=" + systemInfo.getCurrentLogFile()
|
||||||
|
+ "&nodeId=" + nodeId, "Current")));
|
||||||
|
table.addElement(line);
|
||||||
|
//
|
||||||
|
line = new tr();
|
||||||
|
p tlp = new p();
|
||||||
|
tlp.addElement(new a ("idempiereMonitor?Trace=ROTATE&nodeId="+nodeId, "Rotate Trace Log"))
|
||||||
|
.addElement(" - ")
|
||||||
|
.addElement(new a ("idempiereMonitor?Trace=DELETE&nodeId="+nodeId, "Delete all Trace Logs"));
|
||||||
|
line.addElement(new th());
|
||||||
|
line.addElement(new td().addElement(tlp));
|
||||||
|
table.addElement(line);
|
||||||
|
//
|
||||||
|
bb.addElement(table);
|
||||||
|
|
||||||
|
// List Log Files
|
||||||
|
p p = new p();
|
||||||
|
p.addElement(new b("All Log Files: "));
|
||||||
|
// All in dir
|
||||||
|
LogFileInfo logFiles[] = systemInfo.getLogFileInfos();
|
||||||
|
for (LogFileInfo logFile : logFiles)
|
||||||
|
{
|
||||||
|
if (logFile != logFiles[0])
|
||||||
|
p.addElement(" - ");
|
||||||
|
String fileName = logFile.getFileName();
|
||||||
|
a link = new a ("idempiereMonitor?Trace=" + fileName + "&nodeId="+nodeId, fileName);
|
||||||
|
p.addElement(link);
|
||||||
|
int size = (int)(logFile.getFileSize()/1024);
|
||||||
|
if (size < 1024)
|
||||||
|
p.addElement(" (" + size + "k)");
|
||||||
|
else
|
||||||
|
p.addElement(" (" + size/1024 + "M)");
|
||||||
|
}
|
||||||
|
bb.addElement(p);
|
||||||
|
|
||||||
|
//
|
||||||
|
line = new tr();
|
||||||
|
line.addElement(new th().addElement("Active sessions for node" ));
|
||||||
|
line.addElement(new td().addElement(""+systemInfo.getSessionCount()));
|
||||||
|
table.addElement(line);
|
||||||
|
//
|
||||||
|
bb.addElement(table);
|
||||||
|
}
|
||||||
|
|
||||||
} // AdempiereMonitor
|
} // AdempiereMonitor
|
||||||
|
|
Loading…
Reference in New Issue