| File: ExternalAccess\UnitTesting\SolutionCrawler\UnitTestingSolutionCrawlerLogger.cs | Web Access |
| Project: src\roslyn\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api; using Microsoft.CodeAnalysis.Internal.Log; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.SolutionCrawler; internal static class UnitTestingSolutionCrawlerLogger { private const string Id = nameof(Id); private const string Kind = nameof(Kind); private const string Analyzer = nameof(Analyzer); private const string DocumentCount = nameof(DocumentCount); private const string Languages = nameof(Languages); private const string HighPriority = nameof(HighPriority); private const string Enabled = nameof(Enabled); private const string AnalyzerCount = nameof(AnalyzerCount); private const string PersistentStorage = nameof(PersistentStorage); private const string GlobalOperation = nameof(GlobalOperation); private const string HigherPriority = nameof(HigherPriority); private const string LowerPriority = nameof(LowerPriority); private const string TopLevel = nameof(TopLevel); private const string MemberLevel = nameof(MemberLevel); private const string NewWorkItem = nameof(NewWorkItem); private const string UpdateWorkItem = nameof(UpdateWorkItem); private const string ProjectEnqueue = nameof(ProjectEnqueue); private const string ResetStates = nameof(ResetStates); private const string ProjectNotExist = nameof(ProjectNotExist); private const string DocumentNotExist = nameof(DocumentNotExist); private const string ProcessProject = nameof(ProcessProject); private const string OpenDocument = nameof(OpenDocument); private const string CloseDocument = nameof(CloseDocument); private const string SolutionHash = nameof(SolutionHash); private const string ProcessDocument = nameof(ProcessDocument); private const string ProcessDocumentCancellation = nameof(ProcessDocumentCancellation); private const string ProcessProjectCancellation = nameof(ProcessProjectCancellation); private const string ActiveFileEnqueue = nameof(ActiveFileEnqueue); private const string ActiveFileProcessDocument = nameof(ActiveFileProcessDocument); private const string ActiveFileProcessDocumentCancellation = nameof(ActiveFileProcessDocumentCancellation); public static void LogRegistration(int correlationId, string workspaceKind) { Logger.Log(FunctionId.WorkCoordinatorRegistrationService_Register, KeyValueLogMessage.Create(m => { m[Id] = correlationId; m[Kind] = workspaceKind; })); } public static void LogUnregistration(int correlationId) { Logger.Log(FunctionId.WorkCoordinatorRegistrationService_Unregister, KeyValueLogMessage.Create(m => { m[Id] = correlationId; })); } public static void LogReanalyze( int correlationId, IUnitTestingIncrementalAnalyzer analyzer, int documentCount, string languages) { Logger.Log(FunctionId.WorkCoordinatorRegistrationService_Reanalyze, KeyValueLogMessage.Create(m => { m[Id] = correlationId; m[Analyzer] = analyzer.ToString(); m[DocumentCount] = documentCount; m[Languages] = languages; })); } public static void LogAnalyzers(int correlationId, string workspaceKind, ImmutableArray<IUnitTestingIncrementalAnalyzer> reordered, bool onlyHighPriorityAnalyzer) { if (onlyHighPriorityAnalyzer) { LogAnalyzersWorker( FunctionId.IncrementalAnalyzerProcessor_ActiveFileAnalyzers, FunctionId.IncrementalAnalyzerProcessor_ActiveFileAnalyzer, correlationId, workspaceKind, reordered); } else { LogAnalyzersWorker( FunctionId.IncrementalAnalyzerProcessor_Analyzers, FunctionId.IncrementalAnalyzerProcessor_Analyzer, correlationId, workspaceKind, reordered); } } private static void LogAnalyzersWorker( FunctionId analyzersId, FunctionId analyzerId, int correlationId, string workspaceKind, ImmutableArray<IUnitTestingIncrementalAnalyzer> reordered) { if (workspaceKind == WorkspaceKind.Preview) { return; } // log registered analyzers. Logger.Log(analyzersId, KeyValueLogMessage.Create(m => { m[Id] = correlationId; m[AnalyzerCount] = reordered.Length; })); foreach (var analyzer in reordered) { Logger.Log(analyzerId, KeyValueLogMessage.Create(m => { m[Id] = correlationId; m[Analyzer] = analyzer.ToString(); })); } } public static void LogWorkCoordinatorShutdownTimeout(int correlationId) { Logger.Log(FunctionId.WorkCoordinator_ShutdownTimeout, KeyValueLogMessage.Create(m => { m[Id] = correlationId; })); } public static void LogWorkspaceEvent(CountLogAggregator<WorkspaceChangeKind> logAggregator, WorkspaceChangeKind kind) => logAggregator.IncreaseCount(kind); public static void LogWorkCoordinatorShutdown(int correlationId, CountLogAggregator<WorkspaceChangeKind> logAggregator) { Logger.Log(FunctionId.WorkCoordinator_Shutdown, KeyValueLogMessage.Create(m => { m[Id] = correlationId; foreach (var kv in logAggregator) { var change = kv.Key.ToString(); m[change] = kv.Value.GetCount(); } })); } public static void LogGlobalOperation(CountLogAggregator<object> logAggregator) => logAggregator.IncreaseCount(GlobalOperation); public static void LogActiveFileEnqueue(CountLogAggregator<object> logAggregator) => logAggregator.IncreaseCount(ActiveFileEnqueue); public static void LogWorkItemEnqueue(CountLogAggregator<object> logAggregator, ProjectId _) => logAggregator.IncreaseCount(ProjectEnqueue); public static void LogWorkItemEnqueue( CountLogAggregator<object> logAggregator, string language, DocumentId? documentId, UnitTestingInvocationReasons reasons, bool lowPriority, SyntaxPath? activeMember, bool added) { logAggregator.IncreaseCount(language); logAggregator.IncreaseCount(added ? NewWorkItem : UpdateWorkItem); if (documentId != null) { logAggregator.IncreaseCount(activeMember == null ? TopLevel : MemberLevel); if (lowPriority) { logAggregator.IncreaseCount(LowerPriority); logAggregator.IncreaseCount(ValueTuple.Create(LowerPriority, documentId.Id)); } } foreach (var reason in reasons) { logAggregator.IncreaseCount(reason); } } public static void LogHigherPriority(CountLogAggregator<object> logAggregator, Guid documentId) { logAggregator.IncreaseCount(HigherPriority); logAggregator.IncreaseCount(ValueTuple.Create(HigherPriority, documentId)); } public static void LogResetStates(CountLogAggregator<object> logAggregator) => logAggregator.IncreaseCount(ResetStates); public static void LogIncrementalAnalyzerProcessorStatistics(int correlationId, Solution solution, CountLogAggregator<object> logAggregator) { Logger.Log(FunctionId.IncrementalAnalyzerProcessor_Shutdown, KeyValueLogMessage.Create(m => { var solutionHash = GetSolutionHash(solution); m[Id] = correlationId; m[SolutionHash] = solutionHash.ToString(); var statMap = new Dictionary<string, List<int>>(); foreach (var (key, counter) in logAggregator) { if (key is string stringKey) { m[stringKey] = counter.GetCount(); } else if (key is ValueTuple<string, Guid> propertyNameAndId) { var list = statMap.GetOrAdd(propertyNameAndId.Item1, _ => []); list.Add(counter.GetCount()); } else { throw ExceptionUtilities.Unreachable(); } } foreach (var (propertyName, propertyValues) in statMap) { var result = StatisticResult.FromList(propertyValues); result.WriteTelemetryPropertiesTo(m, prefix: propertyName); } })); } private static int GetSolutionHash(Solution solution) { if (solution != null && solution.FilePath != null) { return solution.FilePath.ToLowerInvariant().GetHashCode(); } return 0; } public static void LogProcessCloseDocument(CountLogAggregator<object> logAggregator, Guid documentId) { logAggregator.IncreaseCount(CloseDocument); logAggregator.IncreaseCount(ValueTuple.Create(CloseDocument, documentId)); } public static void LogProcessOpenDocument(CountLogAggregator<object> logAggregator, Guid documentId) { logAggregator.IncreaseCount(OpenDocument); logAggregator.IncreaseCount(ValueTuple.Create(OpenDocument, documentId)); } public static void LogProcessActiveFileDocument(CountLogAggregator<object> logAggregator, Guid _, bool processed) { if (processed) { logAggregator.IncreaseCount(ActiveFileProcessDocument); } else { logAggregator.IncreaseCount(ActiveFileProcessDocumentCancellation); } } public static void LogProcessDocument(CountLogAggregator<object> logAggregator, Guid documentId, bool processed) { if (processed) { logAggregator.IncreaseCount(ProcessDocument); } else { logAggregator.IncreaseCount(ProcessDocumentCancellation); } logAggregator.IncreaseCount(ValueTuple.Create(ProcessDocument, documentId)); } public static void LogProcessDocumentNotExist(CountLogAggregator<object> logAggregator) => logAggregator.IncreaseCount(DocumentNotExist); public static void LogProcessProject(CountLogAggregator<object> logAggregator, Guid projectId, bool processed) { if (processed) { logAggregator.IncreaseCount(ProcessProject); } else { logAggregator.IncreaseCount(ProcessProjectCancellation); } logAggregator.IncreaseCount(ValueTuple.Create(ProcessProject, projectId)); } public static void LogProcessProjectNotExist(CountLogAggregator<object> logAggregator) => logAggregator.IncreaseCount(ProjectNotExist); }