protected override void Track(TrackingRecord record, TimeSpan timeout) { Console.ForegroundColor = ConsoleColor.Cyan; if (record is ActivityScheduledRecord) { ActivityScheduledRecord actSchedule = record as ActivityScheduledRecord; Console.WriteLine("Name: {0}, Scheduled", actSchedule.Child.Name); } else if (record is ActivityStateRecord) { ActivityStateRecord actState = record as ActivityStateRecord; Console.WriteLine("Name: {0}, {1}", actState.Activity.Name, actState.State); } else if (record is WorkflowInstanceRecord) { WorkflowInstanceRecord wInstanceRecord = record as WorkflowInstanceRecord; Console.WriteLine("WorkFlow, {0}", wInstanceRecord.State); } else { Console.WriteLine(record.ToString()); } Console.ResetColor(); }
public ActivityTrace(string activityName, ActivityInstanceState activityStatus, TrackingRecord record) { _activityName = activityName; _activityStatus = activityStatus; if (record != null) { this.ActivityInstanceId = record.InstanceId.ToString(); if (record is ActivityStateRecord) { if ((record as ActivityStateRecord).Activity != null) { this.ActivityId = (record as ActivityStateRecord).Activity.Id; this.ActivityInstanceId = (record as ActivityStateRecord).Activity.InstanceId; } } if (record is ActivityScheduledRecord) { this.IsScheduled = true; ActivityScheduledRecord activityScheduledRecord = record as ActivityScheduledRecord; if (activityScheduledRecord.Activity != null) { this.ActivityId = activityScheduledRecord.Activity.Id; this.ActivityInstanceId = activityScheduledRecord.Activity.InstanceId; ChildActivityId = activityScheduledRecord.Child.Id; ChildActivityInstanceId = activityScheduledRecord.Child.InstanceId; } } } }
public TrackingCommand(TrackingRecord record) : this() { ActivityScheduledRecord activityScheduledRecord = record as ActivityScheduledRecord; if (activityScheduledRecord != null) { CreateTrackingCommand(activityScheduledRecord); return; } CancelRequestedRecord cancelRequestedRecord = record as CancelRequestedRecord; if (cancelRequestedRecord != null) { CreateTrackingCommand(cancelRequestedRecord); return; } FaultPropagationRecord faultPropagationRecord = record as FaultPropagationRecord; if (faultPropagationRecord != null) { CreateTrackingCommand(faultPropagationRecord); return; } ActivityStateRecord activityStateRecord = record as ActivityStateRecord; if (activityStateRecord != null) { CreateTrackingCommand(activityStateRecord); return; } WorkflowInstanceRecord workflowInstanceRecord = record as WorkflowInstanceRecord; if (workflowInstanceRecord != null) { CreateTrackingCommand(workflowInstanceRecord); return; } BookmarkResumptionRecord bookmarkResumptionRecord = record as BookmarkResumptionRecord; if (bookmarkResumptionRecord != null) { CreateTrackingCommand(bookmarkResumptionRecord); return; } CustomTrackingRecord customTrackingRecord = record as CustomTrackingRecord; if (customTrackingRecord != null) { CreateTrackingCommand(customTrackingRecord); return; } }
/// <summary> /// Records an event. /// </summary> /// <param name="record"></param> internal void ActivityScheduled(ActivityScheduledRecord record) { if (record == null) { throw new ArgumentNullException(nameof(record)); } switch (record.Level) { case TraceLevel.Verbose: ActivityScheduledTrack(record, SeverityLevel.Verbose); break; case TraceLevel.Info: ActivityScheduledTrack(record, SeverityLevel.Information); break; case TraceLevel.Warning: ActivityScheduledTrack(record, SeverityLevel.Warning); break; case TraceLevel.Error: ActivityScheduledTrack(record, SeverityLevel.Error); break; } }
private void TrackActivityScheduledRecord(ActivityScheduledRecord activityScheduledRecord, ActualTrace _trace) { //the scheduling record simply states that i am scheduled blah. Currently we do not have any support in TO for this. //Hence, turning it off for now. we will have the tracking tests cover the validation. TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]activityScheduledRecord.TargetName = {0}", activityScheduledRecord.Child.Name); _trace.Add(new ActivityTrace(activityScheduledRecord.Child.Name, ActivityInstanceState.Executing, activityScheduledRecord)); }
protected override void Track(TrackingRecord record, TimeSpan timeout) { if (record is ActivityStateRecord) { ActivityStateRecord state = record as ActivityStateRecord; if (null == state.Activity) { return; } bool closed = state.State.Equals("Closed"); //NOXLATE StringBuilder logLine = new StringBuilder(); logLine.Append(String.Format( "{0}{1}{2} {3} {4}", //NOXLATE state.Level.ToString(), _indent, closed ? "<-" : "--", //NOXLATE state.Activity.Id, GetName(state.Activity))); if (record.Level == TraceLevel.Info) { if (closed) { if (state.Arguments.ContainsKey("Result")) // NOXLATE { logLine.Append(String.Format( " == \"{0}\"", state.Arguments["Result"])); //NOXLATE } DecrementIndent(); } else { foreach (KeyValuePair <string, object> keyValue in state.Arguments) { Track(keyValue, logLine); } } } _log.AppendLine(logLine.ToString()); } else if (record is ActivityScheduledRecord) { ActivityScheduledRecord scheduled = record as ActivityScheduledRecord; if (null == scheduled.Activity || null == scheduled.Child) { return; } if (record.Level == TraceLevel.Info) { IncrementIndent(); } StringBuilder logLine = new StringBuilder(); logLine.Append(String.Format( "{0}{1}-> {2} {3}", //NOXLATE scheduled.Level.ToString(), _indent, //scheduled.Activity.Id, GetName(scheduled.Activity), <- parent activity scheduled.Child.Id, GetName(scheduled.Child))); _log.AppendLine(logLine.ToString()); } }
private void TrackActivityScheduledRecord(ActivityScheduledRecord scheduledRecord) { if (WfEtwTrackingEventSource.Instance.ActivityScheduledRecordIsEnabled()) { WfEtwTrackingEventSource.Instance.ActivityScheduledRecord(scheduledRecord.InstanceId, scheduledRecord.RecordNumber, scheduledRecord.EventTime, scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Name, scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Id, scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.InstanceId, scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.TypeName, scheduledRecord.Child.Name, scheduledRecord.Child.Id, scheduledRecord.Child.InstanceId, scheduledRecord.Child.TypeName, scheduledRecord.HasAnnotations ? JsonConvert.SerializeObject(scheduledRecord.Annotations, Formatting.Indented) : emptyItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference); } }
//On Tracing Record Received call the TrackingRecordReceived with the record received information from the TrackingParticipant. //We also do not worry about Expressions' tracking data protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout) { try { System.Diagnostics.Debug.WriteLine( String.Format("Tracking Record Received: {0} with timeout: {1} seconds.", record, timeout.TotalSeconds) ); if (TrackingRecordReceived != null) { ActivityStateRecord activityStateRecord = record as ActivityStateRecord; ActivityScheduledRecord activityScheduledRecord = record as ActivityScheduledRecord; if (((activityStateRecord != null) && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions"))) || (activityScheduledRecord != null)) { string activId = null; if (activityStateRecord != null) { activId = activityStateRecord.Activity.Id; } else if (activityScheduledRecord != null) { activId = activityScheduledRecord.Child.Id; } if ((ActivityIdToWorkflowElementMap.ContainsKey(activId))) { TrackingRecordReceived(this, new TrackingEventArgs( record, timeout, ActivityIdToWorkflowElementMap[activId] ) ); } } else { TrackingRecordReceived(this, new TrackingEventArgs(record, timeout, null)); } } } catch (Exception ex) { Log.Logger.LogData(ex.Message, LogLevel.Error); } }
protected override void Track(TrackingRecord record, TimeSpan timeout) { WorkflowInstanceRecord instanceRecord = record as WorkflowInstanceRecord; if (instanceRecord != null) { this.InstanceStates.Add(instanceRecord.State); return; } ActivityStateRecord activityStateRecord = record as ActivityStateRecord; if (activityStateRecord != null) { this.ActivityStates.Add(Colonize(activityStateRecord.Activity.Name, activityStateRecord.State)); return; } CustomTrackingRecord customRecord = record as CustomTrackingRecord; if (customRecord != null) { foreach (KeyValuePair <string, object> kvp in customRecord.Data) { this.CustomRecords.Add(Colonize(kvp.Key, kvp.Value.ToString())); } return; } BookmarkResumptionRecord bookmarkRecord = record as BookmarkResumptionRecord; if (bookmarkRecord != null) { this.BookmarkResumptionRecords.Add(Colonize(bookmarkRecord.BookmarkName, bookmarkRecord.Payload.ToString())); return; } ActivityScheduledRecord scheduledRecord = record as ActivityScheduledRecord; if (scheduledRecord != null) { // For the root activity, the "parent" will be null, so tolerate that case. this.ActivityScheduledRecords.Add(Colonize((scheduledRecord.Activity != null) ? scheduledRecord.Activity.Name : "<null>", scheduledRecord.Child.Name)); return; } }
void CreateTrackingCommand(ActivityScheduledRecord record) { this.Procedure = "[MOJ.WorkflowManger.Tracking].[InsertActivityScheduledEvent]"; this.parameters.Add(CreateTrackingCommandParameter("@WorkflowInstanceId", SqlDbType.UniqueIdentifier, null, record.InstanceId)); this.parameters.Add(CreateTrackingCommandParameter("@RecordNumber", SqlDbType.BigInt, null, record.RecordNumber)); this.parameters.Add(CreateTrackingCommandParameter("@TraceLevelId", SqlDbType.TinyInt, null, record.Level)); this.parameters.Add(CreateTrackingCommandParameter("@ActivityRecordType", SqlDbType.NVarChar, 128, "ActivityScheduled")); this.parameters.Add(CreateTrackingCommandParameter("@ActivityName", SqlDbType.NVarChar, 1024, record.Activity == null ? null : record.Activity.Name)); this.parameters.Add(CreateTrackingCommandParameter("@ActivityId", SqlDbType.NVarChar, 256, record.Activity == null ? null : record.Activity.Id)); this.parameters.Add(CreateTrackingCommandParameter("@ActivityInstanceId", SqlDbType.NVarChar, 256, record.Activity == null ? null : record.Activity.InstanceId)); this.parameters.Add(CreateTrackingCommandParameter("@ActivityType", SqlDbType.NVarChar, 2048, record.Activity == null ? null : record.Activity.TypeName)); this.parameters.Add(CreateTrackingCommandParameter("@ChildActivityName", SqlDbType.NVarChar, 1024, record.Child.Name)); this.parameters.Add(CreateTrackingCommandParameter("@ChildActivityId", SqlDbType.NVarChar, 256, record.Child.Id)); this.parameters.Add(CreateTrackingCommandParameter("@ChildActivityInstanceId", SqlDbType.NVarChar, 256, record.Child.InstanceId)); this.parameters.Add(CreateTrackingCommandParameter("@ChildActivityType", SqlDbType.NVarChar, 2048, record.Child.TypeName)); this.parameters.Add(CreateTrackingCommandParameter("@AnnotationsXml", SqlDbType.NVarChar, null, this.SerializeData(record.Annotations))); this.parameters.Add(CreateTrackingCommandParameter("@TimeCreated", SqlDbType.DateTime, null, record.EventTime)); }
private void LogActivityScheduledRecord(ActivityScheduledRecord record) { Contract.Requires(null != record); var annotations = JsonConvert.SerializeObject(record.Annotations, Formatting.Indented); var activity = JsonConvert.SerializeObject(record.Activity, Formatting.Indented); var child = JsonConvert.SerializeObject(record.Child, Formatting.Indented); Logger.Get(_loggingTrackingParticipantSettings.TraceSourceName) .TraceInformation("{0} {1} {2} - InstanceId = '{3}', Annotations = '{4}', Activity = '{5}', Child = '{6}'", record.GetType().Name, record.EventTime, record.Level, record.InstanceId, annotations, activity, child ); }
/// <summary> /// Records an event. /// </summary> /// <param name="record"></param> /// <param name="severityLevel"></param> internal void ActivityScheduledTrack(ActivityScheduledRecord record, SeverityLevel severityLevel) { if (record == null) { throw new ArgumentNullException(nameof(record)); } var telemetry = new TraceTelemetry(); telemetry.Context.Operation.Id = record.InstanceId.ToString(); telemetry.Timestamp = record.EventTime; telemetry.Sequence = record.RecordNumber.ToString(); telemetry.Message = "ActivityScheduled"; telemetry.SeverityLevel = severityLevel; telemetry.Properties["annotations"] = PrepareAnnotations(record.Annotations); telemetry.Properties["activityName"] = record.Activity?.Name; telemetry.Properties["activityId"] = record.Activity?.Id; telemetry.Properties["activityInstanceId"] = record.Activity?.InstanceId; telemetry.Properties["activityTypeName"] = record.Activity?.TypeName; TrackTelemetry(telemetry); }
protected override void Track(TrackingRecord trackRecord, TimeSpan timeStamp) { try { string State = "unknown"; Guid InstanceId = trackRecord.InstanceId; ActivityStateRecord activityStateRecord = trackRecord as ActivityStateRecord; ActivityScheduledRecord activityScheduledRecord = trackRecord as ActivityScheduledRecord; WorkflowInstanceRecord workflowInstanceRecord = trackRecord as WorkflowInstanceRecord; if (workflowInstanceRecord != null) { var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (workflowInstanceRecord.State == WorkflowInstanceStates.Started || workflowInstanceRecord.State == WorkflowInstanceStates.Resumed) { lock (timerslock) timers.Add(InstanceId.ToString(), new Dictionary <string, Stopwatch>()); System.Diagnostics.Activity.Current = null; // Instance.RootActivity = Instance.source.StartActivity(workflowInstanceRecord.State.ToString() + " " + Instance.Workflow.name, ActivityKind.Consumer, Instance.ParentSpanId); Instance.RootActivity = Instance.source.StartActivity(workflowInstanceRecord.State.ToString() + " " + Instance.Workflow.name, ActivityKind.Consumer); if (Instance.RootActivity != null) { if (!string.IsNullOrEmpty(Instance.ParentSpanId)) { Instance.RootActivity?.SetParentId(Instance.ParentSpanId); } Instance.SpanId = Instance.RootActivity.SpanId.ToHexString(); } Instance.RootActivity?.SetTag("status.code", 200); Instance.RootActivity?.SetTag("status.state", workflowInstanceRecord.State.ToString()); Instance.RootActivity?.SetTag("ofid", Config.local.openflow_uniqueid); try { if (global.webSocketClient != null && global.webSocketClient.user != null && !string.IsNullOrEmpty(global.webSocketClient.user.username)) { Instance.RootActivity?.SetTag("username", global.webSocketClient.user.username); } else { Instance.RootActivity?.SetTag("username", System.Security.Principal.WindowsIdentity.GetCurrent().Name); } } catch (Exception) { } try { if (hostname == null) { hostname = System.Net.Dns.GetHostName(); } Instance.RootActivity?.SetTag("hostname", hostname); } catch (Exception) { hostname = ""; } Instance.Activities.Push(Instance.RootActivity); } else if (workflowInstanceRecord.State == WorkflowInstanceStates.Aborted || workflowInstanceRecord.State == WorkflowInstanceStates.Canceled || workflowInstanceRecord.State == WorkflowInstanceStates.Completed || workflowInstanceRecord.State == WorkflowInstanceStates.Deleted || workflowInstanceRecord.State == WorkflowInstanceStates.Suspended || workflowInstanceRecord.State == WorkflowInstanceStates.Terminated || workflowInstanceRecord.State == WorkflowInstanceStates.UnhandledException || workflowInstanceRecord.State == WorkflowInstanceStates.UpdateFailed) { if (timers.ContainsKey(InstanceId.ToString())) { lock (timerslock) timers.Remove(InstanceId.ToString()); } if (workflowInstanceRecord.State != WorkflowInstanceStates.Completed) { Instance.RootActivity?.SetTag("status.state", 500); } if (workflowInstanceRecord.State == WorkflowInstanceStates.UnhandledException) { Instance.RootActivity?.SetTag("Exception", ((System.Activities.Tracking.WorkflowInstanceUnhandledExceptionRecord)workflowInstanceRecord).UnhandledException); } if (workflowInstanceRecord.State == WorkflowInstanceStates.Aborted) { Instance.RootActivity?.SetTag("Reason", ((System.Activities.Tracking.WorkflowInstanceAbortedRecord)workflowInstanceRecord).Reason); } if (workflowInstanceRecord.State == WorkflowInstanceStates.Suspended) { Instance.RootActivity?.SetTag("Reason", ((System.Activities.Tracking.WorkflowInstanceSuspendedRecord)workflowInstanceRecord).Reason); } if (workflowInstanceRecord.State == WorkflowInstanceStates.Terminated) { Instance.RootActivity?.SetTag("Reason", ((System.Activities.Tracking.WorkflowInstanceTerminatedRecord)workflowInstanceRecord).Reason); } Instance.RootActivity?.SetTag("status.state", workflowInstanceRecord.State.ToString()); if (Instance.source != null) { while (Instance.Activities.Count > 0) { var span = Instance.Activities.Pop(); span?.Dispose(); } Instance.RootActivity = null; } } else { Instance.RootActivity?.AddEvent(new ActivityEvent(workflowInstanceRecord.State.ToString())); if (Instance.Activities.Count > 0) { Instance.Activities.First()?.AddEvent(new ActivityEvent(workflowInstanceRecord.State.ToString())); } } } //if (activityStateRecord != null || activityScheduledRecord != null) if (activityStateRecord != null) { string ActivityId = null, name = null; var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Id)) { ActivityId = activityStateRecord.Activity.Id; } if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Name)) { name = activityStateRecord.Activity.Name; } Console.WriteLine(activityStateRecord.State.ToString() + " " + ActivityId + " " + name); // var sw = new Stopwatch(); sw.Start(); if (timers.ContainsKey(InstanceId.ToString()) && !string.IsNullOrEmpty(ActivityId)) { var timer = timers[InstanceId.ToString()]; if (activityStateRecord.State == ActivityStates.Executing) { if (!timer.ContainsKey(ActivityId)) { Stopwatch sw = new Stopwatch(); sw.Start(); timer.Add(ActivityId, sw); var TypeName = activityStateRecord.Activity.TypeName; var Name = activityStateRecord.Activity.Name; if (String.IsNullOrEmpty(Name)) { Name = TypeName; } if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } System.Diagnostics.Activity.Current = Instance.RootActivity; var span = Instance.source.StartActivity(Name, ActivityKind.Consumer); span?.AddTag("type", TypeName); span?.AddTag("ActivityId", ActivityId); // Console.WriteLine("Push " + Name); if (Instance.source != null) { Instance.Activities.Push(span); } // Console.WriteLine("start " + TypeName); } else { // Console.WriteLine("Skip adding new span and timer for " + ActivityId); } } if (activityStateRecord.State != ActivityStates.Executing) { if (timer.ContainsKey(ActivityId)) { Stopwatch sw = timer[ActivityId]; timer.Remove(ActivityId); var TypeName = activityStateRecord.Activity.TypeName; var Name = activityStateRecord.Activity.Name; if (String.IsNullOrEmpty(Name)) { Name = TypeName; } if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } try { if (Instance.Activities.Count > 0) { if (Instance.Activities.First().DisplayName == Name) { // Console.WriteLine("Popping " + Name); var span = Instance.Activities.Pop(); span?.Dispose(); } else { // Console.WriteLine("Skip pop, expected " + Name + " but found " + Instance.Activities.First().DisplayName); } } } catch (Exception ex) { Log.Error(ex.ToString()); } } else { // Console.WriteLine("Skip removing old span and timer for " + ActivityId); } } } if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Name) && Instance != null && Instance.Workflow != null) { var TypeName = activityStateRecord.Activity.TypeName; if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } //RobotInstance.activity_counter.WithLabels((activityStateRecord.Activity.Name, TypeName, Instance.Workflow.name)).Inc(); } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } else { if (v.Value != null) { Instance.Variables.Add(v.Key, new WorkflowInstanceValueType(v.Value.GetType(), v.Value)); } } //wfi.variables.Add(v.Key, v.Value); } // Log.Activity(activityStateRecord.State + " " + activityStateRecord.Activity.Id + " " + activityStateRecord.Activity.Name); } if (activityScheduledRecord != null) { var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (Instance == null || Instance.wfApp == null) { return; } var wfApp = Instance.wfApp; var executor = typeof(System.Activities.Hosting.WorkflowInstance).GetField("executor", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(wfApp); var scheduler = executor.GetType().GetField("scheduler", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); string ActivityId = null; string ChildActivityId = null; if (activityStateRecord != null) { ActivityId = activityStateRecord.Activity.Id; State = activityStateRecord.State.ToLower(); } if (activityScheduledRecord != null) { State = "Scheduled"; if (activityScheduledRecord.Activity != null) { ActivityId = activityScheduledRecord.Activity.Id; } if (activityScheduledRecord.Child != null) { ChildActivityId = activityScheduledRecord.Child.Id; } } if (activityScheduledRecord.Activity == null && activityScheduledRecord.Child != null) { // this will make "1" be handles twice, but "1" is always sendt AFTER being scheduled, but we can catch it here ? ActivityId = activityScheduledRecord.Child.Id; ChildActivityId = activityScheduledRecord.Child.Id; } if (string.IsNullOrEmpty(ActivityId)) { return; } if (activityScheduledRecord.Child.Id == "1.11") { // scheduler.GetType().GetMethod("ClearAllWorkItems", BindingFlags.Public | BindingFlags.Instance).Invoke(scheduler, new object[] { executor }); // scheduler.GetType().GetMethod("ScheduleWork", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { false }); //var firstWorkItem = scheduler.GetType().GetField("firstWorkItem", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(scheduler); //firstWorkItem.GetType().GetMethod("Release", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //firstWorkItem.GetType().GetMethod("Dispose", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //scheduler.GetType().GetMethod("NotifyWorkCompletion", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { }); } if (activityScheduledRecord.Activity != null) { // Log.Activity("Scheduled " + activityScheduledRecord.Activity.Id + " " + activityScheduledRecord.Activity.Name + " -> " + activityScheduledRecord.Child.Id + " " + activityScheduledRecord.Child.Name); } else if (activityScheduledRecord.Child != null) { // Log.Activity("Scheduled " + activityScheduledRecord.Child.Id + " " + activityScheduledRecord.Child.Name); } if (Instance.Variables == null) { Instance.Variables = new Dictionary <string, WorkflowInstanceValueType>(); } if (activityStateRecord != null) { foreach (var v in Instance.Variables.ToList()) { if (!activityStateRecord.Variables.ContainsKey(v.Key)) { Instance.Variables.Remove(v.Key); } } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } } } var instanceMapField = executor.GetType().GetField("instanceMap", BindingFlags.NonPublic | BindingFlags.Instance); // get SerializedProgramMapping to have InstanceMap get filled, needed by SerializedProgramMapping var SerializedProgramMapping = executor.GetType().GetProperty("SerializedProgramMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); ActivityInstance activityInstance = executor.GetType().GetField("rootInstance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor) as ActivityInstance; // Sometimes we can find the ActivityInstance in rootInstance ActivityInstance result = findActivityInstance(executor, activityInstance, ActivityId); // But more often, we find it in InstanceMapping var instanceMap = instanceMapField.GetValue(executor); if (instanceMap != null && result == null) { var _list = SerializedProgramMapping.GetType().GetProperty("InstanceMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(SerializedProgramMapping); foreach (System.Collections.DictionaryEntry kvp in (System.Collections.IDictionary)_list) { var a = kvp.Key as System.Activities.Activity; if (a == null) { continue; } if (result == null && a.Id == ActivityId) { result = findActivityInstance(kvp.Value, ActivityId); } } } if (result != null) { WorkflowDataContext context = null; var cs = typeof(WorkflowDataContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); ConstructorInfo c = cs.First(); try { object o = c.Invoke(new Object[] { executor, result, true }); context = o as WorkflowDataContext; var vars = context.GetProperties(); foreach (dynamic v in vars) { var value = v.GetValue(context); if (Instance.Variables.ContainsKey(v.DisplayName)) { Instance.Variables[v.DisplayName] = new WorkflowInstanceValueType(v.PropertyType, value); } else { Instance.Variables.Add(v.DisplayName, new WorkflowInstanceValueType(v.PropertyType, value)); } } } catch (Exception ex) { Log.Debug(ex.Message); } } OnVisualTracking?.Invoke(Instance, ActivityId, ChildActivityId, State); } else { // Log.Debug(trackRecord.ToString()); } } catch (Exception ex) { Log.Error(ex.ToString()); } }
public void PushDataToTraceManager(TrackingRecord data) { if (this.PushToTrackingDataManager != true) { return; } TraceEventType eventType = TraceEventType.Information; if (data is ActivityScheduledRecord) { ActivityScheduledRecord record = (ActivityScheduledRecord)data; string displayName = record.Child.Name; if (this.TestTraceManager.TraceFilter.Contains(displayName)) { return; } AddActivityTrace(eventType, record.InstanceId, displayName, ActivityInstanceState.Executing, record); } else if (data is ActivityStateRecord) { ActivityStateRecord record = (ActivityStateRecord)data; if (TryConvertToEnum(record.State, out ActivityInstanceState state)) { string displayName = record.Activity.Name; if (this.TestTraceManager.TraceFilter.Contains(displayName)) { return; } AddActivityTrace(eventType, record.InstanceId, displayName, state, record); } } else if (data is WorkflowInstanceAbortedRecord) { WorkflowInstanceAbortedRecord record = (WorkflowInstanceAbortedRecord)data; AddWorkflowInstanceAbortedTrace(eventType, record.InstanceId, record.Reason); } //else if (data is WorkflowInstanceUpdatedRecord) //{ // WorkflowInstanceUpdatedRecord record = (WorkflowInstanceUpdatedRecord)data; // AddWorkflowInstanceUpdatedTrace(eventType, record.InstanceId, record.OriginalDefinitionIdentity, record.WorkflowDefinitionIdentity, record.State, record.BlockingActivities, record.IsSuccessful); //} else if (data is WorkflowInstanceRecord) { WorkflowInstanceRecord record = (WorkflowInstanceRecord)data; WorkflowInstanceState state = (WorkflowInstanceState)Enum.Parse(typeof(WorkflowInstanceState), record.State); //these are new states that got added as part of the DCR = 109342, we do not contain them in the expceted states, hence //explicitly removing them. have separate test cases to test the states. if ((state == WorkflowInstanceState.Suspended) || (state == WorkflowInstanceState.Unsuspended)) { return; } AddWorkflowInstanceTrace(eventType, record.InstanceId, record.WorkflowDefinitionIdentity, state); } else if (data is BookmarkResumptionRecord record) { AddBookmarkResumptionTrace(eventType, record.InstanceId, record.Owner.Name, record.BookmarkName, record.BookmarkScope); } }
protected override void Track(TrackingRecord trackRecord, TimeSpan timeStamp) { try { string State = "unknown"; Guid InstanceId = trackRecord.InstanceId; ActivityStateRecord activityStateRecord = trackRecord as ActivityStateRecord; ActivityScheduledRecord activityScheduledRecord = trackRecord as ActivityScheduledRecord; //if (activityStateRecord != null || activityScheduledRecord != null) if (activityStateRecord != null) { var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } else { if (v.Value != null) { Instance.Variables.Add(v.Key, new WorkflowInstanceValueType(v.Value.GetType(), v.Value)); } } //wfi.variables.Add(v.Key, v.Value); } } if (activityScheduledRecord != null) { string ActivityId = null; string ChildActivityId = null; if (activityStateRecord != null) { ActivityId = activityStateRecord.Activity.Id; State = activityStateRecord.State.ToLower(); } if (activityScheduledRecord != null) { State = "Scheduled"; if (activityScheduledRecord.Activity != null) { ActivityId = activityScheduledRecord.Activity.Id; } if (activityScheduledRecord.Child != null) { ChildActivityId = activityScheduledRecord.Child.Id; } } if (string.IsNullOrEmpty(ActivityId)) { return; } var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (Instance == null || Instance.wfApp == null) { return; } var wfApp = Instance.wfApp; if (Instance.Variables == null) { Instance.Variables = new Dictionary <string, WorkflowInstanceValueType>(); } if (activityStateRecord != null) { foreach (var v in Instance.Variables.ToList()) { if (!activityStateRecord.Variables.ContainsKey(v.Key)) { Instance.Variables.Remove(v.Key); } } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } } } var executor = typeof(System.Activities.Hosting.WorkflowInstance).GetField("executor", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(wfApp); var instanceMapField = executor.GetType().GetField("instanceMap", BindingFlags.NonPublic | BindingFlags.Instance); // get SerializedProgramMapping to have InstanceMap get filled, needed by SerializedProgramMapping var SerializedProgramMapping = executor.GetType().GetProperty("SerializedProgramMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); ActivityInstance activityInstance = executor.GetType().GetField("rootInstance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor) as ActivityInstance; // Sometimes we can find the ActivityInstance in rootInstance ActivityInstance result = findActivityInstance(executor, activityInstance, ActivityId); // But more often, we find it in InstanceMapping var instanceMap = instanceMapField.GetValue(executor); if (instanceMap != null && result == null) { var _list = SerializedProgramMapping.GetType().GetProperty("InstanceMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(SerializedProgramMapping); foreach (System.Collections.DictionaryEntry kvp in (System.Collections.IDictionary)_list) { var a = kvp.Key as Activity; if (a == null) { continue; } if (result == null && a.Id == ActivityId) { result = findActivityInstance(kvp.Value, ActivityId); } } } if (result != null) { WorkflowDataContext context = null; var cs = typeof(WorkflowDataContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); ConstructorInfo c = cs.First(); try { object o = c.Invoke(new Object[] { executor, result, true }); context = o as WorkflowDataContext; var vars = context.GetProperties(); foreach (dynamic v in vars) { var value = v.GetValue(context); if (Instance.Variables.ContainsKey(v.DisplayName)) { Instance.Variables[v.DisplayName] = new WorkflowInstanceValueType(v.PropertyType, value); } else { Instance.Variables.Add(v.DisplayName, new WorkflowInstanceValueType(v.PropertyType, value)); } } } catch (Exception ex) { Log.Debug(ex.Message); } } OnVisualTracking?.Invoke(Instance, ActivityId, ChildActivityId, State); } else { // Log.Debug(trackRecord.ToString()); } } catch (Exception ex) { Log.Error(ex.ToString()); } }
protected override void Track(TrackingRecord trackRecord, TimeSpan timeStamp) { try { string State = "unknown"; Guid InstanceId = trackRecord.InstanceId; ActivityStateRecord activityStateRecord = trackRecord as ActivityStateRecord; ActivityScheduledRecord activityScheduledRecord = trackRecord as ActivityScheduledRecord; WorkflowInstanceRecord workflowInstanceRecord = trackRecord as WorkflowInstanceRecord; if (workflowInstanceRecord != null) { Log.Activity(workflowInstanceRecord.ActivityDefinitionId + " " + workflowInstanceRecord.State); var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (Instance == null) { return; } lock (Instance) { if (workflowInstanceRecord.State == WorkflowInstanceStates.Started || workflowInstanceRecord.State == WorkflowInstanceStates.Resumed) { lock (timerslock) timers.Add(InstanceId.ToString(), new Dictionary <string, Stopwatch>()); } else if (workflowInstanceRecord.State == WorkflowInstanceStates.Aborted || workflowInstanceRecord.State == WorkflowInstanceStates.Canceled || workflowInstanceRecord.State == WorkflowInstanceStates.Completed || workflowInstanceRecord.State == WorkflowInstanceStates.Deleted || workflowInstanceRecord.State == WorkflowInstanceStates.Suspended || workflowInstanceRecord.State == WorkflowInstanceStates.Terminated || workflowInstanceRecord.State == WorkflowInstanceStates.UnhandledException || workflowInstanceRecord.State == WorkflowInstanceStates.UpdateFailed) { if (timers.ContainsKey(InstanceId.ToString())) { lock (timerslock) timers.Remove(InstanceId.ToString()); } } } } if (activityStateRecord != null) { string ActivityId = null, name = null; var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Id)) { ActivityId = activityStateRecord.Activity.Id; } if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Name)) { name = activityStateRecord.Activity.Name; } // var sw = new Stopwatch(); sw.Start(); Log.Activity(name + " " + activityStateRecord.State); if (timers.ContainsKey(InstanceId.ToString()) && !string.IsNullOrEmpty(ActivityId)) { var timer = timers[InstanceId.ToString()]; if (activityStateRecord.State == ActivityStates.Executing) { if (!timer.ContainsKey(ActivityId)) { Stopwatch sw = new Stopwatch(); sw.Start(); timer.Add(ActivityId, sw); var TypeName = activityStateRecord.Activity.TypeName; var Name = activityStateRecord.Activity.Name; if (String.IsNullOrEmpty(Name)) { Name = TypeName; } if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } } } if (activityStateRecord.State != ActivityStates.Executing) { if (timer.ContainsKey(ActivityId)) { Stopwatch sw = timer[ActivityId]; timer.Remove(ActivityId); var TypeName = activityStateRecord.Activity.TypeName; var Name = activityStateRecord.Activity.Name; if (String.IsNullOrEmpty(Name)) { Name = TypeName; } if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } } } } if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Name) && Instance != null && Instance.Workflow != null) { var TypeName = activityStateRecord.Activity.TypeName; if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } else { if (v.Value != null) { Instance.Variables.Add(v.Key, new WorkflowInstanceValueType(v.Value.GetType(), v.Value)); } } } } if (activityScheduledRecord != null) { var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (Instance == null || Instance.wfApp == null) { return; } var wfApp = Instance.wfApp; var executor = typeof(System.Activities.Hosting.WorkflowInstance).GetField("executor", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(wfApp); var scheduler = executor.GetType().GetField("scheduler", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); string ActivityId = null; string ChildActivityId = null; if (activityStateRecord != null) { ActivityId = activityStateRecord.Activity.Id; State = activityStateRecord.State.ToLower(); } if (activityScheduledRecord != null) { State = "Scheduled"; if (activityScheduledRecord.Activity != null) { ActivityId = activityScheduledRecord.Activity.Id; } if (activityScheduledRecord.Child != null) { ChildActivityId = activityScheduledRecord.Child.Id; } } if (activityScheduledRecord.Activity == null && activityScheduledRecord.Child != null) { // this will make "1" be handles twice, but "1" is always sendt AFTER being scheduled, but we can catch it here ? ActivityId = activityScheduledRecord.Child.Id; ChildActivityId = activityScheduledRecord.Child.Id; } if (string.IsNullOrEmpty(ActivityId)) { return; } if (activityScheduledRecord.Child.Id == "1.11") { // scheduler.GetType().GetMethod("ClearAllWorkItems", BindingFlags.Public | BindingFlags.Instance).Invoke(scheduler, new object[] { executor }); // scheduler.GetType().GetMethod("ScheduleWork", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { false }); //var firstWorkItem = scheduler.GetType().GetField("firstWorkItem", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(scheduler); //firstWorkItem.GetType().GetMethod("Release", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //firstWorkItem.GetType().GetMethod("Dispose", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //scheduler.GetType().GetMethod("NotifyWorkCompletion", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { }); } if (Instance.Variables == null) { Instance.Variables = new Dictionary <string, WorkflowInstanceValueType>(); } if (activityStateRecord != null) { foreach (var v in Instance.Variables.ToList()) { if (!activityStateRecord.Variables.ContainsKey(v.Key)) { Instance.Variables.Remove(v.Key); } } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } } } var instanceMapField = executor.GetType().GetField("instanceMap", BindingFlags.NonPublic | BindingFlags.Instance); // get SerializedProgramMapping to have InstanceMap get filled, needed by SerializedProgramMapping var SerializedProgramMapping = executor.GetType().GetProperty("SerializedProgramMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); ActivityInstance activityInstance = executor.GetType().GetField("rootInstance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor) as ActivityInstance; // Sometimes we can find the ActivityInstance in rootInstance ActivityInstance result = findActivityInstance(executor, activityInstance, ActivityId); // But more often, we find it in InstanceMapping var instanceMap = instanceMapField.GetValue(executor); if (instanceMap != null && result == null) { var _list = SerializedProgramMapping.GetType().GetProperty("InstanceMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(SerializedProgramMapping); foreach (System.Collections.DictionaryEntry kvp in (System.Collections.IDictionary)_list) { var a = kvp.Key as System.Activities.Activity; if (a == null) { continue; } if (result == null && a.Id == ActivityId) { result = findActivityInstance(kvp.Value, ActivityId); } } } if (result != null) { WorkflowDataContext context = null; var cs = typeof(WorkflowDataContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); ConstructorInfo c = cs.First(); try { object o = c.Invoke(new Object[] { executor, result, true }); context = o as WorkflowDataContext; var vars = context.GetProperties(); foreach (dynamic v in vars) { var value = v.GetValue(context); if (Instance.Variables.ContainsKey(v.DisplayName)) { Instance.Variables[v.DisplayName] = new WorkflowInstanceValueType(v.PropertyType, value); } else { Instance.Variables.Add(v.DisplayName, new WorkflowInstanceValueType(v.PropertyType, value)); } } } catch (Exception ex) { Log.Debug(ex.Message); } } OnVisualTracking?.Invoke(Instance, ActivityId, ChildActivityId, State); } } catch (Exception ex) { Log.Error(ex.ToString()); } }