All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.micromata.genome.logging.BaseLogging Maven / Gradle / Ivy

The newest version!
//
// Copyright (C) 2010-2016 Micromata GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package de.micromata.genome.logging;

import de.micromata.genome.logging.events.LogRegisteredCategoryChangedEvent;
import de.micromata.genome.logging.events.LogRegisteredLogAttributesChangedEvent;
import de.micromata.genome.logging.events.LogWriteEntryEvent;
import de.micromata.genome.stats.Stats;
import de.micromata.genome.util.types.Pair;
import org.apache.commons.collections4.map.AbstractReferenceMap;
import org.apache.commons.collections4.map.ReferenceMap;
import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * Common base implementation.
 *
 * @author roger
 */
public abstract class BaseLogging implements Logging
{

  /**
   * The is inited.
   */
  protected static boolean isInited = false;

  /**
   * will be set while initialization. avoid to call recursive
   */
  protected boolean inInitialization = false;

  /**
   * The pre start logs.
   */
  protected static List preStartLogs = new ArrayList<>();

  /**
   * do not call any modifable access to these. But constructes new copy and asign.
   */
  protected static Map registerdLogCategories = new HashMap<>();

  /**
   * do not call any modifable access to these. But constructes new copy and asign.
   */
  protected static Map registerdLogAttributes = new HashMap<>();

  /**
   * do not call any modifable access to these. But constructes new copy and asign.
   */
  protected static Map defaultLogAttributes = new HashMap<>();

  /**
   * do not call any modifable access to these. But constructes new copy and asign.
   */
  protected static Map searchLogAttributes = new HashMap<>();

  /**
   * Default Einstellung fuer Maximalen Logattribute 1MB.
   */
  public static final int DEFAULT_MAX_LOG_ATTR_LENGTH = 1024 * 1024;

  /**
   * Maximale Laenge eines Logattributes.
   */
  private int maxLogAttrLength = DEFAULT_MAX_LOG_ATTR_LENGTH;

  /**
   * Name des LogAttributeType zu maximaler Groesse des Logeintrags.
   *
   * Ueberschreibt maxLogAttrLength.
   */
  private Map logAttributeLimitMap = new HashMap();

  /**
   * filter. Modifiy only on construction time, because not synchronized.
   */
  private List writeFilters = new ArrayList<>();
  /**
   * Modifiy only on construction time, because not synchronized.
   */
  private List readFilters = new ArrayList<>();

  protected static  Map createNewCacheMap(Map oldValues)
  {
    ReferenceMap ret = new ReferenceMap<>(AbstractReferenceMap.ReferenceStrength.HARD, AbstractReferenceMap.ReferenceStrength.WEAK);
    ret.putAll(oldValues);
    return ret;
  }

  protected static  Map createNewDisposableMap(Map oldValues, Map newValues)
  {
    Map ret = createNewCacheMap(oldValues);
    ret.putAll(newValues);
    return ret;

  }

  protected static  Map createNewMap(Map oldValues, Map newValues)
  {
    Map ret = new HashMap<>(oldValues);
    ret.putAll(newValues);
    return ret;

  }

  /**
   * Um die zu Anwendung neu gekommene(z.B. durch ein Plugin) {@link LogCategory} s zu registreren.
   *
   * @param cats beliebige Menge an {@link LogCategory}
   */
  public static void registerLogCategories(LogCategory... cats)
  {
    Map ncats = new HashMap<>(registerdLogCategories);
    for (LogCategory c : cats) {
      if (c.getFqName().length() > 30) {
        /**
         * @logging
         * @reason Eine LogCategory wurde registriert, wobei der Laenge des Bezeichers fuer die DB zu lang ist
         * @action Entwickler kontaktieren
         */
        throw new LoggedRuntimeException(LogLevel.Error, GenomeLogCategory.Configuration,
          "LogCategory to long (30 chars max): "
            + c.getFqName());
      }
      ncats.put(c.getFqName(), new LogCategoryWrapper(c));
    }

    registerdLogCategories = ncats;
    LoggingServiceManager.get().getLoggingEventListenerRegistryService()
      .submitEvent(new LogRegisteredCategoryChangedEvent(registerdLogCategories));
  }

  /**
   * Findet in den registrierten LogCategories eine {@link LogCategory} by name.
   *
   * @param catName the cat name
   * @return the category by string
   */
  public static LogCategory getCategoryByString(String catName)
  {
    return registerdLogCategories.get(catName);
  }

  /**
   * Registrierung neuer {@link LogAttribute}s.
   *
   * @param attTypes Beliebige Menge ans {@link LogAttribute}
   */
  public static void registerLogAttributeType(LogAttributeType... attTypes)
  {
    Map nlogAttr = new HashMap<>();
    Map nlogAttrFiller = new HashMap<>();

    Map nsearchKeys = new HashMap<>();

    for (LogAttributeType c : attTypes) {
      if (c.name().length() > 30) {
        /**
         * @logging
         * @reason Eine LogAttributeType wurde registriert, wobei der Laenge des Bezeichers fuer die DB zu lang ist
         * @action Entwickler kontaktieren
         */
        throw new LoggedRuntimeException(LogLevel.Error, GenomeLogCategory.Configuration,
          "LogAttributeType name to long (30 chars max): "
            + c.name());
      }
      if (c.isSearchKey() == true) {
        LogAttributeTypeWrapper wat = new LogAttributeTypeWrapper(c, true);
        nsearchKeys.put(c.name(), wat);
      }
      if (c.getAttributeDefaultFiller() != null) {
        nlogAttrFiller.put(c.name(), c);
      }
      nlogAttr.put(c.name(), c);
    }
    if (nlogAttr.isEmpty() == false) {
      // the renderer will be used. so do directly add LogAttribute, but as weak reference
      registerdLogAttributes = createNewDisposableMap(registerdLogAttributes, nlogAttr);

    }
    if (nlogAttrFiller.isEmpty() == false) {
      // the filler will be used. so do directly add LogAttribute, but as weak reference
      defaultLogAttributes = createNewDisposableMap(defaultLogAttributes, nlogAttrFiller);
    }
    if (nsearchKeys.isEmpty() == false) {
      // this is stored as dump wrapper, no need to have disposable
      searchLogAttributes = createNewMap(searchLogAttributes, nsearchKeys);
    }
    LoggingServiceManager.get().getLoggingEventListenerRegistryService()
      .submitEvent(new LogRegisteredLogAttributesChangedEvent(registerdLogAttributes));
  }

  /**
   * Gets the attribute type by string.
   *
   * @param attrName the attr name
   * @return the attribute type by string
   */
  public static LogAttributeType getAttributeTypeByString(String attrName)
  {
    LogAttributeType ret = registerdLogAttributes.get(attrName);
    if (ret != null) {
      return ret;
    }
    LogAttributeTypeWrapper la = new LogAttributeTypeWrapper(attrName);
    return la;

  }

  /**
   * Adds the pre start log.
   *
   * @param le the le
   */
  public void addPreStartLog(LogWriteEntry le)
  {
    List tpreStartLogs = preStartLogs;
    if (preStartLogs == null) {
      tpreStartLogs = new ArrayList();
    }
    tpreStartLogs.add(le);
    preStartLogs = tpreStartLogs;

  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#logPreStart(de.micromata.genome.logging.LogLevel,
   * de.micromata.genome.logging.LogCategory, java.lang.String, de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void logPreStart(LogLevel ll, LogCategory cat, String msg, LogAttribute... attributes)
  {
    LogWriteEntry lwe = new LogWriteEntry(ll, cat.getFqName(), msg, attributes);
    addPreStartLog(lwe);

  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#debug(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void debug(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Debug, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#trace(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void trace(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Trace, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#info(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void info(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Info, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#note(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void note(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Note, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#warn(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void warn(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Warn, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#error(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void error(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Error, cat, msg, attributes);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#fatal(de.micromata.genome.logging.LogCategory, java.lang.String,
   * de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void fatal(LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(LogLevel.Fatal, cat, msg, attributes);
  }

  /**
   * Do log.
   *
   * @param ll         the ll
   * @param cat        the cat
   * @param msg        the msg
   * @param attributes the attributes
   */
  public void doLog(LogLevel ll, LogCategory cat, String msg, List attributes)
  {
    LogAttribute[] a = new LogAttribute[] {};
    a = attributes.toArray(a);
    doLog(ll, cat, msg, a);
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#doLog(de.micromata.genome.logging.LogLevel,
   * de.micromata.genome.logging.LogCategory, java.lang.String, de.micromata.genome.logging.LogAttribute[])
   */
  @Override
  public void doLog(LogLevel ll, LogCategory cat, String msg, LogAttribute... attributes)
  {
    doLog(ll, cat.getFqName(), msg, attributes);
  }

  /**
   * Unwrapp log exceptions.
   *
   * @param lwe the lwe
   */
  protected void unwrappLogExceptions(LogWriteEntry lwe)
  {
    List addLogs = null;
    for (LogAttribute la : lwe.getAttributes()) {
      if (la instanceof LogExceptionAttribute) {
        LogExceptionAttribute lea = (LogExceptionAttribute) la;
        if (lea.getException() != null && lea.getException() instanceof WithLogAttributes) {
          WithLogAttributes wa = (WithLogAttributes) lea.getException();
          if (addLogs == null) {
            addLogs = new ArrayList();
          }
          Collection wattrs = wa.getLogAttributes();
          addLogs.addAll(wattrs);
        }
      }
    }
    if (addLogs == null) {
      return;
    }
    for (LogAttribute la : addLogs) {
      pushAttribute(lwe.getAttributes(), la);
    }
  }

  /**
   * Push attribute.
   *
   * @param attributes the attributes
   * @param le         the le
   */
  public static void pushAttribute(List attributes, LogAttribute le)
  {
    if (le == null) {
      return;
    }
    for (LogAttribute a : attributes) {
      if (a.getType() == le.getType()) {
        return;
      }
    }
    attributes.add(le);
  }

  /**
   * Ensure an attribute list contains no duplicates with the same LogAttributeType Duplicates are removed for the list
   * starting at the head. Therefore were there is a duplicate the entry nearest the end of the list will survive.
   *
   * The algoritem has N^2 complexity and should only be used on short lists
   *
   * @param attributes the attributes
   */
  public static void ensureUniqueAttributes(List attributes)
  {
    for (int i = 0; i < attributes.size(); ) {
      LogAttribute la = attributes.get(i);
      boolean duplicate = false;
      for (int j = 0; j < i; ++j) {
        LogAttribute la2 = attributes.get(j);
        if (la2.getType() == la.getType()) {
          duplicate = true;
          break;
        }
      }
      if (duplicate == true) {
        attributes.remove(i);
      } else {
        ++i;
      }
    }
  }

  /**
   * Rework log.
   *
   * @param lwe the lwe
   */
  protected void reworkLog(LogWriteEntry lwe)
  {
    unwrappLogExceptions(lwe);

    pushContainedAttributes(lwe.getAttributes(), lwe.getAttributes());

    // zuerst explizit definierte Logattribute
    LoggingContext ctx = LoggingContext.getContext();
    if (ctx != null) {
      Map attrs = ctx.getAttributes();
      if (attrs != null) {
        for (LogAttributeType at : attrs.keySet()) {
          pushAttribute(lwe.getAttributes(), attrs.get(at));
        }
        pushContainedAttributes(lwe.getAttributes(), attrs.values());
      }
    }

    for (LogAttributeType da : defaultLogAttributes.values()) {
      String v = da.getAttributeDefaultFiller().getValue(lwe, ctx);
      if (StringUtils.isNotEmpty(v) == true) {
        pushAttribute(lwe.getAttributes(), new LogAttribute(da, v));
      }
    }
  }

  /**
   * Durchsucht src nach WithLogAttributes und fügt diese dest hinzu.
   *
   * @param dest the dest
   * @param src  Kann null sein.
   */
  protected void pushContainedAttributes(List dest, Collection src)
  {
    if (src == null) {
      return;
    }
    List addMe = new ArrayList();
    for (LogAttribute sa : src) {
      if (sa instanceof WithLogAttributes) {
        Collection wattrs = ((WithLogAttributes) sa).getLogAttributes();
        for (LogAttribute ctxa : wattrs) {
          addMe.add(ctxa);
        }
      }
    }
    for (LogAttribute la : addMe) {
      pushAttribute(dest, la);
    }
  }

  /**
   * @return a list of filters
   */
  @SuppressWarnings("unchecked")
  public List getWriteFilters()
  {
    return writeFilters;
  }

  public List getReadFilters()
  {

    return readFilters;
  }

  public void setWriteFilters(List writeFilters)
  {
    this.writeFilters = writeFilters;
  }

  public void setReadFilters(List readFilters)
  {
    this.readFilters = readFilters;
  }

  /**
   * Write pre start logs.
   *
   * @param clwe the clwe
   */
  private void writePreStartLogs(List clwe)
  {
    nextLogEntry:
    for (LogWriteEntry lwe : clwe) {
      reworkLog(lwe);
      List filters = getWriteFilters();
      if (filters != null) {
        for (LogWriteFilter filter : filters) {
          if (filter.match(lwe) == false) {
            continue nextLogEntry;
          }
        }
      }
      if (GLog.isLogEnabled(lwe.getLevel()) == false) {
        return;
      }
      ensureUniqueAttributes(lwe.getAttributes());
      doLogImpl(lwe);
    }
  }

  /**
   * Shorten log attribute.
   *
   * @param lwe the lwe
   * @param la  the la
   */
  protected void shortenLogAttribute(LogWriteEntry lwe, LogAttribute la)
  {
    String value = la.getValueToWrite(lwe);
    if (value == null) {
      return;
    }
    int size = la.getType().maxValueSize();
    if (size <= 0) {
      size = getMaxLogAttrLength();
      Integer maxi = getLogAttributeLimitMap().get(la.getType().name());
      if (maxi != null) {
        size = maxi;
      }
    }
    if (value.length() <= size) {
      return;
    }
    if (size > 0) {
      value = value.substring(0, size);
    }
    la.setValue(value);
  }

  /**
   * Shorten log attributes.
   *
   * @param lwe the lwe
   */
  protected void shortenLogAttributes(LogWriteEntry lwe)
  {
    for (LogAttribute la : lwe.getAttributes()) {
      shortenLogAttribute(lwe, la);
    }
  }

  /**
   * Do log.
   *
   * @param ll         the ll
   * @param cat        the cat
   * @param msg        the msg
   * @param attributes the attributes
   */
  public void doLog(LogLevel ll, String cat, String msg, LogAttribute... attributes)
  {
    LogWriteEntry lwe = new LogWriteEntry(ll, cat, msg, attributes);

    logLwe(lwe);
  }

  /**
   * Initialize logger.
   */
  private void init()
  {
    if (inInitialization == true) {
      return;
    }
    inInitialization = true;
    try {
      doCustomInitialization();
      isInited = true;
    } finally {
      inInitialization = false;
    }
  }

  /**
   * Do custom initialization.
   */
  protected void doCustomInitialization()
  {

  }

  /**
   * Writes a prepared LogWriteEntry
   */
  @Override
  public void logLwe(LogWriteEntry lwe)
  {
    if (isInited == false) {
      init();
    }
    if (inInitialization == true) {
      addPreStartLog(lwe);
      return;
    }
    if (preStartLogs != null) {
      List clwe = new ArrayList();
      clwe.addAll(preStartLogs);
      preStartLogs = null;
      writePreStartLogs(clwe);
    }
    reworkLog(lwe);

    List filters = getWriteFilters();
    if (filters != null) {
      for (LogWriteFilter filter : filters) {
        if (filter.match(lwe) == false) {
          return;
        }
      }
    }
    final LogLevel ll = lwe.getLevel();
    Stats.addLogging(lwe);
    boolean enabled = ll.getLevel() >= LogLevel.Note.getLevel();
    enabled = LoggingServiceManager.get().getLogConfigurationDAO().isLogEnabled(lwe.getLevel(), lwe.getCategory(),
      lwe.getMessage());
    if (enabled == false) {
      return;
    }
    ensureUniqueAttributes(lwe.getAttributes());
    shortenLogAttributes(lwe);
    LoggingServiceManager.get().getLoggingEventListenerRegistryService().filterEvent(
      new LogWriteEntryEvent(lwe),
      event -> doLogImpl(event.getResult()));

  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#doLogImpl(de.micromata.genome.logging.LogWriteEntry)
   */
  @Override
  public abstract void doLogImpl(final LogWriteEntry lwe);

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#selectLogs(java.sql.Timestamp, java.sql.Timestamp, java.lang.Integer,
   * java.lang.String, java.lang.String, java.util.List, int, int, java.util.List,
   * de.micromata.genome.logging.LogEntryCallback)
   */
  @Override
  public void selectLogs(final Timestamp start, final Timestamp end, final Integer loglevel, final String category, final String msg,
    final List> logAttributes, final int startRow, final int maxRow, final List orderBy, final boolean masterOnly,
    final LogEntryCallback callback)
  {
    if (this.underlyingClientIsAsync() == false) {
      selectLogsSync(start, end, loglevel, category, msg, logAttributes, startRow, maxRow, orderBy, masterOnly, callback);
    } else {
      selectLogsAsync(start, end, loglevel, category, msg, logAttributes, startRow, maxRow, orderBy, masterOnly, callback);
    }

  }

  /**
   * When the {@link Logging#underlyingClientIsAsync()}  is false this is called
   *
   * @param start         start time
   * @param end           end time
   * @param loglevel      the log level to select
   * @param category      the category to select
   * @param msg           the message to filter on
   * @param logAttributes the log attribute to filter on
   * @param startRow      where to start from
   * @param maxRow        how many entries to select
   * @param orderBy       how to order the logs
   * @param masterOnly    if to select the master only
   * @param callback      the callback which contains the returning logs
   */
  public void selectLogsSync(final Timestamp start, final Timestamp end, final Integer loglevel, final String category, final String msg,
    final List> logAttributes, final int startRow, final int maxRow, final List orderBy, final boolean masterOnly,
    final LogEntryCallback callback)
  {
    final LogEntryFilterCallback filter = new LogEntryFilterCallback(callback,
      LoggingServiceManager.get().getLogConfigurationDAO(), maxRow);
    try {
      selectLogsImpl(start, end, loglevel, category, msg, logAttributes, startRow, maxRow, orderBy, masterOnly, filter);
    } catch (EndOfSearch ex) {
      // just terminate the search
    }
  }

  /**
   * When the {@link Logging#underlyingClientIsAsync()}  is true this is called
   *
   * @param start         start time
   * @param end           end time
   * @param loglevel      the log level to select
   * @param category      the category to select
   * @param msg           the message to filter on
   * @param logAttributes the log attribute to filter on
   * @param startRow      where to start from
   * @param maxRow        how many entries to select
   * @param orderBy       how to order the logs
   * @param masterOnly    if to select the master only
   * @param callback      the callback which contains the returning logs
   */
  public void selectLogsAsync(final Timestamp start, final Timestamp end, final Integer loglevel, final String category, final String msg,
    final List> logAttributes, final int startRow, final int maxRow, final List orderBy, final boolean masterOnly,
    final LogEntryCallback callback)
  {

    final LogEntryFilterAsyncCallback filter = new LogEntryFilterAsyncCallback(callback,
      LoggingServiceManager.get().getLogConfigurationDAO(), maxRow);

    try {
      selectLogsImpl(start, end, loglevel, category, msg, logAttributes, startRow, maxRow, orderBy, masterOnly, filter);
      filter.doGet();
    } catch (EndOfSearch  | InterruptedException  | ExecutionException ex) {
      // just terminate the search
    }
  }

  /**
   * Select logs impl.
   *
   * @param start         the start
   * @param end           the end
   * @param loglevel      the loglevel
   * @param category      the category
   * @param msg           the msg
   * @param logAttributes the log attributes
   * @param startRow      the start row
   * @param maxRow        the max row
   * @param orderBy       the order by
   * @param masterOnly    the master only
   * @param callback      the callback
   * @throws EndOfSearch the end of search
   */
  protected abstract void selectLogsImpl(Timestamp start, Timestamp end, Integer loglevel, String category, String msg,
    List> logAttributes, int startRow, int maxRow, List orderBy, boolean masterOnly,
    LogEntryCallback callback) throws EndOfSearch;

  @Override
  public void selectLogs(final List logId, final boolean masterOnly, final LogEntryCallback callback)
  {
    if (underlyingClientIsAsync() == false) {
      selectLogsSync(logId, masterOnly, callback);
    } else {
      selectLogsAsync(logId, masterOnly, callback);
    }
  }

  /**
   * When the {@link Logging#underlyingClientIsAsync()}  is false this is called
   * @param logId the ids of the log entries to select
   * @param masterOnly if to select the master only
   * @param callback the callback containing the log entries when done
   */
  public void selectLogsSync(final List logId, final boolean masterOnly, final LogEntryCallback callback)
  {
    final LogEntryFilterCallback filter = new LogEntryFilterCallback(callback,
      LoggingServiceManager.get().getLogConfigurationDAO(),
      Integer.MAX_VALUE);

    try {
      selectLogsImpl(logId, masterOnly, filter);
    } catch (EndOfSearch ex) {
      // just terminate the search
    }
  }

  /**
   * When the {@link Logging#underlyingClientIsAsync()}  is true this is called
   * @param logId the ids of the log entries to select
   * @param masterOnly if to select the master only
   * @param callback the callback containing the log entries when done
   */
  public void selectLogsAsync(final List logId, final boolean masterOnly, final LogEntryCallback callback)
  {

    final LogEntryFilterAsyncCallback filter = new LogEntryFilterAsyncCallback(callback,
      LoggingServiceManager.get().getLogConfigurationDAO(),
      Integer.MAX_VALUE);

    try {
      selectLogsImpl(logId, masterOnly, filter);
      filter.doGet();
    } catch (EndOfSearch | InterruptedException | ExecutionException ex) {
      // just terminate the search
    }
  }

  /**
   * Select logs impl.
   *
   * @param logId      the log id
   * @param masterOnly the master only
   * @param callback   the callback
   * @throws EndOfSearch the end of search
   */
  protected abstract void selectLogsImpl(List logId, boolean masterOnly, LogEntryCallback callback)
    throws EndOfSearch;

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#getConfigMinLogLevel()
   */
  @Override
  public LogLevel getConfigMinLogLevel()
  {
    return LoggingServiceManager.get().getLogConfigurationDAO().getThreshold();
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#getRegisteredAttributes()
   */
  @Override
  public Collection getRegisteredAttributes()
  {
    return BaseLogging.registerdLogAttributes.values();
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#getRegisteredCategories()
   */
  @Override
  public Collection getRegisteredCategories()
  {
    return BaseLogging.registerdLogCategories.values();
  }

  /*
   * (non-Javadoc)
   *
   * @see de.micromata.genome.logging.Logging#getSearchAttributes()
   */
  @Override
  public Collection getSearchAttributes()
  {
    return BaseLogging.searchLogAttributes.values();
  }

  public static boolean isInited()
  {
    return isInited;
  }

  public static void setInited(boolean isInited)
  {
    BaseLogging.isInited = isInited;
  }

  public static List getPreStartLogs()
  {
    return preStartLogs;
  }

  /**
   * Sets the pre start logs.
   *
   * @param preStartLogs the new pre start logs
   */
  public static void setPreStartLogs(List preStartLogs)
  {
    BaseLogging.preStartLogs = preStartLogs;
  }

  /**
   * Gets the registerd log categories.
   *
   * @return the registerd log categories
   */
  public static Map getRegisterdLogCategories()
  {
    return registerdLogCategories;
  }

  public static void setRegisterdLogCategories(Map registerdLogCategories)
  {
    BaseLogging.registerdLogCategories = registerdLogCategories;
  }

  public static Map getRegisterdLogAttributes()
  {
    return registerdLogAttributes;
  }

  public static void setRegisterdLogAttributes(Map registerdLogAttributes)
  {
    BaseLogging.registerdLogAttributes = registerdLogAttributes;
  }

  public int getMaxLogAttrLength()
  {
    return maxLogAttrLength;
  }

  public void setMaxLogAttrLength(int maxLogAttrLength)
  {
    this.maxLogAttrLength = maxLogAttrLength;
  }

  public Map getLogAttributeLimitMap()
  {
    return logAttributeLimitMap;
  }

  public void setLogAttributeLimitMap(Map logAttributeLimitMap)
  {
    this.logAttributeLimitMap = logAttributeLimitMap;
  }

  public static Map getDefaultLogAttributes()
  {
    return defaultLogAttributes;
  }

  public static void setDefaultLogAttributes(Map defaultLogAttributes)
  {
    BaseLogging.defaultLogAttributes = defaultLogAttributes;
  }

  public static Map getSearchLogAttributes()
  {
    return searchLogAttributes;
  }

  public static void setSearchLogAttributes(Map searchLogAttributes)
  {
    BaseLogging.searchLogAttributes = searchLogAttributes;
  }

}