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

LOG4J2-2986: introduce filters.startFrames config element to specifc starting frame(s) during Throwable rendering #460

Closed
wants to merge 2 commits into from

Conversation

ronosaurus
Copy link
Contributor

  • Allow frame (package + method name) specific starting point on stack traces to suppress boilerplate web container, vendor framework, etc frames
  • filters.startFrames(frame1,frame2) name selected because its related to filters(package1,package2)
  • Suppress web container frames beneath the servlet entry point using filters.startFrame(javax.servlet.http.HttpServlet.service)
  • Updated various packages, ignorePackages, hasPackages variables to more descriptive and consistent filterPackages
  • Change a few signatures to accept new filterStartFrames parameter alongside filterPackages
    • Future: combine both Lists into some kind of FilterConfig object to support future filters and reduce arguments to methods

@rgoers
Copy link
Member

rgoers commented Jan 18, 2021

@ronosaurus I am really not sure how you can do something wrong in a pull request, except maybe commit code for the wrong project or something. Sorry, I am in a busy period at work again and just haven't had much time to look at stuff.

@vy
Copy link
Member

vy commented Jan 18, 2021

@ronosaurus, mind updating changes.xml and layouts.adoc too, please.

Keep in mind that this change set needs to be backported to release-2.x as well. (Right?) There one (you? 😅) will need to deal with quite some merge conflicts.

Comment on lines +78 to +80
private final List<String> filterPackages;

private final List<String> filterStartFrames;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterPackages suppresses the stack frames, whereas filterStartFrames truncates the stringified stack trace after any occurrence of the given package name. Correct me if I am wrong.

IMHO, filter here is already used in the wrong context. It is generally used for selecting something, not excluding it, e.g., Stream#filter(). I would have called it discardPackages. That said, I am probably more than a decade late to share this great wisdom. But maybe we can do something better for filterStartFrames. Here I see two options:

  1. Stick to the historical context and go with filterStartFrames.
  2. Try to improve the current state with the cost of some inconsistency in the syntax. discardAfterPackages?

if (filterStr.length() > 0) {
final String[] array = filterStr.split(Patterns.COMMA_SEPARATOR);
if (array.length > 0) {
packages = new ArrayList<>(array.length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this totally discard the initial content of the packages?

* Common code for extracting packages from "filters(com.example)" and "filters.startFrames(com.example)"
*
*/
private static List<String> extractFilters(List<String> packages, String option, String conversionWord) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't want to get @garydgregory on your neck, you better have final modifiers here. 😜

for (String token : array) {
token = token.trim();
if (token.length() > 0) {
packages.add(token);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should move the earlier initialization of packages here?

final String className = element.getClassName();
for (final String pkg : ignorePackages) {
if (className.startsWith(pkg)) {
private static boolean elementStartsWith(final StackTraceElement element, final List<String> packagesOrStartFrames, boolean includeMethodName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I am allergic to these kind of unions. Why not simply having two arguments: packages and startFrames? (Please mind the final modifiers.)

@@ -287,7 +287,7 @@ public void testSeparator_getExtendedStackTraceAsString() throws Exception {
final ThrowableProxy proxy = new ThrowableProxy(throwable);

final String separator = " | ";
final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString(null,
final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString(null,null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing whitespace.

@@ -132,6 +132,55 @@ public void testFiltering() {
assertTrue(result.contains(" suppressed "), "No suppressed lines");
}

@Test
public void testFiltersStartFrames() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test indeed checks that the given filter pattern should not be found in the output. Though I would also check if the filter is not provided, the pattern indeed can be found.

Comment on lines +147 to +158
final LogEvent event = Log4jLogEvent.newBuilder() //
.setLoggerName("testLogger") //
.setLoggerFqcn(this.getClass().getName()) //
.setLevel(Level.DEBUG) //
.setMessage(new SimpleMessage("test exception")) //
.setThrown(thrown).build();
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
final String parentToString = toString(thrown);
// System.out.println(parentToString);
final String result = sb.toString();
// System.out.println(result);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind removing these empty comment line starts and commented out lines, please?

String result = sb.toString();
result = result.replaceAll(" ~?\\[.*\\]", Strings.EMPTY);
final String expected = sw.toString(); //.replaceAll("\r", Strings.EMPTY);
final String expected = toString(parent); //.replaceAll("\r", Strings.EMPTY);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the commented out replaceAll?

assertEquals(expected, result);
}

private String toString(Throwable ex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind the final modifier, please.

if (includeMethodName) { // support startFrames
className += "." + element.getMethodName();
}
for (final String item : packagesOrStartFrames) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer an index-based iteration instead if you want to avoid the iterator allocation at each call.

@rgoers
Copy link
Member

rgoers commented Nov 21, 2021

Is anything happening with this?

@ronosaurus
Copy link
Contributor Author

Didn't realize this PR is 11 months old. I'm going to close, review the feedback, then eventually submit another PR from more current code.

@ronosaurus ronosaurus closed this Nov 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants