Uploaded image for project: 'logback'
  1. logback
  2. LOGBACK-781

ch.qos.logback.classic.LoggerContext.getLogger() is hard to understand; can be shortend with a little recursion

    XMLWordPrintable

Details

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 1.0.9
    • None
    • None

    Description

      ch.qos.logback.classic.LoggerContext.getLogger() is hard to understand; it can be shortend with a little recursion. Just a suggestion. I will have to run this modified code to see whether it works, I haven't done so yet.

      Additionally, a few edge cases should be checked, right?

      == Original ==

      -------------------
      public final Logger getLogger(final String name) {

      if (name == null)

      { throw new IllegalArgumentException("name argument cannot be null"); }

      // if we are asking for the root logger, then let us return it without
      // wasting time
      if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name))

      { return root; }

      int i = 0;
      Logger logger = root;

      // check if the desired logger exists, if it does, return it
      // without further ado.
      Logger childLogger = (Logger) loggerCache.get(name);
      // if we have the child, then let us return it without wasting time
      if (childLogger != null) { return childLogger; }

      // if the desired logger does not exist, them create all the loggers
      // in between as well (if they don't already exist)
      String childName;
      while (true) {
      int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
      if (h == -1) { childName = name; } else { childName = name.substring(0, h); }
      // move i left of the last point
      i = h + 1;
      synchronized (logger) {
      childLogger = logger.getChildByName(childName);
      if (childLogger == null) { childLogger = logger.createChildByName(childName); loggerCache.put(childName, childLogger); incSize(); }
      }
      logger = childLogger;
      if (h == -1) { return childLogger; }
      }
      }
      -------------------

      == With recursion ==


      public final Logger getLogger(final String name) {
      if (name == null) { throw new IllegalArgumentException("name argument cannot be null"); // can it be empty though?? }
      // if we are asking for the root logger, then let us return it without wasting time
      // note that this is not the empty name but "ROOT"
      if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) { return root; }

      // check if the desired logger exists, if it does, return it without further ado.
      {
      Logger childLogger = (Logger) loggerCache.get(name);
      if (loggerCache.get(name) != null)

      { return childLogger; }

      }
      // if the desired logger does not exist, then create all the loggers in between as well (if they don't exist yet)
      // this means
      // 1) splitting the "name" along the DOT/DOLLAR separators (but refusing the empty string result)
      // 2) creating all the loggers along that path if they don't exist yet
      createLoggerPathRecursively(name, "", 0, root);
      }

      /**

      • Recursively build logger path
      • On the first call, "originalName" is the full logger name, "currentName" is the empty string,
      • currentPos (the position beyond which to search for logger name components) is 0 and
      • "parentLogger" is the "root"
        */

      private void createLoggerPathRecursively(String originalName, String currentName, int currentPos, Logger parentLogger) {
      assert originalName != null;
      assert currentName != null;
      assert currentPos >= 0;
      assert parentLogger != null;
      if (currentPos >= originalName.length())

      { throw new IllegalArgumentException("The logger name '" + originalName + "' is either empty or ends with a separator"); }

      // find the next separator in "originalName" starting from "currentPos"
      int ix = getSeparatorIndexOf(originalName, currentPos);
      if (ix < 0)

      { // No more separators, so we are done but still need to register this last logger. // So let ix point past the end! ix = originalName.length(); }

      String nameComponent = originalName.substring(currentPos, ix);
      // Depending on specification use one of the two below:
      String childName = currentName + CoreConstants.DOT + nameComponent; // DOTify any DOLLAR
      // String childName = originalName.substring(0, ix); // unmodified part of original
      // Accept empty components? Nope!
      if (nameComponent.isEmpty())

      { throw new IllegalArgumentException("The logger name '" + originalName + "' has an empty component starting at position " + currentPos); }

      // See whether the child logger exists, if not, create it
      Logger childLogger;
      synchronized (parentLogger) {
      childLogger = parentLogger.getChildByName(childName); // does not check the childName; returns null if not found
      if (childLogger == null)

      { // Depending on taste use this (which dotifies any dollars) // childLogger = parentLogger.createChildByLastNamePart(nameComponent); // checks that name component has no DOT or DOLLAR // or this (which keeps the DOT or DOLLAR as is); this is in the original (this means that the root must have the empty name) childLogger = parentLogger.createChildByName(childName); // checks that name component beyond parent's name has no DOT or DOLLAR loggerCache.put(childName, childLogger); incSize(); }

      assert childLogger != null;
      }
      // (tail)-recursive call if not done
      if (ix < originalName.length())

      { createLoggerPathRecursively(originalName, childName, ix + 1, childLogger); }

      }

      Attachments

        Activity

          People

            logback-dev Logback dev list
            dtonhofer David Tonhofer
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: