2013-04-08 24 views
8

Tôi muốn đăng nhập user_id của người tạo yêu cầu và tên phương thức của mọi phương thức được gọi cho một lớp javascript. Ví dụ:làm cách nào tôi có thể ghi lại mọi cuộc gọi phương thức trong node.js mà không cần thêm các dòng gỡ lỗi ở mọi nơi?

35 - log_in 
35 - list_of_other_users 
78 - log_in 
35 - send_message_to_user 
35 - connect_to_redis 
78 - list_of_other_users 

Vì mọi thứ đều là người dùng không đồng bộ 35 và 78 có thể đang làm công cụ cùng một lúc. Vì vậy, tôi muốn đảm bảo mỗi dòng nhật ký bắt đầu bằng user_id của họ để tôi có thể grep cho nó và chỉ xem hoạt động của một người dùng tại một thời điểm.

Có cách nào siêu thông minh để thực hiện việc này mà không thêm câu lệnh logger vào mọi phương thức không?

+0

có thể trùng lặp của [Làm thế nào để gỡ lỗi các ứng dụng Node.js?] (Http://stackoverflow.com/questions/1911015/how-do-i-debug-node-js- ứng dụng) – Sylar

Trả lời

2

Tôi đoán đây là ứng dụng web, trong trường hợp này nếu bạn đang sử dụng kết nối, bạn có thể sử dụng trình ghi nhật ký để ghi nhật ký người dùng và đường dẫn URL, có thể là đủ. Nếu không, bạn sẽ phải làm một số metaprogramming dọc theo các dòng của gói mỗi chức năng trong một hàm wrapper để làm việc đăng nhập.

function logCall(realFunc, instance) { 
    return function() { 
     log.debug('User: ' + instance.user_id + ' method ' + realFunc.name); 
     return realFunc.apply(instance, arguments); 
    }; 
} 

Để làm việc này, bạn phải đặt tên cho hàm của lớp, chứ không phải ẩn danh.

function sendMessage() { 
    //code to send message 
    //can use `this` to access instance properties 
} 
function MyClass(userId) { 
    this.userId = userId; //or whatever 
    this.sendMessage = logCall(sendMessage, this); 
    //repeat above line for each instance method you want instrumented for logging 
} 
4

Đây là một thay thế, không hoàn toàn chắc chắn như thế nào đáng tin cậy đó là mặc dù, nó cảm thấy một chút sai:

(function() { 
    var oldCall = Function.prototype.call; 
    var newCall = function(self) { 
    Function.prototype.call = oldCall; 
    console.log('Function called:', this.name); 
    var args = Array.prototype.slice.call(arguments, 1); 
    Function.prototype.call = newCall; 
    this.apply(self, args); 
    } 
    Function.prototype.call = newCall; 
})(); 

Như bạn có thể thấy, nó ghi đè call chức năng - điều này tạo ra một vấn đề nhỏ khi bạn cố gắng gọi console.log(), do đó bạn cần trao đổi lại chức năng. Nhưng có vẻ như nó hoạt động!

EDIT

Vì đây được gắn thẻ CoffeeScript:

do -> 
    oldCall = Function::call 
    newCall = (self) -> 
    Function::call = oldCall 
    console.log "Function called: #{this.name}" 
    args = Array.prototype.slice.call arguments, 1 
    Function::call = newCall 
    this.apply self, args 
    Function::call = newCall 
+0

Điều này đang đi vào một đệ quy vô hạn đối với tôi vì slice được gọi là hàm. Tôi đã phải di chuyển cuộc gọi slice trước khi thiết lập newCall và chuyển kết quả dưới dạng biến dưới đây. Bạn không chắc chắn nếu điều đó hoạt động ngay bây giờ –

+1

@AlexLehmann làm thế nào để thay đổi mã để tránh đệ quy vô hạn? –

5

Câu trả lời là về cơ bản chính xác, nhưng đây là cách để tránh đệ quy vô hạn

Javascript

(function() { 
    var oldCall = Function.prototype.call; 
    var newCall = function(self) { 
    Function.prototype.call = oldCall; 
    console.log('Function called:', this.name); 
    var args = Array.prototype.slice.call(arguments, 1); 
    var res = this.apply(self, args); 
    Function.prototype.call = newCall; 
    return res 
    } 
    Function.prototype.call = newCall; 
})(); 

Coffeescript

do -> 
    oldCall = Function::call 
    newCall = (self) -> 
    Function::call = oldCall 
    console.log "Function called: #{this.name}" 
    args = Array.prototype.slice.call arguments, 1 
    res = this.apply self, args 
    Function::call = newCall 
    res 
    Function::call = newCall 
+1

Điều này là tuyệt vời nhưng bạn có thể làm sáng tỏ một chút về cách hoạt động của nó và có thể cung cấp một ví dụ sử dụng? Nó là khá tiến và SE cũng cho người mới bắt đầu/intermidiate người dùng. : D – zehelvion

Các vấn đề liên quan