오늘 Spring  Boot 에 Logback 설정을 하다가 profile 에 따라 분리의 필요성을 느껴 찾아보고 적용하였습니다.

 

우선 logback.xml 파일은 spring extention 을 사용할 수 있게 logback-spring.xml 로 이름을 짓습니다.

 

그리고 2가지 경우로 나누어 설정해 보았습니다.

 

첫번째로 미리 appender 를 선언하고 호출하여 쓰는 경우.

 

<property name="LOG_PATH" value=""/>
<property name="LOG_FILE_NAME" value=""/>

 

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%-5level %d{HH:mm:ss.SSS} [%thread %F:%L] %method - %msg%n
</pattern>
</encoder>
</appender>

 

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<encoder>
<pattern>%-5level %d{HH:mm:ss.SSS} [%thread %F:%L] %method - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>

 

<springProfile name="dev | stage">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>

<appender-ref ref="ROLLING_FILE"/>

</root>
</springProfile>

 

이렇게 쓸경우 springProfile 에 따라 appender 가 중복되지 않고 호출만 하여 사용하면 되어 편리합니다.

하지만 로그 파일의 위치가 권한이 필요한 곳이라면 미리 appender 를 선언하고 해당 설정을 읽을때 파일에 접근, 생성하기 때문에 따로 권한을 줘야합니다. (제 경우에는 앱 실행당시 바로 access denied 가 떴었습니다.)

 

 

두번째로 springProfile 별로 선언하고 쓰는 경우.

 

<springProfile name="dev | stage">

<property name="LOG_PATH" value=""/>
<property name="LOG_FILE_NAME" value=""/>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%-5level %d{HH:mm:ss.SSS} [%thread %F:%L] %method - %msg%n
</pattern>
</encoder>
</appender>

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<encoder>
<pattern>%-5level %d{HH:mm:ss.SSS} [%thread %F:%L] %method - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>

<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_FILE"/>
</root>
</springProfile>

 

이렇게 쓸경우 중복은 되지만 환경에 따라 세부적인 설정을 변경하기도 좋고 파일 생성이 필요없는 환경에서는 쓸데없이 파일을 만드는 appender 에 접근하지 않아 파일을 만들지 않아서 좋았습니다.

 

 

 

 

 

'Programming > Spring' 카테고리의 다른 글

profiles 를 활용하여 설정 값 변경하기.  (0) 2018.08.13

어느날 코딩을 하던 도중 Listadd() 를 하였는데 에러가 발생하였다.

 

익셉션은 UnsupportedOperationException.

 

원인을 찾던 도중 해결에 결정적인 역활을 하는 글과 재밌는 것을 발견하였다.

 

우선 글은

 

https://stackoverflow.com/questions/5755477/java-list-add-unsupportedoperationexception

 

Java List.add() UnsupportedOperationException

I try to add objects to a List instance but it throws an UnsupportedOperationException. Does anyone know why? My Java code: String[] membersArray = request.getParameterValues('membe...

stackoverflow.com

인데 내용을 번역해보자면

모든 Listadd() 메서드를 구현, 지원하지 않으며 가장 일반적인 예로 Arrays.asList(); 같은 경우 고정된 사이즈의 Array 를 리턴한다.
그렇기에 사이즈를 수정할 수 없다.

 

이다.

나같은 경우 Arrays.asList(); 를 통해 만들어진 ArrayListadd 를 하고 있었다.

 

그래서 궁금한 마음에 Arrays  클래스를 확인해본 결과 우리가 흔히 사용하는 ArrayList 를 반환하는게 아니라 

 

Arrays 클래스 내부에 inner Class 로 구현해놓은 ArrayList 를 반환하고 있었다.

당연하게도 Arrays 클래스의 inner ClassArrayList 에는 사이즈 측정 및 조절을 위한 size 와 DEFAULT_CAPACITY 변수가 존재하지 않는다.

그리고 AbstractList 클래스를 상속받고 있어 상속받은 AbstractList 클래스의 add() 메서드는 존재하고 사용할 수는 있지만 


해당 AbstractList 클래스의 add() 메서드를  Override 하여 사용하지 않으면 해당 add() 메서드는  

throw new
UnsupportedOperationException(); 하도록 구현되어있기 때문에 UnsupportedOperationException 에러가 나게 된다.

 

 

 

3장. 함수 에 대한 의견 교환




이 글은 로버트C. 마틴이 지은 클린코드를 읽고 각 챕터에 대한 의견 교환 및 토론을 한 내용 입니다.

댓글로 의견 교환 및 토론은 환영합니다.




오늘은 함께 스터디하는 4명 중 2명이 일과 건강 문제로 스터디에 빠져서 나를 포함해 2명이서 스터디를 진행하였다.




: 

  • 더러운 함수는 이해가 안간다.
  • 함수를 작게 만들라는게 마음에 든다.
  • 함수를 한가지 일만 해야한다고 하는게 뇌리에 박힌다.
  • Switch 문을 사용할때 클린코드 규칙이 깨진다고 하는게 가장 중요한 이야기인것 같고 Switch 뿐만 아니라 if 문을 여러번 사용할때도 같다고 생각된다.
  • 나머지는 와닿지 않는다.
    • ) 함수인수 갯수, boolean 타입을 넘기는것 ..
  • 아직 경험이 별로 없어서 와닿지 않고 enum 크게 와닿진 않는다.




나: 

  • enum 오류 코드를 사용하는 것이 의존성 자석이고 그렇게 쓰지말라고 한 것 같은 경우는 기존의 exception 클래스를 상속받아서 새롭게 해당 예외만 생성하고 사용하면 된다는 말 같다.
  • Enum 사용할때 타입 같은 것을 정의하고 값을 DB에 저장하면 좋다고 생각한다.
    • string 이라는게 에러가 생길수 있는 구석이 많음, 예를 넘겨주거나 받을때 String 이면 kakaopay 인데 kakpay 같이 될수 있는데 이를 방지할수 있다.
  • 함수 챕터에서 로버트C. 마틴이 함수인수의 갯수에 대해 이야기한 것이 중요하다고 생각되는 이유는 함수 인수가 많으면 설계와 정의를 못한거라고 생각한다.
  • 알고리즘 문제를 풀더라도 객체지향적으로 설계하고 정의하면 함수 인수가 많아질 일은 없다고 생각한다.
    • 예를 들어 이진수 변환 문제가 나오면 나는 하나의 이진수 클래스로 만들어 이진수를 저장하는 것을 멤버변수로 만들고 변환하는 과정을 매서드로 만들 것이다.
  • 챕터에서 가장 중요한 말은우리가 함수를 만드는 이유는 개념을 다음 추상화 수준에서 여러단계로 나눠 수행하기 위해서가 아니던가인듯하다.
    • 말에 객체지향의 목표가 있다고 생각든다.
    • 예를 들어 함수에서 다음 함수로 넘어가거나 쪼갤때 단순히 줄을 나눠서 쪼개거나 그냥 인수를 그대로 넘기면 절차지향과 다름없다.
    • 함수를 쪼갤 , 혹은 구현 혹은 리팩토링할 함수를 추상화하고 함수에서 호출하는 다음 함수의 레벨(깊이, 레이어) 나눠줘야 한다고 생각한다.
  • 이는 단순히 함수뿐만 아니라 다른곳에도 적용된다고 생각한다.
    • 예를 들면 DDD 에서 도메인 레이어에서 인프라 레이어로 넘어가는데 이때에도 적용되는 말이라고 생각한다. 
    • 그래서 인프라 레이어에서의 변경이 일어나도 도메인 레이어에는 영향이 없도록 인프라 레이어를 사용, 호출하는 도메인 레이어에서는 인프라 레이어를 추상화(인터페이스화) 하는 것이 중요하다고 생각한다.

+ Recent posts