public void LogEvent(Event e) { // Unwrap aggregate exceptions if (e.Exception != null && e.Exception is AggregateException) { Exception ex = e.Exception; while (ex != null && ex is AggregateException) { ex = ex.InnerException; } e.Exception = ex; e.ExceptionType = ex.GetType().ToString(); } lock (this) { foreach (LogWriter writer in writers) { if ((writer.EventSourceMask & e.EventSource) > 0) { writer.WriteEvent(e); } } } }
public override void WriteEvent(Event e) { textWriter.WriteLine("{0} : {1} : {2}", e.EventDateTime, e.Operation, e.ExecutionStatus); if (e.Exception != null) { textWriter.WriteLine(" {0}", e.Exception.Message); } }
/// <summary> /// Process jobs that are found in an intermediate stage, possibly /// due to an unexpected shutdown of the scheduler. /// </summary> private void ProcessInterruptedJobs() { using (Context context = ContextManager.Instance.CreateContext(ConnectionMode.AutoOpen, TransactionMode.AutoCommit)) { int q; Event e; var jf = new JobInstanceFactory(context); q = 1; foreach (var qi in Cluster.Queues.Keys) { // Process previously interrupted jobs (that are marked as running) // Process jobs that are marked as executing - these remained in this state // because of a failure in the scheduler foreach (var j in jf.FindJobInstances(Guid.Empty, qi, null, JobExecutionState.Executing | JobExecutionState.Persisting | JobExecutionState.Cancelling)) { // Locking must be handled context.ContextGuid = j.WorkflowInstanceId; j.ReleaseLock(true); j.JobExecutionStatus = JobExecutionState.Failed; j.ExceptionMessage = Jhu.Graywulf.Registry.ExceptionMessages.SchedulerUnexpectedShutdown; j.Save(); j.RescheduleIfRecurring(); q++; } } if (q > 0) { e = new Event("Jhu.Graywulf.Scheduler.QueueManager.ProcessInterruptedJobs[Executing]", Guid.Empty); e.Message = String.Format("Marked {0} jobs as failed.", q); LogEvent(e); } q = 0; foreach (var qi in Cluster.Queues.Keys) { // Jobs marked as waiting probably can be restarted without a side effect foreach (var j in jf.FindJobInstances(Guid.Empty, qi, null, JobExecutionState.Starting)) { // Locking must be handled context.ContextGuid = j.WorkflowInstanceId; j.ReleaseLock(true); j.JobExecutionStatus = JobExecutionState.Scheduled; j.Save(); q++; } } if (q > 0) { e = new Event("Jhu.Graywulf.Scheduler.QueueManager.ProcessInterruptedJobs[Starting]", Guid.Empty); e.Message = String.Format("Marked {0} jobs as scheduled.", q); LogEvent(e); } } }
/// <summary> /// Starts the scheduler /// </summary> /// <param name="interactive"></param> public void Start(string clusterName, bool interactive) { // Initialize Queue Manager this.interactive = interactive; this.appDomains = new Dictionary<int, AppDomainHost>(); this.runningJobs = new Dictionary<Guid, Job>(); this.eventOrder = 0; this.contextGuid = Guid.NewGuid(); // Initialize logger if (interactive) { Jhu.Graywulf.Logging.Logger.Instance.Writers.Add(new Jhu.Graywulf.Logging.StreamLogWriter(Console.Out)); } Event e = new Event("Jhu.Graywulf.Scheduler.Start", Guid.Empty); e.UserData.Add("MachineName", Environment.MachineName); e.UserData.Add("UserAccount", String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName)); LogEvent(e); // *** TODO: error handling, and repeat a couple of times, then shut down with exception InitializeCluster(clusterName); InitializeScheduler(); ProcessInterruptedJobs(); StartPoller(); }
/// <summary> /// Logs scheduler events /// </summary> /// <param name="e"></param> public void LogEvent(Event e) { e.UserGuid = Guid.Empty; e.EventSource = EventSource.Scheduler; e.ExecutionStatus = ExecutionStatus.Closed; e.JobGuid = Guid.Empty; e.ContextGuid = contextGuid; e.EventOrder = ++eventOrder; Logger.Instance.LogEvent(e); }
/// <summary> /// Writes an event into the log database. /// </summary> /// <param name="e"></param> public void LogEvent(Event e) { e.UserGuid = this.userGuid; e.JobGuid = this.jobGuid; e.ContextGuid = this.contextGuid; e.EventSource = EventSource.Registry; e.ExecutionStatus = ExecutionStatus.Closed; // Logging is different inside activities if (activityContext == null) { // Direct logging invoked from code running outside a workflow. // Event will be written directly into the database. e.EventOrder = ++eventOrder; Logger.Instance.LogEvent(e); } else { // Logging event sent by code running inside a workflow. // In this case event will be routed to the workflow // tracking service. System.Activities.Tracking.CustomTrackingRecord r = new System.Activities.Tracking.CustomTrackingRecord("Jhu.Graywulf.Logging"); r.Data.Add("Jhu.Graywulf.Logging.Event", e); activityContext.Track(r); } }
public Event(Event old) { CopyMembers(old); }
private void CopyMembers(Event old) { this.eventId = old.eventId; this.userGuid = old.userGuid; this.jobGuid = old.jobGuid; this.contextGuid = old.contextGuid; this.eventSource = old.eventSource; this.eventSeverity = old.eventSeverity; this.eventDateTime = old.eventDateTime; this.eventOrder = old.eventOrder; this.executionStatus = old.executionStatus; this.operation = old.operation; this.entityGuid = old.entityGuid; this.entityGuidFrom = old.entityGuidFrom; this.entityGuidTo = old.entityGuidTo; this.exceptionType = old.exceptionType; this.site = old.site; this.message = old.message; this.stackTrace = old.stackTrace; this.userData = new Dictionary<string, object>(old.userData); this.exception = old.exception; }
public virtual void WriteEvent(Event e) { }