2012-04-11 19 views
6

Tôi cần xử lý các sự kiện đến từ EventLog. Điều này rất dễ dàng bằng cách sử dụng EventLogWatcher gắn với sự kiện EventRecordWritten. Tuy nhiên truy vấn mà tôi quan tâm (eventid == 299 || eventid == 500) cung cấp nhiều sự kiện hơn những gì tôi cần. Dưới đây là ví dụ về luồngXử lý sự kiện từ Nhật ký Sự kiện và phản ứng trên một mẫu nhất định (Rx?)

Event ID Correlation ID 
299  1AD... (this is actually a guid) X1 
500  1AD...        X2 
500  1AD... 
500  1AD... 
299  43B...        Y1 
299  EDB...        Z1 
500  43B...        Y2 
500  EDB...        Z2 
500  43B... 
500  43B... 

Tôi quan tâm đến sự kiện 299 và sự kiện 500 đầu tiên khớp với id tương quan của sự kiện 299. Tôi đánh dấu chúng trong dòng ở trên, đó là bộ sưu tập đầu ra Tôi quan tâm đến: [X1, X2, Y1, Y2, Z1, Z2] mà có lẽ là một từ điển bằng cách sử dụng id tương quan như một chìa khóa và một tuple của EventRecord như giá trị

{ 1AD.., <X1, X2> } 
{ 43B.., <Y1, Y2> } 
{ EDB.., <Z1, Z2> } 

Trong sự kiện chung có thể đến theo thứ tự (299 và sau đó 500) nhưng trong một tình huống tương tranh cao, tôi thấy trước hai sự kiện kết hợp với nhau và sau đó là 500 sự kiện nên tôi không muốn dựa vào thứ tự các sự kiện đến. Các tương quan id là chìa khóa để tương quan chúng (đó là tài sản đầu tiên của sự kiện eventRecord.Properties[0])

Tôi nghĩ rằng điều này có thể được giải quyết với một máy nhà nước nhưng nó sẽ là thú vị để xem nếu có ai đến với một giải pháp với Rx đại diện bởi một truy vấn đến một quan sát được. Điều đó sẽ giữ cho mô hình phù hợp với logic ở một nơi duy nhất.

CẬP NHẬT: đây là câu trả lời cho giải pháp. Cảm ơn Gideon, đó chính là điểm khởi đầu tôi cần!

var pairs = events 
      .Where(e299 => e299.EventArgs.EventRecord.Id == 299) 
      .SelectMany(e299 => events.Where(e500 => e500.EventArgs.EventRecord.Id == 500 && 
                e299.EventArgs.EventRecord.Properties[0].Value.ToString() == 
                e500.EventArgs.EventRecord.Properties[0].Value.ToString()) 
            .Take(1), 
         (e299, e500) => new { First = e299, Second = e500 }); 

Cảm ơn trước, Matias

Trả lời

5

Nếu 299 sự kiện luôn xảy ra trước 500 sự kiện, SelectManyWhere là đủ.

var events; //declared somewhere 

var pairs = from e299 in events 
      where e299.eventid == 299 
      from e500 in events 
      where e500.eventid == 500 && 
        e299.Correlation == e500.Correlation 
      select new with {Correlation = e299.Correlation, 
          First = e299, 
          Second = e500} 

Nếu nguồn của bạn có nhiều sự kiện 500 cho mỗi tương quan 299 sự kiện, bạn có thể cần phải chuyển sang cú pháp lambda và thêm một Take(1) để đăng ký thứ hai.

+0

phát ngay! Cảm ơn Gideon ... truy vấn sử dụng lambda và lấy (1) được đưa vào câu trả lời của tôi – woloski

0

Tôi không biết những gì bạn có ý nghĩa với "một cỗ máy nhà nước".

Nhưng bạn có thể viết một người quan sát thu thập (eventid == 299 || eventid == 500). Sử dụng chiến lược ga (thu thập 1000 sự kiện mới nhất, hoặc phút cuối cùng, tôi không biết), nó nâng cao một sự kiện khi phát hiện một cặp sự kiện 299, 500 có cùng một guid, loại bỏ sau đó từ từ điển/danh sách nội bộ của nó sự kiện.

Sau đó, người quan sát loại đó CÓ THỂ quan sát được đối với phần còn lại của hệ thống của bạn.

Có lẽ một danh sách có thể được thu thập các sự kiện, và khi một sự kiện mới được phát hiện, một cái gì đó giống như

events.Where (e => e.eventid == newevent.eventid & & ((e.id = = 299 & & == newev.id 500) || (e.id == 500 & & newev.id == 299))

có thể là đủ trong hoạt động, thay vì có một cuốn từ điển bằng cách guid.

Hẹn gặp lại sau, Mathew!

+0

Cảm ơn Angel ... Đang lưu các sự kiện và phân tích chúng là cách tiếp cận đầu tiên của tôi. Tôi muốn một cái gì đó tinh khiết RX. – woloski

2

Bạn nên xem xét sử dụng Observable.When, with Joins. Điều này sẽ cho phép bạn soạn các mẫu kết hợp phức tạp như bạn mong muốn.

Ví dụ: https://stackoverflow.com/a/3868608/13131Guide to System.Reactive.Joins.

+0

Tôi đã thử sử dụng And và When nhưng không thể đạt được hành vi đúng. Tôi chắc chắn nó có thể được giải quyết bằng cách nào đó, vẫn cần thực hành nhiều hơn với RX :). Cảm ơn bạn đã giúp đỡ! – woloski

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