Repository: karaf Updated Branches: refs/heads/karaf-3.0.x 136ff1aa8 -> 3ca841c2b
[KARAF-3432] Add support of console System.in and System.out streams logging Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/3ca841c2 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/3ca841c2 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/3ca841c2 Branch: refs/heads/karaf-3.0.x Commit: 3ca841c2b1ebe9fbb35779159f30e381a1d1c553 Parents: 136ff1a Author: Jean-Baptiste Onofré <[email protected]> Authored: Wed Jan 7 19:12:05 2015 +0100 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Wed Jan 7 19:12:05 2015 +0100 ---------------------------------------------------------------------- .../resources/etc/org.apache.karaf.shell.cfg | 20 ++++++ .../resources/etc/org.apache.karaf.shell.cfg | 20 ++++++ shell/console/pom.xml | 6 ++ .../shell/console/impl/jline/ConsoleImpl.java | 61 +++++++++++++++---- .../apache/karaf/shell/ssh/ShellCommand.java | 25 +++++++- .../karaf/shell/ssh/ShellCommandFactory.java | 22 ++++++- .../karaf/shell/ssh/ShellFactoryImpl.java | 25 +++++++- .../resources/OSGI-INF/blueprint/shell-ssh.xml | 12 ++++ util/pom.xml | 4 ++ .../karaf/util/StreamLoggerInterceptor.java | 64 ++++++++++++++++++++ 10 files changed, 240 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.shell.cfg ---------------------------------------------------------------------- diff --git a/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.shell.cfg b/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.shell.cfg index 19701fe..cf92e2e 100644 --- a/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.shell.cfg +++ b/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.shell.cfg @@ -71,3 +71,23 @@ hostKey = ${karaf.etc}/host.key # You can change the completion mode directly in the shell console, using shell:completion command. # completionMode = GLOBAL + +# +# Enable the console logger. +# The console logger allows to generate log messages for all actions/commands performed in the shell console. +# +# consoleLogger property enable/disable the logger. The logger is disabled by default +# +consoleLogger = false +# +# consoleLoggerName allows you to define the logger name used for the log messages +# +consoleLoggerName = org.apache.karaf.shell.console.Logger +# +# consoleLoggerOutLevel allows you to define the log level for the log messages corresponding to the System.out stream +# +consoleLoggerOutLevel = debug +# +# consoleLoggerErrLevel allows you to define the log level for the log messages corresponding to the System.err stream +# +consoleLoggerErrLevel = error \ No newline at end of file http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg ---------------------------------------------------------------------- diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg b/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg index 65a49f3..f2aa4c3 100644 --- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg +++ b/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg @@ -71,3 +71,23 @@ hostKey = ${karaf.etc}/host.key # You can change the completion mode directly in the shell console, using shell:completion command. # completionMode = GLOBAL + +# +# Enable the console logger. +# The console logger allows to generate log messages for all actions/commands performed in the shell console. +# +# consoleLogger property enable/disable the logger. The logger is disabled by default +# +consoleLogger = false +# +# consoleLoggerName allows you to define the logger name used for the log messages +# +consoleLoggerName = org.apache.karaf.shell.console.Logger +# +# consoleLoggerOutLevel allows you to define the log level for the log messages corresponding to the System.out stream +# +consoleLoggerOutLevel = debug +# +# consoleLoggerErrLevel allows you to define the log level for the log messages corresponding to the System.err stream +# +consoleLoggerErrLevel = error http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/console/pom.xml ---------------------------------------------------------------------- diff --git a/shell/console/pom.xml b/shell/console/pom.xml index 5c9f082..3841439 100644 --- a/shell/console/pom.xml +++ b/shell/console/pom.xml @@ -86,6 +86,11 @@ <groupId>org.apache.sshd</groupId> <artifactId>sshd-core</artifactId> </dependency> + <dependency> + <groupId>org.apache.karaf</groupId> + <artifactId>org.apache.karaf.util</artifactId> + <scope>provided</scope> + </dependency> </dependencies> <build> @@ -163,6 +168,7 @@ <Private-Package> org.apache.karaf.shell.console.impl*, org.apache.karaf.shell.security.impl*, + org.apache.karaf.util, <!-- We need to embed gogo runtime to be able to create SecuredCommandProcessorImpl which needs CommandProcessorImpl --> http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/ConsoleImpl.java ---------------------------------------------------------------------- diff --git a/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/ConsoleImpl.java b/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/ConsoleImpl.java index 82e1705..7f18a8e 100644 --- a/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/ConsoleImpl.java +++ b/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/ConsoleImpl.java @@ -18,15 +18,7 @@ */ package org.apache.karaf.shell.console.impl.jline; -import java.io.CharArrayWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.InterruptedIOException; -import java.io.PrintStream; -import java.io.Reader; +import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -51,6 +43,7 @@ import org.apache.karaf.shell.console.Console; import org.apache.karaf.shell.console.SessionProperties; import org.apache.karaf.shell.console.completer.CommandsCompleter; import org.apache.karaf.shell.util.ShellUtil; +import org.apache.karaf.util.StreamLoggerInterceptor; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,6 +75,12 @@ public class ConsoleImpl implements Console { private Thread thread; private final BundleContext bundleContext; + // logging + private boolean consoleLogger = false; + private String consoleLoggerName; + private String consoleLoggerOutLevel; + private String consoleLoggerErrLevel; + public ConsoleImpl(CommandProcessor processor, ThreadIO threadIO, InputStream in, @@ -93,12 +92,19 @@ public class ConsoleImpl implements Console { BundleContext bc) { this.threadIO = threadIO; this.in = in; - this.out = out; - this.err = err; + // load and configure the logger + this.setLogger(); + if (consoleLogger) { + this.out = new StreamLoggerInterceptor(out, consoleLoggerName, consoleLoggerOutLevel); + this.err = new StreamLoggerInterceptor(err, consoleLoggerName, consoleLoggerErrLevel); + } else { + this.out = out; + this.err = err; + } this.queue = new ArrayBlockingQueue<Integer>(1024); this.terminal = term == null ? new UnsupportedTerminal() : term; this.consoleInput = new ConsoleInputStream(); - this.session = processor.createSession(consoleInput, out, err); + this.session = processor.createSession(consoleInput, this.out, this.err); this.session.put("SCOPE", "shell:bundle:*"); this.session.put("SUBSHELL", ""); this.setCompletionMode(); @@ -223,6 +229,37 @@ public class ConsoleImpl implements Console { } } } + + private void setLogger() { + try { + File shellCfg = new File(System.getProperty("karaf.etc"), "/org.apache.karaf.shell.cfg"); + Properties properties = new Properties(); + properties.load(new FileInputStream(shellCfg)); + if (properties.get("consoleLogger") != null && ((String) properties.get("consoleLogger")).equalsIgnoreCase("true")) { + consoleLogger = true; + if (properties.get("consoleLoggerName") != null && ((String) properties.get("consoleLoggerName")).isEmpty()) { + consoleLoggerName = (String) properties.get("consoleLoggerName"); + } else { + consoleLoggerName = "org.apache.karaf.shell.console.Logger"; + } + if (properties.get("consoleLoggerOutLevel") != null && ((String) properties.get("consoleLoggerOutLevel")).isEmpty()) { + consoleLoggerOutLevel = (String) properties.get("consoleLoggerOutLevel"); + } else { + consoleLoggerOutLevel = "trace"; + } + if (properties.get("consoleLoggerErrLevel") != null && ((String) properties.get("consoleLoggerErrLevel")).isEmpty()) { + consoleLoggerErrLevel = (String) properties.get("consoleLoggerErrLevel"); + } else { + consoleLoggerErrLevel = "error"; + } + } else { + LOGGER.debug("console logger is disabled."); + } + } catch (Exception e) { + LOGGER.warn("Can't read {}/org.apache.karaf.shell.cfg file. The console logger is disabled.", System.getProperty("karaf.etc")); + } + } + private void setCompletionMode() { try { File shellCfg = new File(System.getProperty("karaf.etc"), "/org.apache.karaf.shell.cfg"); http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java ---------------------------------------------------------------------- diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java index dd271fb..e963007 100644 --- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java +++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java @@ -22,6 +22,7 @@ import java.io.*; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Map; +import java.util.Properties; import javax.security.auth.Subject; @@ -30,6 +31,7 @@ import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Converter; import org.apache.karaf.jaas.modules.JaasHelper; import org.apache.karaf.shell.util.ShellUtil; +import org.apache.karaf.util.StreamLoggerInterceptor; import org.apache.karaf.util.StreamUtils; import org.apache.sshd.server.Command; import org.apache.sshd.server.Environment; @@ -59,9 +61,18 @@ public class ShellCommand implements Command, SessionAware { private ServerSession session; private CommandProcessor commandProcessor; - public ShellCommand(CommandProcessor commandProcessor, String command) { + private boolean consoleLogger = false; + private String consoleLoggerName; + private String consoleLoggerOutLevel; + private String consoleLoggerErrLevel; + + public ShellCommand(CommandProcessor commandProcessor, String command, boolean consoleLogger, String consoleLoggerName, String consoleLoggerOutLevel, String consoleLoggerErrLevel) { this.commandProcessor = commandProcessor; this.command = command; + this.consoleLogger = consoleLogger; + this.consoleLoggerName = consoleLoggerName; + this.consoleLoggerOutLevel = consoleLoggerOutLevel; + this.consoleLoggerErrLevel = consoleLoggerErrLevel; } public void setInputStream(InputStream in) { @@ -69,11 +80,19 @@ public class ShellCommand implements Command, SessionAware { } public void setOutputStream(OutputStream out) { - this.out = out; + if (consoleLogger) { + this.out = new StreamLoggerInterceptor(out, consoleLoggerName, consoleLoggerOutLevel); + } else { + this.out = out; + } } public void setErrorStream(OutputStream err) { - this.err = err; + if (consoleLogger) { + this.err = new StreamLoggerInterceptor(err, consoleLoggerName, consoleLoggerErrLevel); + } else { + this.err = err; + } } public void setExitCallback(ExitCallback callback) { http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java ---------------------------------------------------------------------- diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java index a1de13d..bd9916a 100644 --- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java +++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java @@ -25,13 +25,33 @@ import org.apache.sshd.server.CommandFactory; public class ShellCommandFactory implements CommandFactory { private CommandProcessor commandProcessor; + private boolean consoleLogger = false; + private String consoleLoggerName; + private String consoleLoggerOutLevel; + private String consoleLoggerErrLevel; public void setCommandProcessor(CommandProcessor commandProcessor) { this.commandProcessor = commandProcessor; } + public void setConsoleLogger(boolean consoleLogger) { + this.consoleLogger = consoleLogger; + } + + public void setConsoleLoggerName(String consoleLoggerName) { + this.consoleLoggerName = consoleLoggerName; + } + + public void setConsoleLoggerOutLevel(String consoleLoggerOutLevel) { + this.consoleLoggerOutLevel = consoleLoggerOutLevel; + } + + public void setConsoleLoggerErrLevel(String consoleLoggerErrLevel) { + this.consoleLoggerErrLevel = consoleLoggerErrLevel; + } + public Command createCommand(String command) { - return new ShellCommand(commandProcessor, command); + return new ShellCommand(commandProcessor, command, consoleLogger, consoleLoggerName, consoleLoggerOutLevel, consoleLoggerErrLevel); } } http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java ---------------------------------------------------------------------- diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java index f919ebb..6f81da8 100644 --- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java +++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java @@ -38,6 +38,7 @@ import org.apache.karaf.shell.console.Console; import org.apache.karaf.shell.console.ConsoleFactory; import org.apache.felix.service.command.Function; import org.apache.felix.service.threadio.ThreadIO; +import org.apache.karaf.util.StreamLoggerInterceptor; import org.apache.sshd.common.Factory; import org.apache.sshd.server.Command; import org.apache.sshd.server.Environment; @@ -59,11 +60,19 @@ public class ShellFactoryImpl implements Factory<Command> { private CommandProcessor commandProcessor; private ConsoleFactory consoleFactory; private ThreadIO threadIO; + private boolean consoleLogger; + private String consoleLoggerName; + private String consoleLoggerOutLevel; + private String consoleLoggerErrLevel; - public ShellFactoryImpl(CommandProcessor commandProcessor, ConsoleFactory consoleFactory, ThreadIO threadIO) { + public ShellFactoryImpl(CommandProcessor commandProcessor, ConsoleFactory consoleFactory, ThreadIO threadIO, boolean consoleLogger, String consoleLoggerName, String consoleLoggerOutLevel, String consoleLoggerErrLevel) { this.commandProcessor = commandProcessor; this.consoleFactory = consoleFactory; this.threadIO = threadIO; + this.consoleLogger = consoleLogger; + this.consoleLoggerName = consoleLoggerName; + this.consoleLoggerOutLevel = consoleLoggerOutLevel; + this.consoleLoggerErrLevel = consoleLoggerErrLevel; } public Command create() { @@ -88,11 +97,19 @@ public class ShellFactoryImpl implements Factory<Command> { } public void setOutputStream(final OutputStream out) { - this.out = out; + if (consoleLogger) { + this.out = new StreamLoggerInterceptor(out, consoleLoggerName, consoleLoggerOutLevel); + } else { + this.out = out; + } } public void setErrorStream(final OutputStream err) { - this.err = err; + if (consoleLogger) { + this.err = new StreamLoggerInterceptor(err, consoleLoggerName, consoleLoggerErrLevel); + } else { + this.err = err; + } } public void setExitCallback(ExitCallback callback) { @@ -263,4 +280,6 @@ public class ShellFactoryImpl implements Factory<Command> { } + + } http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/shell/ssh/src/main/resources/OSGI-INF/blueprint/shell-ssh.xml ---------------------------------------------------------------------- diff --git a/shell/ssh/src/main/resources/OSGI-INF/blueprint/shell-ssh.xml b/shell/ssh/src/main/resources/OSGI-INF/blueprint/shell-ssh.xml index b8b64ec..954b2cf 100644 --- a/shell/ssh/src/main/resources/OSGI-INF/blueprint/shell-ssh.xml +++ b/shell/ssh/src/main/resources/OSGI-INF/blueprint/shell-ssh.xml @@ -52,6 +52,10 @@ <cm:property name="macs" value="hmac-sha1" /> <cm:property name="ciphers" value="aes256-ctr,aes192-ctr,aes128-ctr,arcfour256" /> <cm:property name="welcomeBanner" value="" /> + <cm:property name="consoleLogger" value="false" /> + <cm:property name="consoleLoggerName" value="org.apache.karaf.shell.console.Logger" /> + <cm:property name="consoleLoggerOutLevel" value="trace" /> + <cm:property name="consoleLoggerErrLevel" value="error" /> </cm:default-properties> </cm:property-placeholder> @@ -97,6 +101,10 @@ <argument ref="commandProcessor"/> <argument ref="consoleFactory"/> <argument ref="threadIO"/> + <argument value="${consoleLogger}"/> + <argument value="${consoleLoggerName}"/> + <argument value="${consoleLoggerOutLevel}"/> + <argument value="${consoleLoggerErrLevel}"/> </bean> </property> <property name="commandFactory"> @@ -104,6 +112,10 @@ <argument> <bean class="org.apache.karaf.shell.ssh.ShellCommandFactory"> <property name="commandProcessor" ref="commandProcessor"/> + <property name="consoleLogger" value="${consoleLogger}"/> + <property name="consoleLoggerName" value="${consoleLoggerName}"/> + <property name="consoleLoggerOutLevel" value="${consoleLoggerOutLevel}"/> + <property name="consoleLoggerErrLevel" value="${consoleLoggerErrLevel}"/> </bean> </argument> </bean> http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/util/pom.xml ---------------------------------------------------------------------- diff --git a/util/pom.xml b/util/pom.xml index e656c11..b971db5 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -43,6 +43,10 @@ <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.utils</artifactId> </dependency> + <dependency> + <groupId>org.ops4j.pax.logging</groupId> + <artifactId>pax-logging-api</artifactId> + </dependency> </dependencies> <properties> http://git-wip-us.apache.org/repos/asf/karaf/blob/3ca841c2/util/src/main/java/org/apache/karaf/util/StreamLoggerInterceptor.java ---------------------------------------------------------------------- diff --git a/util/src/main/java/org/apache/karaf/util/StreamLoggerInterceptor.java b/util/src/main/java/org/apache/karaf/util/StreamLoggerInterceptor.java new file mode 100644 index 0000000..cfd90a8 --- /dev/null +++ b/util/src/main/java/org/apache/karaf/util/StreamLoggerInterceptor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.karaf.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.OutputStream; +import java.io.PrintStream; + +public class StreamLoggerInterceptor extends PrintStream { + + private Logger logger; + private String logLevel; + + public StreamLoggerInterceptor(OutputStream stream, String loggerName, String logLevel) { + super(stream, true); + this.logger = LoggerFactory.getLogger(loggerName); + this.logLevel = logLevel; + } + + @Override + public void print(String s) { + log(s); + super.print(s); + } + + @Override + public void println(String s) { + log(s); + super.println(s); + } + + private void log(String s) { + if (logLevel.equalsIgnoreCase("debug")) { + logger.debug(s); + } else if (logLevel.equalsIgnoreCase("error")) { + logger.error(s); + } else if (logLevel.equalsIgnoreCase("fatal")) { + logger.error(s); + } else if (logLevel.equalsIgnoreCase("info")) { + logger.info(s); + } else if (logLevel.equalsIgnoreCase("trace")) { + logger.trace(s); + } else if (logLevel.equalsIgnoreCase("warn")) { + logger.warn(s); + } + } + +}
