diff --git a/GVFS/FastFetch/FastFetchVerb.cs b/GVFS/FastFetch/FastFetchVerb.cs index 82cf59fcc..cd37e371b 100644 --- a/GVFS/FastFetch/FastFetchVerb.cs +++ b/GVFS/FastFetch/FastFetchVerb.cs @@ -206,7 +206,7 @@ private int ExecuteWithExitCode() Console.WriteLine("The ParentActivityId provided (" + this.ParentActivityId + ") is not a valid GUID."); } - using (JsonTracer tracer = new JsonTracer("Microsoft.Git.FastFetch", parentActivityId, "FastFetch", disableTelemetry: true)) + using (JsonTracer tracer = new JsonTracer("Microsoft.Git.FastFetch", parentActivityId, "FastFetch", enlistmentId: null, mountId: null, disableTelemetry: true)) { if (this.Verbose) { diff --git a/GVFS/GVFS.Common/GVFSPlatform.cs b/GVFS/GVFS.Common/GVFSPlatform.cs index acb0aa2f3..2297a75d9 100644 --- a/GVFS/GVFS.Common/GVFSPlatform.cs +++ b/GVFS/GVFS.Common/GVFSPlatform.cs @@ -50,7 +50,7 @@ public static void Register(GVFSPlatform platform) public abstract bool TryGetGVFSHooksPathAndVersion(out string hooksPaths, out string hooksVersion, out string error); public abstract bool TryInstallGitCommandHooks(GVFSContext context, string executingDirectory, string hookName, string commandHookPath, out string errorMessage); - public abstract InProcEventListener CreateTelemetryListenerIfEnabled(string providerName); + public abstract InProcEventListener CreateTelemetryListenerIfEnabled(string providerName, string enlistmentId, string mountId); public abstract Dictionary GetPhysicalDiskInfo(string path); diff --git a/GVFS/GVFS.Common/Tracing/JsonTracer.cs b/GVFS/GVFS.Common/Tracing/JsonTracer.cs index aad25dcd8..07e424b23 100644 --- a/GVFS/GVFS.Common/Tracing/JsonTracer.cs +++ b/GVFS/GVFS.Common/Tracing/JsonTracer.cs @@ -20,13 +20,17 @@ public class JsonTracer : ITracer private EventLevel startStopLevel; private Keywords startStopKeywords; - public JsonTracer(string providerName, string activityName, bool disableTelemetry = false) - : this(providerName, Guid.Empty, activityName, disableTelemetry) + : this(providerName, Guid.Empty, activityName, enlistmentId: null, mountId: null, disableTelemetry: disableTelemetry) { } - public JsonTracer(string providerName, Guid providerActivityId, string activityName, bool disableTelemetry = false) + public JsonTracer(string providerName, string activityName, string enlistmentId, string mountId, bool disableTelemetry = false) + : this(providerName, Guid.Empty, activityName, enlistmentId, mountId, disableTelemetry) + { + } + + public JsonTracer(string providerName, Guid providerActivityId, string activityName, string enlistmentId, string mountId, bool disableTelemetry = false) : this( new List(), providerActivityId, @@ -36,7 +40,7 @@ public JsonTracer(string providerName, Guid providerActivityId, string activityN { if (!disableTelemetry) { - InProcEventListener telemetryListener = GVFSPlatform.Instance.CreateTelemetryListenerIfEnabled(providerName); + InProcEventListener telemetryListener = GVFSPlatform.Instance.CreateTelemetryListenerIfEnabled(providerName, enlistmentId, mountId); if (telemetryListener != null) { this.listeners.Add(telemetryListener); @@ -252,7 +256,6 @@ private static string GetCategorizedErrorEventName(Keywords keywords) private void WriteEvent(string eventName, EventLevel level, Keywords keywords, EventMetadata metadata, EventOpcode opcode) { string jsonPayload = metadata != null ? JsonConvert.SerializeObject(metadata) : null; - foreach (InProcEventListener listener in this.listeners) { listener.RecordMessage(eventName, this.activityId, this.parentActivityId, level, keywords, opcode, jsonPayload); diff --git a/GVFS/GVFS.Mount/InProcessMountVerb.cs b/GVFS/GVFS.Mount/InProcessMountVerb.cs index b1c1e19ce..71e835004 100644 --- a/GVFS/GVFS.Mount/InProcessMountVerb.cs +++ b/GVFS/GVFS.Mount/InProcessMountVerb.cs @@ -1,5 +1,6 @@ using CommandLine; using GVFS.Common; +using GVFS.Common.Git; using GVFS.Common.Http; using GVFS.Common.Tracing; using System; @@ -124,7 +125,23 @@ private void UnhandledGVFSExceptionHandler(ITracer tracer, object sender, Unhand private JsonTracer CreateTracer(GVFSEnlistment enlistment, EventLevel verbosity, Keywords keywords) { - JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "GVFSMount"); + string enlistmentId = null; + string mountId = null; + + GitProcess git = new GitProcess(enlistment); + GitProcess.Result configResult = git.GetFromLocalConfig(GVFSConstants.GitConfig.EnlistmentId); + if (!configResult.HasErrors) + { + enlistmentId = configResult.Output.Trim(); + } + + configResult = git.GetFromLocalConfig(GVFSConstants.GitConfig.MountId); + if (!configResult.HasErrors) + { + mountId = configResult.Output.Trim(); + } + + JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "GVFSMount", enlistmentId: enlistmentId, mountId: mountId); tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.MountProcess), verbosity, diff --git a/GVFS/GVFS.Platform.Mac/MacPlatform.cs b/GVFS/GVFS.Platform.Mac/MacPlatform.cs index c5683de6b..9be9a5ed9 100644 --- a/GVFS/GVFS.Platform.Mac/MacPlatform.cs +++ b/GVFS/GVFS.Platform.Mac/MacPlatform.cs @@ -75,7 +75,7 @@ public override NamedPipeServerStream CreatePipeByName(string pipeName) return pipe; } - public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName) + public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName, string enlistmentId, string mountId) { return null; } diff --git a/GVFS/GVFS.Platform.Windows/ETWTelemetryEventListener.cs b/GVFS/GVFS.Platform.Windows/ETWTelemetryEventListener.cs index 9f4140867..3ca1adcd5 100644 --- a/GVFS/GVFS.Platform.Windows/ETWTelemetryEventListener.cs +++ b/GVFS/GVFS.Platform.Windows/ETWTelemetryEventListener.cs @@ -32,14 +32,18 @@ public class ETWTelemetryEventListener : InProcEventListener private const long MeasureKeyword = 0x400000000000; private EventSource eventSource; + private string enlistmentId; + private string mountId; - private ETWTelemetryEventListener(string providerName, string[] traitsList) + private ETWTelemetryEventListener(string providerName, string[] traitsList, string enlistmentId, string mountId) : base(EventLevel.Verbose, Keywords.Telemetry) { this.eventSource = new EventSource(providerName, EventSourceSettings.EtwSelfDescribingEventFormat, traitsList); + this.enlistmentId = enlistmentId; + this.mountId = mountId; } - public static ETWTelemetryEventListener CreateTelemetryListenerIfEnabled(string gitBinRoot, string providerName) + public static ETWTelemetryEventListener CreateTelemetryListenerIfEnabled(string gitBinRoot, string providerName, string enlistmentId, string mountId) { // This listener is disabled unless the user specifies the proper git config setting. @@ -52,7 +56,7 @@ public static ETWTelemetryEventListener CreateTelemetryListenerIfEnabled(string if (!result.HasErrors && !string.IsNullOrEmpty(result.Output.TrimEnd('\r', '\n'))) { string[] traitsList = result.Output.TrimEnd('\r', '\n').Split('|'); - return new ETWTelemetryEventListener(providerName, traitsList); + return new ETWTelemetryEventListener(providerName, traitsList, enlistmentId, mountId); } else { @@ -83,12 +87,12 @@ protected override void RecordMessageInternal( if (jsonPayload != null) { - JsonPayload payload = new JsonPayload(jsonPayload); + JsonPayload payload = new JsonPayload(jsonPayload, this.enlistmentId, this.mountId); this.eventSource.Write(eventName, ref options, ref activityId, ref parentActivityId, ref payload); } else { - EmptyStruct payload = new EmptyStruct(); + Payload payload = new Payload(this.enlistmentId, this.mountId); this.eventSource.Write(eventName, ref options, ref activityId, ref parentActivityId, ref payload); } } @@ -105,22 +109,38 @@ private EventSourceOptions CreateOptions(EventLevel level, Keywords keywords, Ev return options; } - // Needed to pass relatedId without metadata [EventData] - public struct EmptyStruct + public struct Payload { + public Payload(string enlistmentId, string mountId) + { + this.EnlistmentId = enlistmentId; + this.MountId = mountId; + } + + [EventField] + public string EnlistmentId { get; } + [EventField] + public string MountId { get; } } [EventData] public struct JsonPayload { - public JsonPayload(string payload) + public JsonPayload(string payload, string enlistmentId, string mountId) { this.Json = payload; + this.EnlistmentId = enlistmentId; + this.MountId = mountId; } [EventField] public string Json { get; } + + [EventField] + public string EnlistmentId { get; } + [EventField] + public string MountId { get; } } } } diff --git a/GVFS/GVFS.Platform.Windows/WindowsPlatform.cs b/GVFS/GVFS.Platform.Windows/WindowsPlatform.cs index 80dde743b..aa8c3953b 100644 --- a/GVFS/GVFS.Platform.Windows/WindowsPlatform.cs +++ b/GVFS/GVFS.Platform.Windows/WindowsPlatform.cs @@ -69,11 +69,13 @@ public static bool TrySetDWordInRegistry(RegistryHive registryHive, string key, return true; } - public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName) + public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName, string enlistmentId, string mountId) { return ETWTelemetryEventListener.CreateTelemetryListenerIfEnabled( this.GitInstallation.GetInstalledGitBinPath(), - providerName); + providerName, + enlistmentId, + mountId); } public override void InitializeEnlistmentACLs(string enlistmentPath) diff --git a/GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs b/GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs index 0062d7e08..b0cd6d43f 100644 --- a/GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs +++ b/GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs @@ -50,7 +50,7 @@ public override NamedPipeServerStream CreatePipeByName(string pipeName) throw new NotSupportedException(); } - public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName) + public override InProcEventListener CreateTelemetryListenerIfEnabled(string providerName, string enlistmentId, string mountId) { return new MockListener(EventLevel.Verbose, Keywords.Telemetry); }