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

Log messages mixed with formatted code on stdout #2246

Open
lassik opened this issue Sep 6, 2023 · 8 comments
Open

Log messages mixed with formatted code on stdout #2246

lassik opened this issue Sep 6, 2023 · 8 comments
Labels
Parked Issue is not likely to be solved or has no clear resolution yet

Comments

@lassik
Copy link

lassik commented Sep 6, 2023

When formatting code from stdin to stdout, all log messages should go to stderr. Only the formatted code should go to stdout.

Is there a current or planned way to accomplish this using command line flags?

(Prompted by lassik/emacs-format-all-the-code#237)

@lassik
Copy link
Author

lassik commented Sep 6, 2023

Possibly related: #589, #1327

@paul-dingemans
Copy link
Collaborator

No there are no plans to add a new toggle. But theoretically should should be able to manage this with the logger configuration. Ktlint CLI uses logback classic as logger implementation. If you provide a logback.xml file on the classpath of Ktlint CLI this config should be picked up. You can start with something like:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="SystemErr"
              class="ch.qos.logback.core.ConsoleAppender">

        <target>System.err</target>

        <encoder>
            <pattern>[%level] %logger{36} - %msg%n</pattern>
        </encoder>

    </appender>

    <root level="trace">
        <appender-ref ref="SystemErr"/>
    </root>

</configuration>

Please let me know if you can get it to work and provide some details back so that it can be transformed to a FAQ in the documentation. It would be supercool if you could write that documentation and raise a PR for it.

@torgeir
Copy link

torgeir commented Sep 14, 2023

Where would you place/refer this file if you installed ktlint with something like brew install ktlint and run it with just the binary ktlint?

@paul-dingemans
Copy link
Collaborator

I have never tried. But with some googling I found that you can pass an option logback.configurationFile to the jvm (https://logback.qos.ch/manual/configuration.html#configFileProperty). So technically it should at least be possible to pass that flag to the ktlint.jar. It does not work with the self-executable jar ktlint though.

@lassik
Copy link
Author

lassik commented Sep 16, 2023

Thanks for hearing us. Unfortunately It is quite inconvenient for editor plugins to modify the classpath, and placing a file on the classpath is more complicated still. Stdin->stdout formatting, with logging to stderr, is the easiest and most reliable way to implement editor plugins. The plugin I maintain, Format-All for Emacs, calls out to 80 different formatters all using this convention. It would really help plugin authors if ktlint had robust native support for this use case.

It's been years since I wrote any Java code, but I found the following Groovy snippet to do the same thing as the above XML.

appender("SystemErr", ConsoleAppender) {
    // Enable coloured output.
    withJansi = true

    encoder(PatternLayoutEncoder) {
        pattern = "%blue(%-5level) %green(%logger{35}) - %msg %n"
    }

    // Redirect output to the System.err.
    target = 'System.err'
}

root(DEBUG, ["SystemErr"])

@paul-dingemans
Copy link
Collaborator

Btw, one thing that you can do is to add --log-level=none which entirely disables the logging. But do note, that in case ktlint throws an exception or an error is printed, that it will be suppressed as well.

I will park the issue for now. I see no way to change this behavior in ktlint without affect other use cases.

@paul-dingemans paul-dingemans added the Parked Issue is not likely to be solved or has no clear resolution yet label Sep 17, 2023
@lassik
Copy link
Author

lassik commented Sep 20, 2023

Thank you for the tip. We adopted --log-level=none as a workaround for the time being.

Just to clarify: Adding a --log-stderr flag would also interfere with existing use cases?

@paul-dingemans
Copy link
Collaborator

Just to clarify: Adding a --log-stderr flag would also interfere with existing use cases?

No that would not interfere. But I see no way how I can implement that in a reasonable way. Ktlint uses io.github.oshai.kotlinlogging logging implementation and not simply a println to either stdout or stderr. Not only the ktlint-cli module but every other module in ktlint uses the same logger. So the ktlint-cli module would need to dynamically change the logging configuration based on parameter which only can be interpreted at runtime. This is also done for the log level but that case is simpler than what you request.

I do think it is possible to do so. But to be honest I don't want to spend my time on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Parked Issue is not likely to be solved or has no clear resolution yet
Projects
None yet
Development

No branches or pull requests

3 participants