로그파일 설정

main
박성영 1 month ago
parent d13da9b5ab
commit bea56a8e30

1
.gitignore vendored

@ -21,3 +21,4 @@
/.gradle/
/build/
/gradle/
/.claude/settings.local.json

@ -29,9 +29,6 @@ dependencies {
// GPKI JNI local library
implementation files('lib/libgpkiapi_jni_1.5.jar')
// Log4j 1.x for legacy util (NewGpkiUtil). Consider replacing with SLF4J in future.
implementation 'log4j:log4j:1.2.17'
// Configuration metadata
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

@ -10,13 +10,13 @@ import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import com.vmis.interfaceapp.model.ledger.LedgerResponse;
import com.vmis.interfaceapp.util.TxIdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
/**
@ -55,22 +55,10 @@ import java.nio.charset.StandardCharsets;
* @see GpkiService
* @see VmisProperties
*/
@Slf4j
@Component
public class GovernmentApiClient {
/**
* SLF4J
*
* <p> API , , .
* :</p>
* <ul>
* <li>INFO: API </li>
* <li>WARN: HTTP </li>
* <li>ERROR: ( RuntimeException )</li>
* </ul>
*/
private static final Logger log = LoggerFactory.getLogger(GovernmentApiClient.class);
/**
* Spring RestTemplate
*
@ -358,18 +346,6 @@ public class GovernmentApiClient {
* <td>VMIS_SEOUL</td>
* <td></td>
* </tr>
* <tr>
* <td>REGION_CODE</td>
* <td> ( )</td>
* <td>11010 ( )</td>
* <td></td>
* </tr>
* <tr>
* <td>DEPT_CODE</td>
* <td> </td>
* <td>TRANS_001</td>
* <td></td>
* </tr>
* </table>
*
* <h3> :</h3>
@ -426,16 +402,6 @@ public class GovernmentApiClient {
// 호출하는 시스템을 식별하는 필수 값
headers.add("INFO_SYS_ID", props.getSystem().getInfoSysId());
// 10. 지역 코드 (선택 사항)
// 시군구 코드 (예: 11010 = 서울특별시 종로구)
// null이 아닌 경우에만 헤더에 추가
if (props.getSystem().getRegionCode() != null) headers.add("REGION_CODE", props.getSystem().getRegionCode());
// 11. 부서 코드 (선택 사항)
// 호출하는 부서의 코드
// null이 아닌 경우에만 헤더에 추가
if (props.getSystem().getDepartmentCode() != null) headers.add("DEPT_CODE", props.getSystem().getDepartmentCode());
// 구성 완료된 헤더 반환
return headers;
}

@ -4,10 +4,10 @@ import com.vmis.interfaceapp.config.properties.VmisProperties;
import com.vmis.interfaceapp.model.basic.BasicRequest;
import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
/**
* Populates incoming request models with values from YAML configuration.
* Unconditionally overwrites the listed fields per requirement:
@ -15,9 +15,9 @@ import org.springframework.stereotype.Component;
* - CNTC_INFO_CODE (service specific)
* - CHARGER_ID, CHARGER_IP, CHARGER_NM
*/
@Slf4j
@Component
public class RequestEnricher {
private static final Logger log = LoggerFactory.getLogger(RequestEnricher.class);
private final VmisProperties props;

@ -4,16 +4,16 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import com.gpki.gpkiapi_jni;
import com.gpki.gpkiapi.GpkiApi;
import com.gpki.gpkiapi.cert.X509Certificate;
import com.gpki.gpkiapi.crypto.PrivateKey;
import com.gpki.gpkiapi.storage.Disk;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class NewGpkiUtil {
private static Logger logger = Logger.getLogger(NewGpkiUtil.class);
byte[] myEnvCert, myEnvKey, mySigCert, mySigKey;
private Map<String, X509Certificate> targetServerCertMap = new HashMap<String, X509Certificate>();
@ -35,11 +35,11 @@ public class NewGpkiUtil {
public void init() throws Exception {
GpkiApi.init(gpkiLicPath);
gpkiapi_jni gpki = this.getGPKI();
if(logger.isDebugEnabled()){
if(log.isDebugEnabled()){
if(gpki.API_GetInfo()==0)
logger.debug(gpki.sReturnString);
log.debug(gpki.sReturnString);
else
logger.error(gpki.sDetailErrorString);
log.error(gpki.sDetailErrorString);
}
if(targetServerIdList!=null){
String certIdList[] = targetServerIdList.split(",");
@ -51,7 +51,7 @@ public class NewGpkiUtil {
}
}
logger.info("Loading gpki certificate : myServerId="
log.info("Loading gpki certificate : myServerId="
+ this.getMyServerId());
X509Certificate _myEnvCert = Disk.readCert(this
@ -76,12 +76,12 @@ public class NewGpkiUtil {
testGpki(gpki);
}
this.finish(gpki);
logger.info("GpkiUtil initialized");
log.info("GpkiUtil initialized");
}
private void load(gpkiapi_jni gpki, String certId) throws Exception {
logger.debug("Loading gpki certificate : targetServerId="+ certId);
log.debug("Loading gpki certificate : targetServerId="+ certId);
X509Certificate cert = targetServerCertMap.get(certId);
if (cert != null) {
@ -107,7 +107,7 @@ public class NewGpkiUtil {
if(certFilePath != null){
cert = Disk.readCert(certFilePath + File.separator + certId + ".cer");
}else{
logger.debug("not certFilePath");
log.debug("not certFilePath");
}
}
@ -117,13 +117,13 @@ public class NewGpkiUtil {
private gpkiapi_jni getGPKI(){
gpkiapi_jni gpki = new gpkiapi_jni();
if(gpki.API_Init(gpkiLicPath) != 0){
logger.error(gpki.sDetailErrorString);
log.error(gpki.sDetailErrorString);
}
return gpki;
}
private void finish(gpkiapi_jni gpki){
if(gpki.API_Finish() != 0){
logger.error(gpki.sDetailErrorString);
log.error(gpki.sDetailErrorString);
}
}
@ -243,44 +243,44 @@ public class NewGpkiUtil {
public void testGpki(gpkiapi_jni gpki) throws Exception{
//gpki test eng
logger.info("=======================================================");
logger.info("================ TEST GPKI START ======================");
logger.info("=======================================================");
log.info("=======================================================");
log.info("================ TEST GPKI START ======================");
log.info("=======================================================");
String original_Eng = "abc";
logger.info("=== TEST ENG STRING: "+ original_Eng);
log.info("=== TEST ENG STRING: "+ original_Eng);
try {
byte[] encrypted = encrypt(original_Eng.getBytes(), myServerId);
logger.info("=== TEST ENG ENCRYPT STRING: "+ encode(encrypted));
log.info("=== TEST ENG ENCRYPT STRING: "+ encode(encrypted));
String decrypted = new String(decrypt(encrypted));
logger.info("=== TEST ENG DECRYPT STRING: "+decrypted);
log.info("=== TEST ENG DECRYPT STRING: "+decrypted);
if (!original_Eng.equals(decrypted)) {
throw new Exception("GpkiUtil not initialized properly(english)");
}
logger.info("=== TEST ENG: OK");
log.info("=== TEST ENG: OK");
} catch (Exception e) {
logger.warn("Gpki Test error(english)", e);
log.warn("Gpki Test error(english)", e);
throw e;
}
//gpki test kor
String original = "한글테스트";
logger.info("=== TEST KOR STRING: "+ original);
log.info("=== TEST KOR STRING: "+ original);
try {
byte[] encrypted = encrypt(original.getBytes(), myServerId);
logger.info("=== TEST KOR ENCRYPT STRING: "+ encode(encrypted));
log.info("=== TEST KOR ENCRYPT STRING: "+ encode(encrypted));
String decrypted = new String(decrypt(encrypted));
logger.info("=== TEST KOR DECRYPT STRING: "+decrypted);
log.info("=== TEST KOR DECRYPT STRING: "+decrypted);
if (!original.equals(decrypted)) {
throw new Exception("GpkiUtil not initialized properly(korean)");
}
logger.info("=== TEST KOR: OK");
log.info("=== TEST KOR: OK");
} catch (Exception e) {
logger.warn("Gpki Test error(korean)", e);
log.warn("Gpki Test error(korean)", e);
throw e;
}finally{
logger.info("=======================================================");
logger.info("================ TEST GPKI END ========================");
logger.info("=======================================================");
log.info("=======================================================");
log.info("================ TEST GPKI END ========================");
log.info("=======================================================");
}
}

@ -1,6 +1,22 @@
server:
port: 8080
# 로그 설정 - 개발(DEV) 환경
logging:
config: classpath:logback-spring.xml
file:
path: d:/data/VMIS-interface/logs
name: vmis-interface
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 30
level:
root: INFO
com.vmis.interfaceapp: DEBUG
org.springframework: INFO
org.springframework.web: DEBUG
# 인터페이스 및 연계 설정 - 개발(DEV) 환경
vmis:
system:

@ -1,6 +1,22 @@
server:
port: 8080
# 로그 설정 - 운영(PRD) 환경
logging:
config: classpath:logback-spring.xml
file:
path: d:/data/VMIS-interface/logs
name: vmis-interface
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 90
level:
root: WARN
com.vmis.interfaceapp: INFO
org.springframework: WARN
org.springframework.web: INFO
# 인터페이스 및 연계 설정 - 운영(PRD) 환경
# 주의: 실제 운영 키/호스트는 배포 환경 변수나 외부 설정(Secret)로 주입 권장
vmis:

@ -8,48 +8,16 @@ spring:
server:
port: 8080
# 인터페이스 및 연계 설정 (공통 기본값)
vmis:
system:
infoSysId: "41-345" # INFO_SYS_ID
infoSysIp: "" # INFO_SYS_IP (예: 105.19.10.135)
# 예시: 경기도 용인시 수지구 장애인복지과
regionCode: "" # 시군구코드 (SIGUNGU_CODE, 예: 41460)
departmentCode: "" # 행정부서코드 필요 시 입력
# 담당자 기본값(미입력 시 빈 값)
chargerId: ""
chargerIp: ""
chargerNm: ""
gpki:
enabled: "Y" # Y 또는 N (환경별 yml에서 재정의 가능)
useSign: true
charset: "UTF-8"
certServerId: "SVR5640020001" # 이용기관 인증서 ID (ENV/SIG 공통 서버 ID)
targetServerId: "SVR1611000006" # 보유기관 인증서 ID(교통안전공단)
# 아래는 네이티브 GPKI 유틸(NewGpkiUtil) 설정값 (필요 시 사용)
ldap: true # LDAP 사용 여부 (true: LDAP에서 대상서버 인증서 조회)
gpkiLicPath: "C:/gpki2/gpkisecureweb/conf"
certFilePath: "C:/gpki2/gpkisecureweb/certs" # LDAP 미사용 시 대상서버 인증서 파일 폴더
envCertFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_env.cer"
envPrivateKeyFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_env.key"
envPrivateKeyPasswd: "change-me"
sigCertFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_sig.cer"
sigPrivateKeyFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_sig.key"
sigPrivateKeyPasswd: "change-me"
gov:
scheme: "http"
host: "localhost:18080" # 환경별 yml에서 재정의
basePath: "/piss/api/molit"
connectTimeoutMillis: 5000
readTimeoutMillis: 10000
services:
basic: # 시군구연계 자동차기본사항조회
path: "/SignguCarBassMatterInqireService"
cntcInfoCode: "AC1_FD11_01"
apiKey: "change-me"
cvmisApikey: "change-me"
ledger: # 시군구연계 자동차등록원부(갑)
path: "/SignguCarLedgerFrmbkService"
cntcInfoCode: "AC1_FD11_02"
apiKey: "change-me"
cvmisApikey: "change-me"
# 로그 설정
logging:
config: classpath:logback-spring.xml
file:
path: ./logs
name: vmis-interface
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 30
level:
root: INFO
com.vmis.interfaceapp: DEBUG

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 기본 로그 경로 및 파일명 설정 (application.yml에서 설정되지 않은 경우 사용) -->
<springProperty scope="context" name="LOG_PATH" source="logging.file.path" defaultValue="logs" />
<springProperty scope="context" name="LOG_FILE" source="logging.file.name" defaultValue="vmis-interface" />
<springProperty scope="context" name="MAX_FILE_SIZE" source="logging.logback.rollingpolicy.max-file-size" defaultValue="10MB" />
<springProperty scope="context" name="MAX_HISTORY" source="logging.logback.rollingpolicy.max-history" defaultValue="30" />
<!-- 로그 패턴 설정 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="LOG_CHARSET" value="UTF-8"/>
<!-- 콘솔 출력 설정 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
</appender>
<!-- 컬러 콘솔 출력 설정 (개발 환경용) -->
<appender name="CONSOLE_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] %cyan(%logger{36}) - %msg%n</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
</appender>
<!-- 파일 출력 설정 (전체 로그) -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE}.log</file>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 일별 로그 파일 생성 -->
<fileNamePattern>${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 파일당 최고 용량 -->
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<!-- 로그 보관 기간 -->
<maxHistory>${MAX_HISTORY}</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<!-- 전체 로그 파일의 최대 크기 -->
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 에러 로그 파일 출력 설정 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE}-error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE}-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 파일당 최고 용량 -->
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>90</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- 비동기 파일 출력 설정 (성능 향상) -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>false</includeCallerData>
<neverBlock>false</neverBlock>
</appender>
<!-- 비동기 에러 파일 출력 설정 -->
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ERROR_FILE" />
<queueSize>256</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>false</includeCallerData>
<neverBlock>false</neverBlock>
</appender>
<!-- 개발 환경 설정 -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE_COLOR" />
<appender-ref ref="ASYNC_FILE" />
<appender-ref ref="ASYNC_ERROR_FILE" />
</root>
<!-- 애플리케이션 로그 레벨 -->
<logger name="com.vmis.interfaceapp" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE_COLOR"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</logger>
<!-- Spring Framework 로그 -->
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.web" level="DEBUG"/>
</springProfile>
<!-- 운영 환경 설정 -->
<springProfile name="prd">
<root level="WARN">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
<appender-ref ref="ASYNC_ERROR_FILE" />
</root>
<!-- 애플리케이션 로그 레벨 -->
<logger name="com.vmis.interfaceapp" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</logger>
<!-- Spring Framework 로그 -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.web" level="INFO"/>
</springProfile>
<!-- 기본 설정 (프로파일 미지정 시) -->
<springProfile name="default">
<root level="INFO">
<appender-ref ref="CONSOLE_COLOR"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</root>
<logger name="com.vmis.interfaceapp" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE_COLOR"/>
<appender-ref ref="ASYNC_FILE"/>
<appender-ref ref="ASYNC_ERROR_FILE"/>
</logger>
<!-- Spring Framework 로그 -->
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.web" level="DEBUG"/>
</springProfile>
</configuration>
Loading…
Cancel
Save