Program: 134773
Project: 134773
Buggy source:
/** 
 * Adds a <code>LogRecord</code> to the internal queue, so that it gets scheduled for logging. If a high-level log record should be sent out immediately, the caller of this method should  subsequently call   {@link #flush()}, as the log method itself does not trigger a flush based on levels. <p> Threading note: it seems ok to make this method "synchronized". This avoids problems with stale queue size,  even though the damage would be small since the treatment of queue size is somewhat arbitrary anyway. Synchronization should not block callers long at all because flushing is done in a separate thread and only gets triggered here. <p> TODO: there is currently a minor problem with queue overflow: log records get drained from the queue, and when they can't be sent off to the log service, they are resubmitted to the queue. It could happen that in the meantime, some other record with INFO or higher level has been added to the queue, and that resubmitting some of the even more important records may fail. The solution would be to replace the 70%-filter rule with a running priority filter: any incoming record can kick out a less important record if the queue is full. 
 * @param logRecord  to be logged
 * @return true if logRecord was added to the queue for logging. False if queue was too full for this record.
 */
synchronized boolean log(LogRecord logRecord){
  int oldSize=queue.size();
  if (oldSize >= maxQueueSize) {
    if (!outOfCapacity) {
      preOverflowFlushPeriod=currentFlushPeriod;
      setPeriodicFlushing(10000);
    }
    outOfCapacity=true;
    if (LOSSLESS) {
      do {
        try {
          Thread.sleep(1000);
        }
 catch (        InterruptedException ex) {
        }
      }
 while (queue.size() >= maxQueueSize);
    }
 else {
      if (DEBUG || oldSize == maxQueueSize) {
        System.err.println("String_Node_Str" + logRecord.getMessage() + "String_Node_Str");
      }
      return false;
    }
  }
  if (outOfCapacity) {
    outOfCapacity=false;
    setPeriodicFlushing(preOverflowFlushPeriod);
    preOverflowFlushPeriod=0;
  }
  if (!LOSSLESS) {
    final int filterThreshold=maxQueueSize * 7 / 10;
    if (oldSize >= filterThreshold && logRecord.getLevel().intValue() < Level.INFO.intValue()) {
      if (DEBUG) {
        System.err.println("String_Node_Str" + (oldSize + 1) + "String_Node_Str"+ maxQueueSize+ "String_Node_Str"+ logRecord.getMessage()+ "String_Node_Str");
      }
      return false;
    }
  }
  queue.put(logRecord);
  if (DEBUG) {
    System.out.println("String_Node_Str" + logRecord.getMessage());
  }
  flushIfEnoughRecords(true);
  return true;
}

Fixed version (ground truth):
/** 
 * Adds a <code>LogRecord</code> to the internal queue, so that it gets scheduled for logging. If a high-level log record should be sent out immediately, the caller of this method should  subsequently call   {@link #flush()}, as the log method itself does not trigger a flush based on levels. <p> Threading note: it seems ok to make this method "synchronized". This avoids problems with stale queue size,  even though the damage would be small since the treatment of queue size is somewhat arbitrary anyway. Synchronization should not block callers long at all because flushing is done in a separate thread and only gets triggered here. <p> TODO: there is currently a minor problem with queue overflow: log records get drained from the queue, and when they can't be sent off to the log service, they are resubmitted to the queue. It could happen that in the meantime, some other record with INFO or higher level has been added to the queue, and that resubmitting some of the even more important records may fail. The solution would be to replace the 70%-filter rule with a running priority filter: any incoming record can kick out a less important record if the queue is full. 
 * @param logRecord  to be logged
 * @return true if logRecord was added to the queue for logging. False if queue was too full for this record.
 */
synchronized boolean log(LogRecord logRecord){
  int oldSize=queue.size();
  if (oldSize >= maxQueueSize) {
    boolean firstTimeOverflow=!outOfCapacity.getAndSet(true);
    if (firstTimeOverflow) {
      preOverflowFlushPeriod=currentFlushPeriod;
      setPeriodicFlushing(10000);
    }
    if (LOSSLESS) {
      do {
        try {
          Thread.sleep(1000);
        }
 catch (        InterruptedException ex) {
        }
      }
 while (queue.size() >= maxQueueSize);
    }
 else {
      if (DEBUG || firstTimeOverflow) {
        System.out.println("String_Node_Str" + logRecord.getMessage() + "String_Node_Str");
      }
      return false;
    }
  }
  if (outOfCapacity.getAndSet(false)) {
    setPeriodicFlushing(preOverflowFlushPeriod);
    preOverflowFlushPeriod=0;
    if (DEBUG) {
      System.out.println("String_Node_Str");
    }
  }
  if (!LOSSLESS) {
    final int filterThreshold=maxQueueSize * 7 / 10;
    if (oldSize >= filterThreshold && logRecord.getLevel().intValue() < Level.INFO.intValue()) {
      if (DEBUG) {
        System.out.println("String_Node_Str" + (oldSize + 1) + "String_Node_Str"+ maxQueueSize+ "String_Node_Str"+ logRecord.getMessage()+ "String_Node_Str");
      }
      return false;
    }
  }
  queue.put(logRecord);
  if (DEBUG) {
    System.out.println("String_Node_Str" + logRecord.getMessage());
  }
  flushIfEnoughRecords(true);
  return true;
}