Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot Logging and Google Cloud Platform Log Viewer

I'm running a Spring Boot application within the Google Cloud Platform and viewing the log files viewing the Google Platform Logs Viewer. Before using Spring Boot and just using simple servlets, the logging entries would be displayed as:

Logs are grouped and show the blue information icon

Each request would be grouped and all the logging information for that request could be seen by expanding the row. However, when using Spring Boot the requests are no longer grouped and the log entries are just shown line by line. When there are multiple requests the log entries get very confusing as a result because it isn't possible to view them in a grouped way. I have my logging.properties setup in the same way:

.level = INFO
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n

The Logger is initialised in each class as:

private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(MyClass.class.getName());

And then the logging API is used as: LOG.info("My Message");

I don't understand why the statements are being logged differently and no longer grouped but it must have something with the way Spring Boot handles logging?

like image 742
Adam Boulton Avatar asked Feb 07 '20 14:02

Adam Boulton


People also ask

How do I view log files in spring boot?

Java. Now we simply need to run the application and hit http://localhost:8080/log to see the log messages.

Which logging framework is best for spring boot?

If you are using Spring Boot Starters, Logback will provide a good support for logging. Besides, Logback also provides a use of good support for Common Logging, Util Logging, Log4J, and SLF4J.

How do you write logs in Google Cloud logging in Java?

You can write logs to Cloud Logging from Java applications by using the Logback appender or a java. util. logging handler, or by using the Cloud Logging library for Java directly. The Cloud Logging agent does not have to be installed to use the Cloud Logging library for Java.


1 Answers

Since recent runtimes, AppEngine is evolving with a behaviour that is more and more converging with a container based approach, more "opened" as new other products (like Cloud Run for example).

This is changing a little the way we're developing with GAE, specific legacy libraries aren't available (SearchAPI...), and it is changing also how logs are managed.

We can reproduce this "nested log feature" with new java11 runtime, but we need to manage it ourself.

As official docs mentioned:

In the Logs Viewer, log entries correlated by the same trace can be viewed in a "parent-child" format.

It means, if we retrieve the trace identifier received inside X-Cloud-Trace-Context HTTP header of our request, we can then use it to add a new LogEntry by passing it as the trace identifier attribute.

This can be done by using Stackdriver Logging Client libraries

With Spring GCP

Fortunately, Spring Cloud GCP is there to make our lives easier.

You can find a sample project which implements it. Be careful, it's a AppEngine Flexible example, but it will work fine with Standard runtime. It uses Logback.

From a working Spring Boot project on GAE Java11, steps to follow are :

  • Add spring-cloud-gcp-starter-logging dependency :
<!-- Starter for Stackriver Logging -->   
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-gcp-starter-logging</artifactId>
   <version>1.2.1.RELEASE</version>
</dependency>

  • Add a logback-spring.xml inside src/main/resources folder :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/cloud/gcp/autoconfigure/logging/logback-appender.xml" />
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    <root level="INFO">
        <!-- If running in GCP, remove the CONSOLE appender otherwise logs will be duplicated. -->
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="STACKDRIVER" />
    </root>
</configuration>
  • Enable Spring GCP logging feature, inside src/main/resources/application.properties :
spring.cloud.gcp.logging.enabled=true
  • And use LOGGER inside your code:
@SpringBootApplication
@RestController
public class DemoApplication {
    private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping()
    public SomeData get() {
        LOGGER.info("My info message");
        LOGGER.warn("My warning message");
        LOGGER.error("My error message");

        return new SomeData("Hello from Spring boot !");
    }
}

Result will be in Stackdriver Logging viewer, for appengine.googleapis.com/request_log :

Stackdriver Logging Viewer

like image 198
Thierry Falvo Avatar answered Oct 22 '22 07:10

Thierry Falvo