Application log 압축해서 다운 받아보자.

안녕하세요. 오늘도 열심히 일을 하는 초보 개발자 입니다. 솔루션이 아직 미흡해서 로그 관리 하기가 쉽지가 않습니다. 담당자에게 로그 파일을 요청을 하려면 원격 데스크톱 연결을 해서 파일을 복사해서 압축해서 메일로 보내달라고 해야 하는데 원격 데스크톱에 수시로 접속하는 저희 개발자들이야 쉽게 할 수 있지만 일반인 분들은 “얘네들이 무슨 소리를 하는 건가…“ 라는 표정을 보여주십니다. 그래서 조금 이라도 쉽게 하기 위해서 로그를 압축해서 관리자 PC로 다운 받을 수 있게 하면 좋겠다 라는 생각을 했습니다.

  1. 로그 디렉토리 경로를 구한다.
  2. 로그 파일을 압축한다.
  3. 압축 파일을 관리자 PC 에 다운 받게 한다.

로직은 위와 같은 순서로 생각을 했습니다. 

 


 

로직 처리

  1. 디렉토리 경로를 구하는 것은 생각보다 쉽지 않았습니다. 구글에서 검색해본 결과 보안 때문에 파일 선택에서 디렉토리 설정하는 것은 막혀 있다고 합니다. 그래도 하려면 ActiveX를 사용해서 해야 한다고 하는데 그렇게 까지는 하고 싶지 않습니다..
  2. 로그 파일 압축은 Java의 ZipOuputStream 을 사용해서 하려고 했습니다. 문제점은 저희 로그 파일이야 2 Depth 밖에 되지 않지만 만약 Depth 가 아주 높거나 하면 문제가 되는 겁니다. 그래서 Depth 가 크면 같은 로직으로 처리 되는 Recursion 을 사용해보자는 생각이 들었습니다. 그래서 “Java Directory Recursion” 구글링을 시작했습니다. 많은 분들이 저와 같은 생각을 하고 계신 것을 느꼈습니다. 그 중 하나를 찾아서 테스트 했습니다.
  3. 압축 파일을 관리자 PC에 다운 받게 하는 방법은 JSP 파일 다운로드 하는 방법을 참조 했습니다. response.setContentType 설정에 ‘application x-zip compressed’를 사용해서 다운을 받을 수 있게 해봤습니다.

 

Source Code

FileRecurser.java

import java.io.File;
import java.io.FilenameFilter;
import java.util.Collection;
import java.util.Vector;

/**
* 디렉토리에서 파일 목록을 구하는 클래스
* 참조 : {@link http://snippets.dzone.com/posts/show/1875}
*
*/
public class FileRecurser {

/**
* 디렉토리에서 파일 목록을 리턴한다.
* @param directory 탐색 경로
* @param filter
* @param recurse
* @return array of File
*/
public static File[] listFilesAsArray(File directory, FilenameFilter filter, int recurse) {
// 재귀 호출을 시작한다.
Collection files = listFiles(directory, filter, recurse);
File[] arr = new File[files.size()];
return files.toArray(arr);
}

/**
* 해당하는 디렉토리에서 파일만 저장하는 객체를 리턴한다.
* @param directory
* @param filter
* @param recurse
* @return Vector
*/
private static Collection listFiles(File directory,
FilenameFilter filter, int recurse) {
// 해당 디렉토리에 있는 파일 목록을 저장하는 객체
Vector files = new Vector();
// 모든 파일과 디렉토리 목록을 꺼낸다.
File[] entries = directory.listFiles();
// 목록이 없다면 종료.
if(entries != null) {
for (File entry : entries) {
// 필터와 파일명에 '.log' 를 포함한다면 파일 목록 객체에 넣는다.
if(filter == null || filter.accept(directory, entry.getName())) {
files.add(entry);
}

/*
* 재귀를 한다.
* 해당 디렉토리에 파일이 없을때까지 반복한다.
*/
if((recurse 0 && entry.isDirectory())) {
recurse--;
files.addAll(listFiles(entry, filter, recurse));
recurse++;
}
}
}
return files;
}

}

Controller.downloadLogFile

/**
* 로그 파일을 다운 받는다.
* @param request
* @param response
*/
public void downloadLogFile(HttpServletRequest request, HttpServletResponse response) {

// Buffer 사이즈를 설정한다.
byte[] buffer = new byte[4096];

// 파일 이름용 시간 포맷을 구한다.
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmss");
ServletContext ctx = request.getSession().getServletContext();
String path = ctx.getRealPath("/WEB-INF/upload") + File.separator;

// 파일 명을 설정한다.

String fileName = path + formatter.format(new Date())+"_uc.zip";

try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(fileName));
File logDir = new File("D:\\cafe\\logs");
// 필터를 설정한다.
FilenameFilter logFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
// 파일명에 .log 가 포함되면 log파일이다.
return name.contains(".log");
}
};
FileRecurser fr = new FileRecurser();
// 파일 목록을 구한다.
File[] logFiles = fr.listFilesAsArray(logDir, logFilter, -1);
for (File file : logFiles) {
FileInputStream fis = new FileInputStream(file);
out.putNextEntry(new ZipEntry(file.getName()));
int len = 0;
while((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
fis.close();
}
out.close();

} catch (FileNotFoundException e) {
logger.warn("디렉토리를 찾을 수 없습니다.", e);
} catch (Exception e) {
logger.warn("예외 발생", e);
}
// ZIP 파일 다운로드 설정을 한다.
response.setContentType("application/x-zip-compressed; charset=utf-8");
response.setHeader("Content-Disposition", "inline; filename="+new File(fileName).getName());

try {
OutputStream out = response.getOutputStream();
InputStream in = new FileInputStream(new File(fileName));
byte[] buf = new byte[4096];
int read = in.read(buffer);
while (read != -1) {
out.write(buffer, 0, read);
read = in.read(buffer);
}
} catch (FileNotFoundException e) {
logger.warn("파일을 찾을 수 없습니다.",e);
} catch (Exception e) {
logger.warn("예외가 발생 했습니다.", e);
}
}// downloadLogFile

ContentType 설정을 통해서 다운 받을 수 있게 한다. 위와 같은 생각을 하게 된 것은 텍스트 파일의 경우에는 압축하면 용량이 많이 줄어서 대용량 메일이 아니더라도 보낼 수 있기 때문에 생각하게 되었습니다.파일을 첨부 하려고 했는데 첨부가 안되네요.

 


참고

  1. Recursion 을 사용한 파일 탐색
  2. While을 사용한 파일 탐색
  3. Zip 파일을 사용한 로그 압축하기
  4. JSP 파일 다운로드

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s