__defineGetter__ 사용하기
MDN에 따르면 __defineGetter__는 표준도 아니고 폐기된 API이지만 현재 Node.js에서 사용할 수 있다.(즉, 아직 V8이 지원한다.) 이 특이한 이름의 __defineGetter__는 객체의 프로퍼티를 함수에 바인딩해서 해당 프로퍼티가 조회될 때 바인딩된 함수가 호출되도록 하는데 stdout, stderr를 가로채는 방법을 검색하다 보면 이 방법이 많이 나온다.
fs = require('fs');
console.log('first log message');
console.error('first error message');
var oldStdout = process.stdout,
oldStderr = process.stderr,
newStdout = fs.createWriteStream('log.log', {flags: 'a'}),
newStderr = fs.createWriteStream('err.log', {flags: 'a'});
// stdout, stderr 가로챔
process.__defineGetter__('stdout', function() {
return newStdout;
});
process.__defineGetter__('stderr', function() {
return newStderr;
});
console.log('second log message');
console.error('second error message');
// stdout, stderr 복구
process.__defineGetter__('stdout', function() {
return oldStdout;
});
process.__defineGetter__('stderr', function() {
return oldStderr;
});
console.log('third log message');
console.error('third error message');
앞부분에서 console.log와 console.error로 메시지를 출력하고 __defineGetter__를 이용해서 process 객체의 stdout과 stderr 프로퍼티에 새로운 함수를 바인딩했고 이 함수에서는 위에서 생성한 파일스트림을 각각 리턴하도록 했다. 그리고 마지막에서는 원래의 stdout, stderr로 다시 복구해 주었다.
$ node example.js
first log message
first error message
??third log message
third error message
$ cat log.log
second log message
$ cat err.log
second error message
위의 실행결과에서 보듯이 앞부분에서 출력한 메시지는 js파일 실행시 그대로 출력되었지만 stdout, stderr을 가로챈 뒤에 실행한 뒤에 출력한 console.log과 console.err는 터미널에 출력되는 대신 각각 파일에 출력되었다.
write 함수 오버라이드하기
__defineGetter__를 이용한 방법도 잘 동작하지만 표준이 아닌 __defineGetter__를 사용하는 부분이 약간 찝찝하다. stdout과 stderr 에는 실제 메시지를 출력하는 write 함수가 있는데 이 함수가 실제로 메시지를 출력하는 함수이므로 이 함수를 통째로 가로챌 수 있다.
var fs = require('fs');
console.log('first log message');
console.error('first error message');
var oldStdoutWrite = process.stdout.write,
oldStderrWrite = process.stderr.write;
// stdout, stderr 가로챔
process.stdout.write = function(str, encoding, fg) {
fs.appendFile('log.log', str, function(err) {});
}
process.stderr.write = function(str, encoding, fg) {
fs.appendFile('err.log', str, function(err) {});
}
console.log('second log message');
console.error('second error message');
// stdout, stderr 복구
process.stdout.write = oldStdoutWrite;
process.stderr.write = oldStderrWrite;
console.log('third log message');
console.error('third error message');
앞에서 보았던 과정과 비슷하다. 달라진 점은 stdout과 stderr의 write함수를 백업한 뒤에 새로운 함수로 덮어쓰고 나중에 원래의 write함수로 복구해 준 것이다. write함수가 스트림이 아니라서 여기서는 pipe대신에 그냥 문자열을 받아서 파일에 쓰도록 했다.
$ node test2.js
first log message
first error message
third log message
third error message
$ cat log.log
second log message
$ cat err.log
second error message
물론 결과는 앞에와 동일하다.
Outsider님, 생뚱맞은 질문이 있는데요,
포스팅 본문에 주요 키워드들 (stdout, stderr 등...)에만 오렌지색 컬러를 예쁘게 입히셨는데, 저걸 다 수작업으로 하시진 않으셨을 것 같고..
어떤 식으로 컬러링 하신건지 여쭤봐도 될까요?
그리고 아마도 맥에서 포스팅 하셨을 것 같은데.. 포스팅에 사용하시는 별도 툴 같은게 있으시면 그것도 여쭤보고 싶어요~ 알려주세요~
실망시켜드려 죄송하지만 수작업입니다. ㅠㅠ
아주 오래전에는 블로그툴을 찾아본적도 있지만 그닥 맘에 드는게 없어서 그냥 웹에디터에서 주로 작성합니다. 긴 글은 그냥 에디터 혹은 마크다운 에디터에서 내용만 작성후에 블로그에 가져와서 스타일을 적용합니다.
개인적인 마음으로는 마크다운으로 작성하고 자동으로 스타일입히고 싶지만 과거글들도 있고 시간도 여의치 않아서 쉽사리 손을 못대고 있습니다.
와... 엄청난 정성입니다 ㅜㅜ)b
오늘 하늘도 울고 outsider님도 울고 저도 우는군요..ㅜㅜ
좀 귀찮기는 한데 또 습관되서 괜찮습니다. ㅎㅎ