/*(non-Javadoc) * @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent) */ protected void append(LoggingEvent event) { String ndcStr = null; int depth = -1; { // IMPORTANT: this section is something MUST be called! ndcStr = event.getNDC(); depth = NDC.getDepth(); event.getThreadName(); // Get a copy of this thread's MDC. event.getMDCCopy(); } if (shallRecursionPrevented(this.getClass(), event.getLoggerName()) || shallRecursionPrevented(ZMLog.class, event.getLoggerName())) return; { // IMPORTANT: this section is something MUST be called! event.getRenderedMessage(); event.getThrowableStrRep(); /* * SCENARIO: * while tl!=started, we suppose to start a new tl. * log4j shoulden't terminate other's tl, it can only terminate it's selves. * * depth=0, tl==started, controlBySelf [complete] this tl is reaching it's end, should be terminated. * depth=0, tl==started, controlByOthers [recording] this tl is controlled by others, log4j is simply an interceptor, do recording. * * depth=0, tl!=started, controlBySelf [doNothing] because tl can only be started while depth>0. * depth=0, tl!=started, controlByOthers [doNothing] because tl can only be started while depth>0. * * depth>0, tl==started, controlBySelf [recording] watch out the depth problem. * depth>0, tl==started, controlByOthers [recording] watch out the depth problem. * * depth>0, tl!=started, controlBySelf [do Start] * depth>0, tl!=started, controlByOthers [do Start] * */ TimelineLifecycle lfc = ZMonitorManager.getInstance().getTimelineLifecycle(); String mesg = event.getRenderedMessage(); if (depth == 0) { if (ZMonitor.isTimelineStarted()) { if (isControlledBySelf(lfc)) { complete(event, mesg, lfc); } else { record(event, depth, lfc, ndcStr); } } // do nothing... // tl.start must satisfy (depth > 0), otherwise there's no way for appender to know when to // complete timeline. } else { if (ZMonitor.isTimelineStarted()) { record(event, depth, lfc, ndcStr); } else { start(event, depth, lfc, ndcStr); setControlledBySelf(lfc); } } } }