Skip to content

Add org.apache.logging.log4j.core.appender.FileManager.getPath() #3855

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

Open
wants to merge 1 commit into
base: 2.x
Choose a base branch
from

Conversation

garydgregory
Copy link
Member

Add org.apache.logging.log4j.core.appender.FileManager.getPath()

Important

Base your changes on 2.x branch if you are targeting Log4j 2; use main otherwise.

Checklist

Before we can review and merge your changes, please go through the checklist below. If you're still working on some items, feel free to submit your pull request as a draft—our CI will help guide you through the remaining steps.

✅ Required checks

  • License: I confirm that my changes are submitted under the Apache License, Version 2.0.

  • Commit signatures: All commits are signed and verifiable. (See GitHub Docs on Commit Signature Verification).

  • Code formatting: The code is formatted according to the project’s style guide.

    How to check and fix formatting
    • To check formatting: ./mvnw spotless:check
    • To fix formatting: ./mvnw spotless:apply

    See the build instructions for details.

  • Build & Test: I verified that the project builds and all unit tests pass.

    How to build the project

    Run: ./mvnw verify

    See the build instructions for details.

Note that there are still problems on Windows:

[ERROR] Failures:
[ERROR]   SyslogAppenderCustomLayoutTest>SyslogAppenderTest.testTCPAppender:56->SyslogAppenderTestBase.sendAndCheckLegacyBsdMessage:74->SyslogAppenderTestBase.checkTheNumberOfSentAndReceivedMessages:112 The number of received messages should be equal with the number of sent messages ==> expected: <1> but was: <0>
[ERROR]   RollingAppenderDeleteScriptTest.testAppender:74 target\rolling-with-delete-script\test\test-2.log should have odd index expected:<1> but was:<0>
[ERROR]   AsyncLoggersWithAsyncLoggerConfigTest.testLoggingWorks:46 Incorrect number of events. Expected 2, got 0 expected:<2> but was:<0>
[INFO]
[ERROR] Tests run: 8447, Failures: 3, Errors: 0, Skipped: 36

🧪 Tests (select one)

  • I have added or updated tests to cover my changes.
  • No additional tests are needed for this change.

📝 Changelog (select one)

  • I added a changelog entry in src/changelog/.2.x.x. (See Changelog Entry File Guide).
  • This is a trivial change and does not require a changelog entry.

Copy link

Job Requested goals Build Tool Version Build Outcome Build Scan®
build-macos-latest clean install 3.9.8 Build Scan PUBLISHED
build-ubuntu-latest clean install 3.9.8 Build Scan PUBLISHED
build-windows-latest clean install 3.9.8 Build Scan PUBLISHED
Generated by gradle/develocity-actions

@vy
Copy link
Member

vy commented Jul 24, 2025

@garydgregory, would you mind sharing the use case, please? What problem is this change set addressing?

@garydgregory
Copy link
Member Author

garydgregory commented Jul 24, 2025

The use case is that we (proprietary code base) have custom code that interacts with configurations, file Appender and Managers, we are moving from IO to NIO, and Strings shouldn't be used as an abstraction for where to find a file. Java has a nice abstraction for that: Path.

You can also see that internally the file manager also needs a Path.

HTH

@ppkarwasz
Copy link
Contributor

I'm a strong advocate for using Path instead of String or File. This proposal, however, feels like an ad hoc patch that only addresses one of the file appenders and doesn't even touch on rolling file appenders.

Given that this is clearly important for your employer, would it be possible to ask them to let you work on #2117 during work hours? 🙏 I recall you volunteered for that on Slack, though it's totally understandable that tackling something of that scope in your spare time isn’t feasible, especially with all the Commons tasks already on your plate.

There are clear benefits to transitioning Log4j’s file handling from IO to NIO:

  • You're primarily developing on Windows, where the low-level file access flags differ: NIO automatically sets FILE_SHARE_DELETE, which avoids many file locking issues.
  • A NIO-based Log4j would better align with your employer’s own applications, after you migrate them to NIO.
  • NIO opens the door to alternative FileSystemProvider implementations. This could make it possible (for example) to write logs from Unix-based servers directly to Windows shares using SMB or CIFS.
  • Testing Log4j from Windows would become more reliable: many current flaky tests stem from attempts to delete files with open handles.
  • This change feels incremental and uninspired. In contrast, tackling Consider replacing FileOutputStream with Files.newOutputStream #2117 would be a substantial improvement, something we could confidently showcase in the release notes for 2.26.0 or 2.27.0 (whenever the timing works for you).

@garydgregory
Copy link
Member Author

garydgregory commented Jul 24, 2025

Hi all,

TLDR: Let's bring this PR in and then...

Let's not confuse file Appenders and file Managers ;-)

I took a glance at the rolling file manager and it's a much larger code base. This PR is small and focused, which is a good thing. I am willing to volunteer to migrate the other manager code ((rolling) from IO to NIO in a separate PR over the weekend probably, or at the very least initially from presenting Path instead/in addition to String in the API. I can do this in a binary compatible way of course, but view is that these are internal classes up for breakage. So we'd need to agree on what kind of compatibility we want for AbstractRolloverStrategy and friends. This work would include #2117 as part of PR 2 (see below).

I want to think about the migration from IO to NIO in two steps:

  • PR 1: Migrate the API: Use Path where possible instead of String and File
  • PR 2: Migrate the implementation, there might be behavioral differences using Files that we only want to give users in 3.0 for example.

WDYT?

For 3.0, all bets are off and breaking BC is OK IMO in this area.

@ppkarwasz
Copy link
Contributor

Hi @garydgregory,

TLDR: Let's bring this PR in and then...

This PR is small and focused, which is a good thing. I am willing to volunteer to migrate the other manager code ((rolling) from IO to NIO in a separate PR over the weekend probably, or at the very least initially from presenting Path instead/in addition to String in the API.

I believe it's actually too narrowly scoped, to the point where it loses sight of the broader context. To be candid: would anyone upgrade Log4j just because the changelog says that FileManager gained a new getPath() method? Instead of merging this in isolation, I’d suggest a slightly broader approach.

Tackling the rolling file appender is definitely hard (otherwise I wouldn’t have asked you in the first place!). I’ve actually got a local branch where I started migrating the o.a.l.l.core.appender.rolling.action.Action to NIO but it still requires a lot of work.

What would you say about:

Step 1: Fix fileName handling in the config layer

  • Convert fileName from String to Path during configuration parsing (there’s already a TypeConverters.PathConverter that makes this easier).
    This would have immediate security and maintenance benefits. Every call to new File(String) or Paths.get(String) triggers a PATH_TRAVERSAL_IN warning in SpotBugs. By confining all Path creation to the appender builders, we make the codebase more robust and auditable from a security standpoint.
  • Expose the Path-based filename via the APIs of all relevant file appenders: File, RandomFile, and MemoryMappedFile.

This change would provide real value worth highlighting in release notes. Would you be open to expand your PR to cover this step?

Step 2: Migrate rolling file appenders to NIO

  • This is a larger task and can be handled in a follow-up PR or even after the release of Step 1.
  • I’d love to bundle that with an additional feature: protection against accidental file overwrites during rollover.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: To triage
Development

Successfully merging this pull request may close these issues.

3 participants