Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasArdal committed Sep 6, 2024
0 parents commit 1c34f54
Show file tree
Hide file tree
Showing 22 changed files with 1,108 additions and 0 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: build

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:

jobs:
build:

runs-on: windows-latest

steps:
- uses: actions/checkout@v4
- uses: nuget/setup-nuget@v2
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Update version
run: |
(Get-Content -Path src\LoggerVisualizerVsix\source.extension.vsixmanifest) |
ForEach-Object {$_ -Replace '0.1.0', '0.1.${{ github.run_number }}'} |
Set-Content -Path src\LoggerVisualizerVsix\source.extension.vsixmanifest
- name: Restore
run: nuget restore
- name: Build
run: msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
- uses: actions/upload-artifact@v3
with:
name: LoggerVisualizer.vsix
path: src\LoggerVisualizerVsix\bin\Release\net8.0-windows\LoggerVisualizerVsix.vsix
- name: Create Release
id: create_release
if: ${{ github.event_name == 'push' }}
uses: actions/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: 0.1.${{ github.run_number }}
release_name: Release 0.1.${{ github.run_number }}
draft: false
- name: Upload VSIX
if: ${{ github.event_name == 'push' }}
uses: actions/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: src\LoggerVisualizerVsix\bin\Release\net8.0-windows\LoggerVisualizerVsix.vsix
asset_name: LoggerVisualizerVsix.vsix
asset_content_type: application/zip
112 changes: 112 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
[Bb]in/
[Oo]bj/

# mstest test results
TestResults

## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results
[Dd]ebug/
[Rr]elease/
x64/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.log
*.vspscc
*.vssscc
.builds

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*

# dotCover
*.DotSettings

# NCrunch
*.ncrunch*
.*crunch*.local.xml

# Installshield output folder
[Ee]xpress

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish

# Publish Web Output
*.Publish.xml

# NuGet Packages Directory
packages

# Windows Azure Build Output
csx
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
[Bb]in
[Oo]bj
sql
TestResults
[Tt]est[Rr]esult*
*.Cache
ClientBin
[Ss]tyle[Cc]op.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects

# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
.vs/
44 changes: 44 additions & 0 deletions LoggerVisualizer.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{09C88280-ACF9-4043-8326-9F8D891B375E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerVisualizer", "src\LoggerVisualizer\LoggerVisualizer.csproj", "{782FFF6B-3794-4082-BB88-869CE205B6EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerVisualizerSource", "src\LoggerVisualizerSource\LoggerVisualizerSource.csproj", "{A1FF4041-D57C-431F-B349-B133BC77D579}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerVisualizerVsix", "src\LoggerVisualizerVsix\LoggerVisualizerVsix.csproj", "{1BC66681-8DB1-4401-B9D3-A8DF34E072AC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{782FFF6B-3794-4082-BB88-869CE205B6EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{782FFF6B-3794-4082-BB88-869CE205B6EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{782FFF6B-3794-4082-BB88-869CE205B6EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{782FFF6B-3794-4082-BB88-869CE205B6EC}.Release|Any CPU.Build.0 = Release|Any CPU
{A1FF4041-D57C-431F-B349-B133BC77D579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1FF4041-D57C-431F-B349-B133BC77D579}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1FF4041-D57C-431F-B349-B133BC77D579}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1FF4041-D57C-431F-B349-B133BC77D579}.Release|Any CPU.Build.0 = Release|Any CPU
{1BC66681-8DB1-4401-B9D3-A8DF34E072AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BC66681-8DB1-4401-B9D3-A8DF34E072AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BC66681-8DB1-4401-B9D3-A8DF34E072AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BC66681-8DB1-4401-B9D3-A8DF34E072AC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{782FFF6B-3794-4082-BB88-869CE205B6EC} = {09C88280-ACF9-4043-8326-9F8D891B375E}
{A1FF4041-D57C-431F-B349-B133BC77D579} = {09C88280-ACF9-4043-8326-9F8D891B375E}
{1BC66681-8DB1-4401-B9D3-A8DF34E072AC} = {09C88280-ACF9-4043-8326-9F8D891B375E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E2F3EFB2-8BF1-4571-A7D4-43F97741FF09}
EndGlobalSection
EndGlobal
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Logger Visualizer
====================

Logger Debug Visualizer for Visual Studio.

When debugging applications and an `ILogger` is available in the code you can view the logger configuration details in a more structured and visually pleasing form:

![Logger Visualizer](screenshot.png)

The extension shows all configured loggers with a set of default properties. For a range of known logging providers, the extension show a special UI. Like for `EventLog`:

![EventLog Logger Visualizer](screenshot2.png)

And elmah.io:

![ElmahIo Logger Visualizer](screenshot3.png)

Feel free to reach out or send a PR if you own a provider with additional content.

---

Sponsored by [elmah.io](https://elmah.io).
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshot3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions src/LoggerVisualizer/ExtensionEntrypoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.Extensibility;

namespace LoggerVisualizer
{
[VisualStudioContribution]
public class ExtensionEntrypoint : Extension
{
public override ExtensionConfiguration ExtensionConfiguration => new()
{
Metadata = new(
id: "LoggerVisualizer",
version: this.ExtensionAssemblyVersion,
publisherName: "elmah.io",
displayName: "ILogger Debugger Visualizer Extension",
description:"djlkæjklæ"),
};

/// <inheritdoc />
protected override void InitializeServices(IServiceCollection serviceCollection)
{
Telemetry.Initialize(ExtensionAssemblyVersion?.ToString());
try
{
base.InitializeServices(serviceCollection);
}
catch (Exception ex)
{
Telemetry.TrackException(ex);
throw;
}

// You can configure dependency injection here by adding services to the serviceCollection.
}
}
}
97 changes: 97 additions & 0 deletions src/LoggerVisualizer/LoggerDebuggerVisualizerProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using Microsoft.VisualStudio.Extensibility.DebuggerVisualizers;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.RpcContracts.RemoteUI;
using Microsoft.Extensions.Logging;
using LoggerVisualizerSource;
using System.Collections.ObjectModel;
using LoggerVisualizer.Models;
using System.Windows.Media.Imaging;
using System.Windows;

namespace LoggerVisualizer
{
[VisualStudioContribution]
internal class LoggerDebuggerVisualizerProvider : DebuggerVisualizerProvider
{
public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new("Logger Visualizer", typeof(Logger<>))
{
VisualizerObjectSourceType = new(typeof(LoggerObjectSource)),
};
public override async Task<IRemoteUserControl> CreateVisualizerAsync(VisualizerTarget visualizerTarget, CancellationToken cancellationToken)
{
LoggerModel? model = null;
try
{
model = await visualizerTarget
.ObjectSource
.RequestDataAsync<LoggerModel?>(jsonSerializer: null, CancellationToken.None);
}
catch (Exception ex)
{
Telemetry.TrackException(ex);
throw;
}

return await Task.FromResult<IRemoteUserControl>(new LoggerVisualizerUserControl(ToViewModel(model)));
}

private LoggerRootViewModel ToViewModel(LoggerModel logger)
{
if (logger == null) return null;
var viewModel = new LoggerRootViewModel
{
Name = logger.Name,
Enabled = logger.Enabled,
MinLevel = logger.MinLevel,
MinLevelColor = MinLevelColor(logger.MinLevel),
Loggers = new ObservableCollection<LoggerViewModel>(logger.Loggers.Select(l => new LoggerViewModel
{
Name = l.Name,
ExternalScope = l.ExternalScope,
MinLevel = l.MinLevel,
MinLevelColor = MinLevelColor(l.MinLevel),
ShortName = "📄 " + l.Name[(1 + l.Name.LastIndexOf('.'))..].Replace("LoggerProvider", string.Empty),
// Console
IsConsole = l.Name == "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider" ? Visibility.Visible : Visibility.Collapsed,
FormatterName = l.FormatterName,
DisableColors = l.DisableColors,
LogToStandardErrorThreshold = l.LogToStandardErrorThreshold,
MaxQueueLength = l.MaxQueueLength,
QueueFullMode = l.QueueFullMode,
TimestampFormat = l.TimestampFormat,
UseUtcTimestamp = l.UseUtcTimestamp,
// EventLog
IsEventLog = l.Name == "Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider" ? Visibility.Visible : Visibility.Collapsed,
MachineName = l.MachineName,
SourceName = l.SourceName,
LogName = l.LogName,
// EventSource
IsEventSource = l.Name == "Microsoft.Extensions.Logging.EventSource.EventSourceLoggerProvider" ? Visibility.Visible : Visibility.Collapsed,
// ElmahIo
IsElmahIo = l.Name == "Elmah.Io.Extensions.Logging.ElmahIoLoggerProvider" ? Visibility.Visible : Visibility.Collapsed,
ApiKey = l.ApiKey,
LogId = l.LogId,
CanBrowse = !string.IsNullOrWhiteSpace(l.LogId) && Guid.TryParse(l.LogId, out Guid _),
CanDiagnose = !string.IsNullOrWhiteSpace(l.LogId) && Guid.TryParse(l.LogId, out Guid _)
&& !string.IsNullOrWhiteSpace(l.ApiKey) && l.ApiKey.Length == 32,
})),
};

return viewModel;
}

private static string MinLevelColor(string minLevel)
{
return minLevel switch
{
"Critical" => "#993636",
"Debug" => "#95c1ba",
"Error" => "#e6614f",
"Information" => "#0da58e",
"Trace" => "#ccc",
"Warning" => "#ffc936",
_ => "#6c757d",
};
}
}
}
Loading

0 comments on commit 1c34f54

Please sign in to comment.