问题:使用SLF4J和Logback创建日志文件时出错。

huangapple go评论78阅读模式
英文:

Issue creating file for logs with SLF4J and Logback

问题

我想在特定文件夹中创建错误日志文件文件夹的结构如下

    app 
      |_ application.jar
      |_ configuration.json
      |_ logs
          |_ log-error.log

我构建了包并且当我用命令行运行应用程序时
java -jar readExternalFilesFromJar-jar-with-dependencies.jar 

我获得以下结果

    [main] INFO fr.mydomain.app.ReadJson - 主应用程序已调用
    [main] INFO fr.mydomain.app.JsonReader - 调用getJson()方法
    [main] ERROR fr.mydomain.app.ReadJson - 错误消息

在控制台上记录日志没有问题我的问题是日志文件没有被创建

我在我的 pom.xml 中添加了 SLF4J 和 Logback 依赖

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.30</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.3</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>

我还尝试通过在资源文件夹中使用 logback.xml 文件来配置 Logback

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
        <timestamp key="times" datePattern="yyyyMMdd.HHmmss" />
    
        <appender name="STDOUT" class="ch.qos.logback.core.FileAppender">
            <file>${path}/${log.name}-${times}.log</file>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <appender name="FILE" class="ch.qos.logback.core.FileAppender">
            <file>${path}/${log.name}-${times}.log</file>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <logger name="fr.mydomain.app" level="debug" additivity="false">
            <appender-ref ref="FILE" />
        </logger>
    
        <logger name="fr.mydomain.app" level="error" additivity="false">
            <appender-ref ref="STDOUT" />
        </logger>
    
        <root level="error">
            <appender-ref ref="FILE" />
        </root>
    
    </configuration>

在我的主类中我希望能够配置日志文件的路径和名称为什么要在Java方法中配置这些值原因相当简单我希望能够从配置文件中读取这些值

我阅读了一些关于如何设置文件名和路径的文档
https://mkyong.com/logging/logback-set-log-file-name-programmatically/

为此我添加了以下代码

public class ReadJson {
    private static Logger logger = LoggerFactory.getLogger(ReadJson.class);

    public static void main( String[] args ) throws Exception {
        System.setProperty("path", "./logs");
        System.setProperty("log.name", "error");
        logger.info("主应用程序已调用");
        // 变量声明

        System.setProperty("path", ".");
        System.setProperty("log.name", "error");
        ...
    }
}
英文:

I want to create an error log file in a specific folder. The folder has the following structure:

app 
|_ application.jar
|_ configuration.json
|_ logs
|_ log-error.log

I build the package and when I run the application with command line :
java -jar readExternalFilesFromJar-jar-with-dependencies.jar

I do obtain the following result:

[main] INFO fr.mydomain.app.ReadJson - Main Application called
[main] INFO fr.mydomain.app.JsonReader - getJson() method called
[main] ERROR fr.mydomain.app.ReadJson - Error message

I do not have issue making a log on console. My issue is that the log file is not created.

I added SLF4J and Logback dependencies in my pom.xml:

&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
&lt;version&gt;1.7.30&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-simple&lt;/artifactId&gt;
&lt;version&gt;1.7.30&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;ch.qos.logback&lt;/groupId&gt;
&lt;artifactId&gt;logback-core&lt;/artifactId&gt;
&lt;version&gt;1.2.3&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;ch.qos.logback&lt;/groupId&gt;
&lt;artifactId&gt;logback-classic&lt;/artifactId&gt;
&lt;version&gt;1.2.3&lt;/version&gt;
&lt;/dependency&gt;

I also tried to configure Logback with a logback.xml file in my resource folder:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration&gt;
&lt;timestamp key=&quot;times&quot; datePattern=&quot;yyyyMMdd.HHmmss&quot; /&gt;
&lt;appender name=&quot;STDOUT&quot; class=&quot;ch.qos.logback.core.FileAppender&quot;&gt;
&lt;file&gt;${path}/${log.name}-${times}.log&lt;/file&gt;
&lt;encoder&gt;
&lt;pattern&gt;%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;
&lt;/encoder&gt;
&lt;/appender&gt;
&lt;appender name=&quot;FILE&quot; class=&quot;ch.qos.logback.core.FileAppender&quot;&gt;
&lt;file&gt;${path}/${log.name}-${times}.log&lt;/file&gt;
&lt;encoder&gt;
&lt;pattern&gt;%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;
&lt;/encoder&gt;
&lt;/appender&gt;
&lt;logger name=&quot;fr.mydomain.app&quot; level=&quot;debug&quot; additivity=&quot;false&quot;&gt;
&lt;appender-ref ref=&quot;FILE&quot; /&gt;
&lt;/logger&gt;
&lt;logger name=&quot;fr.mydomain.app&quot; level=&quot;error&quot; additivity=&quot;false&quot;&gt;
&lt;appender-ref ref=&quot;STDOUT&quot; /&gt;
&lt;/logger&gt;
&lt;root level=&quot;error&quot;&gt;
&lt;appender-ref ref=&quot;FILE&quot; /&gt;
&lt;/root&gt;
&lt;/configuration&gt;

In my main class I want to be able to configure the log file path and name. Why configuring those values in a java method ? the reason is rather simple. I want to be able to read those values from a configuration file.

I read some documentation on how to set file name and path :
https://mkyong.com/logging/logback-set-log-file-name-programmatically/

For this I added the following code :

public class ReadJson {
private static Logger logger = LoggerFactory.getLogger(ReadJson.class);
public static void main( String[] args ) throws Exception {
System.setProperty(&quot;path&quot;, &quot;./logs&quot;);
System.setProperty(&quot;log.name&quot;, &quot;error&quot;);
logger.info(&quot;Main Application called&quot;);
// d&#233;claration de variables
System.setProperty(&quot;path&quot;, &quot;.&quot;);
System.setProperty(&quot;log.name&quot;, &quot;error&quot;);
...
}
}

答案1

得分: 0

我创建了一个LogConfigurer类,其中有一个getLogger方法:

public Logger getLogger(Configuration configuration, String docType) {
    ...
    String logFileName = "whateverILog";
    fileAppender = new FileAppender();
    fileAppender.setContext(loggerContext);
    fileAppender.setName("timestamp");
    Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    root.setLevel(Level.ERROR);
    fileAppender.setFile(logFolder + "\\" + logFilename + ".log");
    encoder.setContext(loggerContext);
    encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n");
    encoder.start();
    fileAppender.setEncoder(encoder);
    fileAppender.start();
    logger = loggerContext.getLogger(getClass().getSimpleName());
    logger.addAppender(fileAppender);

    // OPTIONAL: print logback internal status messages
    StatusPrinter.print(loggerContext);
    // log something
    logger.debug("Logger Implemented");
    return logger;
}

在主方法中我调用:

LogConfigurer logConfigurer = new LogConfigurer();
Logger logger = logConfigurer.getLogger(configuration, docType);
英文:

I created a LogConfigurer class with a getLogger method:

public Logger getLogger(Configuration configuration, String docType) {
...
String logFileName = &quot;whateverILog&quot;;
fileAppender = new FileAppender();
fileAppender.setContext(loggerContext);
fileAppender.setName(&quot;timestamp&quot;);
Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.ERROR);
fileAppender.setFile(logFolder + &quot;\\&quot;+ logFilename +&quot;.log&quot;);
encoder.setContext(loggerContext);
encoder.setPattern(&quot;%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n&quot;);
encoder.start();
fileAppender.setEncoder(encoder);
fileAppender.start();
logger = loggerContext.getLogger(getClass().getSimpleName());
logger.addAppender(fileAppender);
// OPTIONAL: print logback internal status messages
StatusPrinter.print(loggerContext);
// log something
logger.debug(&quot;Logger Implemented&quot;);
return logger;
}

In the main method I call :

LogConfigurer logConfigurer = new LogConfigurer();
Logger logger = logConfigurer.getLogger(configuration, docType);

huangapple
  • 本文由 发表于 2020年9月17日 18:09:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63935816.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定