Skip to content

Instantly share code, notes, and snippets.

@bkahlert
Last active July 11, 2024 16:21
Show Gist options
  • Save bkahlert/21bb76d3a45de74c5a3861ecc34f78af to your computer and use it in GitHub Desktop.
Save bkahlert/21bb76d3a45de74c5a3861ecc34f78af to your computer and use it in GitHub Desktop.
Enabled Spring Boot banner while using JSON formatted logging using spring.main.banner-mode=LOG
package demo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@SpringBootApplication
class JsonBannerDemo {
public static void main(String[] args) throws Exception {
// prepares output capturing
PrintStream oldOut = System.out;
ByteArrayOutputStream capture = Stream.of(new ByteArrayOutputStream())
.peek(out -> System.setOut(new PrintStream(out))).findAny().get();
// runs Spring application with activated JSON logging and banner printed to log
// so INGREDIENT #1: spring.main.banner-mode=log
// INGREDIENT #2: a logger capable of logging multi-line strings (e.g. JSON logger)
SpringApplication.run(JsonBannerDemo.class, new String[]{
"--spring.main.banner-mode=log"
});
// restores System.out, prints JSON log containing the escaped banner
// and prints extracted unescaped banner
System.setOut(oldOut);
String bannerJsonLog = capture.toString().split(System.lineSeparator())[0];
Map<String, Object> json = new ObjectMapper().readValue(bannerJsonLog, new TypeReference<Map<String, Object>>() {});
String printedBanner = (String) json.get("message");
System.out.println(Stream.of("JSON formatted log entry:", bannerJsonLog, "", "contains banner completely unchanged if you simply use spring.main.banner-mode=log", printedBanner).collect(Collectors.joining(System.lineSeparator())));
System.exit(0);
}
}
@bkahlert
Copy link
Author

bkahlert commented Apr 9, 2020

Spring Boot banner output does not need to be disabled for JSON formatted logging to work, as this gist shows.
The program has the following output:

JSON formatted log entry:
{"timestamp":"2020-04-09 02:35:58.703","level":"INFO","service":"JsonBannerDemo","logger":"org.springframework.boot.SpringApplication","thread":"main","message":"\n  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n\u001B[32m :: Spring Boot :: \u001B[39m      \u001B[2m (v2.2.5.RELEASE)\u001B[0;39m\n\n"}

contains banner completely unchanged if you simply use spring.main.banner-mode=log

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

If set up correctly the logger should serialize the banner to:

  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n\u001B[32m :: Spring Boot :: \u001B[39m      \u001B[2m (v2.2.5.RELEASE)\u001B[0;39m

Even the ANSI formatting is correctly escaped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment