설정방법

1. log4j.xml파일을 생성(수정)

Spring 으로 세팅하면 기본적으로 log4j를 포함하고 있기 때문에 별도 생성할 필요는 없지만 혹시 없다면 log4j.xml 파일을 생성해야 한다.

Path : src/main/resources/log4j.xml

 

1.log4j.xml 구성

Appender, logger, root 로 구성되어있는 걸로 보인다.

 

Appender는 로그를 찍을 대상이나 어떤 방식으로 찍을 지를 결정하는 설정으로 보인다.

기본 설정값은 console에 찍는 방식으로 되어있고 PatternLayout 클래스를 사용해서 Layout을 잡는다.

 

logger는 Application Loggers라고 주석이 달린 것처럼 package와 같이 영역을 지정하고 해당 영역에서 사용할 logger를 정의하는 태그로 보인다.

하위 파라미터로 level을 받아서 출력할 로그수준을 정한다.

appender-ref 태그를 사용하여 ref 값에 참조할 appender를 입력하여 출력방식을 정할 수 있다.

 

root는 default라고 생각하면 되는 것 같다. 설정하지 않은 logger에 대해서만 root logger를 출력하게 한다. 구성요소는 logger와 유사하다.

**같은 로그가 두번 찍힌다면 Additivity 속성에 대해 확인

 

 

2.설정 파일 기본값

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="kr.co.ohjooyeo">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
			
</log4j:configuration>

 

사용방법

사용할 클래스에 private static final 로거 변수 선언 이렇게 선언을 하면 xml에서 해당 어플리케이션(패키지)의 로거를 생성

1. 선언

Logger의 name을 패키지로 잡았을 경우, 패키지내의 클래스명.class를 파리미터로 선언

private static final Logger logger = LoggerFactory.getLogger(선언한 클래스명.class);

 

Logger의 name을 변수명으로 잡았을 경우, logger의 이름(문자열)을 파리미터로 선언

private static final Logger logger = LoggerFactory.getLogger("test");
<!-- Application Loggers --> <logger name="test"> <level value="info" /> </logger>

Log4j의 구조

1. Logger

  • 로그의 주체 : 로그 파일을 작성하는 클래스
  • 로그레벨을 가짐 (로그문의 레벨과 로거 레벨를 비교하여 로그의 출력여부를 결정)
  • 출력할 메시지를 Appender에 전달

2.Appender

  • 전달된 로그를 어디에 출력할지 결정 ( 콘솔 / 파일 / DB 등)
    • Appender 종류
      • WriterAppender :
        Writer 객체에 로그를 남기는 Appender
      • ConsoleAppender :
        System.out, System.err에 로그를 남기는 Appender

        - 옵션
        Target : System.out / System.err
        Follow : true -> SystemOutStream 에 저장
        activeOption : appender를 활성화

      • FileAppender :
        파일에 로그를 남기는 Appender

        - 옵션
        File : 파일명 Append : 추가 모드 여부 (true/false)
        BufferedIO : 버퍼 사용 여부 (true/false)
        BufferSize : 버퍼 사이즈

        --??--
        Threshold : (AppenderSkelton으로부터 계승)
        ImmediateFlush : (WriteAppender로부터 계승)
        Encoding : (WriteAppender로부터 계승)

      • RollingFileAppender :
        크기에 따라 File명을 변환하며 로그를 남기는 Appender

        - 옵션
        MaxFileSize : 최대 파일 사이즈
        MaxBackupIndex : 로그를 최대 개수
        File, Append, BufferdIO, BufferSize, Threshold, ImmediateFlush, Encoding

      • DailyRollingFileAppender :
        날짜에 따라 File명을 변환하며 로그를 남기는 Appender

        - 옵션 DatePattern : 날짜 형식(yyyy-MM, yyyy-ww,yyyy-MM-dd, yyyy-MM-dd-a, yyyy-MM-dd-HH 등등)

      • RollingFileAppender : 크기에 따라 File명을 변환하며 로그를 남기는 Appender
      • AsyncAppender : Logging Event 발생시 Thread를 생성하여 로그를 남기는 Appender

        -옵션
        triggeringPolicy : 로그 트리거 옵션
        rollingPolicy : 로그 정책 옵션
        org.apache.log4j.rolling.TimeBasedRollingPolicy : 시간 베이스 org.apache.log4j.rolling.SizeBasedTriggeringPolicy : 사이즈 베이스org.apache.log4j.rolling.FilterBasedTriggeringPolicy : 필터 베이스org.apache.log4j.rolling.FixedWindowRollingPolicy : 인덱스 베이스 백업 파일
      • SMTPAppender :
        로그를 이메일로 전달하는 Appender

출처: <https://m.blog.naver.com/PostView.nhn?blogId=youngchanmm&logNo=221029597791&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F>

 

 

3. Layout

  • 어떤 형식으로 출력할지 결정
  • Layout 종류
    • DateLayout
    • HTMLLayout
    • PatternLayout (일반적으로 사용)
      • PatternLayout (org.apache.log4j.PatternLayout) 상세 설명
        • C : 클래스명을 출력
          설정을 추가하여 클래스 이름 또는 특정 패키지 이상만 출력하도록 설정 가능

          - 추가 설정 -
          m : 로그로 전달된 메시지를 출력한다.
          M : 로그를 수행한 메소드명을 출력한다.
          n : 줄 바꿈
          p : 로그 이벤트명 (DEBUG등)
          r : 로그 처리시간 (milliseconds)

        • d : 로그 시간을 출력한다. java.text.SimpleDateFormat에서 적절한 출력 포맷을 지정할 수 있다.
        • F : 파일 이름을 출력한다. 로그 시 수행한 메소드, 라인번호가 함께 출력된다.
        • l (location) : 로깅 이벤트가 발생한 클래스의 풀네임.메서드명(파일명:라인번호) 출력
        • L : 라인 번호만 출력
        • m : 로그로 전달된 메시지 출력
        • M : 로그를 수행한 메소드명 출력
        • n : 줄바꿈
        • p : 로그 이벤트명 (레벨명)
        • r : 로그 처리시간 (milliseconds)
        • T : 로깅 이벤트가 발생한 스레드명

          출처: <https://androphil.tistory.com/420>
      • SimpleLayout
      • XMLLayout

 

 

Log4j 란?
log4j는 프로그램을 작성하는 도중에 로그를 남기기 위해 사용되는 자바기반 로깅 유틸리티이다. 디버그용 도구로 주로 사용되고 있다.
log4j의 최근 버전에 의하면 높은 등급에서 낮은 등급으로의 6개 로그 레벨을 가지고 있다. 설정 파일에 대상별(자바에서는 패키지)로 레벨을 지정이 가능하고 그 등급 이상의 로그만 저장하는 방식이다.
1. 목적
System.out.println() 을 사용하여 로그를 확인할 경우 사용하지 않게 되면 일일이 주석처리를 해야 한다.
로그의 레벨이나 로그문의 레벨에 따라서 로그를 유연하게 출력하여 불필요한 업무를 줄이고 성능을 최적화 할 수 있다.
(그대로 둔다면 프로그램 성능에 영향을 미칠 수 있다.)
2. 종류
6개의 레벨로 구성됨
1.
FATAL : 아주 심각한 에러가 발생한 상태를 나타낸다.
2.
ERROR : 어떠한 요청을 처리하는 중 문제가 발생한 상태를 나타낸다.
3.
WARN : 프로그램의 실행에는 문제가 없지만, 향후 시스템 에러의 원인이 될 수 있는 경고성 메시지를 나타낸다.
4.
INFO : 어떠한 상태변경과 같은 정보성 메시지를 나타낸다.
5.
DEBUG : 개발 시 디버그 용도로 사용하는 메시지를 나타낸다.
6.
TRACE : 디버그 레벨이 너무 광범위한 것을 해결하기 위해서 좀 더 상세한 이벤트를 나타낸다.

문제:  https://www.acmicpc.net/problem/15683



시험에서는 참조값 초기화에서 버벅거려서 DFS까지 다 구현해놓고 에러를 찾다가 제시간에 제출하지 못했다 ....또륵.,.

소 잃고 외양간이라도 고쳐본다...


백준 사이트에 올린 소스코드에는 주석이 달려있으니 코드보고 이해가 안간다면 주석을 풀어가면서 실행해보면 이해가 빠를 거에요!



백준 사이트에 제출한 소스 코드 : https://www.acmicpc.net/source/8390315


 import java.util.LinkedList;
import java.util.Scanner;

public class Main {
    
    static LinkedList cctv = new LinkedList<>();
    static int min;
    static int col;
    static int row;
    static int [][] map;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
            col = scan.nextInt();
            row = scan.nextInt();
            min = col * row;
            map = new int[col][row]; 
            boolean [][] chk_map = new boolean[col][row];
            
            for(int i = 0 ; i < col ; i++) {
                for(int j = 0 ; j < row; j ++) {
                    map[i][j] = scan.nextInt();
                    if(map[i][j] > 0 && map[i][j] < 6) {
                        cctv.add(new Node(map[i][j],i,j));
                    }
                    if(map[i][j] ==6){
                        chk_map[i][j] = true;
                    }
                }
            }
            search(0,chk_map);
            System.out.println(min);
        scan.close();
    }
    
    public static void search(int start, boolean[][] arr) {
        
        boolean[][] resArr = new boolean[col][row];
       
        if (start >= cctv.size() ) {
            int count = count(arr);
            if(min > count) {
                min = count;
            }
            return ;
        }
        
        Node n = cctv.get(start);
        
        switch (n.value) {
        case 1: 
//            System.out.println("type : " + n.value);
            for(int i =  0; i < 4; i++) {

                for(int z = 0 ; z < col ; z++) {
                    for( int j = 0 ; j = 0 ; i--) {
                if(map[i][node.row] == 6) {
                    break;
                }
                    arr[i][node.row] = true;
            }
            
            break;
        case 1 : 
//            System.out.println("하");
            for(int i = node.col ; i < col ; i++) {
                if(map[i][node.row] == 6) {
                    break;
                }
                    arr[i][node.row] = true;
            }

            break;
        case 2 : 
//            System.out.println("좌");
            for(int i = node.row ; i >= 0 ; i--) {
                if(map[node.col][i] == 6) {
                    break;
                }
                    arr[node.col][i] = true;
            }
            break;
            
        case 3 : 
//            System.out.println("우");
            for(int i = node.row ; i < row; i++) {
                if(map[node.col][i] == 6) {
                    break;
                }
                    arr[node.col][i] = true;
            }
            
            break;
        }
        return arr;
    }
    
    static class Node {
        int value;
        int col;
        int row;
        public Node(int v, int c, int r) {
            value = v ;
            col = c;
            row = r;
        }
    }
}

문제 : https://www.acmicpc.net/problem/2606



import java.util.Scanner;

public class Main {
    static int vCnt;
    static int pair_cnt;
    
    static int [][] vMap;
    static int [] chkVisited;
    
    static int count;
    
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        vCnt = scan.nextInt();
        pair_cnt = scan.nextInt();
        
        vMap = new int[vCnt+1][vCnt+1];
        chkVisited = new int [vCnt+1];
        count = 0;
        //인접행렬 만들기
        for (int i = 0; i < pair_cnt; i++) {
            int a = scan.nextInt();
            int b = scan.nextInt();
            
            vMap[a][b] = vMap[b][a] =1 ;
            
        }
        
/*        for (int i = 0; i < vMap.length ; i++) {
            for (int j = 0 ; j < vMap[i].length ; j++) {
                System.out.print(vMap[i][j]);
            }
            System.out.println();
        }*/
        
        dfs(1);
        System.out.println(count);
    }
    
    public static void dfs (int start) {
        chkVisited[start] = 1;
        
        for(int i = 1 ; i < chkVisited.length ; i ++) {
            if(vMap[start][i] == 1 && chkVisited[i] == 0) {
//                System.out.println(start +"->"+ i);
                count ++;
                dfs(i);
            }
        }
    }
}

문제 : https://www.acmicpc.net/problem/9012


import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int repeat = Integer.parseInt(scan.next());
        for (int j = 0; j < repeat; j++) {

            String input = scan.next();
            String res = "YES";
            Stack st = new Stack<>();
            for (int i = 0; i < input.length(); i++) {
                if (input.charAt(i) == '(') {
                    st.push(1);
                } else if (input.charAt(i) == ')') {
                    if (st.isEmpty()) {
                        res = "NO";
                        break;
                    } else {
                        st.pop();
                    }
                }

            }
            if(!st.isEmpty()) {
                res = "NO";
            }
            System.out.println(res);
        }


    }
}

문제 : https://www.acmicpc.net/problem/10828


import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new  Scanner(System.in);
        InnerStack s = new InnerStack();
        int input = Integer.parseInt(scan.next());
        
        for(int i = 0 ; i < input ; i++) {
            String str = scan.next();
            if("push".equals(str)) {
                int num = Integer.parseInt(scan.next());    
                s.push(num);
            }else if("pop".equals(str)) {
                System.out.println(s.pop());
            }else if("size".equals(str)) {
                System.out.println(s.size());
            }else if("empty".equals(str)) {
                System.out.println(s.isEmpty());
            }else if("top".equals(str)) {
                System.out.println(s.top());
            }    
            
        }
    }
    
    public static class InnerStack {
        InnerStack(){
        }
        List list = new LinkedList<>();
        private int cursor = 0 ;
    
        public void push(int i ) {
            list.add(i);
            cursor++;
        }
        
        public int pop() {
            int res;
            
            if(cursor > 0) {
                res=list.get(cursor-1);
                list.remove(cursor-1);
                cursor--;
            }else {
                res = -1;
            }
            
            return res;
        }
        
        public int top() {
            int res;
            if(cursor > 0) {
                res=list.get(cursor-1);
            }else {
                res = -1;
            }
            return res;
        }
        
        public int size() {
            return cursor;
        }
        
        public int isEmpty() {
            int res;
            if (cursor ==0) {
                res = 1;
            }else {
                res = 0;
            }
            return res;
        }
        
    }
}

문제 : https://www.acmicpc.net/problem/2750


import java.util.Scanner;

public class Main {
    static int[] bubleSort(int[] array) {
        int[] result = new int[array.length];
            for(int i = array.length ; i > 1 ; i -- ) {
                for(int j = 0 ; j < i-1 ; j++ ) {
                    if(array[j]>array[j+1]) {
                        int temp = array[j+1];
                        array[j+1] = array[j];
                        array[j] = temp;
                    }
                    
                }
            }
        result = array;
        return result;
    }
    
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int count = 0;
        int num = scan.nextInt();
        int[] arr = new int[num];
        for (int i = 0; i < num; i++) {
            arr[count] = scan.nextInt();
            count++;
        }
        // int[] arr = {5,3,4,7,6,2,1};
        for (int a : bubleSort(arr)) {
            System.out.println(a);
        }

        scan.close();
    }
}

문제 : https://www.acmicpc.net/problem/2750


import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		int count = 0;
		int num = scan.nextInt();
		int[] arr = new int[num];
		for (int i = 0 ; i< num ; i++){
			arr[count] = scan.nextInt();
			// System.out.println(arr[count]);
			count++;
		}
		// int[] arr = {5,3,4,7,6,2,1};
		for (int i = 1; i < arr.length; i++) {
			int a = i - 1;
			int std = arr[i];
			while (a >= 0 && std < arr[a]) {
				arr[a + 1] = arr[a];
				a = a - 1;

			}
			arr[a + 1] = std;
		}

		for (int a : arr) {
			System.out.println(a);
		}
		scan.close();
	}
}

문제 : https://www.acmicpc.net/problem/2748


간단하게 구현할 수 있는 피보나치 수열에 동적계획법을 적용해봤다.

배열을 만들어서 피보나치 메소드에 배열의 위치를 알려주어 한번 계산한 피보나치수는 다시 계산하지 않도록 만들었다.


import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		//피보나치
		
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		long [] arr = new long [n+1];
		for( int i = 0 ; i < arr.length; i ++) {
			arr[i] = -1;
		}
		System.out.println(fi(n, arr));
//		for(int a : arr) {
//			System.out.print(a+" ");
//		}
		scan.close();
	}
	static long fi(int num,long [] arr) {
		if(arr[num] != -1) {
			return arr[num];
		}
		if (num == 0 || num == 1) {
			arr[num] = num;
			return num;
		} else {
			long result = fi(num-1,arr) + fi(num-2,arr);
			arr[num] = result;
			return result;
		}
	}

}

+ Recent posts

"여기"를 클릭하면 광고 제거.