merge
This commit is contained in:
commit
6212631566
|
@ -319,5 +319,12 @@ public class MSession extends X_AD_Session
|
|||
return null;
|
||||
} // changeLog
|
||||
|
||||
/**
|
||||
*
|
||||
* @return number of cached sessions
|
||||
*/
|
||||
public static int getCachedSessionCount() {
|
||||
return s_sessions.size()-1;
|
||||
}
|
||||
} // MSession
|
||||
|
||||
|
|
|
@ -427,4 +427,8 @@ public class CCache<K,V> implements CacheInterface, Map<K, V>, Serializable
|
|||
public int getMaxSize() {
|
||||
return m_maxSize;
|
||||
}
|
||||
|
||||
public boolean isDistributed() {
|
||||
return m_distributed;
|
||||
}
|
||||
} // 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.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -385,6 +386,21 @@ public class CacheMgt
|
|||
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> {
|
||||
/**
|
||||
* 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 int Record_ID;
|
||||
|
||||
protected ResetCacheCallable(String tableName, int Record_ID)
|
||||
public ResetCacheCallable(String tableName, int Record_ID)
|
||||
{
|
||||
this.tableName = tableName;
|
||||
this.Record_ID = Record_ID;
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.compiere.util.Env;
|
|||
import org.idempiere.distributed.ICacheService;
|
||||
import org.idempiere.distributed.IClusterMember;
|
||||
import org.idempiere.distributed.IClusterService;
|
||||
import org.idempiere.server.cluster.ClusterServerMgr;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
@ -840,14 +841,8 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
|
|||
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() {
|
||||
IClusterService service = getClusterService();
|
||||
IClusterService service = ClusterServerMgr.getClusterService();
|
||||
if (service != null) {
|
||||
IClusterMember local = service.getLocalMember();
|
||||
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 IClusterService getClusterService() {
|
||||
/**
|
||||
*
|
||||
* @return cluster service
|
||||
*/
|
||||
public static IClusterService getClusterService() {
|
||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
||||
IClusterService service = holder != null ? holder.getService() : null;
|
||||
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
|
||||
public ServerInstance getServerInstance(String serverId) {
|
||||
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.IOException;
|
||||
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.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
@ -40,9 +37,6 @@ import javax.servlet.http.HttpServlet;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
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.xhtml.a;
|
||||
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.tr;
|
||||
import org.compiere.Adempiere;
|
||||
import org.compiere.db.AdempiereDatabase;
|
||||
import org.compiere.db.CConnection;
|
||||
import org.compiere.model.AdempiereProcessorLog;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MSession;
|
||||
|
@ -75,24 +67,30 @@ import org.compiere.model.Query;
|
|||
import org.compiere.server.AdempiereServerGroup;
|
||||
import org.compiere.server.AdempiereServerMgr;
|
||||
import org.compiere.server.IServerManager;
|
||||
import org.compiere.server.LogFileInfo;
|
||||
import org.compiere.server.ServerCount;
|
||||
import org.compiere.server.ServerInstance;
|
||||
import org.compiere.server.SystemInfo;
|
||||
import org.compiere.server.TrxInfo;
|
||||
import org.compiere.util.CLogFile;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.CMemoryUsage;
|
||||
import org.compiere.util.CacheInfo;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Ini;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.util.Trx;
|
||||
import org.compiere.util.Util;
|
||||
import org.compiere.util.WebDoc;
|
||||
import org.compiere.util.WebEnv;
|
||||
import org.compiere.util.WebUtil;
|
||||
import org.idempiere.distributed.IClusterMember;
|
||||
import org.idempiere.distributed.IClusterService;
|
||||
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
|
||||
|
@ -155,6 +153,12 @@ public class AdempiereMonitor extends HttpServlet
|
|||
createXMLSummaryPage(request, response);
|
||||
return;
|
||||
}
|
||||
if (processNodeInfoPage(request, response))
|
||||
{
|
||||
if (xmlOutput)
|
||||
createXMLSummaryPage(request, response);
|
||||
return;
|
||||
}
|
||||
//
|
||||
if (processRunNowParameter (request))
|
||||
;
|
||||
|
@ -366,12 +370,26 @@ public class AdempiereMonitor extends HttpServlet
|
|||
{
|
||||
String traceCmd = WebUtil.getParameter (request, "Trace");
|
||||
String traceLevel = WebUtil.getParameter (request, "TraceLevel");
|
||||
String nodeId = WebUtil.getParameter (request, "nodeId");
|
||||
if (traceLevel != null && traceLevel.length() > 0)
|
||||
{
|
||||
if (log.isLoggable(Level.INFO)) log.info ("New Level: " + traceLevel);
|
||||
CLogMgt.setLevel(traceLevel);
|
||||
Ini.setProperty(Ini.P_TRACELEVEL, traceLevel);
|
||||
Ini.saveProperties(false);
|
||||
SetTraceLevelCallable callable = new SetTraceLevelCallable(traceLevel);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -383,32 +401,68 @@ public class AdempiereMonitor extends HttpServlet
|
|||
//
|
||||
if (traceCmd.equals("ROTATE"))
|
||||
{
|
||||
if (fileHandler != null)
|
||||
fileHandler.rotateLog();
|
||||
RotateLogCallable callable = new RotateLogCallable();
|
||||
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
|
||||
}
|
||||
else if (traceCmd.equals("DELETE"))
|
||||
{
|
||||
File logDir = fileHandler.getLogDirectory();
|
||||
if (logDir != null && logDir.isDirectory())
|
||||
DeleteLogsCallable callable = new DeleteLogsCallable();
|
||||
try
|
||||
{
|
||||
File[] logs = logDir.listFiles();
|
||||
for (int i = 0; i < logs.length; i++)
|
||||
if (!Util.isEmpty(nodeId, true))
|
||||
{
|
||||
String fileName = logs[i].getAbsolutePath();
|
||||
if (fileName.equals(fileHandler.getFileName()))
|
||||
continue;
|
||||
if (fileName.endsWith(LogAuthFailure.authFailureFilename)) // Do not delete login failure
|
||||
continue;
|
||||
if (logs[i].delete())
|
||||
log.warning("Deleted: " + fileName);
|
||||
else
|
||||
log.warning("Not Deleted: " + fileName);
|
||||
ClusterServerMgr.getClusterService().execute(callable, ClusterServerMgr.getClusterMember(nodeId)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
callable.call();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
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
|
||||
if (fileHandler != null && fileHandler.getFileName().equals(traceCmd))
|
||||
fileHandler.flush();
|
||||
|
@ -538,7 +592,8 @@ public class AdempiereMonitor extends HttpServlet
|
|||
{
|
||||
String cmd = WebUtil.getParameter (request, "CacheReset");
|
||||
if (cmd == null || cmd.length() == 0)
|
||||
return false;
|
||||
return createCacheDetailsPage(request, response);
|
||||
|
||||
String tableName = WebUtil.getParameter (request, "CacheTableName");
|
||||
String record_ID = WebUtil.getParameter (request, "CacheRecord_ID");
|
||||
|
||||
|
@ -628,15 +683,56 @@ public class AdempiereMonitor extends HttpServlet
|
|||
table.addElement(line);
|
||||
bb.addElement(table);
|
||||
|
||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
||||
IClusterService service = holder != null ? holder.getService() : null;
|
||||
if (service != null && service.getLocalMember() != null)
|
||||
IClusterService service = ClusterServerMgr.getClusterService();
|
||||
Collection<IClusterMember> members = null;
|
||||
IClusterMember local = null;
|
||||
if (service != null)
|
||||
{
|
||||
members = service.getMembers();
|
||||
local = service.getLocalMember();
|
||||
if (members.size() > 1 && local != null)
|
||||
{
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Cluster Node Id"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(service.getLocalMember().getId())));
|
||||
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);
|
||||
bb.addElement(table);
|
||||
}
|
||||
}
|
||||
//
|
||||
p para = new p();
|
||||
|
@ -674,7 +770,7 @@ public class AdempiereMonitor extends HttpServlet
|
|||
bb.addElement(para);
|
||||
|
||||
// **** Log Management ****
|
||||
createLogMgtPage(bb);
|
||||
createLogMgtPage(bb, members, local);
|
||||
|
||||
// ***** Server Details *****
|
||||
bb.removeEndEndModifier();
|
||||
|
@ -749,7 +845,7 @@ public class AdempiereMonitor extends HttpServlet
|
|||
line.addElement(new td().addElement(server.getStatistics()));
|
||||
table.addElement(line);
|
||||
//
|
||||
if (server.getClusterMember() != null)
|
||||
if (server.getClusterMember() != null && members != null && members.size() > 1)
|
||||
{
|
||||
InetAddress address = server.getClusterMember().getAddress();
|
||||
String ip = address != null ? address.getHostAddress() : null;
|
||||
|
@ -904,8 +1000,10 @@ public class AdempiereMonitor extends HttpServlet
|
|||
/**
|
||||
* Add Log Management to page
|
||||
* @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());
|
||||
|
||||
|
@ -917,95 +1015,91 @@ public class AdempiereMonitor extends HttpServlet
|
|||
//
|
||||
Properties ctx = new Properties();
|
||||
MSystem system = MSystem.get(ctx);
|
||||
SystemInfo systemInfo = SystemInfo.getLocalSystemInfo();
|
||||
tr line = new tr();
|
||||
line.addElement(new th().addElement(system.getDBAddress()));
|
||||
line.addElement(new td().addElement(Ini.getAdempiereHome()));
|
||||
line.addElement(new th().addElement(Adempiere.getURL()));
|
||||
line.addElement(new td().addElement(Adempiere.getAdempiereHome()));
|
||||
table.addElement(line);
|
||||
// OS + Name
|
||||
line = new tr();
|
||||
String info = System.getProperty("os.name")
|
||||
+ " " + System.getProperty("os.version");
|
||||
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();
|
||||
line.addElement(new th().addElement(systemInfo.getOperatingSystem()));
|
||||
String info = system.getName();
|
||||
if (system.getCustomPrefix() != null)
|
||||
info += " (" + system.getCustomPrefix() + ")";
|
||||
line.addElement(new td().addElement(info));
|
||||
table.addElement(line);
|
||||
// Java + email
|
||||
line = new tr();
|
||||
info = System.getProperty("java.vm.name")
|
||||
+ " " + System.getProperty("java.vm.version");
|
||||
line.addElement(new th().addElement(info));
|
||||
line.addElement(new td().addElement(system.getUserName()));
|
||||
line.addElement(new th().addElement(systemInfo.getJavaVM()));
|
||||
line.addElement(new td().addElement(system.getSupportEMail()));
|
||||
table.addElement(line);
|
||||
// DB + Instance
|
||||
line = new tr();
|
||||
CConnection cc = CConnection.get();
|
||||
AdempiereDatabase db = cc.getDatabase();
|
||||
info = db.getDescription();
|
||||
line.addElement(new th().addElement(info));
|
||||
line.addElement(new td().addElement(cc.getConnectionURL()));
|
||||
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(cc.getDatabase().getStatus()));
|
||||
line.addElement(new td().addElement(systemInfo.getDatabaseStatus()));
|
||||
table.addElement(line);
|
||||
// Processors/Support
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Processor/Support"));
|
||||
line.addElement(new td().addElement(system.getNoProcessors() + "/" + system.getSupportUnits()));
|
||||
line.addElement(new th().addElement("Processor"));
|
||||
line.addElement(new td().addElement(systemInfo.getAvailableProcessors()+""));
|
||||
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
|
||||
line = new tr();
|
||||
MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
|
||||
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);
|
||||
line = new tr();
|
||||
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);
|
||||
// Runtime
|
||||
line = new tr();
|
||||
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
|
||||
line.addElement(new th().addElement("Runtime " + rt.getName()));
|
||||
line.addElement(new td().addElement(TimeUtil.formatElapsed(rt.getUptime())));
|
||||
line.addElement(new th().addElement("Runtime " + systemInfo.getRuntimeName()));
|
||||
line.addElement(new td().addElement(TimeUtil.formatElapsed(systemInfo.getRuntimeUpTime())));
|
||||
table.addElement(line);
|
||||
// Threads
|
||||
line = new tr();
|
||||
ThreadMXBean th = ManagementFactory.getThreadMXBean();
|
||||
line.addElement(new th().addElement("Threads " + th.getThreadCount()));
|
||||
line.addElement(new td().addElement("Peak=" + th.getPeakThreadCount()
|
||||
+ ", Demons=" + th.getDaemonThreadCount()
|
||||
+ ", Total=" + th.getTotalStartedThreadCount()));
|
||||
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
|
||||
Trx[] trxs = Trx.getActiveTransactions();
|
||||
for (Trx trx : trxs)
|
||||
{
|
||||
if (trx != null && trx.isActive())
|
||||
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.getStrackTrace()) + "</pre>')");
|
||||
+ "<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);
|
||||
}
|
||||
}
|
||||
|
||||
// Cache Reset
|
||||
line = new tr();
|
||||
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);
|
||||
|
||||
// Trace Level
|
||||
|
@ -1018,7 +1112,7 @@ public class AdempiereMonitor extends HttpServlet
|
|||
{
|
||||
options[i] = new option(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);
|
||||
}
|
||||
select sel = new select("TraceLevel", options);
|
||||
|
@ -1028,14 +1122,17 @@ public class AdempiereMonitor extends HttpServlet
|
|||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
CLogFile fileHandler = CLogFile.get (true, null, false);
|
||||
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);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=ROTATE", "Rotate Trace Log")));
|
||||
line.addElement(new td().addElement(new a ("idempiereMonitor?Trace=DELETE", "Delete all Trace Logs")));
|
||||
p tlp = new p();
|
||||
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);
|
||||
//
|
||||
bb.addElement(table);
|
||||
|
@ -1044,28 +1141,20 @@ public class AdempiereMonitor extends HttpServlet
|
|||
p p = new p();
|
||||
p.addElement(new b("All Log Files: "));
|
||||
// All in dir
|
||||
File logDir = fileHandler.getLogDirectory();
|
||||
if (logDir != null && logDir.isDirectory())
|
||||
LogFileInfo logFiles[] = systemInfo.getLogFileInfos();
|
||||
for (LogFileInfo logFile : logFiles)
|
||||
{
|
||||
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;
|
||||
|
||||
if (i != 0)
|
||||
if (logFile != logFiles[0])
|
||||
p.addElement(" - ");
|
||||
String fileName = logs[i].getAbsolutePath();
|
||||
String fileName = logFile.getFileName();
|
||||
a link = new a ("idempiereMonitor?Trace=" + fileName, fileName);
|
||||
p.addElement(link);
|
||||
int size = (int)(logs[i].length()/1024);
|
||||
int size = (int)(logFile.getFileSize()/1024);
|
||||
if (size < 1024)
|
||||
p.addElement(" (" + size + "k)");
|
||||
else
|
||||
p.addElement(" (" + size/1024 + "M)");
|
||||
}
|
||||
}
|
||||
bb.addElement(p);
|
||||
|
||||
// Clients and Web Stores
|
||||
|
@ -1131,6 +1220,20 @@ public class AdempiereMonitor extends HttpServlet
|
|||
p.addElement(" ");
|
||||
line.addElement(new td().addElement(p));
|
||||
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();
|
||||
|
||||
|
@ -1187,9 +1290,7 @@ public class AdempiereMonitor extends HttpServlet
|
|||
m_serverMgr = AdempiereServerMgr.get();
|
||||
|
||||
//switch to cluster manager if cluster service is available
|
||||
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
|
||||
IClusterService service = holder != null ? holder.getService() : null;
|
||||
if (service != null)
|
||||
if (ClusterServerMgr.getClusterService() != null)
|
||||
m_serverMgr = ClusterServerMgr.getInstance();
|
||||
|
||||
m_dirAccessList = getDirAcessList();
|
||||
|
@ -1307,4 +1408,257 @@ public class AdempiereMonitor extends HttpServlet
|
|||
input = input.replace("\t", "\\t");
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue