-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create one session/telemetry configuration per run #515
Changes from 2 commits
a837219
ae1548b
aef6a64
e119e62
9099778
da02bdc
df00214
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,15 +20,19 @@ public class CompilerDataLogger | |
private const string CommandLineEventName = "CommandLineInformation"; | ||
private const string AssemblyReferencesEventName = "AssemblyReferencesInformation"; | ||
|
||
private readonly int ChunkSize; | ||
private readonly string sha256; | ||
private string Sha256 => context?.Hashes?.Sha256; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when we send a null to AppInsights, it won't render the key value pair. If we try to print it in console, a null is showed as an empty string. so, in this case, we don't need to create a default to empty |
||
|
||
private readonly int chunkSize; | ||
private readonly string relativeFilePath; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
private readonly IAnalysisContext context; | ||
|
||
private static string s_sessionId; | ||
internal static string s_sessionId; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please pull aside all the internal static properties (that are overridden by tests) and group them together. we do this to improve the readability of code, i.e., that accessibility is a clue to the maintainer there is a special external caller (our tests) that update these values. make sense? you are future-proofing this code to help whoever comes along when those tests fail. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it! |
||
private static bool s_printHeader = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
private static TelemetryClient s_telemetryClient; | ||
private static TelemetryConfiguration s_telemetryConfiguration; | ||
|
||
private static readonly object s_syncRoot = new object(); | ||
|
||
public static bool TelemetryEnabled => s_telemetryClient != null; | ||
|
||
public CompilerDataLogger(IAnalysisContext analysisContext, | ||
|
@@ -37,10 +41,10 @@ public CompilerDataLogger(IAnalysisContext analysisContext, | |
TelemetryClient telemetryClient = null, | ||
int chunkSize = 8192) | ||
{ | ||
s_telemetryConfiguration = telemetryConfiguration; | ||
s_telemetryClient = telemetryClient; | ||
s_sessionId = TelemetryEnabled ? Guid.NewGuid().ToString() : null; | ||
ChunkSize = chunkSize; | ||
s_telemetryConfiguration ??= telemetryConfiguration; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
s_telemetryClient ??= telemetryClient; | ||
s_sessionId ??= Guid.NewGuid().ToString(); | ||
this.chunkSize = chunkSize; | ||
|
||
if (!TelemetryEnabled) | ||
{ | ||
|
@@ -58,7 +62,7 @@ public CompilerDataLogger(IAnalysisContext analysisContext, | |
} | ||
} | ||
|
||
this.sha256 = analysisContext?.Hashes?.Sha256 ?? string.Empty; | ||
this.context = analysisContext; | ||
this.relativeFilePath = analysisContext?.TargetUri?.LocalPath ?? string.Empty; | ||
|
||
foreach (string path in targetFileSpecifiers) | ||
|
@@ -77,9 +81,15 @@ public static void Initialize(string instrumentationKey) | |
{ | ||
if (s_telemetryConfiguration == null && s_telemetryClient == null) | ||
{ | ||
s_sessionId = Guid.NewGuid().ToString(); | ||
s_telemetryConfiguration = new TelemetryConfiguration(instrumentationKey); | ||
s_telemetryClient = new TelemetryClient(s_telemetryConfiguration); | ||
lock (s_syncRoot) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when we changed from single thread to multi thread, we started to create multiple configurations/clients/sessions. With that in mind, we must synchronize the threads to prevent this behavior. |
||
{ | ||
if (s_telemetryConfiguration == null && s_telemetryClient == null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. session/configuration/client can be injected using the constructor but the session is always defined when we have the telemetry enabled. It's why we don't need to make the configuration/client internal. |
||
{ | ||
s_sessionId = Guid.NewGuid().ToString(); | ||
s_telemetryConfiguration = new TelemetryConfiguration(instrumentationKey); | ||
s_telemetryClient = new TelemetryClient(s_telemetryConfiguration); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
@@ -152,7 +162,7 @@ public void Write(CompilerData compilerData) | |
{ "moduleName", compilerData.ModuleName ?? string.Empty }, | ||
{ "moduleLibrary", (compilerData.ModuleName == compilerData.ModuleLibrary ? string.Empty : compilerData.ModuleLibrary ?? string.Empty) }, | ||
{ "sessionId", s_sessionId }, | ||
{ "hash", this.sha256 }, | ||
{ "hash", this.Sha256 }, | ||
{ "error", string.Empty } | ||
}; | ||
|
||
|
@@ -183,7 +193,7 @@ public void Write(CompilerData compilerData) | |
} | ||
else | ||
{ | ||
string log = $"{this.relativeFilePath},{compilerData},{this.sha256},"; | ||
string log = $"{this.relativeFilePath},{compilerData},{this.Sha256},"; | ||
Console.WriteLine(log); | ||
} | ||
} | ||
|
@@ -208,13 +218,13 @@ public void WriteException(string errorMessage) | |
{ "moduleName", string.Empty }, | ||
{ "moduleLibrary", string.Empty }, | ||
{ "sessionId", s_sessionId }, | ||
{ "hash", this.sha256 }, | ||
{ "hash", this.Sha256 }, | ||
{ "error", errorMessage }, | ||
}); | ||
} | ||
else | ||
{ | ||
string log = $"{this.relativeFilePath},,,,,,,,,,,,,{this.sha256},{errorMessage}"; | ||
string log = $"{this.relativeFilePath},,,,,,,,,,,,,{this.Sha256},{errorMessage}"; | ||
Console.WriteLine(log); | ||
} | ||
} | ||
|
@@ -268,13 +278,20 @@ public static void Summarize(AnalysisSummary summary) | |
} | ||
} | ||
|
||
internal static void Reset() | ||
{ | ||
s_sessionId = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added some docs in this method. We don't need a lock because it will only be called during tests. |
||
s_telemetryClient = null; | ||
s_telemetryConfiguration = null; | ||
} | ||
|
||
private void SendChunkedContent(string eventName, string contentId, string contentName, string content) | ||
{ | ||
int j = 1; | ||
int size = (int)Math.Ceiling(1.0 * content.Length / ChunkSize); | ||
for (int i = 0; i < content.Length; i += ChunkSize) | ||
int size = (int)Math.Ceiling(1.0 * content.Length / this.chunkSize); | ||
for (int i = 0; i < content.Length; i += this.chunkSize) | ||
{ | ||
string chunckedContent = content.Substring(i, Math.Min(ChunkSize, content.Length - i)); | ||
string chunckedContent = content.Substring(i, Math.Min(this.chunkSize, content.Length - i)); | ||
|
||
s_telemetryClient.TrackEvent(eventName, properties: new Dictionary<string, string> | ||
{ | ||
|
@@ -284,6 +301,7 @@ private void SendChunkedContent(string eventName, string contentId, string conte | |
{ "totalNumber", size.ToString() }, | ||
{ $"chunked{contentName}", chunckedContent }, | ||
}); | ||
|
||
j++; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: AssemblyTitle("BinSkim SDK")] | ||
[assembly: AssemblyDescription("BinSkim SDK and utilities for authoring analysis checks")] | ||
|
||
[assembly: InternalsVisibleTo("Test.UnitTests.BinSkim.Driver")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we changed how hashes are generated, we should make a reference to the context so we will have the correct value of the hash when needed. #ByDesign