📄 asyncappender.java
字号:
/** * Determines if specified appender is attached. * @param appender appender. * @return true if attached. */ public boolean isAttached(final Appender appender) { synchronized (appenders) { return appenders.isAttached(appender); } } /** * {@inheritDoc} */ public boolean requiresLayout() { return false; } /** * Removes and closes all attached appenders. */ public void removeAllAppenders() { synchronized (appenders) { appenders.removeAllAppenders(); } } /** * Removes an appender. * @param appender appender to remove. */ public void removeAppender(final Appender appender) { synchronized (appenders) { appenders.removeAppender(appender); } } /** * Remove appender by name. * @param name name. */ public void removeAppender(final String name) { synchronized (appenders) { appenders.removeAppender(name); } } /** * The <b>LocationInfo</b> option takes a boolean value. By default, it is * set to false which means there will be no effort to extract the location * information related to the event. As a result, the event that will be * ultimately logged will likely to contain the wrong location information * (if present in the log format). * <p/> * <p/> * Location information extraction is comparatively very slow and should be * avoided unless performance is not a concern. * </p> * @param flag true if location information should be extracted. */ public void setLocationInfo(final boolean flag) { locationInfo = flag; } /** * Sets the number of messages allowed in the event buffer * before the calling thread is blocked (if blocking is true) * or until messages are summarized and discarded. Changing * the size will not affect messages already in the buffer. * * @param size buffer size, must be positive. */ public void setBufferSize(final int size) { // // log4j 1.2 would throw exception if size was negative // and deadlock if size was zero. // if (size < 0) { throw new java.lang.NegativeArraySizeException("size"); } synchronized (buffer) { // // don't let size be zero. // bufferSize = (size < 1) ? 1 : size; buffer.notifyAll(); } } /** * Gets the current buffer size. * @return the current value of the <b>BufferSize</b> option. */ public int getBufferSize() { return bufferSize; } /** * Sets whether appender should wait if there is no * space available in the event buffer or immediately return. * * @param value true if appender should wait until available space in buffer. */ public void setBlocking(final boolean value) { synchronized (buffer) { blocking = value; buffer.notifyAll(); } } /** * Gets whether appender should block calling thread when buffer is full. * If false, messages will be counted by logger and a summary * message appended after the contents of the buffer have been appended. * * @return true if calling thread will be blocked when buffer is full. */ public boolean getBlocking() { return blocking; } /** * Summary of discarded logging events for a logger. */ private static final class DiscardSummary { /** * First event of the highest severity. */ private LoggingEvent maxEvent; /** * Total count of messages discarded. */ private int count; /** * Create new instance. * * @param event event, may not be null. */ public DiscardSummary(final LoggingEvent event) { maxEvent = event; count = 1; } /** * Add discarded event to summary. * * @param event event, may not be null. */ public void add(final LoggingEvent event) { if (event.getLevel().toInt() > maxEvent.getLevel().toInt()) { maxEvent = event; } count++; } /** * Create event with summary information. * * @return new event. */ public LoggingEvent createEvent() { String msg = MessageFormat.format( "Discarded {0} messages due to full event buffer including: {1}", new Object[] { new Integer(count), maxEvent.getMessage() }); return new LoggingEvent( "org.apache.log4j.AsyncAppender.DONT_REPORT_LOCATION", Logger.getLogger(maxEvent.getLoggerName()), maxEvent.getLevel(), msg, null); } } /** * Event dispatcher. */ private static class Dispatcher implements Runnable { /** * Parent AsyncAppender. */ private final AsyncAppender parent; /** * Event buffer. */ private final List buffer; /** * Map of DiscardSummary keyed by logger name. */ private final Map discardMap; /** * Wrapped appenders. */ private final AppenderAttachableImpl appenders; /** * Create new instance of dispatcher. * * @param parent parent AsyncAppender, may not be null. * @param buffer event buffer, may not be null. * @param discardMap discard map, may not be null. * @param appenders appenders, may not be null. */ public Dispatcher( final AsyncAppender parent, final List buffer, final Map discardMap, final AppenderAttachableImpl appenders) { this.parent = parent; this.buffer = buffer; this.appenders = appenders; this.discardMap = discardMap; } /** * {@inheritDoc} */ public void run() { boolean isActive = true; // // if interrupted (unlikely), end thread // try { // // loop until the AsyncAppender is closed. // while (isActive) { LoggingEvent[] events = null; // // extract pending events while synchronized // on buffer // synchronized (buffer) { int bufferSize = buffer.size(); isActive = !parent.closed; while ((bufferSize == 0) && isActive) { buffer.wait(); bufferSize = buffer.size(); isActive = !parent.closed; } if (bufferSize > 0) { events = new LoggingEvent[bufferSize + discardMap.size()]; buffer.toArray(events); // // add events due to buffer overflow // int index = bufferSize; for ( Iterator iter = discardMap.values().iterator(); iter.hasNext();) { events[index++] = ((DiscardSummary) iter.next()).createEvent(); } // // clear buffer and discard map // buffer.clear(); discardMap.clear(); // // allow blocked appends to continue buffer.notifyAll(); } } // // process events after lock on buffer is released. // if (events != null) { for (int i = 0; i < events.length; i++) { synchronized (appenders) { appenders.appendLoopOnAppenders(events[i]); } } } } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -