2013-02-13 25 views
18

Tôi có một dự án hiện tại nơi tôi muốn tìm hiểu tất cả các cuộc gọi đang được thực hiện và có thể đổ vào một tệp nhật ký.Làm thế nào để theo dõi mọi phương pháp được gọi là

Tôi đã xem at this thread nhưng không giúp được gì nhiều. Tôi đã thử PostSharp và ví dụ cho thấy cách đạt được nó. Nhưng tôi cần thêm thuộc tính vào mọi phương thức darn. Là một dự án hiện có, với nhiều phương pháp không phải là một lựa chọn khả thi.

Có phương tiện nào khác để tôi có thể nhanh chóng theo dõi tất cả các cuộc gọi được thực hiện không?

+0

Bạn đã xem http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method –

+0

Tôi không thể trợ giúp nhưng tự hỏi tại sao bạn lại muốn điều đó. Trong trường hợp ngoại lệ, bạn có thể xem stacktrace. Nhưng tại sao bạn muốn một bản ghi của tất cả các cuộc gọi phương thức? – comecme

+0

Có một lỗi mà chúng tôi có thể theo dõi cho đến một điểm nhất định, và sau đó điều khiển đi đến ứng dụng mẹ không phải là ứng dụng của chúng tôi - vì vậy không có mã nguồn (một nơi nào đó sau khi ứng dụng ngừng đáp ứng). Để tìm hiểu những gì được gọi trong ứng dụng của chúng tôi sau đó chúng tôi đang cố gắng này. –

Trả lời

9

Bạn có thể làm điều này với Unity Interception

Xem article for a sample này. Bài viết sử dụng các thuộc tính, nhưng mẫu mã của tôi dưới đây sử dụng hệ thống tiêm phụ thuộc (mã hóa cho một giao diện) để thiết lập chặn.

Nếu bạn muốn đăng nhập MyClass, nó đi một cái gì đó như thế này:

  1. Thực hiện một giao diện có chứa tất cả các phương pháp trong MyClass =>IMyClass
  2. Bạn thiết lập InterfaceInterception (như tôi đã thực hiện dưới đây) HOẶC có một vài cách khác mà bạn có thể thiết lập. Xem here for all options.
  3. Bạn sẽ thiết lập chính sách chặn tất cả các phương thức khớp với IMatchingRule.
  4. Hiện tại, tất cả các cuộc gọi sẽ bị chặn bởi triển khai ICallHandler của bạn.

Code:

//You will use the code like this: 
MyContainer container = new MyContainer(); 
//setup interception for this type.. 
container.SetupForInteception(typeof(IMyClass)); 
//what happens here is you get a proxy class 
//that intercepts every method call. 
IMyClass cls = container.Resolve<IMyClass>(); 

//You need the following for it to work: 
public class MyContainer: UnityContainer 
{ 
    public MyContainer() 
    { 
     this.AddNewExtension<Interception>(); 
     this.RegisterType(typeof(ICallHandler), 
        typeof(LogCallHandler), "MyCallHandler"); 
     this.RegisterType(typeof(IMatchingRule), 
         typeof(AnyMatchingRule), "AnyMatchingRule"); 

     this.RegisterType<IMyClass, MyClass>(); 
    } 
    //apparently there is a new way to do this part 
    // http://msdn.microsoft.com/en-us/library/ff660911%28PandP.20%29.aspx 

    public void SetupForInteception(Type t) 
    { 
     this.Configure<Interception>() 
     .SetInterceptorFor(t, new InterfaceInterceptor()) 
     .AddPolicy("LoggingPolicy") 
     .AddMatchingRule("AnyMatchingRule") 
     .AddCallHandler("MyCallHandler"); 

    } 
} 
//THIS will match which methods to log. 
public class AnyMatchingRule : IMatchingRule 
{ 
    public bool Matches(MethodBase member) 
    { 
     return true;//this ends up loggin ALL methods. 
    } 
} 
public class LogCallHandler : ICallHandler 
{ 
    public IMethodReturn 
      Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     //All method calls will result in a call here FIRST. 
     //IMethodInvocation has an exception property which will let you know 
     //if an exception occurred during the method call. 
    } 
} 
+0

Tôi nghĩ anh ấy đang cố gắng làm điều đó mà không cần thêm thuộc tính cho từng phương thức/lớp (khác với mẫu) – eyossi

+0

Nhưng mã của tôi không cần bất kỳ thuộc tính nào. – gideon

+0

Âm thanh như nó đòi hỏi bạn phải tạo ra một giao diện cho mỗi lớp; đó là công việc nhiều hơn so với các thuộc tính, theo ý kiến ​​của tôi. –

4

Sử dụng Profiler trong chế độ truy tìm. Sau đó, bạn sẽ thấy mọi thứ sẽ gọi nhau như thế nào và thời gian được sử dụng. Bên cạnh đó profilers thương mại cũng có những cái miễn phí. Đối với mã được quản lý, có NP Profiler là khá tốt.

Nếu bạn muốn đi sâu hơn, bạn có thể sử dụng Windows Performance Toolkit cung cấp cho bạn thông tin đầy đủ về tất cả các chủ đề và cách tương tác với nhau nếu bạn muốn biết. Sự khác biệt duy nhất là bạn nhận được các ngăn xếp khác nhau, từ hạt nhân cho đến khi khung được quản lý của bạn.

Nếu điều này là không đủ, bạn có thể thiết lập mã của bạn bằng thư viện truy tìm (tự động với PostSharp, ....) hoặc theo cách thủ công hoặc với macro cho từng tệp nguồn. Tôi đã thực hiện một thư viện truy tìm nhỏ khá nhanh và có khả năng cấu hình cao. Xem here. Là tính năng độc đáo, nó có thể theo dõi bất kỳ ngoại lệ ném tự động.

private void SomeOtherMethod() 
{ 
    using (Tracer t = new Tracer(myType, "SomeOtherMethod")) 
    { 
     FaultyMethod(); 
    } 
} 

private void FaultyMethod() 
{ 
    throw new NotImplementedException("Hi this a fault"); 
} 

Ở đây có kết quả:

18:57:46.665 03064/05180 <{{   > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod 
    18:57:46.668 03064/05180 <{{   > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod 
    18:57:46.670 03064/05180 <   }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Exception thrown: System.NotImplementedException: Hi this a fault  
at ApiChange.IntegrationTests.Diagnostics.TracingTests.FaultyMethod() 
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod() 
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod()  
at ApiChange.IntegrationTests.Diagnostics.TracingTests.Demo_Show_Leaving_Trace_With_Exception() 

18:57:46.670 03064/05180 <   }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Duration 2ms 18:57:46.689 03064/05180 <   }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod Duration 24ms 
5

PostSharp chắc chắn cung cấp một cách để áp dụng một khía cạnh quan đến một số chỉ tiêu mà không cần trang trí chúng với các thuộc tính một cách rõ ràng. Xem Multicast attributes.

Khi đang phát triển (multicast) khía cạnh bạn phải chỉ định sử dụng của nó:

[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)] 
[AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)] 
[Serializable] 
public class TraceAttribute : MethodInterceptionAspect 
{ 
// Details skipped. 
} 

Và sau đó áp dụng các khía cạnh trong một cách mà bao gồm trường hợp sử dụng của bạn (ví dụ như tất cả các thành viên cộng đồng trong AdventureWorks.BusinessLayer namespace.):

[assembly: Trace(AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public)] 
Các vấn đề liên quan