logbackのログ出力時の改行を削除してログ出力したい

業務でログ出力時に改行コードを半角スペースで置換してログ出力したい要件がったのやり方を調査した


## logback.xml

### 修正前

```修正前logback.xml

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>
          <![CDATA[
              %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} --- %msg%n
          ]]>
      </pattern>
    </encoder>
  </appender>
```



### 修正後
+ `%replace`を追加
+ `%ex`を追加してstacktraceの出力時にも置換するように追加


[PatternLayout#replace](https://xy2401.com/local-docs/java/logback/manual/layouts_ja.html#replace)

```修正後logback.xml
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>
          <![CDATA[
              %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} --- %replace(%msg){'\r\n|\r|\n', ' '} %replace(%ex){'\r\n|\r|\n', ' '} %nopex%n
          ]]>
      </pattern>
    </encoder>
  </appender>
```


## ログ結果


## 実装

```java
log.debug("debug",new Throwable("a"));
log.info("info {} {}", "ho\nge", "fu\r\nga");
log.warn("warn");
log.error("trace test", new RuntimeException("例外発生！"));

var userInfo = new UserInfo();
userInfo.setUserId("user1234");
userInfo.setPassword("password");
userInfo.setMail("""
        1
        2
        3
        4
        5
        """);
```

```改行コード置換前
2023-09-17 21:25:02.353 DEBUG c.example.demo.Application --- debug
java.lang.Throwable: a
	at com.example.demo.Application.run(Application.java:34)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:319)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
	at com.example.demo.Application.main(Application.java:27)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)
2023-09-17 21:25:02.355 INFO  c.example.demo.Application --- info ho
ge fu
ga
2023-09-17 21:25:02.355 WARN  c.example.demo.Application --- warn
2023-09-17 21:25:02.355 ERROR c.example.demo.Application --- trace test
java.lang.RuntimeException: 例外発生！
	at com.example.demo.Application.run(Application.java:37)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:319)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
	at com.example.demo.Application.main(Application.java:27)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)
2023-09-17 21:25:02.356 INFO  c.example.demo.Application --- UserInfo(userId=user1234, password=password, mail=1
2
3
4
5
)
```


```改行コード置換後
2023-09-17 21:27:12.456 DEBUG c.example.demo.Application --- debug java.lang.Throwable: a 	at com.example.demo.Application.run(Application.java:34) 	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) 	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:319) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) 	at com.example.demo.Application.main(Application.java:27) 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 	at java.base/java.lang.reflect.Method.invoke(Method.java:568) 	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)  
2023-09-17 21:27:12.456 INFO  c.example.demo.Application --- info ho ge fu ga  
2023-09-17 21:27:12.456 WARN  c.example.demo.Application --- warn  
2023-09-17 21:27:12.456 ERROR c.example.demo.Application --- trace test java.lang.RuntimeException: 例外発生！ 	at com.example.demo.Application.run(Application.java:37) 	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) 	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:319) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) 	at com.example.demo.Application.main(Application.java:27) 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 	at java.base/java.lang.reflect.Method.invoke(Method.java:568) 	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)  
2023-09-17 21:27:12.457 INFO  c.example.demo.Application --- UserInfo(userId=user1234, password=password, mail=1 2 3 4 5 )  

```