2013-01-05 11 views
36

現在の関数を呼び出す関数の名前と行を取得するにはどうすればよいですか?私は(npmloglog.debugを定義して)このように、基本的なデバッグ機能を持っているしたいと思います:node.jsの名前と関数の呼び出しを取得します

function debug() { 
    var callee, line; 
    /* MAGIC */ 
    log.debug(callee + ":" + line, arguments) 
} 

別の関数から呼び出された場合、それはこのようなものになるだろう:私が欲しいものを、明確にするために

function hello() { 
    debug("world!") 
} 
// outputs something like: 
// "hello:2 'world!'" 

本質的にはthis in Pythonに似ています。

import inspect 
def caller(): 
    return inspect.stack()[2][3] 
// line no from getframeinfo().lineno 

これを達成するために同等のノードはありますか?

+1

これは便利かもしれないが、私は同様の質問をしたが、関連するノードではありません。http://stackoverflow.com/questions/6885659/determining-source-line-and-file-of-function-reference-how -does-firebug-do-it –

答えて

43

Accessing line number in V8 JavaScript (Chrome & Node.js)

はあなたには、いくつかのプロトタイプを追加することができ、このへのアクセスを提供するために、 info from V8:

Object.defineProperty(global, '__stack', { 
get: function() { 
     var orig = Error.prepareStackTrace; 
     Error.prepareStackTrace = function(_, stack) { 
      return stack; 
     }; 
     var err = new Error; 
     Error.captureStackTrace(err, arguments.callee); 
     var stack = err.stack; 
     Error.prepareStackTrace = orig; 
     return stack; 
    } 
}); 

Object.defineProperty(global, '__line', { 
get: function() { 
     return __stack[1].getLineNumber(); 
    } 
}); 

Object.defineProperty(global, '__function', { 
get: function() { 
     return __stack[1].getFunctionName(); 
    } 
}); 

function foo() { 
    console.log(__line); 
    console.log(__function); 
} 

foo() 

それぞれ '28'と 'foo'を返します。

+1

ありがとうジョー。おそらく '__line'と' __function'は '__parent_line'と' __parent_function_name'という名前が良いかもしれませんが、それ以外はこれは素晴らしいことです。 –

+0

2番目のフレームを使用している場合は、__lineと__functionに関する情報を取得するだけです。 :)スタックトレースに面白いことはチェックアウトする必要があります。 – Joe

+0

このソリューションは優れていますが、高価です。私はプロダクションコードで使用しません。 bunyan loggerを使用する場合は、[srcオプション](https://github.com/trentm/node-bunyan#src)をオンにすることができます。しかし、再び、彼らは生産コードのためのそのオプションを推奨していません。コードを実行する前に、各ロガー呼び出しを関数名と行番号に関する情報で置き換えることができるトランスヒーラーが大好きです。誰でも?? – Vibgy

12

私が発見し、(npm install stack-traceでインストール)node-stack-traceモジュールをインストールし、次にとしてechoを定義しました。ここからの情報を使用して

function echo() { 
    var args, file, frame, line, method; 
    args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 

    frame = stackTrace.get()[1]; 
    file = path.basename(frame.getFileName()); 
    line = frame.getLineNumber(); 
    method = frame.getFunctionName(); 

    args.unshift("" + file + ":" + line + " in " + method + "()"); 
    return log.info.apply(log, args); // changed 'debug' to canonical npmlog 'info' 
}; 
+0

これは他の人が上記の行を以下のように変更しているので非常にいいです:args = 1 <= arguments.length? [] .slice.call(引数、0):[]; console.log.apply(this、args)を返します。 – Kus

+0

私はTitaniumを実行していて、メッセージの起点を記録するこの関数を持っています: '' 'function log(msg){ stackTrace = require(" stack-trace/lib/stack-trace "); var thistrace = stackTrace.get(); var parent_name = thistrace [1] .getFunctionName(); var parent_eval = thistrace [1] .getEvalOrigin(); msg = sprintf( "[%s] [%s]:%s"、parent_eval、parent_name、msg); Ti.API.info(msg); } '' ' –

9

私も同様の要件を持っていました。 nodejsが提供するErrorクラスのstackプロパティを使用しました。
私はまだノードを学んでいるので、エラーの可能性があります。

以下、同じことについて説明します。また、そのためのNPMモジュールを作成し、あなたが好きなら、あなたはでチェックすることができます。

2. git repo

我々の方法で「ロガー」オブジェクトが

var logger = { 
log: log 
} 
function log(msg){ 
    let logLineDetails = ((new Error().stack).split("at ")[3]).trim(); 
    console.log('DEBUG', new Date().toUTCString(), logLineDetails, msg); 
} 

「をログに記録」とし例:上記の例の

//suppose file name: /home/vikash/example/age.js 
function getAge(age) { 
    logger.log('Inside getAge function'); //suppose line no: 9 
} 

出力:

DEBUG on Sat, 24 Sept 2016 12:12:10 GMT at getAge(/home/vikash/example/age.js:9:12) 
    Inside getAge function 
関連する問題