2013-01-05 33 views
36

Làm cách nào để có thể nhận được tên và dòng của hàm được gọi là hiện tại? Tôi muốn có một chức năng gỡ lỗi sơ đẳng như thế này (với npmlog định log.debug):Nhận tên và chức năng gọi điện trong node.js

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

Khi gọi từ chức năng khác nó sẽ là một cái gì đó như thế này:

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

Để rõ ràng, những gì tôi muốn về cơ bản tương tự như this in Python:

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

Có một nút tương đương để thực hiện việc này không?

+1

Điều này có thể hữu ích, tôi đã hỏi một câu hỏi tương tự nhưng không liên quan đến nút: http://stackoverflow.com/questions/6885659/determining-source-line-and-file-of-function-reference-how -does-firebug-do-it –

Trả lời

43

Sử dụng thông tin từ đây: Accessing line number in V8 JavaScript (Chrome & Node.js)

bạn có thể thêm một số nguyên mẫu để cung cấp quyền truy cập vào đây thông tin từ 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() 

Trả về '28' và 'foo' tương ứng.

+1

Cảm ơn Joe.Có lẽ '__line' và' __function' có thể được đặt tên tốt hơn là '__parent_line' và' __parent_function_name', nhưng nếu không thì điều này thật tuyệt vời (và thật ra, cách 'stack-trace' hoạt động trong câu trả lời của tôi). –

+0

Họ sử dụng khung thứ 2 nếu không bạn sẽ chỉ nhận được thông tin về __line và __function. :) Thú vị trên 'stack-trace' sẽ phải kiểm tra. – Joe

+0

Trong khi giải pháp này là tuyệt vời, nó là tốn kém. Tôi sẽ không sử dụng nó trong mã sản xuất. Nếu bạn sử dụng trình ghi nhật ký thỏ, bạn có thể bật [tùy chọn src] (https://github.com/trentm/node-bunyan#src). Nhưng một lần nữa, họ cũng không khuyên bạn nên lựa chọn cho mã sản xuất. Tôi rất thích một transpiler có thể thay thế mỗi cuộc gọi logger với thông tin về tên hàm và số dòng trước khi tôi chạy mã của mình. Bất kỳ ai?? – Vibgy

12

Tôi tìm thấy và cài đặt node-stack-trace mô-đun (cài đặt với npm install stack-trace), và sau đó được xác định echo như:

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

Điều này rất hay, đối với những người khác thay đổi các dòng trên thành điều này: args = 1 <= arguments.length? [] .slice.call (đối số, 0): []; return console.log.apply (this, args); – Kus

+0

Cảm ơn, tôi đang chạy Titanium và có chức năng này để ghi lại xuất xứ của tin nhắn: '' 'hàm 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

Tôi cũng có yêu cầu tương tự. Tôi đã sử dụng thuộc tính stack của lớp Error do nodej cung cấp.
Tôi vẫn đang học nút vì vậy, có thể có lỗi.

Dưới đây là giải thích cho tương tự. Cũng tạo ra mô-đun NPM cho cùng, nếu bạn thích, bạn có thể kiểm tra tại địa chỉ:
1. npm module 'logat'
2. git repo

giả sử chúng ta 'logger' đối tượng với phương pháp 'đăng nhập'

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

Ví dụ:

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

Sản lượng ví dụ trên:

DEBUG on Sat, 24 Sept 2016 12:12:10 GMT at getAge(/home/vikash/example/age.js:9:12) 
    Inside getAge function 
Các vấn đề liên quan