From b594ab1ac985e7b49d8f8f4c5e6bfc72231d5641 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Feb 2025 16:01:46 +0700 Subject: [PATCH 1/5] trace HgRunner.Run calls --- src/LibChorus/LibChorus.csproj | 2 ++ src/LibChorus/LibChorusActivitySource.cs | 13 +++++++++++++ src/LibChorus/VcsDrivers/Mercurial/HgRunner.cs | 10 ++++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/LibChorus/LibChorusActivitySource.cs diff --git a/src/LibChorus/LibChorus.csproj b/src/LibChorus/LibChorus.csproj index 70f2c2326..b93c90a44 100644 --- a/src/LibChorus/LibChorus.csproj +++ b/src/LibChorus/LibChorus.csproj @@ -6,6 +6,7 @@ SIL.Chorus.LibChorus net462;netstandard2.0 https://github.com/sillsdev/chorus.git + default @@ -21,6 +22,7 @@ + diff --git a/src/LibChorus/LibChorusActivitySource.cs b/src/LibChorus/LibChorusActivitySource.cs new file mode 100644 index 000000000..fcdc3a005 --- /dev/null +++ b/src/LibChorus/LibChorusActivitySource.cs @@ -0,0 +1,13 @@ +// // Copyright (c) 2025-2025 SIL International +// // This software is licensed under the MIT License (http://opensource.org/licenses/MIT) + +using System.Diagnostics; + +namespace Chorus +{ + public static class LibChorusActivitySource + { + public const string ActivitySourceName = "SIL.LibChorus"; + internal static readonly ActivitySource Value = new ActivitySource(ActivitySourceName); + } +} \ No newline at end of file diff --git a/src/LibChorus/VcsDrivers/Mercurial/HgRunner.cs b/src/LibChorus/VcsDrivers/Mercurial/HgRunner.cs index e7cbe8e67..78cd0c752 100644 --- a/src/LibChorus/VcsDrivers/Mercurial/HgRunner.cs +++ b/src/LibChorus/VcsDrivers/Mercurial/HgRunner.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; +using Chorus.Model; using Chorus.Utilities; using SIL.Progress; using SIL.Reporting; @@ -44,10 +45,14 @@ public static ExecutionResult Run(string commandLine, string fromDirectory) public static ExecutionResult Run(string commandLine, string fromDirectory, int secondsBeforeTimeOut, IProgress progress) { + using var activity = LibChorusActivitySource.Value.StartActivity(); + activity?.SetTag("app.hg.cmd", ServerSettingsModel.RemovePasswordForLog(commandLine)); + activity?.SetTag("app.hg.timeout-sec", secondsBeforeTimeOut); ExecutionResult result = new ExecutionResult(); Process process = new Process(); if (String.IsNullOrEmpty(MercurialLocation.PathToMercurialFolder)) { + activity?.SetStatus(ActivityStatusCode.Error, "Mercurial location not configured"); throw new ApplicationException("Mercurial location has not been configured."); } process.StartInfo.EnvironmentVariables["PYTHONPATH"] = Path.Combine(MercurialLocation.PathToMercurialFolder, "library.zip"); @@ -60,6 +65,7 @@ public static ExecutionResult Run(string commandLine, string fromDirectory, int process.StartInfo.CreateNoWindow = true; process.StartInfo.WorkingDirectory = fromDirectory; process.StartInfo.FileName = MercurialLocation.PathToHgExecutable; + activity?.SetTag("app.hg.binary-path", MercurialLocation.PathToHgExecutable); var debug = Environment.GetEnvironmentVariable(@"CHORUSDEBUGGING") == null ? String.Empty : @"--debug "; process.StartInfo.Arguments = commandLine.Replace("hg ", debug); //we don't want the whole command line, just the args portion @@ -69,6 +75,7 @@ public static ExecutionResult Run(string commandLine, string fromDirectory, int process.StartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8; if(!String.IsNullOrEmpty(debug)) { + activity?.SetTag("app.hg.debug", true); Logger.WriteEvent("Running hg command: hg --debug {0}", commandLine); } try @@ -128,16 +135,19 @@ public static ExecutionResult Run(string commandLine, string fromDirectory, int { result.StandardError += Environment.NewLine + "Timed Out after waiting " + secondsBeforeTimeOut + " seconds."; result.ExitCode = ProcessStream.kTimedOut; + activity?.SetStatus(ActivityStatusCode.Error, "Timeout"); } else if (progress.CancelRequested) { result.StandardError += Environment.NewLine + "User Cancelled."; result.ExitCode = ProcessStream.kCancelled; + activity?.SetStatus(ActivityStatusCode.Error, "User Cancelled"); } else { result.ExitCode = process.ExitCode; + activity?.SetTag("app.hg.exit-code", result.ExitCode); } return result; } From 46313887370de746bf658e24c7ed4b16cb4576ba Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Feb 2025 16:36:06 +0700 Subject: [PATCH 2/5] trace individual hg resume pushes and pulls --- src/LibChorus/LibChorusActivitySource.cs | 11 +++++++++++ .../VcsDrivers/Mercurial/HgResumeTransport.cs | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/LibChorus/LibChorusActivitySource.cs b/src/LibChorus/LibChorusActivitySource.cs index fcdc3a005..57fa76396 100644 --- a/src/LibChorus/LibChorusActivitySource.cs +++ b/src/LibChorus/LibChorusActivitySource.cs @@ -2,6 +2,7 @@ // // This software is licensed under the MIT License (http://opensource.org/licenses/MIT) using System.Diagnostics; +using Chorus.VcsDrivers.Mercurial; namespace Chorus { @@ -9,5 +10,15 @@ public static class LibChorusActivitySource { public const string ActivitySourceName = "SIL.LibChorus"; internal static readonly ActivitySource Value = new ActivitySource(ActivitySourceName); + + public static void TagResumableParameters(this Activity activity, string direction, HgResumeApiParameters request) + { + activity.SetTag($"app.chorus.resumable.{direction}.chunk-size", request.ChunkSize); + activity.SetTag($"app.chorus.resumable.{direction}.bundle-size", request.BundleSize); + activity.SetTag($"app.chorus.resumable.{direction}.start-of-window", request.StartOfWindow); + activity.SetTag($"app.chorus.resumable.{direction}.trans-id", request.TransId); + activity.SetTag($"app.chorus.resumable.{direction}.repo-id", request.RepoId); + activity.SetTag($"app.chorus.resumable.{direction}.quantity", request.Quantity); + } } } \ No newline at end of file diff --git a/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs b/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs index b2e506c6a..6545fd234 100644 --- a/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs +++ b/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs @@ -505,6 +505,9 @@ private PushStatus FinishPush(string transactionId) private PushResponse PushOneChunk(HgResumeApiParameters request, byte[] dataToPush) { + using var activity = LibChorusActivitySource.Value.StartActivity(); + activity?.TagResumableParameters("push", request); + var pushResponse = new PushResponse(PushStatus.Fail); try { @@ -810,6 +813,8 @@ private PullStatus FinishPull(string transactionId) private PullResponse PullOneChunk(HgResumeApiParameters request) { + using var activity = LibChorusActivitySource.Value.StartActivity(); + activity?.TagResumableParameters("pull", request); var pullResponse = new PullResponse(PullStatus.Fail); try { From ba8f1bfa94b721b00d2a752b9d77e8f91a9f4ffa Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Feb 2025 16:36:38 +0700 Subject: [PATCH 3/5] trace Synchronizer.cs SyncNow, SendToOthers, PullFromOthers and Merge --- src/LibChorus/sync/Synchronizer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/LibChorus/sync/Synchronizer.cs b/src/LibChorus/sync/Synchronizer.cs index 01786db21..c2173e302 100644 --- a/src/LibChorus/sync/Synchronizer.cs +++ b/src/LibChorus/sync/Synchronizer.cs @@ -104,6 +104,8 @@ public static Synchronizer FromProjectConfiguration(ProjectFolderConfiguration p public SyncResults SyncNow(SyncOptions options) { + using var activity = LibChorusActivitySource.Value.StartActivity(); + SyncResults results = new SyncResults(); List sourcesToTry = options.RepositorySourcesToTry; // this saves us from trying to connect twice to the same repo that is, for example, not there. @@ -156,12 +158,14 @@ public SyncResults SyncNow(SyncOptions options) error.DoNotifications(Repository, _progress); results.Succeeded = false; results.ErrorEncountered = error; + activity?.AddException(error); } catch (UserCancelledException) { results.Succeeded = false; results.Cancelled = true; results.ErrorEncountered = null; + activity?.SetTag("app.chorus.sync.cancelled", true); } catch (Exception error) { @@ -178,6 +182,7 @@ public SyncResults SyncNow(SyncOptions options) results.Succeeded = false; results.ErrorEncountered = error; + activity?.AddException(error); } finally { @@ -245,6 +250,7 @@ public void SetIsOneOfDefaultSyncAddresses(RepositoryAddress address, bool enabl private void SendToOthers(HgRepository repo, List sourcesToTry, Dictionary connectionAttempt) { + using var activity = LibChorusActivitySource.Value.StartActivity(); foreach (RepositoryAddress address in sourcesToTry) { ThrowIfCancelPending(); @@ -325,6 +331,7 @@ private void SendToOneOther(RepositoryAddress address, Dictionarytrue if there was at least one successful pull private bool PullFromOthers(HgRepository repo, List sourcesToTry, Dictionary connectionAttempt) { + using var activity = LibChorusActivitySource.Value.StartActivity(); bool didGetFromAtLeastOneSource = false; foreach (RepositoryAddress source in new List(sourcesToTry)) // LT-18276: apparently possible to modify sourcesToTry { @@ -628,6 +635,7 @@ private void TryToMakeCloneForSource(RepositoryAddress repoDescriptor) #region Merging private void MergeHeadsOrRollbackAndThrow(HgRepository repo, Revision workingRevBeforeSync) { + using var activity = LibChorusActivitySource.Value.StartActivity(); try { MergeHeads(); @@ -642,6 +650,7 @@ private void MergeHeadsOrRollbackAndThrow(HgRepository repo, Revision workingRev _progress.WriteException(error); _progress.WriteError("Rolling back..."); UpdateToTheDescendantRevision(repo, workingRevBeforeSync); //rollback + activity?.AddException(error); throw; } } From b5e4b43099931dd3d2a89c8f1994b9b442ced843 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Thu, 20 Feb 2025 14:49:37 +0700 Subject: [PATCH 4/5] apply pr feedback --- src/LibChorus/LibChorusActivitySource.cs | 4 ++-- src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/LibChorus/LibChorusActivitySource.cs b/src/LibChorus/LibChorusActivitySource.cs index 57fa76396..dfddbc5bc 100644 --- a/src/LibChorus/LibChorusActivitySource.cs +++ b/src/LibChorus/LibChorusActivitySource.cs @@ -1,5 +1,5 @@ -// // Copyright (c) 2025-2025 SIL International -// // This software is licensed under the MIT License (http://opensource.org/licenses/MIT) +// Copyright (c) 2025-2025 SIL International +// This software is licensed under the MIT License (http://opensource.org/licenses/MIT) using System.Diagnostics; using Chorus.VcsDrivers.Mercurial; diff --git a/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs b/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs index 6545fd234..5672524fd 100644 --- a/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs +++ b/src/LibChorus/VcsDrivers/Mercurial/HgResumeTransport.cs @@ -815,6 +815,7 @@ private PullResponse PullOneChunk(HgResumeApiParameters request) { using var activity = LibChorusActivitySource.Value.StartActivity(); activity?.TagResumableParameters("pull", request); + var pullResponse = new PullResponse(PullStatus.Fail); try { From f357ab13e6c727862a494ddbe2ae54ca8138d510 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Thu, 20 Feb 2025 16:23:33 +0700 Subject: [PATCH 5/5] guard against null activity in `TagResumableParameters` --- src/LibChorus/LibChorusActivitySource.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/LibChorus/LibChorusActivitySource.cs b/src/LibChorus/LibChorusActivitySource.cs index dfddbc5bc..71295fbad 100644 --- a/src/LibChorus/LibChorusActivitySource.cs +++ b/src/LibChorus/LibChorusActivitySource.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Chorus.VcsDrivers.Mercurial; +using JetBrains.Annotations; namespace Chorus { @@ -13,6 +14,7 @@ public static class LibChorusActivitySource public static void TagResumableParameters(this Activity activity, string direction, HgResumeApiParameters request) { + if (activity is null) return; activity.SetTag($"app.chorus.resumable.{direction}.chunk-size", request.ChunkSize); activity.SetTag($"app.chorus.resumable.{direction}.bundle-size", request.BundleSize); activity.SetTag($"app.chorus.resumable.{direction}.start-of-window", request.StartOfWindow);