diff --git a/src/shared/Core/Trace2.cs b/src/shared/Core/Trace2.cs index bd511d12d..d929e0a29 100644 --- a/src/shared/Core/Trace2.cs +++ b/src/shared/Core/Trace2.cs @@ -22,6 +22,8 @@ public enum Trace2Event Version = 0, [EnumMember(Value = "start")] Start = 1, + [EnumMember(Value = "exit")] + Exit = 2 } public class Trace2Settings @@ -49,6 +51,16 @@ public interface ITrace2 : IDisposable string appPath, [System.Runtime.CompilerServices.CallerFilePath] string filePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0); + + /// + /// Shut down TRACE2 tracing by writing Exit event and disposing of writers. + /// + /// The exit code of the GCM application. + /// Path of the file this method is called from. + /// Line number of file this method is called from. + void Stop(int exitCode, + [System.Runtime.CompilerServices.CallerFilePath] string filePath = "", + [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0); } public class Trace2 : DisposableObject, ITrace2 @@ -93,6 +105,12 @@ public Trace2(IEnvironment environment, Trace2Settings settings, string[] argv, WriteStart(appPath, filePath, lineNumber); } + public void Stop(int exitCode, string filePath, int lineNumber) + { + WriteExit(exitCode, filePath, lineNumber); + ReleaseManagedResources(); + } + protected override void ReleaseManagedResources() { lock (_writersLock) @@ -233,6 +251,22 @@ private void TryParseSettings(TextWriter error, IFileSystem fileSystem) }); } + private void WriteExit(int code, string filePath = "", int lineNumber = 0) + { + EnsureArgument.NotNull(code, nameof(code)); + + WriteMessage(new ExitMessage() + { + Event = Trace2Event.Exit, + Sid = _sid, + Time = DateTimeOffset.Now, + File = Path.GetFileName(filePath).ToLower(), + Line = lineNumber, + Code = code, + ElapsedTime = (DateTimeOffset.UtcNow - _applicationStartTime).TotalSeconds + }); + } + private void AddWriter(ITrace2Writer writer) { ThrowIfDisposed(); @@ -362,3 +396,27 @@ public override string ToNormalString() return BuildNormalString(string.Join(" ", Argv)); } } + +public class ExitMessage : Trace2Message +{ + [JsonProperty("t_abs", Order = 7)] + public double ElapsedTime { get; set; } + + [JsonProperty("code", Order = 8)] + public int Code { get; set; } + + public override string ToJson() + { + return JsonConvert.SerializeObject(this, + new StringEnumConverter(), + new IsoDateTimeConverter() + { + DateTimeFormat = TimeFormat + }); + } + + public override string ToNormalString() + { + return BuildNormalString($"elapsed:{ElapsedTime} code:{Code}"); + } +} diff --git a/src/shared/Git-Credential-Manager/Program.cs b/src/shared/Git-Credential-Manager/Program.cs index 973726df5..d3e382548 100644 --- a/src/shared/Git-Credential-Manager/Program.cs +++ b/src/shared/Git-Credential-Manager/Program.cs @@ -75,6 +75,7 @@ public static void Main(string[] args) .GetAwaiter() .GetResult(); + context.Trace2.Stop(exitCode); Environment.Exit(exitCode); } } diff --git a/src/shared/TestInfrastructure/Objects/NullTrace.cs b/src/shared/TestInfrastructure/Objects/NullTrace.cs index 0ba338cd0..8d708d0be 100644 --- a/src/shared/TestInfrastructure/Objects/NullTrace.cs +++ b/src/shared/TestInfrastructure/Objects/NullTrace.cs @@ -59,6 +59,8 @@ public class NullTrace2 : ITrace2 string filePath = "", int lineNumber = 0) { } + public void Stop(int exitCode, string fileName, int lineNumber) { } + #endregion #region IDisposable