This is an automated email from the ASF dual-hosted git repository.
kiranchavala pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new cddd2c6e57b Add timestamps to management, server and agent .err logs
(#12967)
cddd2c6e57b is described below
commit cddd2c6e57b85396b9836cc222f34fa285218b5a
Author: Dheeraj Bansal <[email protected]>
AuthorDate: Wed Sep 9 17:06:12 2026 +0530
Add timestamps to management, server and agent .err logs (#12967)
* Add timestamps to management, server and agent .err logs
* Add timestamps to stderr console logs for agent, management and API server
* usage: add timestamped stderr console logging
* WIP: console proxy timeout changes
* Clean up whitespace in log4j config files
---
agent/conf/log4j-cloud.xml.in | 16 ++---
client/conf/log4j-cloud.xml.in | 18 +++--
server/conf/log4j-cloud.xml.in | 15 +++--
.../java/com/cloud/consoleproxy/ConsoleProxy.java | 77 ++++++++++++++++------
.../cloud/consoleproxy/ConsoleProxyGCThread.java | 31 +++++----
.../consoleproxy/ConsoleProxyNoVNCHandler.java | 25 ++++++-
usage/conf/log4j-cloud_usage.xml.in | 34 +++++-----
7 files changed, 146 insertions(+), 70 deletions(-)
diff --git a/agent/conf/log4j-cloud.xml.in b/agent/conf/log4j-cloud.xml.in
index 84957edca03..87cc9ae5424 100644
--- a/agent/conf/log4j-cloud.xml.in
+++ b/agent/conf/log4j-cloud.xml.in
@@ -38,8 +38,13 @@ under the License.
<!-- ============================== -->
<Console name="CONSOLE" target="SYSTEM_OUT">
- <ThresholdFilter level="OFF" onMatch="ACCEPT" onMismatch="DENY"/>
- <PatternLayout pattern="%-5p [%c{3}] (%t:%x)
(logid:%X{logcontextid}) %m%ex%n"/>
+ <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{3}] (%t:%x)
(logid:%X{logcontextid}) %m%ex%n"/>
+ </Console>
+
+ <Console name="CONSOLE_ERR" target="SYSTEM_ERR">
+ <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{3}] (%t:%x)
(logid:%X{logcontextid}) %m%ex%n"/>
</Console>
</Appenders>
@@ -50,17 +55,11 @@ under the License.
<!-- ================ -->
<Logger name="com.cloud" level="INFO"/>
-
<Logger name="org.apache" level="INFO"/>
-
<Logger name="org" level="INFO"/>
-
<Logger name="net" level="INFO"/>
-
<Logger name="com.amazonaws" level="INFO"/>
-
<Logger name="httpclient.wire" level="INFO"/>
-
<Logger name="org.apache.http.wire" level="INFO"/>
<!-- ======================= -->
@@ -69,6 +68,7 @@ under the License.
<Root level="INFO">
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="FILE"/>
</Root>
diff --git a/client/conf/log4j-cloud.xml.in b/client/conf/log4j-cloud.xml.in
index 26da171269d..a1e73a412c3 100755
--- a/client/conf/log4j-cloud.xml.in
+++ b/client/conf/log4j-cloud.xml.in
@@ -21,7 +21,7 @@ under the License.
<Appenders>
<properties>
- <property name="filters">net.sf.cglib.proxy</property>
+ <property name="filters">net.sf.cglib.proxy</property>
</properties>
<!-- ================================= -->
@@ -37,7 +37,6 @@ under the License.
<PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x)
(logid:%X{logcontextid}) %m%ex{filters(${filters})}%n"/>
</RollingFile>
-
<RollingFile name="APISERVER" append="true" fileName="@APISERVERLOG@"
filePattern="@APISERVERLOG@.%d{yyyy-MM-dd}.gz">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
@@ -69,8 +68,13 @@ under the License.
<!-- ============================== -->
<Console name="CONSOLE" target="SYSTEM_OUT">
- <ThresholdFilter level="OFF" onMatch="ACCEPT" onMismatch="DENY"/>
- <PatternLayout pattern="%-5p [%c{1.}] (%t:%x)
(logid:%X{logcontextid}) %m%ex{filters(${filters})}%n"/>
+ <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x)
(logid:%X{logcontextid}) %m%ex{filters(${filters})}%n"/>
+ </Console>
+
+ <Console name="CONSOLE_ERR" target="SYSTEM_ERR">
+ <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x)
(logid:%X{logcontextid}) %m%ex{filters(${filters})}%n"/>
</Console>
<!-- ============================== -->
@@ -78,7 +82,7 @@ under the License.
<!-- ============================== -->
<SnmpTrapAppender name="SNMP" SnmpManagerIpAddresses=""
SnmpManagerPorts="" SnmpManagerCommunities="">
- <ThresholdFilter level="WARN" onMatch="ACCEPT"
onMismatch="DENY"/>
+ <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
</SnmpTrapAppender>
</Appenders>
@@ -102,7 +106,7 @@ under the License.
<Logger name="net" level="INFO"/>
- <Logger name="apiserver.com.cloud" level="DEBUG"/>
+ <Logger name="apiserver.com.cloud" level="DEBUG"/>
<Logger name="apiserver.com.cloud" level="DEBUG" additivity="false">
<AppenderRef ref="APISERVER"/>
@@ -115,6 +119,7 @@ under the License.
<Logger name="org.apache.cloudstack.alert" additivity="false"
level="WARN">
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="FILE"/>
<AppenderRef ref="SNMP"/>
<AppenderRef ref="ALERTSYSLOG"/>
@@ -127,6 +132,7 @@ under the License.
<Root level="INFO">
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="FILE"/>
</Root>
diff --git a/server/conf/log4j-cloud.xml.in b/server/conf/log4j-cloud.xml.in
index 9a8e5dc7bf3..06fa7527a52 100755
--- a/server/conf/log4j-cloud.xml.in
+++ b/server/conf/log4j-cloud.xml.in
@@ -24,7 +24,6 @@ under the License.
<!-- Preserve messages in a local file -->
<!-- ================================= -->
-
<!-- A regular appender -->
<RollingFile name="FILE" append="true" fileName="@MSLOG@"
filePattern="@MSLOG@.%d{yyyy-MM-dd}.gz">
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
@@ -34,7 +33,6 @@ under the License.
<PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x) %m%ex%n"/>
</RollingFile>
-
<RollingFile name="INFO-FILE" append="true"
fileName="/var/log/cloudstack/management/management-server-info.log"
filePattern="/var/log/cloudstack/management/management-server-info.log.%d{yyyy-MM-dd}.gz">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
@@ -43,7 +41,6 @@ under the License.
<PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x)
(logid:%X{logcontextid}) %m%ex%n"/>
</RollingFile>
-
<RollingFile name="APISERVER" append="true" fileName="@APISERVERLOG@"
filePattern="@APISERVERLOG@.%d{yyyy-MM-dd}.gz">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
@@ -56,7 +53,6 @@ under the License.
<!-- Append warnings+ to the syslog if it is listening on UDP port -->
<!-- ============================== -->
-
<Syslog name="SYSLOG" host="localhost" facility="LOCAL6">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%-5p [%c{1.}] (%t:%x) %m%ex%n"/>
@@ -67,8 +63,13 @@ under the License.
<!-- ============================== -->
<Console name="CONSOLE" target="SYSTEM_OUT">
- <ThresholdFilter level="OFF" onMatch="ACCEPT" onMismatch="DENY"/>
- <PatternLayout pattern="%-5p [%c{1.}] (%t:%x) %m%ex%n"/>
+ <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x) %m%ex%n"/>
+ </Console>
+
+ <Console name="CONSOLE_ERR" target="SYSTEM_ERR">
+ <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+ <PatternLayout pattern="%d{DEFAULT} %-5p [%c{1.}] (%t:%x) %m%ex%n"/>
</Console>
</Appenders>
@@ -101,6 +102,7 @@ under the License.
<Logger name="org.apache.cloudstack.alerts" additivity="false"
level="WARN">
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="FILE"/>
<AppenderRef ref="SNMP"/>
<AppenderRef ref="ALERTSYSLOG"/>
@@ -113,6 +115,7 @@ under the License.
<Root level="INFO">
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="FILE"/>
<AppenderRef ref="INFO-FILE"/>
</Root>
diff --git
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
index e75ccea9044..b0a2a1fca76 100644
---
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
+++
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
@@ -80,6 +80,11 @@ public class ConsoleProxy {
static String factoryClzName;
static boolean standaloneStart = false;
+ /**
+ * Session timeout in milliseconds, default 300000 (5 minutes).
+ */
+ public static int sessionTimeoutMillis = 300000;
+
static String encryptorPassword = "Dummy";
static final String[] skipProperties = new String[]{"certificate",
"cacertificate", "keystore_password", "privatekey"};
@@ -92,11 +97,13 @@ public class ConsoleProxy {
private static void configLog4j() {
final ClassLoader loader =
Thread.currentThread().getContextClassLoader();
URL configUrl = loader.getResource("/conf/log4j-cloud.xml");
- if (configUrl == null)
+ if (configUrl == null) {
configUrl = ClassLoader.getSystemResource("log4j-cloud.xml");
+ }
- if (configUrl == null)
+ if (configUrl == null) {
configUrl = ClassLoader.getSystemResource("conf/log4j-cloud.xml");
+ }
if (configUrl != null) {
try {
@@ -121,9 +128,8 @@ public class ConsoleProxy {
private static void configProxy(Properties conf) {
LOGGER.info("Configure console proxy...");
for (Object key : conf.keySet()) {
- LOGGER.info("Property " + (String)key + ": " +
conf.getProperty((String)key));
if (!ArrayUtils.contains(skipProperties, key)) {
- LOGGER.info("Property " + (String)key + ": " +
conf.getProperty((String)key));
+ LOGGER.info("Property " + (String) key + ": " +
conf.getProperty((String) key));
}
}
@@ -165,13 +171,31 @@ public class ConsoleProxy {
defaultBufferSize = Integer.parseInt(s);
LOGGER.info("Setting defaultBufferSize=" + defaultBufferSize);
}
+
+ // Read consoleproxy.session.timeout in milliseconds.
+ s = conf.getProperty("consoleproxy.session.timeout");
+ if (s != null) {
+ try {
+ int parsedTimeout = Integer.parseInt(s);
+ if (parsedTimeout < 1000) {
+ LOGGER.warn("Invalid value for
consoleproxy.session.timeout: " + s
+ + " ms, must be >= 1000 ms, keeping default " +
sessionTimeoutMillis + " ms");
+ } else {
+ sessionTimeoutMillis = parsedTimeout;
+ LOGGER.info("Setting consoleproxy.session.timeout=" +
sessionTimeoutMillis + " ms");
+ }
+ } catch (NumberFormatException e) {
+ LOGGER.warn("Invalid value for consoleproxy.session.timeout: "
+ s
+ + ", keeping default " + sessionTimeoutMillis + " ms",
e);
+ }
+ }
}
public static ConsoleProxyServerFactory getHttpServerFactory() {
try {
Class<?> clz = Class.forName(factoryClzName);
try {
- ConsoleProxyServerFactory factory =
(ConsoleProxyServerFactory)clz.newInstance();
+ ConsoleProxyServerFactory factory =
(ConsoleProxyServerFactory) clz.newInstance();
factory.init(ConsoleProxy.ksBits, ConsoleProxy.ksPassword);
return factory;
} catch (InstantiationException e) {
@@ -243,7 +267,7 @@ public class ConsoleProxy {
}
if (result != null && result instanceof String) {
- authResult = new Gson().fromJson((String)result,
ConsoleProxyAuthenticationResult.class);
+ authResult = new Gson().fromJson((String) result,
ConsoleProxyAuthenticationResult.class);
} else {
LOGGER.error("Invalid authentication return object " + result
+ " for vm: " + param.getClientTag() + ", decline the access");
authResult.setSuccess(false);
@@ -318,19 +342,25 @@ public class ConsoleProxy {
LOGGER.error("Unable to setup private channel due to
ClassNotFoundException", e);
}
+ // ensure we have a Properties object before merging defaults
+ if (conf == null) {
+ conf = new Properties();
+ }
+
// merge properties from conf file
InputStream confs =
ConsoleProxy.class.getResourceAsStream("/conf/consoleproxy.properties");
Properties props = new Properties();
if (confs == null) {
final File file =
PropertiesUtil.findConfigFile("consoleproxy.properties");
- if (file == null)
+ if (file == null) {
LOGGER.info("Can't load consoleproxy.properties from
classpath, will use default configuration");
- else
+ } else {
try {
confs = new FileInputStream(file);
} catch (FileNotFoundException e) {
LOGGER.info("Ignoring file not found exception and using
defaults");
}
+ }
}
if (confs != null) {
try {
@@ -339,15 +369,18 @@ public class ConsoleProxy {
for (Object key : props.keySet()) {
// give properties passed via context high priority, treat
properties from consoleproxy.properties
// as default values
- if (conf.get(key) == null)
+ if (conf.get(key) == null) {
conf.put(key, props.get(key));
+ }
}
} catch (Exception e) {
LOGGER.error(e.toString(), e);
}
}
try {
- confs.close();
+ if (confs != null) {
+ confs.close();
+ }
} catch (IOException e) {
LOGGER.error("Failed to close consolepropxy.properties : " +
e.toString(), e);
}
@@ -481,8 +514,9 @@ public class ConsoleProxy {
ConsoleProxyClientStatsCollector statsCollector =
getStatsCollector();
String loadInfo = statsCollector.getStatsReport();
reportLoadInfo(loadInfo);
- if (LOGGER.isDebugEnabled())
+ if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Report load change : " + loadInfo);
+ }
}
return viewer;
@@ -506,13 +540,15 @@ public class ConsoleProxy {
// protected against malicious attack by modifying URL content
if (ajaxSession != null) {
long ajaxSessionIdFromUrl = Long.parseLong(ajaxSession);
- if (ajaxSessionIdFromUrl != viewer.getAjaxSessionId())
+ if (ajaxSessionIdFromUrl != viewer.getAjaxSessionId()) {
throw new AuthenticationException("Cannot use the
existing viewer " + viewer + ": modified AJAX session id");
+ }
}
if (param.getClientHostPassword() == null ||
param.getClientHostPassword().isEmpty() ||
-
!param.getClientHostPassword().equals(viewer.getClientHostPassword()))
+
!param.getClientHostPassword().equals(viewer.getClientHostPassword())) {
throw new AuthenticationException("Cannot use the existing
viewer " + viewer + ": bad sid");
+ }
if (!viewer.isFrontEndAlive()) {
@@ -526,8 +562,9 @@ public class ConsoleProxy {
ConsoleProxyClientStatsCollector statsCollector =
getStatsCollector();
String loadInfo = statsCollector.getStatsReport();
reportLoadInfo(loadInfo);
- if (LOGGER.isDebugEnabled())
+ if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Report load change : " + loadInfo);
+ }
}
return viewer;
}
@@ -593,7 +630,7 @@ public class ConsoleProxy {
}
public static ConsoleProxyNoVncClient
getNoVncViewer(ConsoleProxyClientParam param, String ajaxSession,
- Session session) throws AuthenticationException {
+ Session session)
throws AuthenticationException {
boolean reportLoadChange = false;
String clientKey = param.getClientMapKey();
LOGGER.debug("Getting NoVNC viewer for {}. Session requires new
viewer: {}, client tag: {}. session UUID: {}",
@@ -609,8 +646,9 @@ public class ConsoleProxy {
reportLoadChange = true;
} else {
if (param.getClientHostPassword() == null ||
param.getClientHostPassword().isEmpty() ||
-
!param.getClientHostPassword().equals(viewer.getClientHostPassword()))
+
!param.getClientHostPassword().equals(viewer.getClientHostPassword())) {
throw new AuthenticationException("Cannot use the existing
viewer " + viewer + ": bad sid");
+ }
try {
authenticationExternally(param);
@@ -620,7 +658,7 @@ public class ConsoleProxy {
}
LOGGER.info("Initializing new novnc client and disconnecting
existing session");
try {
-
((ConsoleProxyNoVncClient)viewer).getSession().disconnect();
+ ((ConsoleProxyNoVncClient)
viewer).getSession().disconnect();
} catch (IOException e) {
LOGGER.error("Exception while disconnect session of novnc
viewer object: " + viewer, e);
}
@@ -635,10 +673,11 @@ public class ConsoleProxy {
ConsoleProxyClientStatsCollector statsCollector =
getStatsCollector();
String loadInfo = statsCollector.getStatsReport();
reportLoadInfo(loadInfo);
- if (LOGGER.isDebugEnabled())
+ if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Report load change : " + loadInfo);
+ }
}
- return (ConsoleProxyNoVncClient)viewer;
+ return (ConsoleProxyNoVncClient) viewer;
}
}
}
diff --git
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
index 0e8f576cf6d..66d14e4da79 100644
---
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
+++
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
@@ -22,8 +22,8 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
*
@@ -34,7 +34,7 @@ import org.apache.logging.log4j.LogManager;
public class ConsoleProxyGCThread extends Thread {
protected Logger logger = LogManager.getLogger(ConsoleProxyGCThread.class);
- private final static int MAX_SESSION_IDLE_SECONDS = 180;
+ private static final int DEFAULT_MAX_SESSION_IDLE_SECONDS = 180;
private final Map<String, ConsoleProxyClient> connMap;
private final Set<String> removedSessionsSet;
@@ -45,22 +45,30 @@ public class ConsoleProxyGCThread extends Thread {
this.removedSessionsSet = removedSet;
}
+ private int getMaxSessionIdleSeconds() {
+ if (ConsoleProxy.sessionTimeoutMillis <= 0) {
+ return DEFAULT_MAX_SESSION_IDLE_SECONDS;
+ }
+
+ return Math.max(1, ConsoleProxy.sessionTimeoutMillis / 1000);
+ }
+
private void cleanupLogging() {
- if (lastLogScan != 0 && System.currentTimeMillis() - lastLogScan <
3600000)
+ if (lastLogScan != 0 && System.currentTimeMillis() - lastLogScan <
3600000) {
return;
+ }
lastLogScan = System.currentTimeMillis();
File logDir = new File("./logs");
- File files[] = logDir.listFiles();
+ File[] files = logDir.listFiles();
if (files != null) {
for (File file : files) {
if (System.currentTimeMillis() - file.lastModified() >=
86400000L) {
try {
file.delete();
} catch (Throwable e) {
- logger.info("[ignored]"
- + "failed to delete file: " +
e.getLocalizedMessage());
+ logger.info("[ignored]failed to delete file: " +
e.getLocalizedMessage());
}
}
}
@@ -69,7 +77,6 @@ public class ConsoleProxyGCThread extends Thread {
@Override
public void run() {
-
boolean bReportLoad = false;
long lastReportTick = System.currentTimeMillis();
@@ -80,6 +87,7 @@ public class ConsoleProxyGCThread extends Thread {
if (logger.isDebugEnabled()) {
logger.debug(String.format("connMap=%s, removedSessions=%s",
connMap, removedSessionsSet));
}
+
Set<String> e = connMap.keySet();
Iterator<String> iterator = e.iterator();
while (iterator.hasNext()) {
@@ -91,8 +99,8 @@ public class ConsoleProxyGCThread extends Thread {
client = connMap.get(key);
}
- long seconds_unused = (System.currentTimeMillis() -
client.getClientLastFrontEndActivityTime()) / 1000;
- if (seconds_unused < MAX_SESSION_IDLE_SECONDS) {
+ long secondsUnused = (System.currentTimeMillis() -
client.getClientLastFrontEndActivityTime()) / 1000;
+ if (secondsUnused < getMaxSessionIdleSeconds()) {
continue;
}
@@ -101,18 +109,17 @@ public class ConsoleProxyGCThread extends Thread {
bReportLoad = true;
}
- // close the server connection
- logger.info("Dropping " + client + " which has not been used
for " + seconds_unused + " seconds");
+ logger.info("Dropping " + client + " which has not been used
for " + secondsUnused + " seconds");
client.closeClient();
}
if (bReportLoad || System.currentTimeMillis() - lastReportTick >
5000) {
- // report load changes
ConsoleProxyClientStatsCollector collector = new
ConsoleProxyClientStatsCollector(connMap);
collector.setRemovedSessions(new
ArrayList<>(removedSessionsSet));
String loadInfo = collector.getStatsReport();
ConsoleProxy.reportLoadInfo(loadInfo);
lastReportTick = System.currentTimeMillis();
+
synchronized (removedSessionsSet) {
removedSessionsSet.clear();
}
diff --git
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyNoVNCHandler.java
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyNoVNCHandler.java
index a148b988e40..0f8b54e078e 100644
---
a/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyNoVNCHandler.java
+++
b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyNoVNCHandler.java
@@ -95,14 +95,16 @@ public class ConsoleProxyNoVNCHandler extends
WebSocketHandler {
String clientIp =
session.getRemoteAddress().getAddress().getHostAddress();
boolean sessionRequiresNewViewer =
Boolean.parseBoolean(queryMap.get("sessionRequiresNewViewer"));
- if (tag == null)
+ if (tag == null) {
tag = "";
+ }
long ajaxSessionId = 0;
int port;
- if (host == null || portStr == null || sid == null)
+ if (host == null || portStr == null || sid == null) {
throw new IllegalArgumentException();
+ }
try {
port = Integer.parseInt(portStr);
@@ -125,6 +127,14 @@ public class ConsoleProxyNoVNCHandler extends
WebSocketHandler {
}
try {
+ if (ConsoleProxy.sessionTimeoutMillis > 0) {
+ session.setIdleTimeout(ConsoleProxy.sessionTimeoutMillis);
+ logger.debug("Set noVNC WebSocket idle timeout to {} ms for
session UUID {}.",
+ ConsoleProxy.sessionTimeoutMillis, sessionUuid);
+ } else {
+ logger.debug("Using default noVNC WebSocket idle timeout for
session UUID {}.", sessionUuid);
+ }
+
ConsoleProxyClientParam param = new ConsoleProxyClientParam();
param.setClientHostAddress(host);
param.setClientHostPort(port);
@@ -185,12 +195,21 @@ public class ConsoleProxyNoVNCHandler extends
WebSocketHandler {
@OnWebSocketFrame
public void onFrame(Frame f) throws IOException {
+ if (viewer == null) {
+ logger.warn("Ignoring WebSocket frame because viewer is not
initialized yet.");
+ return;
+ }
logger.trace("Sending client [ID: {}] frame of {} bytes.",
viewer.getClientId(), f.getPayloadLength());
viewer.sendClientFrame(f);
}
@OnWebSocketError
public void onError(Throwable cause) {
- logger.error("Error on WebSocket [client ID: {}, session UUID: {}].",
cause, viewer.getClientId(), viewer.getSessionUuid());
+ if (viewer != null) {
+ logger.error("Error on WebSocket [client ID: {}, session UUID:
{}].",
+ viewer.getClientId(), viewer.getSessionUuid(), cause);
+ } else {
+ logger.error("Error on WebSocket before viewer initialization.",
cause);
+ }
}
}
diff --git a/usage/conf/log4j-cloud_usage.xml.in
b/usage/conf/log4j-cloud_usage.xml.in
index 871d6fb5a7a..fb09b4374ac 100644
--- a/usage/conf/log4j-cloud_usage.xml.in
+++ b/usage/conf/log4j-cloud_usage.xml.in
@@ -20,19 +20,23 @@ under the License.
<Configuration monitorInterval="60">
<Appenders>
- <!-- ============================== -->
- <!-- Append messages to the console -->
- <!-- ============================== -->
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
- <Console name="CONSOLE" target="SYSTEM_OUT">
- <ThresholdFilter level="OFF" onMatch="ACCEPT" onMismatch="DENY"/>
- <PatternLayout pattern="%d{ABSOLUTE}{GMT} %5p %c{1}:%L - %m%ex%n"/>
- </Console>
+ <Console name="CONSOLE" target="SYSTEM_OUT">
+ <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
+ <PatternLayout pattern="%d{ABSOLUTE}{GMT} %5p %c{1}:%L - %m%ex%n"/>
+ </Console>
+ <Console name="CONSOLE_ERR" target="SYSTEM_ERR">
+ <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+ <PatternLayout pattern="%d{ABSOLUTE}{GMT} %5p %c{1}:%L - %m%ex%n"/>
+ </Console>
- <!-- ================================ -->
- <!-- Append messages to the usage log -->
- <!-- ================================ -->
+ <!-- ================================ -->
+ <!-- Append messages to the usage log -->
+ <!-- ================================ -->
<RollingFile name="USAGE" append="true" fileName="@USAGELOG@"
filePattern="@USAGELOG@.%d{yyyy-MM-dd}{GMT}.gz">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
@@ -44,16 +48,13 @@ under the License.
</Appenders>
<Loggers>
- <!-- ================ -->
- <!-- Limit categories -->
- <!-- ================ -->
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
<Logger name="com.cloud" level="DEBUG"/>
-
<Logger name="org.apache" level="INFO"/>
-
<Logger name="org" level="INFO"/>
-
<Logger name="net" level="INFO"/>
<!-- ======================= -->
@@ -62,6 +63,7 @@ under the License.
<Root level="INFO">
<AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="CONSOLE_ERR"/>
<AppenderRef ref="USAGE"/>
</Root>