Feature/agent finishes (#606)

* added step status

* made job history request faster and efficient

* cr comments
This commit is contained in:
Aditya Bist
2018-05-01 17:41:42 -07:00
committed by GitHub
parent 70724b9167
commit 5a55e8b35c
4 changed files with 162 additions and 180 deletions

View File

@@ -106,7 +106,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
var fetcher = new JobFetcher(serverConnection);
var filter = new JobActivityFilter();
this.jobs = fetcher.FetchJobs(filter);
var agentJobs = new List<AgentJobInfo>();
if (this.jobs != null)
{
@@ -118,8 +117,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
}
result.Succeeded = true;
result.Jobs = agentJobs.ToArray();
sqlConnection.Close();
}
await requestContext.SendResult(result);
}
catch (Exception e)
@@ -142,47 +141,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
out connInfo);
if (connInfo != null)
{
Tuple<SqlConnectionInfo, DataTable> tuple = CreateSqlConnection(connInfo, parameters.JobId);
Tuple<SqlConnectionInfo, DataTable, ServerConnection> tuple = CreateSqlConnection(connInfo, parameters.JobId);
SqlConnectionInfo sqlConnInfo = tuple.Item1;
DataTable dt = tuple.Item2;
ServerConnection connection = tuple.Item3;
int count = dt.Rows.Count;
var agentJobs = new List<AgentJobHistoryInfo>();
var agentStepMap = new Dictionary<DateTime, List<AgentJobStep>>();
for (int i = 0; i < count; ++i)
List<AgentJobHistoryInfo> jobHistories = new List<AgentJobHistoryInfo>();
if (count > 0)
{
var job = dt.Rows[i];
if (JobUtilities.IsStep(job, sqlConnInfo))
{
var agentJobStep = JobUtilities.ConvertToAgentJobStep(job, sqlConnInfo);
if (agentStepMap.ContainsKey(agentJobStep.RunDate))
{
agentStepMap[agentJobStep.RunDate].Add(agentJobStep);
}
else
{
var agentJobSteps = new List<AgentJobStep>();
agentJobSteps.Add(agentJobStep);
agentStepMap[agentJobStep.RunDate] = agentJobSteps;
}
}
else
{
var agentJobHistoryInfo = JobUtilities.ConvertToAgentJobHistoryInfo(job, sqlConnInfo);
agentJobs.Add(agentJobHistoryInfo);
}
var job = dt.Rows[0];
string jobName = Convert.ToString(job[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture);
Guid jobId = (Guid) job[JobUtilities.UrnJobId];
int runStatus = Convert.ToInt32(job[JobUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
var t = new LogSourceJobHistory(jobName, sqlConnInfo, null, runStatus, jobId, null);
var tlog = t as ILogSource;
tlog.Initialize();
var logEntries = t.LogEntries;
jobHistories = JobUtilities.ConvertToAgentJobHistoryInfo(logEntries, job);
tlog.CloseReader();
}
result.Jobs = jobHistories.ToArray();
result.Succeeded = true;
foreach (AgentJobHistoryInfo agentJobHistoryInfo in agentJobs)
{
if (agentStepMap.ContainsKey(agentJobHistoryInfo.RunDate))
{
var agentStepList = agentStepMap[agentJobHistoryInfo.RunDate].ToList();
agentStepList.Sort(delegate (AgentJobStep s1, AgentJobStep s2) { return s1.StepId.CompareTo(s2.StepId); });
agentJobHistoryInfo.Steps = agentStepList.ToArray();
}
}
result.Jobs = agentJobs.ToArray();
connection.Disconnect();
await requestContext.SendResult(result);
}
}
@@ -242,7 +222,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
}
}
private Tuple<SqlConnectionInfo, DataTable> CreateSqlConnection(ConnectionInfo connInfo, String jobId)
private Tuple<SqlConnectionInfo, DataTable, ServerConnection> CreateSqlConnection(ConnectionInfo connInfo, String jobId)
{
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
var serverConnection = new ServerConnection(sqlConnection);
@@ -251,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
filter.JobID = new Guid(jobId);
var dt = server.JobServer.EnumJobHistory(filter);
var sqlConnInfo = new SqlConnectionInfo(serverConnection, SqlServer.Management.Common.ConnectionType.SqlConnection);
return new Tuple<SqlConnectionInfo, DataTable>(sqlConnInfo, dt);
return new Tuple<SqlConnectionInfo, DataTable, ServerConnection>(sqlConnInfo, dt, serverConnection);
}
}

View File

@@ -18,27 +18,27 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
public class AgentJobHistoryInfo
{
public int InstanceId { get; set; }
public int SqlMessageId { get; set; }
public string SqlMessageId { get; set; }
public string Message { get; set; }
public int StepId { get; set; }
public string StepId { get; set; }
public string StepName { get; set; }
public int SqlSeverity { get; set; }
public string SqlSeverity { get; set; }
public Guid JobId { get; set; }
public string JobName { get; set; }
public int RunStatus { get; set; }
public DateTime RunDate { get; set; }
public int RunDuration { get; set; }
public string RunDuration { get; set; }
public string OperatorEmailed { get; set; }
public string OperatorNetsent { get; set; }
public string OperatorPaged { get; set; }
public int RetriesAttempted { get; set; }
public string RetriesAttempted { get; set; }
public string Server { get; set; }
public AgentJobStep[] Steps { get; set; }
}
public class AgentJobStep
{
public int StepId { get; set; }
public string StepId { get; set; }
public string StepName { get; set; }
public string Message { get; set; }
public DateTime RunDate { get; set; }

View File

@@ -38,33 +38,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
Error
}
/// <summary>
/// command that can be executed by a log viewer (ILogViewer)
/// </summary>
internal enum LogViewerCommand
{
Load = 0,
Refresh,
Export,
Columns,
Filter,
Search,
Delete,
Help,
Close,
Cancel
}
/// <summary>
/// command options
/// </summary>
internal enum LogViewerCommandOption
{
None = 0,
Hide,
Show
}
public interface ILogEntry
{
string OriginalSourceTypeName {get;}
@@ -79,15 +52,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
internal class LogSourceJobHistory : ILogSource, IDisposable //, ITypedColumns, ILogCommandTarget
{
internal const string JobDialogParameterTemplate = "<params><jobid></jobid></params>";
internal const string JobStepDialogParameterTemplate = "<params><jobid></jobid><acceptedits>true</acceptedits></params>";
internal enum DialogType
{
JobDialog = 0,
JobStepDialog = 1
}
#region Variables
private string m_jobName = null;
//assigning invalid jobCategoryId
@@ -105,8 +69,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
private TypedColumnCollection columnTypes;
private IServiceProvider serviceProvider = null;
// ILogCommandHandler m_customCommandHandler = null;
private static string historyTableDeclaration = "declare @tmp_sp_help_jobhistory table";
private static string historyTableDeclaration80 = "create table #tmp_sp_help_jobhistory";
private static string historyTableName = "@tmp_sp_help_jobhistory";
@@ -173,6 +135,14 @@ ORDER BY [InstanceID] ASC";
return m_jobName;
}
}
public List<ILogEntry> LogEntries
{
get
{
return m_logEntries;
}
}
#endregion
public void Dispose()
@@ -206,11 +176,8 @@ ORDER BY [InstanceID] ASC";
}
}
#region Constructor
public LogSourceJobHistory(string jobName, SqlConnectionInfo sqlCi, object customCommandHandler, int jobCategoryId, Guid JobId, IServiceProvider serviceProvider)
{
m_logName = jobName;
@@ -429,27 +396,8 @@ ORDER BY [InstanceID] ASC";
/// </summary>
internal class LogEntryJobHistory : ILogEntry
{
#region Constants
internal const string cUrnRunDate = "RunDate";
internal const string cUrnRunStatus = "RunStatus";
internal const string cUrnRunDuration = "RunDuration";
internal const string cUrnJobName = "JobName";
internal const string cUrnStepID = "StepID";
internal const string cUrnStepName = "StepName";
internal const string cUrnMessage = "Message";
internal const string cUrnSqlSeverity = "SqlSeverity";
internal const string cUrnSqlMessageID = "SqlMessageID";
internal const string cUrnOperatorEmailed = "OperatorEmailed";
internal const string cUrnOperatorNetsent = "OperatorNetsent";
internal const string cUrnOperatorPaged = "OperatorPaged";
internal const string cUrnRetriesAttempted = "RetriesAttempted";
internal const string cUrnServerName = "Server";
internal const string cUrnServerTime = "CurrentDate";
internal const string cUrnInstanceID = "InstanceID"; // internally used by Agent to mark order in which steps were executed
#endregion
#region Variables
string m_originalSourceName = null;
DateTime m_pointInTime = DateTime.MinValue;
@@ -526,10 +474,10 @@ ORDER BY [InstanceID] ASC";
{
m_originalSourceName = sourceName;
m_pointInTime = Convert.ToDateTime(dr[cUrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
m_serverName = Convert.ToString(dr[cUrnServerName], System.Globalization.CultureInfo.InvariantCulture);
m_fieldJobName = Convert.ToString(dr[cUrnJobName], System.Globalization.CultureInfo.InvariantCulture);
switch ((Microsoft.SqlServer.Management.Smo.Agent.CompletionResult)Convert.ToInt32(dr[cUrnRunStatus], System.Globalization.CultureInfo.InvariantCulture))
m_pointInTime = Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
m_serverName = Convert.ToString(dr[JobUtilities.UrnServer], System.Globalization.CultureInfo.InvariantCulture);
m_fieldJobName = Convert.ToString(dr[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture);
switch ((Microsoft.SqlServer.Management.Smo.Agent.CompletionResult)Convert.ToInt32(dr[JobUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture))
{
case CompletionResult.Cancelled:
m_severity = SeverityClass.Cancelled;
@@ -576,7 +524,7 @@ ORDER BY [InstanceID] ASC";
// if stepId is zero then dont show stepID and step name in log viewer
// Valid step Ids starts from index 1
int currentStepId = (int)dr[cUrnStepID];
int currentStepId = (int)dr[JobUtilities.UrnStepID];
if (currentStepId == 0)
{
m_fieldStepID = String.Empty;
@@ -586,18 +534,18 @@ ORDER BY [InstanceID] ASC";
else
{
m_fieldStepID = Convert.ToString(currentStepId, System.Globalization.CultureInfo.CurrentCulture);
m_fieldStepName = Convert.ToString(dr[cUrnStepName], System.Globalization.CultureInfo.CurrentCulture);
m_fieldStepName = Convert.ToString(dr[JobUtilities.UrnStepName], System.Globalization.CultureInfo.CurrentCulture);
}
m_fieldMessage = Convert.ToString(dr[cUrnMessage], System.Globalization.CultureInfo.CurrentCulture);
m_fieldSqlSeverity = Convert.ToString(dr[cUrnSqlSeverity], System.Globalization.CultureInfo.CurrentCulture);
m_fieldSqlMessageID = Convert.ToString(dr[cUrnSqlMessageID], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorEmailed = Convert.ToString(dr[cUrnOperatorEmailed], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorNetsent = Convert.ToString(dr[cUrnOperatorNetsent], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorPaged = Convert.ToString(dr[cUrnOperatorPaged], System.Globalization.CultureInfo.CurrentCulture);
m_fieldRetriesAttempted = Convert.ToString(dr[cUrnRetriesAttempted], System.Globalization.CultureInfo.CurrentCulture);
m_fieldMessage = Convert.ToString(dr[JobUtilities.UrnMessage], System.Globalization.CultureInfo.CurrentCulture);
m_fieldSqlSeverity = Convert.ToString(dr[JobUtilities.UrnSqlSeverity], System.Globalization.CultureInfo.CurrentCulture);
m_fieldSqlMessageID = Convert.ToString(dr[JobUtilities.UrnSqlMessageID], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorEmailed = Convert.ToString(dr[JobUtilities.UrnOperatorEmailed], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorNetsent = Convert.ToString(dr[JobUtilities.UrnOperatorNetsent], System.Globalization.CultureInfo.CurrentCulture);
m_fieldOperatorPaged = Convert.ToString(dr[JobUtilities.UrnOperatorPaged], System.Globalization.CultureInfo.CurrentCulture);
m_fieldRetriesAttempted = Convert.ToString(dr[JobUtilities.UrnRetriesAttempted], System.Globalization.CultureInfo.CurrentCulture);
Int64 hhmmss = Convert.ToInt64(dr[cUrnRunDuration], System.Globalization.CultureInfo.InvariantCulture); // HHMMSS
Int64 hhmmss = Convert.ToInt64(dr[JobUtilities.UrnRunDuration], System.Globalization.CultureInfo.InvariantCulture); // HHMMSS
int hh = Convert.ToInt32(hhmmss / 10000, System.Globalization.CultureInfo.InvariantCulture);
int mm = Convert.ToInt32((hhmmss / 100) % 100, System.Globalization.CultureInfo.InvariantCulture);
int ss = Convert.ToInt32(hhmmss % 100, System.Globalization.CultureInfo.InvariantCulture);
@@ -630,7 +578,7 @@ ORDER BY [InstanceID] ASC";
{
DataRow dr = dt.Rows[i];
object o = dr[cUrnStepID];
object o = dr[JobUtilities.UrnStepID];
try
{
@@ -668,8 +616,8 @@ ORDER BY [InstanceID] ASC";
{
m_originalSourceName = sourceName;
m_pointInTime = Convert.ToDateTime(dr[cUrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
m_fieldJobName = Convert.ToString(dr[cUrnJobName], System.Globalization.CultureInfo.InvariantCulture);
m_pointInTime = Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
m_fieldJobName = Convert.ToString(dr[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture);
m_severity = SeverityClass.InProgress;
@@ -684,7 +632,7 @@ ORDER BY [InstanceID] ASC";
m_fieldRetriesAttempted = null;
m_serverName = null;
m_fieldDuration = Convert.ToString(Convert.ToDateTime(dr[cUrnServerTime]) - Convert.ToDateTime(dr[cUrnRunDate], System.Globalization.CultureInfo.InvariantCulture), System.Globalization.CultureInfo.InvariantCulture);
m_fieldDuration = Convert.ToString(Convert.ToDateTime(dr[JobUtilities.UrnServerTime]) - Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture), System.Globalization.CultureInfo.InvariantCulture);
}
catch (InvalidCastException)
{
@@ -745,6 +693,69 @@ ORDER BY [InstanceID] ASC";
{
get { return m_subEntries; }
}
/* Public Properties */
internal string Duration
{
get { return m_fieldDuration; }
}
internal string JobName
{
get { return m_fieldJobName; }
}
internal string Message
{
get { return m_fieldMessage; }
}
internal string StepID
{
get { return m_fieldStepID; }
}
internal string OperatorEmailed
{
get { return m_fieldOperatorEmailed; }
}
internal string OperatorNetsent
{
get { return m_fieldOperatorNetsent; }
}
internal string OperatorPaged
{
get { return m_fieldOperatorPaged; }
}
internal string StepName
{
get { return m_fieldStepName; }
}
internal string RetriesAttempted
{
get { return m_fieldRetriesAttempted; }
}
internal string SqlMessageID
{
get { return m_fieldSqlMessageID; }
}
internal string SqlSeverity
{
get { return m_fieldSqlSeverity; }
}
internal string Server
{
get { return m_serverName; }
}
#endregion
}
#endregion

View File

@@ -33,6 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
public const string UrnOperatorPaged = "OperatorPaged";
public const string UrnRetriesAttempted = "RetriesAttempted";
public const string UrnServer = "Server";
internal const string UrnServerTime = "CurrentDate";
public static AgentJobInfo ConvertToAgentJobInfo(JobProperties job)
{
@@ -56,64 +57,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
};
}
public static bool IsStep(DataRow row, SqlConnectionInfo sqlConnectionInfo)
public static AgentJobStep ConvertToAgentJobStep(ILogEntry logEntry, DataRow jobRow)
{
int stepId = Convert.ToInt32(row[UrnStepID], System.Globalization.CultureInfo.InvariantCulture);
return stepId != 0;
}
public static AgentJobHistoryInfo ConvertToAgentJobHistoryInfo(DataRow jobRow, SqlConnectionInfo sqlConnInfo)
{
// get all the values for a job history
int instanceId = Convert.ToInt32(jobRow[UrnInstanceID], System.Globalization.CultureInfo.InvariantCulture);
int sqlMessageId = Convert.ToInt32(jobRow[UrnSqlMessageID], System.Globalization.CultureInfo.InvariantCulture);
string message = Convert.ToString(jobRow[UrnMessage], System.Globalization.CultureInfo.InvariantCulture);
int stepId = Convert.ToInt32(jobRow[UrnStepID], System.Globalization.CultureInfo.InvariantCulture);
string stepName = Convert.ToString(jobRow[UrnStepName], System.Globalization.CultureInfo.InvariantCulture);
int sqlSeverity = Convert.ToInt32(jobRow[UrnSqlSeverity], System.Globalization.CultureInfo.InvariantCulture);
Guid jobId = (Guid) jobRow[UrnJobId];
string jobName = Convert.ToString(jobRow[UrnJobName], System.Globalization.CultureInfo.InvariantCulture);
int runStatus = Convert.ToInt32(jobRow[UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
DateTime runDate = Convert.ToDateTime(jobRow[UrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
int runDuration = Convert.ToInt32(jobRow[UrnRunDuration], System.Globalization.CultureInfo.InvariantCulture);
string operatorEmailed = Convert.ToString(jobRow[UrnOperatorEmailed], System.Globalization.CultureInfo.InvariantCulture);
string operatorNetsent = Convert.ToString(jobRow[UrnOperatorNetsent], System.Globalization.CultureInfo.InvariantCulture);
string operatorPaged = Convert.ToString(jobRow[UrnOperatorPaged], System.Globalization.CultureInfo.InvariantCulture);
int retriesAttempted = Convert.ToInt32(jobRow[UrnRetriesAttempted], System.Globalization.CultureInfo.InvariantCulture);
string server = Convert.ToString(jobRow[UrnServer], System.Globalization.CultureInfo.InvariantCulture);
// initialize logger
var t = new LogSourceJobHistory(jobName, sqlConnInfo, null, runStatus, jobId, null);
var tlog = t as ILogSource;
tlog.Initialize();
// return new job history object as a result
var jobHistoryInfo = new AgentJobHistoryInfo();
jobHistoryInfo.InstanceId = instanceId;
jobHistoryInfo.SqlMessageId = sqlMessageId;
jobHistoryInfo.Message = message;
jobHistoryInfo.StepId = stepId;
jobHistoryInfo.StepName = stepName;
jobHistoryInfo.SqlSeverity = sqlSeverity;
jobHistoryInfo.JobId = jobId;
jobHistoryInfo.JobName = jobName;
jobHistoryInfo.RunStatus = runStatus;
jobHistoryInfo.RunDate = runDate;
jobHistoryInfo.RunDuration = runDuration;
jobHistoryInfo.OperatorEmailed = operatorEmailed;
jobHistoryInfo.OperatorNetsent = operatorNetsent;
jobHistoryInfo.OperatorPaged = operatorPaged;
jobHistoryInfo.RetriesAttempted = retriesAttempted;
jobHistoryInfo.Server = server;
return jobHistoryInfo;
}
public static AgentJobStep ConvertToAgentJobStep(DataRow jobRow, SqlConnectionInfo sqlConnInfo)
{
int stepId = Convert.ToInt32(jobRow[UrnStepID], System.Globalization.CultureInfo.InvariantCulture);
string stepName = Convert.ToString(jobRow[UrnStepName], System.Globalization.CultureInfo.InvariantCulture);
string message = Convert.ToString(jobRow[UrnMessage], System.Globalization.CultureInfo.InvariantCulture);
DateTime runDate = Convert.ToDateTime(jobRow[UrnRunDate], System.Globalization.CultureInfo.InvariantCulture);
var entry = logEntry as LogSourceJobHistory.LogEntryJobHistory;
string stepId = entry.StepID;
string stepName = entry.StepName;
string message = entry.Message;
DateTime runDate = logEntry.PointInTime;
int runStatus = Convert.ToInt32(jobRow[UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
AgentJobStep step = new AgentJobStep();
step.StepId = stepId;
@@ -123,5 +73,46 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
step.RunStatus = runStatus;
return step;
}
public static List<AgentJobHistoryInfo> ConvertToAgentJobHistoryInfo(List<ILogEntry> logEntries, DataRow jobRow)
{
List<AgentJobHistoryInfo> jobs = new List<AgentJobHistoryInfo>();
// get all the values for a job history
foreach (ILogEntry entry in logEntries)
{
// Make a new AgentJobHistoryInfo object
var jobHistoryInfo = new AgentJobHistoryInfo();
jobHistoryInfo.InstanceId = Convert.ToInt32(jobRow[UrnInstanceID], System.Globalization.CultureInfo.InvariantCulture);
jobHistoryInfo.RunStatus = Convert.ToInt32(jobRow[UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
jobHistoryInfo.JobId = (Guid) jobRow[UrnJobId];
var logEntry = entry as LogSourceJobHistory.LogEntryJobHistory;
jobHistoryInfo.SqlMessageId = logEntry.SqlMessageID;
jobHistoryInfo.Message = logEntry.Message;
jobHistoryInfo.StepId = logEntry.StepID;
jobHistoryInfo.StepName = logEntry.StepName;
jobHistoryInfo.SqlSeverity = logEntry.SqlSeverity;
jobHistoryInfo.JobName = logEntry.JobName;
jobHistoryInfo.RunDate = entry.PointInTime;
jobHistoryInfo.RunDuration = logEntry.Duration;
jobHistoryInfo.OperatorEmailed = logEntry.OperatorEmailed;
jobHistoryInfo.OperatorNetsent = logEntry.OperatorNetsent;
jobHistoryInfo.OperatorPaged = logEntry.OperatorPaged;
jobHistoryInfo.RetriesAttempted = logEntry.RetriesAttempted;
jobHistoryInfo.Server = logEntry.Server;
// Add steps to the job if any
var jobSteps = new List<AgentJobStep>();
if (entry.CanLoadSubEntries)
{
foreach (ILogEntry step in entry.SubEntries)
{
jobSteps.Add(JobUtilities.ConvertToAgentJobStep(step, jobRow));
}
}
jobHistoryInfo.Steps = jobSteps.ToArray();
jobs.Add(jobHistoryInfo);
}
return jobs;
}
}
}