//******************************************************************************************************
// ErrorMonitor.cs - Gbtc
//
// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 3/26/2012 - prasanthgs
// Generated original version of source code.
// 04/12/2012 - prasanthgs
// Reworked as per the comments of codeplex reviewers.
// Reusing ErrorLog instead of creating new table ExceptionLog.
//
//******************************************************************************************************
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using TimeSeriesFramework.UI.DataModels;
using TVA.Data;
namespace TimeSeriesFramework.UI
{
///
/// Provides Error Monitor that checks the ErrorLog
/// to keep the Error Log list updated.
///
///
/// Typically class should be implemented as a singleton since one instance will create.
///
public class ErrorMonitor : IDisposable
{
#region [ Members ]
// Constants
private const int DefaultRefreshInterval = 10;
///
/// Specifies the default value for the property.
///
private const int DefaultErrorLogSize = 2000;
///
/// Event raised when the ErrorList is updated.
///
public event EventHandler UpdatedErrors;
// Fields
private int m_refreshInterval;
private object m_errLock;
private List m_ErrorList;
private System.Timers.Timer m_refreshTimer;
private bool m_disposed;
#endregion
#region [ Constructors ]
///
/// Creates a new instance of the class.
///
/// Indicates whether this instance should
/// be singleton. Default value false
public ErrorMonitor(bool singleton = false)
{
m_refreshInterval = DefaultRefreshInterval;
m_errLock = new object();
m_ErrorList = new List();
m_refreshTimer = new System.Timers.Timer(m_refreshInterval * 1000);
m_refreshTimer.Elapsed += m_refreshTimer_Elapsed;
if (singleton)
Default = this;
}
#endregion
#region [ Properties ]
///
/// Gets or sets the interval, in seconds,
/// between refreshing the error list.
///
public int RefreshInterval
{
get
{
return m_refreshInterval;
}
set
{
m_refreshInterval = value;
m_refreshTimer.Interval = m_refreshInterval * 1000;
}
}
#endregion
#region [ Methods ]
private void m_refreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
RefreshErrorsList();
}
///
/// Reset the refresh interval of Error Monitor to
/// default value = 10 sec(s)
///
public void ResetRefreshInterval()
{
RefreshInterval = DefaultRefreshInterval;
}
///
/// Starts the refresh timer that checks recent errors.
///
public void Start()
{
if (m_disposed)
{
m_refreshTimer = new System.Timers.Timer(m_refreshInterval * 1000);
m_refreshTimer.Elapsed += m_refreshTimer_Elapsed;
m_disposed = false;
}
if (!m_refreshTimer.Enabled)
{
RefreshErrorsList();
m_refreshTimer.Start();
}
}
///
/// Stops the refresh timer.
///
public void Stop()
{
if (m_refreshTimer != null)
{
if (m_refreshTimer.Enabled)
m_refreshTimer.Stop();
}
}
///
/// Gets current Errors.
///
///
public ObservableCollection GetRecentErrors()
{
lock (m_errLock)
{
return new ObservableCollection(m_ErrorList);
}
}
///
/// Performs application-defined tasks associated with freeing, releasing, or
/// resetting unmanaged resources.
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Releases the unmanaged resources used by the
/// object and optionally releases the managed resources.
///
/// true to release both managed and unmanaged resources;
/// false to release only unmanaged resources.
protected virtual void Dispose(bool disposing)
{
if (!m_disposed)
{
try
{
if (disposing)
{
if ((object)m_refreshTimer != null)
{
m_refreshTimer.Dispose();
m_refreshTimer = null;
}
}
}
finally
{
m_disposed = true;
}
}
}
///
/// Fetch recent error details from ErrorLog table.
///
private void RefreshErrorsList()
{
bool createdConnection = false;
AdoDataConnection database = null;
List newTempList = null;
try
{
createdConnection = DataModelBase.CreateConnection(ref database);
DataTable ErrorLogTable = database.Connection.RetrieveData(database.AdapterType,
"SELECT ID, Source, Type, Message, Detail, CreatedOn FROM ErrorLog ORDER BY ID DESC");
// Load only first 2000 Error information to list.
newTempList = ErrorLogTable.Rows.Cast()
.Select(row => new ErrorLog()
{
ID = row.ConvertField("ID"),
Source = row.Field("Source"),
Type = row.Field("Type"),
Message = row.Field("Message"),
Detail = row.Field("Detail"),
CreatedOn = row.Field("CreatedOn")
})
.Distinct()
.Take(DefaultErrorLogSize)
.ToList();
// Update the error list
lock (m_errLock)
{
m_ErrorList = newTempList;
}
// Notify that the ErrorList have been updated
OnUpdatedErrors();
}
catch (Exception)
{
// Do nothing, if exception raised while logging Errors
}
finally
{
if (createdConnection && database != null)
database.Dispose();
}
}
// Triggers the updated ErrorList event.
private void OnUpdatedErrors()
{
if (UpdatedErrors != null)
UpdatedErrors(this, new EventArgs());
}
#endregion
#region [ Static ]
///
/// Gets ErrorMonitor object.
///
public static ErrorMonitor Default { get; set; }
#endregion
}
}