I have a java app that runs jetty:
public class ServerRunner {
private final static org.apache.log4j.Logger logger = LoggingUtils.getLogger();
public static void main(String[] args) throws Exception {
PromptoConfig.s.initLog();
final int port = 8082;
final Server jettyServer = new Server(port);
final HandlerCollection handlers = new HandlerCollection();
// Creating the first web application context
final WebAppContext webappContext = new WebAppContext();
System.out.println("===== PromptoConfig.s.RESOURCES_BASE " + PromptoConfig.s.RESOURCES_BASE);
webappContext.setResourceBase(PromptoConfig.s.RESOURCES_BASE);
webappContext.setContextPath("/");
System.out.println("===== PromptoConfig.s.WEB_XML_PATH " + PromptoConfig.s.WEB_XML_PATH);
webappContext.setDefaultsDescriptor(PromptoConfig.s.WEB_XML_PATH);
// webappContext.setTempDirectory(new File(temp));
DBSQLConfig.s().DB = com.waze.prompto.config.DBSQLConfig.s.DB;
webappContext.setExtractWAR(false);
handlers.addHandler(webappContext);
// Adding the handlers to the server.
jettyServer.setHandler(handlers);
try {
jettyServer.start();
jettyServer.join();
} catch (Exception ex) {
logger.error("failed to init jetty server", ex);
} finally {
jettyServer.destroy();
}
}
}
i see in the logs debug info in intellij console:
633016 [org.eclipse.jetty.server.session.HashSessionManager#22fcf7abTimer] DEBUG org.eclipse.jetty.server.session - Scavenging sessions at 1496325042425
How can i turn this debug logs off?
You appear to have configured log4j on your environment.
private final static org.apache.log4j.Logger logger = LoggingUtils.getLogger();
The output format is also not the default format from Jetty's internal StdErrLog
Yours
633016 [org.eclipse.jetty.server.session.HashSessionManager#22fcf7abTimer] DEBUG org.eclipse.jetty.server.session - Scavenging sessions at 1496325042425
Jetty's StdErrLog
2017-06-01 14:30:17.978:DBUG:oejs.session:main: SessionManager default maxInactiveInterval=1800
At this point, this is no longer a jetty logging configuration, but a log4j configuration.
Just set the org.eclipse.jetty logger level to INFO or WARN in your log4j.properties or log4j.xml
If you use jetty-server from eclipse
Add configuration
log4j.category.org.eclipse.jetty=error
in the file src/main/resources/log4j.properties
Related
I'm actually adding java logging (can't use other framework) to my project. I build my app on a .war, and deployed it over Weblogic, the logger is working with my logging.properties config, except for the formatter i don't know why the app is ignoring it.
This is my class where i prepare the logger;
public class CtgLogger {
private static final String LOAD_ERROR = "Properties could not be loaded.";
private static final Map<String, Level> LEVEL_MAP;
private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
static {
final InputStream inputStream = CtgLogger.class.getResourceAsStream("/logging.properties");
try {
LogManager.getLogManager().readConfiguration(inputStream);
} catch (Exception e) {
Logger.getAnonymousLogger().severe(LOAD_ERROR);
Logger.getAnonymousLogger().severe(e.getMessage());
}
// and I add the LEVEL_MAP to the logger...
And this is my properties...
handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.pattern=logsfolder/CTGLOG_%g.log
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.limit=3000
java.util.logging.FileHandler.count=6
#java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#If I use the SimpleFormatter, apps goes well with it format.
java.util.logging.FileHandler.formatter = com.package.my.log.JsonCustomFormatter
#If I use my custom formatter, the weblogic works with a XMLFormatter (default)
I know the .properties is working, because logger is working with the pattern, limit and count I setted.
PD: If i run my app with JUnit, logs are working with my custom formatter, but do not at weblogic! Don't know why!
Weblogic is going to have multiple class loaders. The standard LogManager can only see classes loaded via the system class loader. Check the Server Log for errors related to not finding your custom class. If that is the case, you have to move your formatter to the system classloader. Otherwise you have have to use code to install your formatter from your web app which is running in a child classloader.
There are also bugs in the LogManager.readConfiguration and alternative methods to use in JDK9 and later.
Using Eclipse and java standard logger may be painful. I found something to produce similar output to Log4J:
"%d{HH:mm:ss,SSS} %-5p %m (%F:%L) in %t%n" in Log4J : you can click on reference and you are there log was issued
21:36:37,9 INFO process model event Digpro2021a/digpro.Digpro(Digpro.java:358) in processModelEvent
21:36:37,9 INFO start polling Digpro2021a/digpro.Digpro(Digpro.java:398) in processEventAutoreload
21:36:37,9 INFO reload now Digpro2021a/digpro.Digpro(Digpro.java:370) in processModelEvent
public class Digpro {
protected static final Logger L = Logger.getLogger("Digpro");
//logger conf
static {
L.setLevel(Level.FINE);
Handler handler = Logger.getLogger("").getHandlers()[0];
handler.setLevel(Level.FINE); // Default console handler
handler.setFormatter(new Formatter() {
#Override
public String format(LogRecord r) {
Date d = new Date(r.getMillis());
String srcClassLong = r.getSourceClassName();
String[] aClass = srcClassLong.split("\\$")[0].split("\\.");
String srcClass = aClass[aClass.length - 1];
StackTraceElement elem = (new Throwable()).getStackTrace()[7];
int line = elem.getLineNumber();
String modulName = elem.getModuleName();
return String.format("%tH:%tM:%tS,%tl %.7s %s %s/%s(%s.java:%d) in %s\n", d, d, d, d, //
r.getLevel(), r.getMessage(), // LEVEL and message
modulName, srcClassLong, srcClass, line, r.getSourceMethodName()); //ref to click on
}
});
}
...
public static class TestDigpro extends Digpro {
//TESTING:
#Test
public void testLogFormat() {
L.info("poll info");
L.fine("got fine");
}
}
}
produses:
21:51:20,9 INFO poll info Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:723) in testLogFormat
21:51:20,9 FINE got fine Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:724) in testLogFormat
I'm trying a self-executable WAR package with Jetty. It configures with web.xml by default. If a run-time option is given, I wanted to override web.xml by Java code-level configuration with ServletContextHandler#addServlet, #addEventListener, and ...
Can I ignore web.xml while loading a WAR package?
% java -jar foobar.jar # Use web.xml
% java -jar foobar.jar --customize=something # Use Java code to configure
// Example
WebAppContext webapp = new WebAppContext();
webapp.setWar(warLocation.toExternalForm());
webapp.setContextPath("/");
if ( /* has run-time options */ ) {
webapp.setWar(warLocation.toExternalForm()); // But, no load web.xml!
// Emulates web.xml.
webapp.addEventListener(...);
webapp.setInitParameter("resteasy.role.based.security", "true");
webapp.addFilter(...);
} else {
webapp.setWar(warLocation.toExternalForm()); // Loading web.xml.
}
Additional Question:
Before server.start() is called, classes under WEB-INF/ are not loaded. Can I do some configuration webapp.something() with some classes under WEB-INF/? (E.g. extend WebInfConfiguration or do a similar class-loading that WebInfConfiguration does?)
For example, I'd like to do something like:
webapp.addEventListener(new SomeClassUnderWebInf()));
webapp.addEventListener(someInjector.inject(SomeClassUnderWebInf.class));
before server.start().
Handle the WebAppContext Configuration yourself.
Eg:
private static class SelfConfiguration extends AbstractConfiguration
{
#Override
public void configure(WebAppContext context) throws Exception
{
// Emulates web.xml.
webapp.addEventListener(...);
webapp.setInitParameter("resteasy.role.based.security", "true");
webapp.addFilter(...);
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
if (useWebXml)
{
webapp.setConfigurationClasses(WebAppContext.getDefaultConfigurationClasses());
}
else
{
webapp.setConfigurations(new Configuration[] {
new SelfConfiguration()
});
}
webapp.setWar("path/to/my/test.war");
webapp.setParentLoaderPriority(true);
server.setHandler(webapp);
server.start();
server.join();
}
I have been using Tomcat,JBoss,Glassfish etc for years.
In these containers I have used Log4j, JDK Logging etc. It is very easy.
I am struggling to get any logging from my application in Weblogic 12c.
The logs get written to stderr and not to a log file.
private final static Logger log = Logger.getLogger(TestingService.class.getName());
log.log(Level.SEVERE,"My log " + text);
In the Admin console
Logging implementation: JDK
Severity level: INFO
The behaviour is the same if I configure Log4J by following the log4j Weblogic config process.
You can try some codes like the following to get the Weblogic domain logger and server logger in your application:
import java.util.logging.Logger;
import weblogic.logging.LoggerNotAvailableException;
import weblogic.logging.LoggingHelper;
public class GetLogger {
public static Logger getLogger(){
Logger logger = null ;
try {
logger = LoggingHelper.getDomainLogger() ;
} catch (LoggerNotAvailableException e) {
logger = LoggingHelper.getServerLogger() ;
}
return logger ;
}
}
logger.setLevel() method is not available in log4j2 API. So how to set log level at run time.
I'm not sure if this is the best way, but you set the level on org.apache.logging.log4j.core.config.LoggerConfig which you can get from the LoggerContext via the LogManager.
Once set, you can update the loggers with the new configuration.
As an example:
public static void main(String[] args) {
Logger log = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
log.error("An error");
log.debug("A debug");
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration conf = ctx.getConfiguration();
conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(Level.DEBUG);
ctx.updateLoggers(conf);
log.error("Another error");
log.debug("Another debug");
}
Yields:
14:03:41.346 [main] ERROR - An error
14:03:41.348 [main] ERROR - Another error
14:03:41.348 [main] DEBUG - Another debug
Credit to amcintosh, I wrapped their answer in a function:
/** Override the logging level of a given logger, return the previous level */
public static Level setLevel(Logger log, Level level) {
LoggerContext ctx = (LoggerContext)LogManager.getContext(false);
Configuration conf = ctx.getConfiguration();
LoggerConfig lconf = conf.getLoggerConfig(log.getName());
Level oldLevel = lconf.getLevel();
lconf.setLevel(level);
ctx.updateLoggers(conf);
return oldLevel;
}
Despite amoe's comment, this seems to be working correctly for me using Log4J 2.5.
Gary Gregory is correct.
Also the answer to this question is right there on the FAQ page in log4j2's site
https://logging.apache.org/log4j/2.x/faq.html#reconfig_level_from_code
Sample Code below:
Configurator.setLevel(logger.getName(), Level.INFO);
On my side, i had to use this code in order to have this working fine (based on previous answers).
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
...
public static void changeLoggerLevel(final String module, final Level level) {
String moduleRenamed = module.replaceAll("/", ".");
LoggerContext ctx = (LoggerContext)LogManager.getContext(false);
AbstractConfiguration configuration = (AbstractConfiguration) ctx
.getConfiguration();
if (configuration.getLogger(moduleRenamed) != null) {
LoggerConfig loggerConfig = configuration.getLoggerConfig(moduleRenamed);
loggerConfig.setLevel(level);
} else {
LoggerConfig loggerConfig = new LoggerConfig(moduleRenamed, level, true);
configuration.addLogger(moduleRenamed, loggerConfig);
}
ctx.updateLoggers(configuration);
}
The problem was with the getLoggerConfig() call; if the module you are trying to give a new level is not yet registered, this method returns the root logger (or any intermediate sub path registered), and thus instead of altering the level for com.mycompany you will alter root or com level. That's why you have to add a new LoggerConfig in case the module to alter is not yet registered.
The following APIs in the class org.apache.logging.log4j.core.config.Configurator allow you to change Levels:
setAllLevels(String, Level)
setLevel(Map)
setLevel(String, Level)
setRootLevel(Level)
I a newbie in Jetty. I have created an application in which I embed the jetty web container. When I run the the application from eclipse it runs perfectly without any issues. However when I export the project with all the required libraries and run it from command line I cannot access the index.jsp web page like I used to in eclispe. This is the file that run the jetty web container.
public class JettyServer {
// The folder containing all the .jsp files
private final static String WEB_ROOT = "src/WebContent";
// Instance of the Jetty server
private final static Server SRV = new Server();
// Context Path
private final static String CONTEXT_PATH = "/smpp";
// Logging
private final static org.slf4j.Logger logger = LoggerFactory.getLogger(JettyServer.class);
/**
* #param args
* #throws ConfigurationException
*/
public static void main(String[] args) throws ConfigurationException {
logger.info("Initializing Web Server......");
// Servlet Context
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
// Set the security constraints
context.setContextPath(CONTEXT_PATH);
context.setResourceBase(WEB_ROOT);
context.setClassLoader(Thread.currentThread().getContextClassLoader());
context.addServlet(DefaultServlet.class, "/");
context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
String [] welcomeFiles = {"index.jsp"};
context.setWelcomeFiles(welcomeFiles);
// Set the .jsp servlet handlers
final ServletHolder jsp = context.addServlet(JspServlet.class, "*.jsp");
jsp.setInitParameter("classpath", context.getClassPath());
// Session Manager
SessionHandler sh = new SessionHandler();
context.setSessionHandler(sh);
/* Http Request Handlers */
context.addServlet(HttpRequestProcessor.class, "/HttpHandler");
// Server configuration setup
// Connector setup
// We explicitly use the SocketConnector because the SelectChannelConnector locks files
Connector connector = new SocketConnector();
connector.setHost("localhost");
connector.setPort(Integer.parseInt(System.getProperty("jetty.port", new PropertiesConfiguration("smpp-config.properties").getString("http_port").trim())));
connector.setMaxIdleTime(60000);
JettyServer.SRV.setConnectors(new Connector[] { connector });
JettyServer.SRV.setHandler(context);
JettyServer.SRV.setAttribute("org.mortbay.jetty.Request.maxFormContentSize", 0);
JettyServer.SRV.setGracefulShutdown(5000);
JettyServer.SRV.setStopAtShutdown(true);
logger.info("Starting Jetty Web Container....");
try{
JettyServer.SRV.start();
}
catch(Exception ex){
logger.error("Jetty Web Container failed to start [CAUSE : " + ex.getMessage() + "]");
return;
}
logger.info("Jetty Web Container running....");
while(true){
try{
JettyServer.SRV.join();
}
catch(InterruptedException iex){
logger.error("Jetty Web Container interrupted [CAUSE : " + iex.getMessage() + "]");
}
}
}
}
code formatted properly
Your use of relative paths in the context.setResourceBase("src/WebContent"); will cause you problems.
Use a full, and absolute, URI reference with context.setResourceBase(String).
Note that you can use the following URI schemes: file, ftp, jar, and even http
Instead of this
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
Can you use this ?
WebAppContext root = new WebAppContext();
and rest of the code as example :
String webappDirLocation = "src/Webcontent/";
Server server = new Server(8080);
root.setContextPath(CONTEXT_PATH);
root.setDescriptor(webappDirLocation + "/WEB-INF/web.xml");
root.setResourceBase(webappDirLocation);
root.setParentLoaderPriority(true);
server.setHandler(root);