wylovelyi commented on issue #2522:
URL: 
https://github.com/apache/logging-log4j2/issues/2522#issuecomment-6055635556

   I reproduced this, but I think the root cause is a bit different from what's 
assumed here, and it affects more patterns than just `1.2.*`. Posting to 
confirm the intended semantics before attempting a fix, because the docs seem 
to be internally inconsistent here.
   
   ## What actually happens
   
   On `2.x` (current `main`, commit `38a9240` for `NameAbbreviator.java`), with 
`org.apache.commons.test.Foo`:
   
   | Pattern | Actual output | Docs say |
   |---|---|---|
   | `%c{1.}` | `o.a.c.Foo` | `o.a.c.Foo` ✅ |
   | `%c{1.1.1.*}` | `o.a.c.test.Foo` | `o.a.c.test.Foo` ✅ |
   | `%c{1.2.*}` | `o.ap.commons.test.Foo` | `o.a.c.test.Foo` ❌ |
   | `%c{1.3.*}` | `o.apa.commons.test.Foo` | `o.a.commons.test.Foo` ❌ |
   | `%c{1.8.*}` | `o.apache.commons.test.Foo` | `org.apache.commons.test.Foo` 
❌ |
   
   So `1.3.*` and `1.8.*` are affected by exactly the same problem — I don't 
see them mentioned anywhere, which suggests they've been silently wrong since 
the pattern support was added. `1.1.1.*` only looks correct by coincidence: all 
three counts happen to be `1`.
   
   ## Root cause
   
   `NameAbbreviator.getAbbreviator()` (the pattern-parsing loop around line 99) 
treats the digit before `*` as a per-segment character count:
   
   ```java
   if (trimmed.charAt(pos) == '*') {
       charCount = Integer.MAX_VALUE;
   } else if (trimmed.charAt(pos) >= '0' && trimmed.charAt(pos) <= '9') {
       charCount = trimmed.charAt(pos) - '0';   // <-- also consumes the digit 
before '*'
       ...
   }
   ```
   
   For `1.2.*` this produces the fragment list `[1 char, 2 chars, keep-all]`, 
so `org` → `o`, `apache` → `ap`, and everything after that is preserved 
verbatim. Hence the extra `p` in `o.ap.…`.
   
   ## Why I'd like maintainer input before patching
   
   The prose in https://logging.apache.org/log4j/2.x/manual/pattern-layout.html 
says:
   
   > If the number after the first period is followed by an asterisk it 
indicates how many of the rightmost tokens will be printed in full.
   
   Read literally, that would make `%c{1.2.*}` = "1 char for leading segments + 
the 2 rightmost tokens in full" = **`o.a.commons.test.Foo`**, i.e. the current 
implementation output would be *wrong* for `1.2.*`.
   
   But the example table in that same section lists `%c{1.3.*}` → 
`o.a.commons.test.Foo`, which is only correct under the "digit = char count" 
reading that the code implements. So the table and the prose disagree with each 
other, and I can't tell which one is intended.
   
   Also worth noting: this report's expected output for `1.2.*` 
(`o.a.c.test.Foo`) is actually the documented result for `1.1.1.*`, so I don't 
want to assume which reading is being requested.
   
   ## Two possible directions
   
   1. **Change the implementation** so that `N.*` means "keep the N rightmost 
tokens in full". This would align the code with the prose, but it changes 
existing behavior for patterns like `1.2*` and `1.3*` and would break current 
assertions in `NameAbbreviatorTest` (e.g. `1.2*` → 
`o.a.l.l.c.pattern.NameAbbreviatorTest`). That's a backward-incompatible 
change, so it would need a deprecation discussion.
   2. **Correct the documentation** — fix the example table so `1.2.*`/`1.3.*` 
show what the code actually produces, and clarify the prose to describe the 
digit-before-`*` semantics explicitly. Zero behavior change, and it would make 
the docs match the (heavily used) existing behavior.
   
   Could you confirm which semantics is intended for `%c{N.*}`? I'm happy to 
prepare a PR either way — I just don't want to pick the breaking option 
unilaterally.
   
   For reference, my analysis above is based on reading 
`log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java`
 and reproducing the parse + abbreviate logic; I haven't yet run it against a 
built jar.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to