arakoodev / FlySpring

Developer-friendly Spring Boot flavor. Supercharged cli "flyfly" to make you fall in love with Java again
MIT License
7 stars 7 forks source link

setup logging in the right way #35

Open sandys opened 1 year ago

sandys commented 1 year ago

built-in json logging and server access log to console

e.g. quarkus.

sandys commented 1 year ago
logging:
  pattern:
    console: "%clr(%d{HH:mm:ss.SSS}){blue} %clr(---){cyan} %clr([%15.15t]){yellow} %clr(:){red} %clr(%m){magenta}%n"
sandys commented 1 year ago

Here's the complete example of a Spring Boot application with WebFlux, Hibernate, Groovy templates, and JSON-based logging, with component scanning disabled and auto-configuration classes imported explicitly.

  1. Update your pom.xml with the required dependencies:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-groovy-templates</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.6</version>
    </dependency>
</dependencies>
  1. Create the ManualConfigApplication class:
package com.example.manualconfig;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {})
public class ManualConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ManualConfigApplication.class, args);
    }
}
  1. Create the AppConfig class:
package com.example.manualconfig;

import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.reactive.config.EnableWebFlux;

@Configuration
@EnableWebFlux
@Import({
        WebFluxAutoConfiguration.class,
        ErrorWebFluxAutoConfiguration.class,
        ClientHttpConnectorAutoConfiguration.class,
        WebClientAutoConfiguration.class,
        JpaRepositoriesAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        GroovyTemplateAutoConfiguration.class
})
public class AppConfig {

    // Define your beans and components here
    @Bean
    public MyService myService() {
        return new MyService();
    }
}
  1. Create the MyService class:
package com.example.manualconfig;

public class MyService {

    public String getMessage() {
        return "Hello from MyService!";
    }
}
  1. Create the MyController class:
package com.example.manualconfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    private final MyService myService;
    private static final Logger logger = LoggerFactory.getLogger(MyController.class);

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    @GetMapping("/")
    public String hello() {
        return myService.getMessage();
    }

    @GetMapping("/log")
    public String log() {
        logger.trace("This is a TRACE level log message");
        logger.debug("This is a DEBUG level log message");
        logger.info("This is an INFO level log message");
        logger.warn("This is a WARN level log message");
        logger.error("This is an ERROR level log message");

        return "Logged messages with different severity levels";
    }
}
  1. Create an application.properties file in the src/main/resources folder with the following content:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
  1. Create a logback-spring.xml file in the src/main/resources folder with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="JSON_CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <logLevel/>
                <loggerName/>
                <pattern>
                    <pattern>
                        {
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "line": "%line",
                        "message": "%message",
                        "exception": "%xThrowable{shortened}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="JSON_CONSOLE_APPENDER"/>
    </root>
</configuration>
  1. Run the ManualConfigApplication class as a Java application. When you access the root URL (http://localhost:8080), you should see the message "Hello from MyService!". When you access the /log endpoint (http://localhost:8080/log), you should see JSON-formatted log messages in the console with different severity levels. Note that only messages with a severity level equal to or higher than the configured log level will be displayed. In this example, the log level is set to INFO, so TRACE and DEBUG messages will not be displayed.