/** * Read configuration from a file. <b>The existing configuration is not cleared nor reset.</b> If * you require a different behavior, then call {@link LogManager#resetConfiguration * resetConfiguration} method before calling <code>doConfigure</code>. * * <p>The configuration file consists of statements in the format <code>key=value</code>. The * syntax of different configuration elements are discussed below. * * <h3>Repository-wide threshold</h3> * * <p>The repository-wide threshold filters logging requests by level regardless of logger. The * syntax is: * * <pre> * log4j.threshold=[level] * </pre> * * <p>The level value can consist of the string values OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL * or a <em>custom level</em> value. A custom level value can be specified in the form * level#classname. By default the repository-wide threshold is set to the lowest possible value, * namely the level <code>ALL</code>. * * <h3>Appender configuration</h3> * * <p>Appender configuration syntax is: * * <pre> * # For appender named <i>appenderName</i>, set its class. * # Note: The appender name can contain dots. * log4j.appender.appenderName=fully.qualified.name.of.appender.class * * # Set appender specific options. * log4j.appender.appenderName.option1=value1 * ... * log4j.appender.appenderName.optionN=valueN * </pre> * * For each named appender you can configure its {@link Layout}. The syntax for configuring an * appender's layout is: * * <pre> * log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class * log4j.appender.appenderName.layout.option1=value1 * .... * log4j.appender.appenderName.layout.optionN=valueN * </pre> * * The syntax for adding {@link Filter}s to an appender is: * * <pre> * log4j.appender.appenderName.filter.ID=fully.qualified.name.of.filter.class * log4j.appender.appenderName.filter.ID.option1=value1 * ... * log4j.appender.appenderName.filter.ID.optionN=valueN * </pre> * * The first line defines the class name of the filter identified by ID; subsequent lines with the * same ID specify filter option - value paris. Multiple filters are added to the appender in the * lexicographic order of IDs. * * <p>The syntax for adding an {@link ErrorHandler} to an appender is: * * <pre> * log4j.appender.appenderName.errorhandler=fully.qualified.name.of.filter.class * log4j.appender.appenderName.errorhandler.root-ref={true|false} * log4j.appender.appenderName.errorhandler.logger-ref=loggerName * log4j.appender.appenderName.errorhandler.appender-ref=appenderName * log4j.appender.appenderName.errorhandler.option1=value1 * ... * log4j.appender.appenderName.errorhandler.optionN=valueN * </pre> * * <h3>Configuring loggers</h3> * * <p>The syntax for configuring the root logger is: * * <pre> * log4j.rootLogger=[level], appenderName, appenderName, ... * </pre> * * <p>This syntax means that an optional <em>level</em> can be supplied followed by appender names * separated by commas. * * <p>The level value can consist of the string values OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL * or a <em>custom level</em> value. A custom level value can be specified in the form <code> * level#classname</code>. * * <p>If a level value is specified, then the root level is set to the corresponding level. If no * level value is specified, then the root level remains untouched. * * <p>The root logger can be assigned multiple appenders. * * <p>Each <i>appenderName</i> (separated by commas) will be added to the root logger. The named * appender is defined using the appender syntax defined above. * * <p>For non-root categories the syntax is almost the same: * * <pre> * log4j.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName, ... * </pre> * * <p>The meaning of the optional level value is discussed above in relation to the root logger. * In addition however, the value INHERITED can be specified meaning that the named logger should * inherit its level from the logger hierarchy. * * <p>If no level value is supplied, then the level of the named logger remains untouched. * * <p>By default categories inherit their level from the hierarchy. However, if you set the level * of a logger and later decide that that logger should inherit its level, then you should specify * INHERITED as the value for the level value. NULL is a synonym for INHERITED. * * <p>Similar to the root logger syntax, each <i>appenderName</i> (separated by commas) will be * attached to the named logger. * * <p>See the <a href="../../../../manual.html#additivity">appender additivity rule</a> in the * user manual for the meaning of the <code>additivity</code> flag. * * <h3>ObjectRenderers</h3> * * You can customize the way message objects of a given type are converted to String before being * logged. This is done by specifying an {@link org.apache.log4j.or.ObjectRenderer ObjectRenderer} * for the object type would like to customize. * * <p>The syntax is: * * <pre> * log4j.renderer.fully.qualified.name.of.rendered.class=fully.qualified.name.of.rendering.class * </pre> * * As in, * * <pre> * log4j.renderer.my.Fruit=my.FruitRenderer * </pre> * * <h3>ThrowableRenderer</h3> * * You can customize the way an instance of Throwable is converted to String before being logged. * This is done by specifying an {@link org.apache.log4j.spi.ThrowableRenderer ThrowableRenderer}. * * <p>The syntax is: * * <pre> * log4j.throwableRenderer=fully.qualified.name.of.rendering.class * log4j.throwableRenderer.paramName=paramValue * </pre> * * As in, * * <pre> * log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer * </pre> * * <h3>Logger Factories</h3> * * The usage of custom logger factories is discouraged and no longer documented. * * <h3>Resetting Hierarchy</h3> * * The hierarchy will be reset before configuration when log4j.reset=true is present in the * properties file. * * <h3>Example</h3> * * <p>An example configuration is given below. Other configuration file examples are given in the * <code>examples</code> folder. * * <pre> * * # Set options for appender named "A1". * # Appender "A1" will be a SyslogAppender * log4j.appender.A1=org.apache.log4j.net.SyslogAppender * * # The syslog daemon resides on www.abc.net * log4j.appender.A1.SyslogHost=www.abc.net * * # A1's layout is a PatternLayout, using the conversion pattern * # <b>%r %-5p %c{2} %M.%L %x - %m\n</b>. Thus, the log output will * # include # the relative time since the start of the application in * # milliseconds, followed by the level of the log request, * # followed by the two rightmost components of the logger name, * # followed by the callers method name, followed by the line number, * # the nested disgnostic context and finally the message itself. * # Refer to the documentation of {@link PatternLayout} for further information * # on the syntax of the ConversionPattern key. * log4j.appender.A1.layout=org.apache.log4j.PatternLayout * log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %c{2} %M.%L %x - %m\n * * # Set options for appender named "A2" * # A2 should be a RollingFileAppender, with maximum file size of 10 MB * # using at most one backup file. A2's layout is TTCC, using the * # ISO8061 date format with context printing enabled. * log4j.appender.A2=org.apache.log4j.RollingFileAppender * log4j.appender.A2.MaxFileSize=10MB * log4j.appender.A2.MaxBackupIndex=1 * log4j.appender.A2.layout=org.apache.log4j.TTCCLayout * log4j.appender.A2.layout.ContextPrinting=enabled * log4j.appender.A2.layout.DateFormat=ISO8601 * * # Root logger set to DEBUG using the A2 appender defined above. * log4j.rootLogger=DEBUG, A2 * * # Logger definitions: * # The SECURITY logger inherits is level from root. However, it's output * # will go to A1 appender defined above. It's additivity is non-cumulative. * log4j.logger.SECURITY=INHERIT, A1 * log4j.additivity.SECURITY=false * * # Only warnings or above will be logged for the logger "SECURITY.access". * # Output will go to A1. * log4j.logger.SECURITY.access=WARN * * * # The logger "class.of.the.day" inherits its level from the * # logger hierarchy. Output will go to the appender's of the root * # logger, A2 in this case. * log4j.logger.class.of.the.day=INHERIT * </pre> * * <p>Refer to the <b>setOption</b> method in each Appender and Layout for class specific options. * * <p>Use the <code>#</code> or <code>!</code> characters at the beginning of a line for comments. * * <p> * * @param configFileName The name of the configuration file where the configuration information is * stored. */ public void doConfigure(String configFileName, LoggerRepository hierarchy) { Properties props = new Properties(); FileInputStream istream = null; try { istream = new FileInputStream(configFileName); props.load(istream); istream.close(); } catch (Exception e) { if (e instanceof InterruptedIOException || e instanceof InterruptedException) { Thread.currentThread().interrupt(); } LogLog.error("Could not read configuration file [" + configFileName + "].", e); LogLog.error("Ignoring configuration file [" + configFileName + "]."); return; } finally { if (istream != null) { try { istream.close(); } catch (InterruptedIOException ignore) { Thread.currentThread().interrupt(); } catch (Throwable ignore) { } } } // If we reach here, then the config file is alright. doConfigure(props, hierarchy); }
/** * Where the actual logging event is processed and a mail message is generated. * * @param event logging event */ public void subAppend(LoggingEvent event) { if (editingContext().hasChanges()) { LogLog.error( "ERProblemMailMessageAppender: editingContext has changes -- infinite loop detected"); } else { String title = composeTitle(event); String content = composeMessage(event); ERCMailMessage message = ERCMailDelivery.sharedInstance() .composeEmail( computedFromAddress(), toAddressesAsArray(), toAddressesAsArray(), bccAddressesAsArray(), title, content, editingContext()); if (getReplyTo() != null) { message.setReplyToAddress(getReplyTo()); } try { editingContext().saveChanges(); } catch (RuntimeException e) { LogLog.error( "Caught exception when saving changes to mail context. Exception: " + e.getMessage()); } finally { editingContext().revert(); } } }
/** Read configuration options from url <code>configURL</code>. */ public void doConfigure(java.net.URL configURL, LoggerRepository hierarchy) { Properties props = new Properties(); LogLog.debug("Reading configuration from URL " + configURL); InputStream istream = null; URLConnection uConn = null; try { uConn = configURL.openConnection(); uConn.setUseCaches(false); istream = uConn.getInputStream(); props.load(istream); } catch (Exception e) { if (e instanceof InterruptedIOException || e instanceof InterruptedException) { Thread.currentThread().interrupt(); } LogLog.error("Could not read configuration file from URL [" + configURL + "].", e); LogLog.error("Ignoring configuration file [" + configURL + "]."); return; } finally { if (istream != null) { try { istream.close(); } catch (InterruptedIOException ignore) { Thread.currentThread().interrupt(); } catch (IOException ignore) { } catch (RuntimeException ignore) { } } } doConfigure(props, hierarchy); }
/** Parse the additivity option for a non-root category. */ void parseAdditivityForLogger(Properties props, Logger cat, String loggerName) { String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, props); LogLog.debug("Handling " + ADDITIVITY_PREFIX + loggerName + "=[" + value + "]"); // touch additivity only if necessary if ((value != null) && (!value.equals(""))) { boolean additivity = OptionConverter.toBoolean(value, true); LogLog.debug("Setting additivity for \"" + loggerName + "\" to " + additivity); cat.setAdditivity(additivity); } }
/** * 滚动文件 * * <pre> * 1.对文件名带的时间戳进行比较,确定是否更新 * 2.如果�?��更新,当前文件重命名为:原文件名+日期,重新开始写新的日志文件 * 3.根据配置的maxBackupIndex,删除过期的文件 * </pre> * * @throws IOException Signals that an I/O exception has occurred. * @version */ void rollOver() throws IOException { String datedFilename = fileName + sdf.format(now); // 如果上次写的日期跟当前日期相同,不需要换文件 if (scheduledFilename.equals(datedFilename)) { return; } // 关闭当前文件,并重命�? this.closeFile(); File target = new File(scheduledFilename); if (target.exists()) { target.delete(); } File file = new File(fileName); boolean result = file.renameTo(target); if (result) { LogLog.debug(fileName + " -> " + scheduledFilename); } else { LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "]."); } // 删除过期文件 if (maxBackupIndex > 0) { File folder = new File(file.getParent()); List<String> maxBackupIndexDates = getMaxBackupIndexDates(); for (File ff : folder.listFiles()) { // 遍历目录,将日期不在备份范围内的日志删掉 if (ff.getName().startsWith(file.getName()) && !ff.getName().equals(file.getName())) { // 获取文件名带的日期时间戳 String markedDate = ff.getName().substring(file.getName().length()); if (!maxBackupIndexDates.contains(markedDate)) { result = ff.delete(); } if (result) { LogLog.debug(ff.getName() + " -> deleted "); } else { LogLog.error("Failed to deleted old DayRollingFileAppender file :" + ff.getName()); } } } } try { // 关闭文件,多个关闭操作并行时安装�? this.setFile(fileName, false, this.bufferedIO, this.bufferSize); } catch (IOException e) { errorHandler.error("setFile(" + fileName + ", false) call failed."); } // 更新�?��更新日期�? scheduledFilename = datedFilename; }
/** * Read configuration options from url <code>configURL</code>. * * @since 1.2.17 */ public void doConfigure(InputStream inputStream, LoggerRepository hierarchy) { Properties props = new Properties(); try { props.load(inputStream); } catch (IOException e) { if (e instanceof InterruptedIOException) { Thread.currentThread().interrupt(); } LogLog.error("Could not read configuration file from InputStream [" + inputStream + "].", e); LogLog.error("Ignoring configuration InputStream [" + inputStream + "]."); return; } this.doConfigure(props, hierarchy); }
/** This method must work for the root category as well. */ void parseCategory( Properties props, Logger logger, String optionKey, String loggerName, String value) { LogLog.debug("Parsing for [" + loggerName + "] with value=[" + value + "]."); // We must skip over ',' but not white space StringTokenizer st = new StringTokenizer(value, ","); // If value is not in the form ", appender.." or "", then we should set // the level of the loggeregory. if (!(value.startsWith(",") || value.equals(""))) { // just to be on the safe side... if (!st.hasMoreTokens()) return; String levelStr = st.nextToken(); LogLog.debug("Level token is [" + levelStr + "]."); // If the level value is inherited, set category level value to // null. We also check that the user has not specified inherited for the // root category. if (INHERITED.equalsIgnoreCase(levelStr) || NULL.equalsIgnoreCase(levelStr)) { if (loggerName.equals(INTERNAL_ROOT_NAME)) { LogLog.warn("The root logger cannot be set to null."); } else { logger.setLevel(null); } } else { logger.setLevel(OptionConverter.toLevel(levelStr, (Level) Level.DEBUG)); } LogLog.debug("Category " + loggerName + " set to " + logger.getLevel()); } // Begin by removing all existing appenders. logger.removeAllAppenders(); Appender appender; String appenderName; while (st.hasMoreTokens()) { appenderName = st.nextToken().trim(); if (appenderName == null || appenderName.equals(",")) continue; LogLog.debug("Parsing appender named \"" + appenderName + "\"."); appender = parseAppender(props, appenderName); if (appender != null) { logger.addAppender(appender); } } }
/** * 初始化操�? * * @version */ public void activateOptions() { super.activateOptions(); if (fileName != null) { now.setTime(System.currentTimeMillis()); sdf = new SimpleDateFormat(datePattern); File file = new File(fileName); // 获取�?��更新时间拼成的文件名 scheduledFilename = fileName + sdf.format(new Date(file.lastModified())); } else { LogLog.error("File is not set for appender [" + name + "]."); } if (maxBackupIndex <= 0) { LogLog.error("maxBackupIndex reset to default value[2],orignal value is:" + maxBackupIndex); maxBackupIndex = 2; } }
/** * This method performs threshold checks and invokes filters before delegating actual logging to * the subclasses specific {@link AppenderSkeleton#append} method. */ public synchronized void doAppend(LoggingEvent event) { if (closed) { LogLog.error("Attempted to append to closed appender named [" + name + "]."); return; } if (!isAsSevereAsThreshold(event.getLevel())) { return; } Filter f = this.headFilter; FILTER_LOOP: while (f != null) { switch (f.decide(event)) { case Filter.DENY: return; case Filter.ACCEPT: break FILTER_LOOP; case Filter.NEUTRAL: f = f.getNext(); } } this.append(event); }
/** AppenderSkeleton回调函数, 事件到达时将时间放入Queue. */ @Override public void append(LoggingEvent event) { if (queue == null) { queue = QueuesHolder.getQueue(queueName); } boolean sucess = queue.offer(event); if (sucess) { LogLog.debug( "put event to queue success:" + new LoggingEventWrapper(event).convertToString()); } else { LogLog.error("Put event to queue fail:" + new LoggingEventWrapper(event).convertToString()); } }
/** * Finalize this appender by calling the derived class' <code>close</code> method. * * @since 0.8.4 */ public void finalize() { // An appender might be closed then garbage collected. There is no // point in closing twice. if (this.closed) return; LogLog.debug("Finalizing appender named [" + name + "]."); close(); }
public void run() { try { String line = dis.readUTF(); LogLog.debug("Got external roll over signal."); if (ExternallyRolledFileAppender.ROLL_OVER.equals(line)) { synchronized (er) { er.rollOver(); } dos.writeUTF(ExternallyRolledFileAppender.OK); } else { dos.writeUTF("Expecting [RollOver] string."); } dos.close(); } catch (Exception e) { LogLog.error("Unexpected exception. Exiting HUPNode.", e); } }
/** * Set the {@link ErrorHandler} for this Appender. * * @since 0.9.0 */ public synchronized void setErrorHandler(ErrorHandler eh) { if (eh == null) { // We do not throw exception here since the cause is probably a // bad config file. LogLog.warn("You have tried to set a null error-handler."); } else { this.errorHandler = eh; } }
/** * Implements the usual roll over behaviour. * * <p>If <code>MaxBackupIndex</code> is positive, then files {<code>File.1</code>, ..., <code> * File.MaxBackupIndex -1</code>} are renamed to {<code>File.2</code>, ..., <code> * File.MaxBackupIndex</code>}. Moreover, <code>File</code> is renamed <code>File.1</code> and * closed. A new <code>File</code> is created to receive further log output. * * <p>If <code>MaxBackupIndex</code> is equal to zero, then the <code>File</code> is truncated * with no backup files created. */ public // synchronization not necessary since doAppend is alreasy synched void rollOver() { File target; File file; LogLog.debug("rolling over count=" + ((CountingQuietWriter) qw).getCount()); LogLog.debug("maxBackupIndex=" + maxBackupIndex); // If maxBackups <= 0, then there is no file renaming to be done. if (maxBackupIndex > 0) { // Delete the oldest file, to keep Windows happy. file = new File(fileName + '.' + maxBackupIndex); if (file.exists()) file.delete(); // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} for (int i = maxBackupIndex - 1; i >= 1; i--) { file = new File(fileName + "." + i); if (file.exists()) { target = new File(fileName + '.' + (i + 1)); LogLog.debug("Renaming file " + file + " to " + target); file.renameTo(target); } } // Rename fileName to fileName.1 target = new File(fileName + "." + 1); this.closeFile(); // keep windows happy. file = new File(fileName); LogLog.debug("Renaming file " + file + " to " + target); file.renameTo(target); } try { // This will also close the file. This is OK since multiple // close operations are safe. this.setFile(fileName, false, bufferedIO, bufferSize); } catch (IOException e) { LogLog.error("setFile(" + fileName + ", false) call failed.", e); } }
/** * Check the provided <code>Properties</code> object for a {@link * org.apache.log4j.spi.LoggerFactory LoggerFactory} entry specified by {@link * #LOGGER_FACTORY_KEY}. If such an entry exists, an attempt is made to create an instance using * the default constructor. This instance is used for subsequent Category creations within this * configurator. * * @see #parseCatsAndRenderers */ protected void configureLoggerFactory(Properties props) { String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, props); if (factoryClassName != null) { LogLog.debug("Setting category factory to [" + factoryClassName + "]."); loggerFactory = (LoggerFactory) OptionConverter.instantiateByClassName( factoryClassName, LoggerFactory.class, loggerFactory); PropertySetter.setProperties(loggerFactory, props, FACTORY_PREFIX + "."); } }
/** * This method differentiates RollingFileAppender from its super class. * * @since 0.9.0 */ protected void subAppend(LoggingEvent event) { long n = System.currentTimeMillis(); if (n >= nextCheck) { now.setTime(n); nextCheck = rc.getNextCheckMillis(now); try { rollOver(DailyRollingFileType); } catch (IOException ioe) { LogLog.error("rollOver() failed.", ioe); } } else if ((fileName != null) && ((CountingQuietWriter) qw).getCount() >= maxFileSize) { try { rollOver(RollingFileType); } catch (IOException ioe) { LogLog.error("rollOver() failed.", ioe); } } super.subAppend(event); }
/** * Gets the editing context to use for creating mail messages in. * * @return editing context with a no-op delegate set. */ public EOEditingContext editingContext() { if (editingContext == null) { if (!hasCooperatingObjectStores()) { LogLog.warn( "Creating editing context for the ERCMailMessageAppender before any cooperating object stores have been added."); } editingContext = new EOEditingContext(); editingContext.setDelegate(_delegate); } return editingContext; }
/** * 写操�? * * @param event event * @version */ protected void subAppend(LoggingEvent event) { long n = System.currentTimeMillis(); if (n >= nextCheck) { // 在每次写操作前判断一下是否需要滚动文�? now.setTime(n); nextCheck = getNextDayCheckPoint(now); try { rollOver(); } catch (IOException ioe) { LogLog.error("rollOver() failed.", ioe); } } super.subAppend(event); }
/* 136: */ /* 137: */ public synchronized void setErrorHandler(ErrorHandler eh) /* 138: */ { /* 139:271 */ if (eh == null) /* 140: */ { /* 141:272 */ LogLog.warn("You have tried to set a null error-handler."); /* 142: */ } /* 143: */ else /* 144: */ { /* 145:274 */ this.errorHandler = eh; /* 146:275 */ if (this.qw != null) { /* 147:276 */ this.qw.setErrorHandler(eh); /* 148: */ } /* 149: */ } /* 150: */ }
/* 101: */ /* 102: */ protected OutputStreamWriter createWriter(OutputStream os) /* 103: */ { /* 104:236 */ OutputStreamWriter retval = null; /* 105: */ /* 106:238 */ String enc = getEncoding(); /* 107:239 */ if (enc != null) { /* 108: */ try /* 109: */ { /* 110:241 */ retval = new OutputStreamWriter(os, enc); /* 111: */ } /* 112: */ catch (IOException e) /* 113: */ { /* 114:243 */ if ((e instanceof InterruptedIOException)) { /* 115:244 */ Thread.currentThread().interrupt(); /* 116: */ } /* 117:246 */ LogLog.warn("Error initializing output writer."); /* 118:247 */ LogLog.warn("Unsupported encoding?"); /* 119: */ } /* 120: */ } /* 121:250 */ if (retval == null) { /* 122:251 */ retval = new OutputStreamWriter(os); /* 123: */ } /* 124:253 */ return retval; /* 125: */ }
public void run() { while (!isInterrupted()) { try { ServerSocket serverSocket = new ServerSocket(port); while (true) { Socket socket = serverSocket.accept(); LogLog.debug("Connected to client at " + socket.getInetAddress()); new Thread(new HUPNode(socket, er)).start(); } } catch (Exception e) { e.printStackTrace(); } } }
/* * (non-Javadoc) * * @see org.apache.log4j.appender.AppenderCommand#execute(org.apache.log4j.Appender) */ public final void execute(final Appender appender, final LoggingEvent event) { try { appender.doAppend(event); } catch (RuntimeException e) { if (this.shouldThrow()) { throw e; } else { this.errors = true; LogLog.warn( Thread.currentThread().getName() + " recovered from fault during LoggingEvent dispatch - events may have been lost", e); } } }
/** * Read configuration options from <code>properties</code>. * * <p>See {@link #doConfigure(String, LoggerRepository)} for the expected format. */ public void doConfigure(Properties properties, LoggerRepository hierarchy) { repository = hierarchy; String value = properties.getProperty(LogLog.DEBUG_KEY); if (value == null) { value = properties.getProperty("log4j.configDebug"); if (value != null) LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead."); } if (value != null) { LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true)); } // // if log4j.reset=true then // reset hierarchy String reset = properties.getProperty(RESET_KEY); if (reset != null && OptionConverter.toBoolean(reset, false)) { hierarchy.resetConfiguration(); } String thresholdStr = OptionConverter.findAndSubst(THRESHOLD_PREFIX, properties); if (thresholdStr != null) { hierarchy.setThreshold(OptionConverter.toLevel(thresholdStr, (Level) Level.ALL)); LogLog.debug("Hierarchy threshold set to [" + hierarchy.getThreshold() + "]."); } configureRootCategory(properties, hierarchy); configureLoggerFactory(properties); parseCatsAndRenderers(properties, hierarchy); LogLog.debug("Finished configuring."); // We don't want to hold references to appenders preventing their // garbage collection. registry.clear(); }
/* 84: */ /* 85: */ protected void closeWriter() /* 86: */ { /* 87:214 */ if (this.qw != null) { /* 88: */ try /* 89: */ { /* 90:216 */ this.qw.close(); /* 91: */ } /* 92: */ catch (IOException e) /* 93: */ { /* 94:218 */ if ((e instanceof InterruptedIOException)) { /* 95:219 */ Thread.currentThread().interrupt(); /* 96: */ } /* 97:223 */ LogLog.error("Could not close " + this.qw, e); /* 98: */ } /* 99: */ } /* 100: */ }
void configureRootCategory(Properties props, LoggerRepository hierarchy) { String effectiveFrefix = ROOT_LOGGER_PREFIX; String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, props); if (value == null) { value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, props); effectiveFrefix = ROOT_CATEGORY_PREFIX; } if (value == null) LogLog.debug("Could not find root logger information. Is this OK?"); else { Logger root = hierarchy.getRootLogger(); synchronized (root) { parseCategory(props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value); } } }
public InputSource resolveEntity(String publicId, String systemId) { if (systemId.endsWith("log4j.dtd")) { Class clazz = getClass(); InputStream in = clazz.getResourceAsStream("/org/apache/log4j/xml/log4j.dtd"); if (in == null) { LogLog.error( "Could not find [log4j.dtd]. Used [" + clazz.getClassLoader() + "] class loader in the search."); return null; } else { return new InputSource(in); } } else { return null; } }
/** Parse non-root elements, such non-root categories and renderers. */ protected void parseCatsAndRenderers(Properties props, LoggerRepository hierarchy) { Enumeration enumeration = props.propertyNames(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); if (key.startsWith(CATEGORY_PREFIX) || key.startsWith(LOGGER_PREFIX)) { String loggerName = null; if (key.startsWith(CATEGORY_PREFIX)) { loggerName = key.substring(CATEGORY_PREFIX.length()); } else if (key.startsWith(LOGGER_PREFIX)) { loggerName = key.substring(LOGGER_PREFIX.length()); } String value = OptionConverter.findAndSubst(key, props); Logger logger = hierarchy.getLogger(loggerName, loggerFactory); synchronized (logger) { parseCategory(props, logger, key, loggerName, value); parseAdditivityForLogger(props, logger, loggerName); } } else if (key.startsWith(RENDERER_PREFIX)) { String renderedClass = key.substring(RENDERER_PREFIX.length()); String renderingClass = OptionConverter.findAndSubst(key, props); if (hierarchy instanceof RendererSupport) { RendererMap.addRenderer((RendererSupport) hierarchy, renderedClass, renderingClass); } } else if (key.equals(THROWABLE_RENDERER_PREFIX)) { if (hierarchy instanceof ThrowableRendererSupport) { ThrowableRenderer tr = (ThrowableRenderer) OptionConverter.instantiateByKey( props, THROWABLE_RENDERER_PREFIX, org.apache.log4j.spi.ThrowableRenderer.class, null); if (tr == null) { LogLog.error("Could not instantiate throwableRenderer."); } else { PropertySetter setter = new PropertySetter(tr); setter.setProperties(props, THROWABLE_RENDERER_PREFIX + "."); ((ThrowableRendererSupport) hierarchy).setThrowableRenderer(tr); } } } } }
/* 53: */ /* 54: */ protected boolean checkEntryConditions() /* 55: */ { /* 56:173 */ if (this.closed) /* 57: */ { /* 58:174 */ LogLog.warn("Not allowed to write to a closed appender."); /* 59:175 */ return false; /* 60: */ } /* 61:178 */ if (this.qw == null) /* 62: */ { /* 63:179 */ this.errorHandler.error( "No output stream or file set for the appender named [" + this.name + "]."); /* 64: */ /* 65:181 */ return false; /* 66: */ } /* 67:184 */ if (this.layout == null) /* 68: */ { /* 69:185 */ this.errorHandler.error( "No layout set for the appender named [" + this.name + "]."); /* 70:186 */ return false; /* 71: */ } /* 72:188 */ return true; /* 73: */ }
public void activateOptions() { LogLog.debug("DBAppender.activateOptions called"); if (connectionSource == null) { throw new IllegalStateException("DBAppender cannot function without a connection source"); } sqlDialect = Util.getDialectFromCode(connectionSource.getSQLDialectCode()); if (GET_GENERATED_KEYS_METHOD != null) { cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys(); } else { cnxSupportsGetGeneratedKeys = false; } cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates(); if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) { throw new IllegalStateException( "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect"); } // all nice and dandy on the eastern front super.activateOptions(); }
public void activateOptions() { if (datePattern != null && name != null) { now.setTime(System.currentTimeMillis()); sdf = new SimpleDateFormat(datePattern); int type = computeCheckPeriod(); printPeriodicity(type); rc.setType(type); fileName = this.buildLogFilePathAnddeleteTimeoutFile(-1); File file = new File(fileName); // Strfilename = String.format("[%s]%s_%d", // sdf.format(now),Strfilename,1); scheduledDate = sdf.format(new Date(file.lastModified())); /* * scheduledFilename = String.format("[%s]%s.%s", sdf.format(new * Date( file.lastModified())), name, extname); */ // Date(file.lastModified())); } else { LogLog.error("Either File or DatePattern options are not set for appender [" + name + "]."); } super.activateOptions(); }