From 551dd7c02a08959d47459819b86cc0d9ced087bc Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 26 Jan 2020 19:58:26 +0100 Subject: [PATCH 1/3] improve tracker log --- Documentation/Troubleshooting.md | 2 +- .../Instrumentation/ModuleTrackerTemplate.cs | 42 ++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Documentation/Troubleshooting.md b/Documentation/Troubleshooting.md index e78afbc9a..2538b0e81 100644 --- a/Documentation/Troubleshooting.md +++ b/Documentation/Troubleshooting.md @@ -222,7 +222,7 @@ We can collect logs from trackers through an enviroment variable set COVERLET_ENABLETRACKERLOG=1 ``` When enabled, tracking event will be collected in log file near to module location. -File name will be something like `moduleName.dll_tracker.txt` +File name will be something like `moduleName.dll_tracker.txt` and files with detailed hits will be in a folder named `TrackersHitsLog`. ## Enable msbuild task instrumentation debugging diff --git a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs index 4fd86a347..b36582f42 100644 --- a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs +++ b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; @@ -116,6 +117,8 @@ public static void UnloadModule(object sender, EventArgs e) using (var bw = new BinaryWriter(fs)) { int hitsLength = br.ReadInt32(); + WriteLog($"Current hit found '{hitsLength}'"); + if (hitsLength != hitsArray.Length) { throw new InvalidOperationException( @@ -134,6 +137,8 @@ public static void UnloadModule(object sender, EventArgs e) } } + WriteHits(); + // On purpose this is not under a try-finally: it is better to have an exception if there was any error writing the hits file // this case is relevant when instrumenting corelib since multiple processes can be running against the same instrumented dll. mutex.ReleaseMutex(); @@ -147,21 +152,38 @@ public static void UnloadModule(object sender, EventArgs e) } } - private static void WriteLog(string logText) + private static void WriteHits() { if (_enableLog) { - try - { - // We don't set path as global var to keep benign possible errors inside try/catch - // I'm not sure that location will be ok in every scenario - string location = Assembly.GetExecutingAssembly().Location; - File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} {Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}"); - } - catch + Assembly currentAssembly = Assembly.GetExecutingAssembly(); + DirectoryInfo location = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(currentAssembly.Location), "TrackersHitsLog")); + location.Create(); + string logFile = Path.Combine(location.FullName, $"{Path.GetFileName(currentAssembly.Location)}_{DateTime.UtcNow.Ticks}_{Process.GetCurrentProcess().Id}.txt"); + using (var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) + using (var log = new FileStream(logFile, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) + using (var logWriter = new StreamWriter(log)) + using (var br = new BinaryReader(fs)) { - // do nothing if log fail + int hitsLength = br.ReadInt32(); + for (int i = 0; i < hitsLength; ++i) + { + logWriter.WriteLine($"{i},{br.ReadInt32()}"); + } } + + File.AppendAllText(logFile, "Hits flushed"); + } + } + + private static void WriteLog(string logText) + { + if (_enableLog) + { + // We don't set path as global var to keep benign possible errors inside try/catch + // I'm not sure that location will be ok in every scenario + string location = Assembly.GetExecutingAssembly().Location; + File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} P:{Process.GetCurrentProcess().Id} T:{Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}"); } } } From 293d6562a108a5f0fc4588b06f6739ddf9178ff0 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 26 Jan 2020 20:03:25 +0100 Subject: [PATCH 2/3] add readonly field --- src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs index b36582f42..ed1ff4b06 100644 --- a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs +++ b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs @@ -21,7 +21,7 @@ internal static class ModuleTrackerTemplate public static string HitsFilePath; public static int[] HitsArray; public static bool SingleHit; - private static bool _enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) ? result == 1 : false; + private static readonly bool _enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) ? result == 1 : false; static ModuleTrackerTemplate() { From 36a24e14fdcd3e5147b8af4212cc8bcb97f9c65a Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 26 Jan 2020 20:12:32 +0100 Subject: [PATCH 3/3] nit: update log --- src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs index ed1ff4b06..b3ae4e302 100644 --- a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs +++ b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs @@ -117,7 +117,7 @@ public static void UnloadModule(object sender, EventArgs e) using (var bw = new BinaryWriter(fs)) { int hitsLength = br.ReadInt32(); - WriteLog($"Current hit found '{hitsLength}'"); + WriteLog($"Current hits found '{hitsLength}'"); if (hitsLength != hitsArray.Length) {