[javascript] 올바른 줄 번호를 가진 console.log에 적합한 래퍼?

현재 응용 프로그램을 개발 중이며 전역 isDebug스위치를 배치하고 있습니다. console.log더 편리한 사용법 을 위해 포장 하고 싶습니다 .

//isDebug controls the entire site.
var isDebug = true;

//debug.js
function debug(msg, level){
    var Global = this;
    if(!(Global.isDebug && Global.console && Global.console.log)){
        return;
    }
    level = level||'info';
    Global.console.log(level + ': '+ msg);
}

//main.js
debug('Here is a msg.');

그런 다음 Firefox 콘솔 에서이 결과를 얻습니다.

info: Here is a msg.                       debug.js (line 8)

debug()호출 되는 곳의 줄 번호로 로그인하려면 어떻게해야합니까?info: Here is a msg. main.js (line 2) 받았 합니까?



답변

이것은 오래된 질문이며 제공된 모든 답변은 지나치게 많은 해키이며 MAJOR 교차 브라우저 문제가 있으며 매우 유용한 것은 없습니다. 이 솔루션은 모든 브라우저에서 작동하며 모든 콘솔 데이터를 정확하게보고합니다. 아니 해킹이 필요없고, 한 줄의 코드는 codepen 확인하세요 .

var debug = console.log.bind(window.console)

다음과 같이 스위치를 작성하십시오.

isDebug = true // toggle this to turn on / off for global controll

if (isDebug) var debug = console.log.bind(window.console)
else var debug = function(){}

그런 다음 다음과 같이 간단히 전화하십시오.

debug('This is happening.')

다음과 같은 스위치로 console.log를 대신 할 수도 있습니다.

if (!isDebug) console.log = function(){}

이것으로 유용한 것을 원한다면. 모든 콘솔 메소드를 추가하고 전역 제어뿐만 아니라 클래스 레벨을 제공하는 재사용 가능한 함수로 묶을 수 있습니다.

var Debugger = function(gState, klass) {

  this.debug = {}

  if (gState && klass.isDebug) {
    for (var m in console)
      if (typeof console[m] == 'function')
        this.debug[m] = console[m].bind(window.console, klass.toString()+": ")
  }else{
    for (var m in console)
      if (typeof console[m] == 'function')
        this.debug[m] = function(){}
  }
  return this.debug
}

isDebug = true //global debug state

debug = Debugger(isDebug, this)

debug.log('Hello log!')
debug.trace('Hello trace!')

이제 클래스에 추가 할 수 있습니다.

var MyClass = function() {
  this.isDebug = true //local state
  this.debug = Debugger(isDebug, this)
  this.debug.warn('It works in classses')
}


답변

@fredrik의 대답이 마음에 들었 으므로 Webkit stacktrace를 분할하는 다른 대답으로 롤업하여 @PaulIrish의 safe console.log wrapper 와 병합했습니다 . 을 ” filename:line특수 객체”로 “표준화”하여 눈에 띄고 FF와 Chrome에서 거의 동일하게 보입니다.

바이올린 테스트 : http://jsfiddle.net/drzaus/pWe6W/

_log = (function (undefined) {
    var Log = Error; // does this do anything?  proper inheritance...?
    Log.prototype.write = function (args) {
        /// <summary>
        /// Paulirish-like console.log wrapper.  Includes stack trace via @fredrik SO suggestion (see remarks for sources).
        /// </summary>
        /// <param name="args" type="Array">list of details to log, as provided by `arguments`</param>
        /// <remarks>Includes line numbers by calling Error object -- see
        /// * http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
        /// * /programming/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
        /// * https://stackoverflow.com/a/3806596/1037948
        /// </remarks>

        // via @fredrik SO trace suggestion; wrapping in special construct so it stands out
        var suffix = {
            "@": (this.lineNumber
                    ? this.fileName + ':' + this.lineNumber + ":1" // add arbitrary column value for chrome linking
                    : extractLineNumberFromStack(this.stack)
            )
        };

        args = args.concat([suffix]);
        // via @paulirish console wrapper
        if (console && console.log) {
            if (console.log.apply) { console.log.apply(console, args); } else { console.log(args); } // nicer display in some browsers
        }
    };
    var extractLineNumberFromStack = function (stack) {
        /// <summary>
        /// Get the line/filename detail from a Webkit stack trace.  See https://stackoverflow.com/a/3806596/1037948
        /// </summary>
        /// <param name="stack" type="String">the stack string</param>

        if(!stack) return '?'; // fix undefined issue reported by @sigod

        // correct line number according to how Log().write implemented
        var line = stack.split('\n')[2];
        // fix for various display text
        line = (line.indexOf(' (') >= 0
            ? line.split(' (')[1].substring(0, line.length - 1)
            : line.split('at ')[1]
            );
        return line;
    };

    return function (params) {
        /// <summary>
        /// Paulirish-like console.log wrapper
        /// </summary>
        /// <param name="params" type="[...]">list your logging parameters</param>

        // only if explicitly true somewhere
        if (typeof DEBUGMODE === typeof undefined || !DEBUGMODE) return;

        // call handler extension which provides stack trace
        Log().write(Array.prototype.slice.call(arguments, 0)); // turn into proper array
    };//--  fn  returned

})();//--- _log

이것은 노드에서도 작동하며 다음을 사용하여 테스트 할 수 있습니다.

// no debug mode
_log('this should not appear');

// turn it on
DEBUGMODE = true;

_log('you should', 'see this', {a:1, b:2, c:3});
console.log('--- regular log ---');
_log('you should', 'also see this', {a:4, b:8, c:16});

// turn it off
DEBUGMODE = false;

_log('disabled, should not appear');
console.log('--- regular log2 ---');


답변

당신은 행 번호를 유지할 수 있습니다 일부 영리한 사용과 출력 로그 수준을 Function.prototype.bind:

function setDebug(isDebug) {
  if (window.isDebug) {
    window.debug = window.console.log.bind(window.console, '%s: %s');
  } else {
    window.debug = function() {};
  }
}

setDebug(true);

// ...

debug('level', 'This is my message.'); // --> level: This is my message. (line X)

한 걸음 더 나아가서 console의 오류 / 경고 / 정보 구분을 사용하고 여전히 사용자 지정 수준을 가질 수 있습니다. 시도 해봐!

function setDebug(isDebug) {
  if (isDebug) {
    window.debug = {
      log: window.console.log.bind(window.console, '%s: %s'),
      error: window.console.error.bind(window.console, 'error: %s'),
      info: window.console.info.bind(window.console, 'info: %s'),
      warn: window.console.warn.bind(window.console, 'warn: %s')
    };
  } else {
    var __no_op = function() {};

    window.debug = {
      log: __no_op,
      error: __no_op,
      warn: __no_op,
      info: __no_op
    }
  }
}

setDebug(true);

// ...

debug.log('wat', 'Yay custom levels.'); // -> wat: Yay custom levels.    (line X)
debug.info('This is info.');            // -> info: This is info.        (line Y)
debug.error('Bad stuff happened.');     // -> error: Bad stuff happened. (line Z)


답변

보낸 사람 : JavaScript 발신자 기능 줄 번호를 얻는 방법은 무엇입니까? JavaScript 발신자 소스 URL을 얻는 방법? Error오브젝트 (FF)에 줄 수 속성을 갖는다. 따라서 이와 같은 것이 작동해야합니다.

var err = new Error();
Global.console.log(level + ': '+ msg + 'file: ' + err.fileName + ' line:' + err.lineNumber);

Webkit 브라우저 err.stack에는 현재 호출 스택을 나타내는 문자열이 있습니다. 현재 줄 번호와 자세한 정보가 표시됩니다.

최신 정보

올바른 줄 번호를 얻으려면 해당 줄에서 오류를 호출해야합니다. 다음과 같은 것 :

var Log = Error;
Log.prototype.write = function () {
    var args = Array.prototype.slice.call(arguments, 0),
        suffix = this.lineNumber ? 'line: '  + this.lineNumber : 'stack: ' + this.stack;

    console.log.apply(console, args.concat([suffix]));
};

var a = Log().write('monkey' + 1, 'test: ' + 2);

var b = Log().write('hello' + 3, 'test: ' + 4);


답변

라인 번호를 유지하는 방법은 https://gist.github.com/bgrins/5108712 입니다. 그것은 다소 이로 비등합니다.

if (Function.prototype.bind) {
    window.log = Function.prototype.bind.call(console.log, console);
}
else {
    window.log = function() {
        Function.prototype.apply.call(console.log, console, arguments);
    };
}

당신은 이것을 포장 할 수 isDebug및 설정 window.logfunction() { }디버깅하지 않는 경우.


답변

다음과 같이 행 번호를 디버그 메소드에 전달할 수 있습니다.

//main.js
debug('Here is a msg.', (new Error).lineNumber);

여기에 코드 (new Error).lineNumber의 현재 줄 번호가 표시 javascript됩니다.


답변

Chrome Devtools를 사용하면 Blackboxing으로 이를 달성 할 수 있습니다 . 부작용이 있거나 다른 함수를 호출하는 등의 래퍼 함수를 ​​계속 호출 할 수있는 console.log 래퍼를 만들 수 있습니다.

작은 console.log 래퍼를 별도의 파일에 넣으십시오.

(function() {
    var consolelog = console.log
    console.log = function() {
        // you may do something with side effects here.
        // log to a remote server, whatever you want. here
        // for example we append the log message to the DOM
        var p = document.createElement('p')
        var args = Array.prototype.slice.apply(arguments)
        p.innerText = JSON.stringify(args)
        document.body.appendChild(p)

        // call the original console.log function
        consolelog.apply(console,arguments)
    }
})()

log-blackbox.js와 같은 이름을 지정하십시오.

그런 다음 Chrome Devtools 설정으로 이동하여 ‘블랙 박스’섹션을 찾고 블랙 박스에 추가하려는 파일 이름의 패턴을 추가합니다 (이 경우 log-blackbox.js).