프로젝트

[LOG] Logback 로그관리

sian han 2022. 10. 22. 20:17

 

팀프로젝트 당시 '투데이 수 집계' 기능 구현을 담당했었다.

일별로 사이트 접속자 수를 파악하여 DB에 넣는 기능을 만들어야 했다.

 

이를 구현하기 위해 Logback 라이브러리를 사용하여 접속자 수를 파악하고

DB에 INSERT 하는 코드를 만들어서

요일별 방문자 수 집계를 자동화했었다. 

 

자바의 컬렉션을 적절하게 사용했던 예제라고 생각되어 정리해본다.

 

코드를 설명하자면

 


 

	 @Scheduled(cron = "0 0 0 * * *")
	    public void readLogFile () throws IOException {

일별 접속자 정보가 들어있는 로그파일을 읽어 DB에 INSERT 하는 기능을 가진

readLogFile() 은 매일 자정에 실행된다

 

 

String basePath = "C:\\logs\\accesslog\\accesslog-";

	    	Date d = new Date();
	        d = new Date(d.getTime()+(1000*60*60*24*-1));
	        SimpleDateFormat yesterday = new SimpleDateFormat("yyyy-MM-dd");

파일이 저장된 경로를 구하고

Date 객체 생성 후 Format 된 어제 날짜를 구한다

 

 

String filePath = basePath+ yesterday.format(d)+".0.log";
List<String> list = Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8);
System.out.println(list);

경로 + 날짜 + 0.log (파일 형식) 으로 구성된 파일 경로를 filePath 변수에 저장한다

어제 날짜의 로그파일 읽어들여 List 에 저장한다.

 

컬렉션 중 하나인 ArrayList 는 데이터의 중복을 허용하는 특징이 있다.

사이트 접속자 수 집계를 위해서는 중복접속한 유저는 제외되어야 하는데, List 의 특성때문에

현재 list 객체에는 중복접속로그까지 포함있는 것이다.

 

중복접속 로그들은 지워버리기 위해 HashSet 을 이용한다.

HashSet 은 중복저장되지 않는다는 특징을 갖고있다. 

HashSet<String>set = new HashSet<>();
	        
	        for(int i = 0; i<list.size(); i++) {
	        	String[] temp = list.get(i).split("[=]");
	        	System.out.println(temp[0]+","+temp[1]);
	        	set.add(temp[1]);
	        }
	        System.out.println("최종 = "+set);

이렇게 list 객체 안의 값을 set 으로 넣어 중복을 제거해준다.

위 단계에서 set으로 바로 데이터를 받으면 list에서 set 으로 옮기는 과정은 생략할 수 있지 않느냐 ? 물을수도있는데

바로 set 으로 받는건 안되더라

 

 

int cnt =0;
Iterator<String> iter = set.iterator();
    while(iter.hasNext()) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("usersNo",iter.next());
        map.put("date", date);

        cnt = userService.insertToday(map);
        }

iterator() 메서드로 iterator 인터페이스를 가져올 수 있는데,

hashset 의 데이터를 iterator 에 담았다고 생각하면 된다.

 

Iterator 는 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스이다. Set에는 순서가 없으니 for 문을 이용해서는 데이터를 출력할 수 없다. 

 

HashMap 은 키는 중복을 허용하지 않으며, 값은 중복을 허용한다는 특징을 가지고 있다.

 

map 에 사용자번호(userNo)와 date(날짜) 를 담아 insert 쿼리를 실행시킨다.

iter 객체의 데이터 수만큼 쿼리가 날라가는 것이다.

 

 

▽ 전체코드

 

public class LogScheduler { 
	
	private final UserService userService;

	 @Scheduled(cron = "0 0 0 * * *") //매일자정
	    public void readLogFile () throws IOException {
        
		 	String basePath = "C:\\logs\\accesslog\\accesslog-"; // 파일 저장경로
            
	    	Date d = new Date(); 
	        d = new Date(d.getTime()+(1000*60*60*24*-1)); //어제날짜
	        SimpleDateFormat yesterday = new SimpleDateFormat("yyyy-MM-dd");
	        
	        //accesslog 파일 찾아서 => 파일 정보 읽어서 => list에 저장
	        String filePath = basePath+ yesterday.format(d)+".0.log";
	        List<String> list = Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8); //어제 날짜의 로그파일 읽어들임
	        System.out.println(list);
	        
	        //중복데이터 제거를 위해 LIST에 담긴 정보를 HashSet에 담는다
	        HashSet<String>set = new HashSet<>();
	        
	        for(int i = 0; i<list.size(); i++) {
	        	String[] temp = list.get(i).split("[=]");
	        	System.out.println(temp[0]+","+temp[1]);
	        	set.add(temp[1]);
	        }
            
	        System.out.println("최종 = "+set); 
	        
	        //today format
	        Date today = new Date();
        	String date = yesterday.format(today);
        	System.out.println("date = "+date);
	        
        	//HashSet size 만큼 insert 쿼리 실행
        	int cnt =0;
	        Iterator<String> iter = set.iterator();
	        while(iter.hasNext()) {
	        	Map<String, Object> map = new HashMap<String, Object>();
	        	map.put("usersNo",iter.next());
	        	map.put("date", date);

	        	cnt = userService.insertToday(map);
	        }
	    }
}