/* * Copyright 1998-2014 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package thredds.util; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.appender.RollingFileAppender; import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy; import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.NullConfiguration; import org.apache.logging.log4j.core.layout.PatternLayout; import ucar.nc2.util.log.LoggerFactory; import ucar.unidata.util.StringUtil2; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; /** * A LoggerFactory that uses log4j to create and configure a special RollingFileAppender * specific to this name. * used by InvDatasetFeatureCollection to create a log for each feature collection. * all wrong see http://logging.apache.org/log4j/2.x/manual/extending.html * * @author caron * @since 3/27/13 */ public class LoggerFactorySpecial implements LoggerFactory { static private org.slf4j.Logger startupLog = org.slf4j.LoggerFactory.getLogger("serverStartup"); static private Map<String, org.slf4j.Logger> map = new HashMap<>(); private String dir = "./"; private long maxSize; private int maxBackups; private Level level = Level.INFO; public LoggerFactorySpecial(long maxSize, int maxBackups, String levels) { String p = System.getProperty("tds.log.dir"); if (p != null) dir = p; this.maxSize = maxSize; this.maxBackups = maxBackups; try { Level tlevel = Level.toLevel(levels); if (tlevel != null) level = tlevel; } catch (Exception e) { startupLog.error("Illegal Logger level="+levels); } } /* @Override public org.slf4j.Logger getLogger(String name) { name = StringUtil2.replace(name.trim(), ' ', "_"); org.slf4j.Logger result = map.get(name); if (result != null) return result; try { org.apache.logging.log4j.core.Logger log4j = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(name, new MyMessageFactory()); log4j.info( new MyMapMessage(name)); startupLog.info("LoggerFactorySpecial add logger= {}", name); result = org.slf4j.LoggerFactory.getLogger(name); // get wrapper in slf4j map.put(name, result); return result; } catch (Throwable ioe) { startupLog.error("LoggerFactorySpecial failed on " + name, ioe); // standard slf4j - rely on external configuration return org.slf4j.LoggerFactory.getLogger(name); } } private class MyMessageFactory implements MessageFactory { @Override public Message newMessage(Object o) { return null; //To change body of implemented methods use File | Settings | File Templates. } @Override public Message newMessage(String s) { return null; //To change body of implemented methods use File | Settings | File Templates. } @Override public Message newMessage(String s, Object... objects) { return null; //To change body of implemented methods use File | Settings | File Templates. } } /* <RollingFile name="fc" fileName="${tds.log.dir}/fc.${map:collectionName}.log" filePattern="${tds.log.dir}/fc.${map:collectionName}.%i.log"> <PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSS Z} %-5p - %m%n"/> <Policies> <SizeBasedTriggeringPolicy size="1 MB"/> </Policies> <DefaultRolloverStrategy max="10"/> </RollingFile> * private class MyMapMessage extends MapMessage { MyMapMessage(String name) { super(); put("collectionName", name); } } */ public org.slf4j.Logger getLogger(String name) { name = StringUtil2.replace(name.trim(), ' ', "_"); org.slf4j.Logger result = map.get(name); if (result != null) return result; try { String fileName = dir + "/" + name + ".log"; String fileNamePattern = dir + "/" + name + "%i.log"; // create logger in log4j2 // TODO: There are Builders that make this logger creation less awkward. Configuration config = new NullConfiguration(); // LOOK: Why are we using this? Why not DefaultConfiguration? PatternLayout layout = PatternLayout.createLayout( "%d{yyyy-MM-dd'T'HH:mm:ss.SSS Z} %-5p - %m%n",// final String pattern, null, // ?? PatternSelector patternSelector, config, // Configuration config, null, // RegexReplacement replace, null, // Charset charset, true, // boolean alwaysWriteExceptions, false, // boolean noConsoleNoAnsi, null, // String headerPattern, null // String footerPattern ); DefaultRolloverStrategy.createStrategy( Integer.toString(maxBackups),// String max, "1", // String min, "max", // String fileIndex, null, // String compressionLevelStr, null, // ?? Action[] customActions, true, // boolean stopCustomActionsOnError, config //Configuration config ); RollingFileAppender app = RollingFileAppender.createAppender( fileName, // String fileName fileNamePattern, // String filePattern "true", // String append name, // String name "true", // String bufferedIO null, // String bufferSizeStr "true", // String immediateFlush SizeBasedTriggeringPolicy.createPolicy(Long.toString(maxSize)), // TriggeringPolicy policy DefaultRolloverStrategy.createStrategy( // RolloverStrategy strategy Integer.toString(maxBackups),// String max, "1", // String min, "max", // String fileIndex, null, // String compressionLevelStr, null, // ?? Action[] customActions, true, // boolean stopCustomActionsOnError, config //Configuration config ), layout, // Layout<? extends Serializable> layout null, // Filter filter "true", // String ignore "false", // String advertise null, // String advertiseURI config); // Configuration config app.start(); /*LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration conf = ctx.getConfiguration(); LoggerConfig lconf = conf.getLoggerConfig(name); lconf.setAdditive(false); // otherwise, it also gets sent to root logger (threddsServlet.log) lconf.setLevel(level); lconf.addAppender(app, level, null); ctx.updateLoggers(conf); */ org.apache.logging.log4j.core.Logger log4j = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(name); log4j.addAppender(app); log4j.setLevel(level); log4j.setAdditive(false); // otherwise, it also gets sent to root logger (threddsServlet.log) startupLog.info("LoggerFactorySpecial add logger= {} file= {}", name, fileName); result = org.slf4j.LoggerFactory.getLogger(name); // get wrapper in slf4j map.put(name, result); return result; } catch (Throwable ioe) { startupLog.error("LoggerFactorySpecial failed on " + name, ioe); // standard slf4j - rely on external configuration return org.slf4j.LoggerFactory.getLogger(name); } } }