From fc47fc619f75a919b297489a4e34e0247030c586 Mon Sep 17 00:00:00 2001 From: "Martin Hinshelwood nkdAgility.com" Date: Sun, 14 Jul 2024 13:39:03 +0100 Subject: [PATCH] Update with better error reporting. (#2148) This fix addre more error reporting so that we can see better what is going on. --- docs/Reference/Generated/MigrationTools.xml | 2 +- .../Endpoints/TfsEndpoint.cs | 11 +++++++---- .../Enrichers/TfsEmbededImagesEnricher.cs | 3 ++- .../Enrichers/TfsGitRepositoryEnricher.cs | 2 +- .../Enrichers/TfsWorkItemEmbededLinkEnricher.cs | 6 ++++-- .../FieldMaps/FieldClearMap.cs | 2 +- .../FieldMaps/FieldLiteralMap.cs | 2 +- .../FieldMaps/FieldMapBase.cs | 6 +++++- .../FieldMaps/FieldMergeMap.cs | 2 +- .../FieldMaps/FieldSkipMap.cs | 2 +- .../FieldMaps/FieldToFieldMap.cs | 2 +- .../FieldMaps/FieldToTagFieldMap.cs | 2 +- .../FieldMaps/FieldValueMap.cs | 2 +- .../FieldMaps/FieldValuetoTagMap.cs | 2 +- .../FieldMaps/FieldtoFieldMultiMap.cs | 2 +- .../FieldMaps/MultiValueConditionalMap.cs | 2 +- .../FieldMaps/RegexFieldMap.cs | 2 +- .../FieldMaps/TreeToTagFieldMap.cs | 2 +- .../ProcessorEnrichers/TfsAttachmentEnricher.cs | 7 +++++-- .../ProcessorEnrichers/TfsNodeStructure.cs | 6 ++++-- .../ProcessorEnrichers/TfsRevisionManager.cs | 4 ++-- .../TfsTeamSettingsEnricher.cs | 5 ++++- .../ProcessorEnrichers/TfsUserMappingEnricher.cs | 3 ++- .../TfsValidateRequiredField.cs | 2 +- .../TfsWorkItemLinkEnricher.cs | 16 ++++++++++------ .../Processors/TfsTeamSettingsProcessor.cs | 7 +++++-- .../Enrichers/EmbededImagesRepairEnricher.cs | 2 +- src/MigrationTools.Host/ExecuteHostedService.cs | 6 +++++- src/MigrationTools.Host/InitHostedService.cs | 1 + .../ProcessorEnrichers/PauseAfterEachItem.cs | 2 +- .../AppendMigrationToolSignatureFooter.cs | 2 +- .../FilterWorkItemsThatAlreadyExistInTarget.cs | 2 +- .../SkipToFinalRevisedWorkItemType.cs | 2 +- .../StringManipulatorEnricher.cs | 4 ++-- .../WorkItemProcessorEnricher.cs | 4 +++- src/MigrationTools/Services/ITelemetryLogger.cs | 2 +- .../Services/TelemetryClientAdapter.cs | 5 +++-- .../Enrichers/EmbededImagesRepairEnricherBase.cs | 2 +- .../TestPlansAndSuitesMigrationContext.cs | 2 +- .../MigrationContext/WorkItemMigrationContext.cs | 8 ++++++++ 40 files changed, 95 insertions(+), 53 deletions(-) diff --git a/docs/Reference/Generated/MigrationTools.xml b/docs/Reference/Generated/MigrationTools.xml index b384d763b..9a3480cc5 100644 --- a/docs/Reference/Generated/MigrationTools.xml +++ b/docs/Reference/Generated/MigrationTools.xml @@ -576,7 +576,7 @@ - + from https://gist.github.com/pietergheysens/792ed505f09557e77ddfc1b83531e4fb diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Endpoints/TfsEndpoint.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Endpoints/TfsEndpoint.cs index 21f1229d2..14d0e5a02 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Endpoints/TfsEndpoint.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Endpoints/TfsEndpoint.cs @@ -115,6 +115,7 @@ private TfsTeamProjectCollection GetTfsCollection() { timer.Stop(); Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", Options.Organisation, "GetTfsCollection", null, startTime, timer.Elapsed, "500", false)); + Telemetry.TrackException(ex, null, null); Log.LogError(ex, "Unable to connect to {Organisation}", Options.Organisation); throw; } @@ -131,16 +132,18 @@ private WorkItemStore GetWorkItemStore(TfsTeamProjectCollection tfs, WorkItemSto try { _Store = new WorkItemStore(tfs, bypassRules); - timer.Stop(); - Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", Options.Organisation, "GetWorkItemStore", null, startTime, timer.Elapsed, "200", true)); } catch (Exception ex) { - timer.Stop(); - Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", Options.Organisation, "GetWorkItemStore", null, startTime, timer.Elapsed, "500", false)); + Telemetry.TrackException(ex, null, null); Log.LogError(ex, "Unable to connect to {Organisation} Store", Options.Organisation); throw; } + finally + { + timer.Stop(); + Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", Options.Organisation, "GetWorkItemStore", null, startTime, timer.Elapsed, "200", true)); + } } return _Store; diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsEmbededImagesEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsEmbededImagesEnricher.cs index 1922d2cca..b354035de 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsEmbededImagesEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsEmbededImagesEnricher.cs @@ -32,7 +32,7 @@ public class TfsEmbededImagesEnricher : EmbededImagesRepairEnricherBase public IMigrationEngine Engine { get; private set; } - public TfsEmbededImagesEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsEmbededImagesEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); _targetProject = Engine.Target.WorkItems.Project.ToProject(); @@ -118,6 +118,7 @@ protected override void FixEmbededImages(WorkItemData wi, string oldTfsurl, stri catch (Exception ex) { Log.LogError(ex, "EmbededImagesRepairEnricher: Unable to fix HTML field attachments for work item {wiId} from {oldTfsurl} to {newTfsurl}", wi.Id, oldTfsurl, newTfsurl); + Telemetry.TrackException(ex, null, null); } } } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsGitRepositoryEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsGitRepositoryEnricher.cs index e0f6b9e09..4cf5bb29a 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsGitRepositoryEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsGitRepositoryEnricher.cs @@ -30,7 +30,7 @@ public class TfsGitRepositoryEnricher : WorkItemProcessorEnricher public IMigrationEngine Engine { get => _Engine; set => _Engine = value; } - public TfsGitRepositoryEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsGitRepositoryEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = Services.GetRequiredService(); _Logger = logger ?? throw new ArgumentNullException(nameof(logger)); diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsWorkItemEmbededLinkEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsWorkItemEmbededLinkEnricher.cs index 8de5ec9d3..329f0178d 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsWorkItemEmbededLinkEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsWorkItemEmbededLinkEnricher.cs @@ -21,8 +21,8 @@ public class TfsWorkItemEmbededLinkEnricher : WorkItemProcessorEnricher private readonly Lazy> _targetTeamFoundationIdentitiesLazyCache; private readonly IMigrationEngine Engine; - public TfsWorkItemEmbededLinkEnricher(IServiceProvider services, ILogger logger) - : base(services, logger) + public TfsWorkItemEmbededLinkEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) + : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); @@ -40,6 +40,7 @@ public TfsWorkItemEmbededLinkEnricher(IServiceProvider services, ILogger(); } }); @@ -136,6 +137,7 @@ public override int Enrich(WorkItemData sourceWorkItem, WorkItemData targetWorkI catch (Exception ex) { Log.LogError(ex, "{LogTypeName}: Unable to fix embedded mention links on field {fieldName} on target work item {targetWorkItemId} from {oldTfsurl} to {newTfsurl}", LogTypeName, field.Name, targetWorkItem.Id, oldTfsurl, newTfsurl); + Telemetry.TrackException(ex, null, null); } } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldClearMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldClearMap.cs index 4e9c9daf2..d68a3ef7e 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldClearMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldClearMap.cs @@ -7,7 +7,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldClearMap : FieldMapBase { - public FieldClearMap(ILogger logger) : base(logger) + public FieldClearMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldLiteralMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldLiteralMap.cs index 02237c026..01d7164a7 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldLiteralMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldLiteralMap.cs @@ -8,7 +8,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldLiteralMap : FieldMapBase { - public FieldLiteralMap(ILogger logger) : base(logger) + public FieldLiteralMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMapBase.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMapBase.cs index 53436cf02..27f96513b 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMapBase.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMapBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Microsoft.ApplicationInsights.Channel; using Microsoft.Extensions.Logging; using Microsoft.TeamFoundation.WorkItemTracking.Client; using MigrationTools._EngineV1.Configuration; @@ -11,10 +12,12 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel public abstract class FieldMapBase : IFieldMap { protected IFieldMapConfig _Config; + protected ITelemetryLogger Telemetry; - public FieldMapBase(ILogger logger) + public FieldMapBase(ILogger logger, ITelemetryLogger telemetryLogger) { Log = logger; + Telemetry = telemetryLogger; } public virtual void Configure(IFieldMapConfig config) @@ -42,6 +45,7 @@ public void Execute(WorkItemData source, WorkItemData target) { "Source", source.ToWorkItem().Id.ToString() }, { "Target", target.ToWorkItem().Id.ToString()} }); + Telemetry.TrackException(ex, null, null); } } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMergeMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMergeMap.cs index 3c741ce49..68a18bd89 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMergeMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldMergeMap.cs @@ -10,7 +10,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldMergeMap : FieldMapBase { - public FieldMergeMap(ILogger logger) : base(logger) + public FieldMergeMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldSkipMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldSkipMap.cs index 2318a1177..a01ccbecc 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldSkipMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldSkipMap.cs @@ -7,7 +7,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldSkipMap : FieldMapBase { - public FieldSkipMap(ILogger logger) : base(logger) + public FieldSkipMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToFieldMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToFieldMap.cs index faede14b5..eca098e06 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToFieldMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToFieldMap.cs @@ -7,7 +7,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldToFieldMap : FieldMapBase { - public FieldToFieldMap(ILogger logger) : base(logger) + public FieldToFieldMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToTagFieldMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToTagFieldMap.cs index 1e9f1aa27..a6b61b2d5 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToTagFieldMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldToTagFieldMap.cs @@ -9,7 +9,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldToTagFieldMap : FieldMapBase { - public FieldToTagFieldMap(ILogger logger) : base(logger) + public FieldToTagFieldMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValueMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValueMap.cs index 2d63f05ad..d62836170 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValueMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValueMap.cs @@ -9,7 +9,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldValueMap : FieldMapBase { - public FieldValueMap(ILogger logger) : base(logger) + public FieldValueMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValuetoTagMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValuetoTagMap.cs index b4a0b0027..eec35f924 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValuetoTagMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldValuetoTagMap.cs @@ -10,7 +10,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldValuetoTagMap : FieldMapBase { - public FieldValuetoTagMap(ILogger logger) : base(logger) + public FieldValuetoTagMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldtoFieldMultiMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldtoFieldMultiMap.cs index 18972d5a9..e2efbe311 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldtoFieldMultiMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/FieldtoFieldMultiMap.cs @@ -8,7 +8,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class FieldtoFieldMultiMap : FieldMapBase { - public FieldtoFieldMultiMap(ILogger logger) : base(logger) + public FieldtoFieldMultiMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/MultiValueConditionalMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/MultiValueConditionalMap.cs index d1d84e23f..49a23ec03 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/MultiValueConditionalMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/MultiValueConditionalMap.cs @@ -8,7 +8,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class MultiValueConditionalMap : FieldMapBase { - public MultiValueConditionalMap(ILogger logger) : base(logger) + public MultiValueConditionalMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/RegexFieldMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/RegexFieldMap.cs index c521e96e5..843fcd9e2 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/RegexFieldMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/RegexFieldMap.cs @@ -10,7 +10,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class RegexFieldMap : FieldMapBase { - public RegexFieldMap(ILogger logger) : base(logger) + public RegexFieldMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/TreeToTagFieldMap.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/TreeToTagFieldMap.cs index 9ab681a8f..a8c4926cd 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/TreeToTagFieldMap.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/FieldMaps/TreeToTagFieldMap.cs @@ -9,7 +9,7 @@ namespace MigrationTools.FieldMaps.AzureDevops.ObjectModel { public class TreeToTagFieldMap : FieldMapBase { - public TreeToTagFieldMap(ILogger logger) : base(logger) + public TreeToTagFieldMap(ILogger logger, ITelemetryLogger telemetryLogger) : base(logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsAttachmentEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsAttachmentEnricher.cs index c77a010ac..98355d3e4 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsAttachmentEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsAttachmentEnricher.cs @@ -25,7 +25,7 @@ public class TfsAttachmentEnricher : WorkItemProcessorEnricher, IAttachmentMigra public TfsAttachmentEnricherOptions Options { get { return _options; } } - public TfsAttachmentEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsAttachmentEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { } @@ -75,6 +75,7 @@ public void ProcessAttachemnts(WorkItemData source, WorkItemData target, bool sa catch (Exception ex) { Log.LogError(ex, "AttachmentMigrationEnricher:Unable to process atachment from source wi {SourceWorkItemId} called {AttachmentName}", source.ToWorkItem().Id, wia.Name); + Telemetry.TrackException(ex, null, null); } } if (save) @@ -95,9 +96,10 @@ public void CleanUpAfterSave() Directory.Delete(_exportWiPath, true); _exportWiPath = null; } - catch (Exception) + catch (Exception ex) { Log.LogWarning(" ERROR: Unable to delete folder {0}", _exportWiPath); + Telemetry.TrackException(ex, null, null); } } } @@ -121,6 +123,7 @@ private string ExportAttachment(WorkItem wi, Attachment wia, string exportpath) catch (Exception ex) { Log.LogError(ex, "Exception downloading attachements"); + Telemetry.TrackException(ex, null, null); return null; } } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsNodeStructure.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsNodeStructure.cs index 4914b75c9..8b5883030 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsNodeStructure.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsNodeStructure.cs @@ -60,8 +60,8 @@ public class TfsNodeStructure : WorkItemProcessorEnricher private string _targetProjectName; private KeyValuePair? _lastResortRemapRule; - public TfsNodeStructure(IServiceProvider services, ILogger logger) - : base(services, logger) + public TfsNodeStructure(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) + : base(services, logger, telemetryLogger) { contextLog = Serilog.Log.ForContext(); } @@ -182,6 +182,7 @@ private NodeInfo GetOrCreateNode(string nodePath, DateTime? startDate, DateTime? } catch (Exception ex) { Log.LogDebug(" Not Found:", currentAncestorPath); + Telemetry.TrackException(ex, null, null); parentNode = null; } @@ -470,6 +471,7 @@ private void ProcessCommonStructure(string treeTypeSource, string localizedTreeT { Exception ex2 = new Exception(string.Format("Unable to load Common Structure for Target.This is usually due to different language versions. Validate that '{0}' is the correct name in your version. ", localizedTreeTypeName), ex); Log.LogError(ex2, "Unable to load Common Structure for Target."); + Telemetry.TrackException(ex2, null, null); throw ex2; } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsRevisionManager.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsRevisionManager.cs index 85ed3087a..2f921c14b 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsRevisionManager.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsRevisionManager.cs @@ -20,8 +20,8 @@ namespace MigrationTools.Enrichers /// public class TfsRevisionManager : WorkItemProcessorEnricher { - public TfsRevisionManager(IServiceProvider services, ILogger logger) - : base(services, logger) + public TfsRevisionManager(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) + : base(services, logger, telemetryLogger) { } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsTeamSettingsEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsTeamSettingsEnricher.cs index 3c43427e4..6e49637f3 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsTeamSettingsEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsTeamSettingsEnricher.cs @@ -45,7 +45,7 @@ public class TfsTeamSettingsEnricher : WorkItemProcessorEnricher public TfsTeamSettingsEnricherOptions Options { get; private set; } - public TfsTeamSettingsEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsTeamSettingsEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Services = services; Engine = services.GetRequiredService(); @@ -60,6 +60,7 @@ public TfsTeamSettingsEnricher(IServiceProvider services, ILogger(); } }); @@ -336,6 +337,7 @@ private void MigrateCapacities(TeamFoundationTeam sourceTeam, TeamFoundationTeam } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); Log.LogError(ex, "[SKIP] Problem migrating team capacities for iteration {iteration}.", sourceIteration.Path); } @@ -343,6 +345,7 @@ private void MigrateCapacities(TeamFoundationTeam sourceTeam, TeamFoundationTeam } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); Log.LogError(ex, "[SKIP] Problem migrating team capacities."); } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsUserMappingEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsUserMappingEnricher.cs index 8ce691cbf..4a37d0c18 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsUserMappingEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsUserMappingEnricher.cs @@ -48,7 +48,7 @@ private IGroupSecurityService GssTarget public TfsUserMappingEnricherOptions Options { get; private set; } - public TfsUserMappingEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsUserMappingEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); } @@ -178,6 +178,7 @@ private List GetUsersListFromServer(IGroupSecurityService gss) } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); Log.LogWarning("TfsUserMappingEnricher::GetUsersListFromServer::[user:{user}] Failed With {Exception}", user, ex.Message); } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsValidateRequiredField.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsValidateRequiredField.cs index f85ab8958..bc115e97e 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsValidateRequiredField.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsValidateRequiredField.cs @@ -14,7 +14,7 @@ public class TfsValidateRequiredField : WorkItemProcessorEnricher { private TfsValidateRequiredFieldOptions _Options; - public TfsValidateRequiredField(IServiceProvider services, ILogger logger) : base(services, logger) + public TfsValidateRequiredField(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); } diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsWorkItemLinkEnricher.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsWorkItemLinkEnricher.cs index f8ba928af..030ad473e 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsWorkItemLinkEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsWorkItemLinkEnricher.cs @@ -17,8 +17,8 @@ public class TfsWorkItemLinkEnricher : WorkItemProcessorEnricher public TfsWorkItemLinkEnricherOptions Options { get; private set; } - public TfsWorkItemLinkEnricher(IServiceProvider services, ILogger logger) - : base(services, logger) + public TfsWorkItemLinkEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) + : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); } @@ -196,9 +196,11 @@ private void CreateExternalLink(ExternalLink sourceLink, WorkItemData target) } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); // Ignore this link because the TFS server didn't recognize its type (There's no point in crashing the rest of the migration due to a link) if (ex.Message.Contains("Unrecognized Resource link")) { + Log.LogError(ex, "[{ExceptionType}] Failed to save link {SourceLinkType} on {TargetId}", ex.GetType().Name, sourceLink.GetType().Name, target.Id); // Remove the link from the target so it doesn't cause problems downstream target.ToWorkItem().Links.Remove(el); @@ -245,6 +247,7 @@ private void CreateRelatedLink(WorkItemData wiSourceL, RelatedLink item, WorkIte } catch (Exception ex) { + Telemetry.TrackException( ex, null, null); Log.LogError(ex, " [FIND-FAIL] Adding Link of type {0} where wiSourceL={1}, wiTargetL={2} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiTargetL.Id); return; } @@ -254,6 +257,7 @@ private void CreateRelatedLink(WorkItemData wiSourceL, RelatedLink item, WorkIte } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); Log.LogError(ex, " [FIND-FAIL] Adding Link of type {0} where wiSourceL={1}, wiTargetL={2} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiTargetL.Id); return; } @@ -274,7 +278,7 @@ where l is RelatedLink } catch (Exception ex) { - Log.LogError(ex, " [SKIP] Unable to migrate links where wiSourceL={0}, wiSourceR={1}, wiTargetL={2}", wiSourceL != null ? wiSourceL.Id.ToString() : "NotFound", wiSourceR != null ? wiSourceR.Id.ToString() : "NotFound", wiTargetL != null ? wiTargetL.Id.ToString() : "NotFound"); + Log.LogWarning(ex, " [SKIP] Unable to migrate links where wiSourceL={0}, wiSourceR={1}, wiTargetL={2}", wiSourceL != null ? wiSourceL.Id.ToString() : "NotFound", wiSourceR != null ? wiSourceR.Id.ToString() : "NotFound", wiTargetL != null ? wiTargetL.Id.ToString() : "NotFound"); return; } @@ -286,7 +290,7 @@ where l is RelatedLink var client = (TfsWorkItemMigrationClient)Engine.Target.WorkItems; if (!client.Store.WorkItemLinkTypes.LinkTypeEnds.Contains(rl.LinkTypeEnd.ImmutableName)) { - Log.LogError($" [SKIP] Unable to migrate Link because type {rl.LinkTypeEnd.ImmutableName} does not exist in the target project."); + Log.LogWarning($" [SKIP] Unable to migrate Link because type {rl.LinkTypeEnd.ImmutableName} does not exist in the target project."); return; } @@ -342,7 +346,7 @@ where l is RelatedLink } else { - Log.LogInformation( + Log.LogWarning( " [SKIP] Unable to migrate link where Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} as target WI has not been migrated", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } @@ -351,7 +355,7 @@ where l is RelatedLink { if (IsExisting) { - Log.LogInformation(" [SKIP] Already Exists a Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); + Log.LogWarning(" [SKIP] Already Exists a Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } if (wiTargetR.ToWorkItem().IsAccessDenied) { diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Processors/TfsTeamSettingsProcessor.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Processors/TfsTeamSettingsProcessor.cs index bfa19a6a6..467033359 100644 --- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Processors/TfsTeamSettingsProcessor.cs +++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Processors/TfsTeamSettingsProcessor.cs @@ -45,6 +45,7 @@ public TfsTeamSettingsProcessor(ProcessorEnricherContainer processorEnrichers, } catch (Exception ex) { + Telemetry.TrackException(ex, null, null); Log.LogError(ex, "{LogTypeName}: Unable load list of identities from target collection.", LogTypeName); return new List(); } @@ -357,14 +358,16 @@ private void MigrateCapacities(WorkHttpClient sourceHttpClient, WorkHttpClient t } catch (Exception ex) { - Log.LogError(ex, "[SKIP] Problem migrating team capacities for iteration {iteration}.", sourceIteration.Path); + Telemetry.TrackException(ex, null, null); + Log.LogWarning(ex, "[SKIP] Problem migrating team capacities for iteration {iteration}.", sourceIteration.Path); } } } catch (Exception ex) { - Log.LogError(ex, "[SKIP] Problem migrating team capacities."); + Telemetry.TrackException(ex, null, null); + Log.LogWarning(ex, "[SKIP] Problem migrating team capacities."); } Log.LogInformation("Team capacities migration done.."); diff --git a/src/MigrationTools.Clients.AzureDevops.Rest/Enrichers/EmbededImagesRepairEnricher.cs b/src/MigrationTools.Clients.AzureDevops.Rest/Enrichers/EmbededImagesRepairEnricher.cs index 8adf9850a..daa450b6a 100644 --- a/src/MigrationTools.Clients.AzureDevops.Rest/Enrichers/EmbededImagesRepairEnricher.cs +++ b/src/MigrationTools.Clients.AzureDevops.Rest/Enrichers/EmbededImagesRepairEnricher.cs @@ -10,7 +10,7 @@ namespace MigrationTools.Clients.AzureDevops.Rest.Enrichers { public class EmbededImagesRepairEnricher : EmbededImagesRepairEnricherBase { - public EmbededImagesRepairEnricher(IServiceProvider services, ILogger logger) : base(services, logger) + public EmbededImagesRepairEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = services.GetRequiredService(); } diff --git a/src/MigrationTools.Host/ExecuteHostedService.cs b/src/MigrationTools.Host/ExecuteHostedService.cs index ae83bb748..ef7e59137 100644 --- a/src/MigrationTools.Host/ExecuteHostedService.cs +++ b/src/MigrationTools.Host/ExecuteHostedService.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Microsoft.ApplicationInsights.Channel; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -12,14 +13,16 @@ public class ExecuteHostedService : IHostedService private readonly IServiceProvider _services; private readonly ILogger _logger; private readonly IHostApplicationLifetime _appLifetime; + private readonly ITelemetryLogger Telemetery; private int? _exitCode; public ExecuteHostedService( IServiceProvider services, ILogger logger, - IHostApplicationLifetime appLifetime) + IHostApplicationLifetime appLifetime, ITelemetryLogger telemetryLogger) { + Telemetery = telemetryLogger; _services = services; _logger = logger; _appLifetime = appLifetime; @@ -39,6 +42,7 @@ public Task StartAsync(CancellationToken cancellationToken) } catch (Exception ex) { + Telemetery.TrackException(ex, null, null); _logger.LogError(ex, "Unhandled exception!"); _exitCode = 1; } diff --git a/src/MigrationTools.Host/InitHostedService.cs b/src/MigrationTools.Host/InitHostedService.cs index 9de79ee91..0140ff544 100644 --- a/src/MigrationTools.Host/InitHostedService.cs +++ b/src/MigrationTools.Host/InitHostedService.cs @@ -93,6 +93,7 @@ public Task StartAsync(CancellationToken cancellationToken) } catch (Exception ex) { + _telemetryLogger.TrackException(ex, null, null); _logger.LogError(ex, "Unhandled exception!"); _exitCode = 1; } diff --git a/src/MigrationTools/ProcessorEnrichers/PauseAfterEachItem.cs b/src/MigrationTools/ProcessorEnrichers/PauseAfterEachItem.cs index e6b336f15..c705124f3 100644 --- a/src/MigrationTools/ProcessorEnrichers/PauseAfterEachItem.cs +++ b/src/MigrationTools/ProcessorEnrichers/PauseAfterEachItem.cs @@ -17,7 +17,7 @@ public PauseAfterEachItemOptions Options public IMigrationEngine Engine { get; private set; } - public PauseAfterEachItem(IServiceProvider services, ILogger logger) : base(services, logger) + public PauseAfterEachItem(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = Services.GetRequiredService(); } diff --git a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/AppendMigrationToolSignatureFooter.cs b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/AppendMigrationToolSignatureFooter.cs index 785966afc..829595443 100644 --- a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/AppendMigrationToolSignatureFooter.cs +++ b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/AppendMigrationToolSignatureFooter.cs @@ -17,7 +17,7 @@ public AppendMigrationToolSignatureFooterOptions Options public IMigrationEngine Engine { get; } - public AppendMigrationToolSignatureFooter(IServiceProvider services, ILogger logger) : base(services, logger) + public AppendMigrationToolSignatureFooter(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = Services.GetRequiredService(); } diff --git a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/FilterWorkItemsThatAlreadyExistInTarget.cs b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/FilterWorkItemsThatAlreadyExistInTarget.cs index 2ccc128b3..7d384362b 100644 --- a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/FilterWorkItemsThatAlreadyExistInTarget.cs +++ b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/FilterWorkItemsThatAlreadyExistInTarget.cs @@ -17,7 +17,7 @@ public FilterWorkItemsThatAlreadyExistInTargetOptions Options public IMigrationEngine Engine { get; private set; } - public FilterWorkItemsThatAlreadyExistInTarget(IServiceProvider services, ILogger logger) : base(services, logger) + public FilterWorkItemsThatAlreadyExistInTarget(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = Services.GetRequiredService(); } diff --git a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/SkipToFinalRevisedWorkItemType.cs b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/SkipToFinalRevisedWorkItemType.cs index 592521b55..d2a74b9ee 100644 --- a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/SkipToFinalRevisedWorkItemType.cs +++ b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/SkipToFinalRevisedWorkItemType.cs @@ -17,7 +17,7 @@ public StringManipulatorEnricherOptions Options public IMigrationEngine Engine { get; private set; } - public SkipToFinalRevisedWorkItemType(IServiceProvider services, ILogger logger) : base(services, logger) + public SkipToFinalRevisedWorkItemType(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { Engine = Services.GetRequiredService(); } diff --git a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/StringManipulatorEnricher.cs b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/StringManipulatorEnricher.cs index 69ae74d53..c3b15f552 100644 --- a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/StringManipulatorEnricher.cs +++ b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/StringManipulatorEnricher.cs @@ -17,8 +17,8 @@ public class StringManipulatorEnricher : WorkItemProcessorEnricher private Serilog.ILogger contextLog; private StringManipulatorEnricherOptions _options; - public StringManipulatorEnricher(IServiceProvider services, ILogger logger) - : base(services, logger) + public StringManipulatorEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) + : base(services, logger, telemetryLogger) { contextLog = Serilog.Log.ForContext(); } diff --git a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/WorkItemProcessorEnricher.cs b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/WorkItemProcessorEnricher.cs index d2e0bf8a6..21743cd5a 100644 --- a/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/WorkItemProcessorEnricher.cs +++ b/src/MigrationTools/ProcessorEnrichers/WorkItemProcessorEnrichers/WorkItemProcessorEnricher.cs @@ -8,13 +8,15 @@ namespace MigrationTools.Enrichers { public abstract class WorkItemProcessorEnricher : IWorkItemProcessorEnricher { + protected ITelemetryLogger Telemetry { get; } protected IServiceProvider Services { get; } protected ILogger Log { get; } - public WorkItemProcessorEnricher(IServiceProvider services, ILogger logger) + public WorkItemProcessorEnricher(IServiceProvider services, ILogger logger, ITelemetryLogger telemetry) { Services = services; Log = logger; + Telemetry = telemetry; } protected abstract void RefreshForProcessorType(IProcessor processor); diff --git a/src/MigrationTools/Services/ITelemetryLogger.cs b/src/MigrationTools/Services/ITelemetryLogger.cs index 7fd11c026..61f3ab85c 100644 --- a/src/MigrationTools/Services/ITelemetryLogger.cs +++ b/src/MigrationTools/Services/ITelemetryLogger.cs @@ -19,7 +19,7 @@ public interface ITelemetryLogger //void TrackRequest(RequestTelemetry requestTelemetry); void TrackRequest(string name, DateTimeOffset startTime, TimeSpan duration, string responseCode, bool success); - void TrackException(Exception ex, IDictionary properties, IDictionary measurements); + void TrackException(Exception ex, IDictionary properties = null, IDictionary measurements = null); void CloseAndFlush(); } diff --git a/src/MigrationTools/Services/TelemetryClientAdapter.cs b/src/MigrationTools/Services/TelemetryClientAdapter.cs index 9a4122469..6c78ad784 100644 --- a/src/MigrationTools/Services/TelemetryClientAdapter.cs +++ b/src/MigrationTools/Services/TelemetryClientAdapter.cs @@ -77,6 +77,7 @@ public void TrackException(Exception ex, IDictionary properties, Type = baseException.GetType().FullName, Title = baseException.Message ?? "An error occurred", Severity = "Error", + Data = new List(), Source = baseException.Source, User = Environment.UserName, Hostname = System.Environment.GetEnvironmentVariable("COMPUTERNAME"), @@ -95,8 +96,8 @@ public void TrackException(Exception ex, IDictionary properties, createMessage.Data.Add(new Item(measurement.Key, measurement.Value.ToString())); } - elmahIoClient.Messages.CreateAndNotify(new Guid("24086b6d-4f58-47f4-8ac7-68d8bc05ca9e"), createMessage); - + var result = elmahIoClient.Messages.CreateAndNotify(new Guid("24086b6d-4f58-47f4-8ac7-68d8bc05ca9e"), createMessage); + Console.WriteLine($"Error logged to Elmah.io"); } public void TrackRequest(string name, DateTimeOffset startTime, TimeSpan duration, string responseCode, bool success) diff --git a/src/MigrationTools/_EngineV1/Enrichers/EmbededImagesRepairEnricherBase.cs b/src/MigrationTools/_EngineV1/Enrichers/EmbededImagesRepairEnricherBase.cs index 1fd7a5420..ff8697b14 100644 --- a/src/MigrationTools/_EngineV1/Enrichers/EmbededImagesRepairEnricherBase.cs +++ b/src/MigrationTools/_EngineV1/Enrichers/EmbededImagesRepairEnricherBase.cs @@ -18,7 +18,7 @@ public abstract class EmbededImagesRepairEnricherBase : WorkItemProcessorEnriche * from https://gist.github.com/pietergheysens/792ed505f09557e77ddfc1b83531e4fb */ - public EmbededImagesRepairEnricherBase(IServiceProvider services, ILogger logger) : base(services, logger) + public EmbededImagesRepairEnricherBase(IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger) : base(services, logger, telemetryLogger) { _httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false, UseDefaultCredentials = true, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; } diff --git a/src/VstsSyncMigrator.Core/Execution/MigrationContext/TestPlansAndSuitesMigrationContext.cs b/src/VstsSyncMigrator.Core/Execution/MigrationContext/TestPlansAndSuitesMigrationContext.cs index c3ff9e526..285dfcd80 100644 --- a/src/VstsSyncMigrator.Core/Execution/MigrationContext/TestPlansAndSuitesMigrationContext.cs +++ b/src/VstsSyncMigrator.Core/Execution/MigrationContext/TestPlansAndSuitesMigrationContext.cs @@ -238,7 +238,7 @@ private void ApplyConfigurations(ITestSuiteEntry sourceEntry, ITestSuiteEntry ta catch (Exception ex) { // SOmetimes this will error out for no reason. - Log.LogError(ex, "Applying Configurations"); + Log.LogWarning(ex, "Applying Configurations"); } } } diff --git a/src/VstsSyncMigrator.Core/Execution/MigrationContext/WorkItemMigrationContext.cs b/src/VstsSyncMigrator.Core/Execution/MigrationContext/WorkItemMigrationContext.cs index 0f995e753..f08118faf 100644 --- a/src/VstsSyncMigrator.Core/Execution/MigrationContext/WorkItemMigrationContext.cs +++ b/src/VstsSyncMigrator.Core/Execution/MigrationContext/WorkItemMigrationContext.cs @@ -666,6 +666,7 @@ private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, int retryLi { Log.LogError(ex, ex.ToString()); Telemetry.TrackRequest("ProcessWorkItem", startTime, witStopWatch.Elapsed, "502", false); + Telemetry.TrackException(ex); throw ex; } witStopWatch.Stop(); @@ -903,6 +904,13 @@ private WorkItemData ReplayRevisions(List revisionsToMigrate, Work } catch (Exception ex) { + Dictionary parameters = new Dictionary(); + if (targetWorkItem != null) + { + foreach (Field f in targetWorkItem.ToWorkItem().Fields) + parameters.Add($"{f.ReferenceName} ({f.Name})", f.Value.ToString()); + } + _telemetry.TrackException(ex, parameters); TraceWriteLine(LogEventLevel.Information, "...FAILED to Save"); Log.LogInformation("==============================================================="); if (targetWorkItem != null)