I need to handle events from EventLog. This is easy to use with the EventLogWatcher associated with the EventRecordWritten event. However, the query I'm interested in (eventid == 299 || eventid == 500) provides more events than I need. Below is an example of a stream
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...
I am interested in event 299 and the first event 500, which corresponds to the correlation identifier of event 299. I noted them in the stream above that the output collection that interests me is: [X1, X2, Y1, Y2, Z1, Z2]
, which is probably a dictionary, using the correlation identifier as the key and EventRecord
tuple as the value
{ 1AD.., <X1, X2> } { 43B.., <Y1, Y2> } { EDB.., <Z1, Z2> }
In the general case, events can occur (299, and then 500), but in conditions of a high level of concurrency, I foresee two 299 events that come together and then 500 events, so I do not want to rely on the order of events to arrive, the correlation ID is the key to their correlations (which is the first property of the eventRecord.Properties[0]
event)
I think this can be resolved using a state machine, but it would be interesting to know if anyone has a solution with Rx represented by a query for the observable. This will support the pattern matching logic in one place.
UPDATE : here is the answer to the solution. Thank you, Gideon, this was exactly the starting point I needed!
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 });
Thanks in advance, Matthias