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