Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparator expressions for LogRecord #120

Open
jmehrens opened this issue Jan 19, 2024 · 0 comments
Open

Comparator expressions for LogRecord #120

jmehrens opened this issue Jan 19, 2024 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@jmehrens
Copy link
Contributor

jmehrens commented Jan 19, 2024

With JDK 8, the Comparator interface was modified to support reversing, key extractors, null handling, and chaining. The current MailHandler and the CollectorFormatter only support named custom comparator classes for ordering log records. This means that custom classes have to ship with applications to perform a chained ordering of log records.

The idea of this feature would be to allow a string expression to be parsed that would build custom comparator. This would allow users to simply place an expression in the log manager properties to create a comparator chain.

For example, the SeverityComparator orders by level, thrown, sequence, and time. However, depending on the audience the preferred order might be level, thrown, time descending, sequence descending to say the the last occurrence is more important than the first. A real world example is if you want to see "Locked account" (most recent) vs. "invalid credentials" (eldest record) in the subject line when the MailHandler publishes a run invalid log in attempts.

Something like:
comparator=java.util.logging.LogRecord.getLevel, java.util.logging.LogRecord.getThrown, java.util.logging.LogRecord.getMillis, java.util.logging.LogRecord.getSequenceNumber

In this expression it would be allowable to use named comparators too. Under the hood this would get converted to:

Comparator<LogRecord> c = Comparator.comparing(logRecord -> logRecord.getLevel().intValue());
        c = c.thenComparing(org.eclipse.angus.mail.util.logging.SeverityComparator::compareThrowable)
        c = c.thenComparing(LogRecord::getMillis);
        c = c.thenComparing(LogRecord::getSequenceNumber);

If the java.util.logging.LogRecord namespace is made optional as the expression could be much shorter:

comparator=getLevel, getThrown, getMillis, getSequenceNumber

We can do even better if we embrace the bean style syntax:

comparator=level, thrown, millis, sequenceNumber

To support null ordering and ascending/descending, there needs to be a defined set of symbols that can be used instead of dot and are not parsed by java.util.Properties.load(Reader). More work is needed to define this part.

For primitive types it would be nice to support signed and unsigned compares. This could be encoded in same place as null ordering as primitives are not nullable.

  • LogRecord::getThrown would always be mapped to org.eclipse.angus.mail.util.logging.SeverityComparator::compareThrowable
  • LogRecord::getParameters would need to be mapped to java.util.Arrays.compare​(T[] a, T[] b, Comparator) from JDK 9. The given comparator should simply compare the toString of the given arguments. Perhaps just using Arrays.toString on each array and then just comparing that might work.
  • LogRecord::getResourceBundle needs a custom comparator. Perhaps sort the keys and compare those? This is TBD.
  • java.util.logging.Formatter::formatMessage would need to be allowed so records are ordered by the rendered text. The result of the rendered text might have to use a java.text.Collator. However, I'm not sure if it would work if the LogRecord locales are different. Might have to fallback to string compare.
  • CollectorFormatter.formatMessage should be updated to support printf formats.
  • sequenceNumber, className, and System.identityHashCode should always be added by the code as the last sort properties to provide a total order for Arrays.sort.

It might be best to simply create a new comparator class that can parse expressions.

@jmehrens jmehrens self-assigned this Jan 19, 2024
@jmehrens jmehrens added the enhancement New feature or request label Jan 22, 2024
jmehrens added a commit to jmehrens/angus-mail that referenced this issue Mar 4, 2024
jmehrens added a commit to jmehrens/angus-mail that referenced this issue Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant