Skip to content

Commit bc1d05d

Browse files
authored
Merge pull request ionide#175 from dawedawe/use_ilogger
Use `Microsoft.Extensions.Logging` instead of `printf` based logging infrastructure
2 parents 112fa6c + a6b77ab commit bc1d05d

21 files changed

+237
-121
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

1010
### Changed
1111
* [Add path to ASTCollecting](https://github.com/ionide/FSharp.Analyzers.SDK/pull/171) (thanks @nojaf!)
12+
* [Use Microsoft.Extensions.Logging instead of printf based logging infrastructure](https://github.com/ionide/FSharp.Analyzers.SDK/pull/175) (thanks @dawedawe!)
1213

1314
## [0.21.0] - 2023-11-22
1415

Directory.Packages.props

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
<PackageVersion Include="Microsoft.Build.Locator" Version="1.4.1" />
2020
<!-- Need to update Directory.Build.props DotNet.ReproducibleBuilds.Isolated version when updating this-->
2121
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.1.1" PrivateAssets="All" />
22+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
23+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
24+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
2225
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
2326
<PackageVersion Include="MSBuild.StructuredLogger" Version="2.1.815" />
2427
<PackageVersion Include="NUnit" Version="3.13.3" />

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ F# analyzers are live, real-time, project based plugins that enables to diagnose
1515
2. Run the console application:
1616

1717
```shell
18-
dotnet run --project src\FSharp.Analyzers.Cli\FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbose
18+
dotnet run --project src\FSharp.Analyzers.Cli\FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbosity d
1919
```
2020

2121
You can also set up a run configuration of FSharp.Analyzers.Cli in your favorite IDE using similar arguments. This also allows you to debug FSharp.Analyzers.Cli.

build.fsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pipeline "Build" {
2828
}
2929
stage "sample" {
3030
run
31-
"dotnet run --project src/FSharp.Analyzers.Cli/FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbose"
31+
"dotnet run --project src/FSharp.Analyzers.Cli/FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbosity d"
3232
}
3333
stage "docs" { run "dotnet fsdocs build --properties Configuration=Release --eval --clean --strict" }
3434
runIfOnlySpecified false

docs/content/Getting Started Using.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ At the time of writing, the [G-Research analyzers](https://github.com/g-research
3333
With the package downloaded, we can run the CLI tool:
3434

3535
```shell
36-
dotnet fsharp-analyzers --project ./YourProject.fsproj --analyzers-path C:\Users\yourusername\.nuget\packages\g-research.fsharp.analyzers\0.4.0\analyzers\dotnet\fs\ --verbose
36+
dotnet fsharp-analyzers --project ./YourProject.fsproj --analyzers-path C:\Users\yourusername\.nuget\packages\g-research.fsharp.analyzers\0.4.0\analyzers\dotnet\fs\ --verbosity d
3737
```
3838

3939
### Using an MSBuild target
@@ -57,7 +57,7 @@ Before we can run `dotnet msbuild /t:AnalyzeFSharpProject`, we need to specify o
5757

5858
```xml
5959
<PropertyGroup>
60-
<FSharpAnalyzersOtherFlags>--analyzers-path &quot;$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs&quot; --report &quot;$(MSBuildProjectName)-$(TargetFramework).sarif&quot; --treat-as-warning IONIDE-004 --verbose</FSharpAnalyzersOtherFlags>
60+
<FSharpAnalyzersOtherFlags>--analyzers-path &quot;$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs&quot; --report &quot;$(MSBuildProjectName)-$(TargetFramework).sarif&quot; --treat-as-warning IONIDE-004 --verbosity d</FSharpAnalyzersOtherFlags>
6161
</PropertyGroup>
6262
```
6363

@@ -101,7 +101,7 @@ This is effectively the same as adding a property to each `*proj` file which exi
101101
<PropertyGroup>
102102
<SarifOutput Condition="$(SarifOutput) == ''">./</SarifOutput>
103103
<CodeRoot Condition="$(CodeRoot) == ''">.</CodeRoot>
104-
<FSharpAnalyzersOtherFlags>--analyzers-path &quot;$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs&quot; --report &quot;$(SarifOutput)$(MSBuildProjectName)-$(TargetFramework).sarif&quot; --code-root $(CodeRoot) --treat-as-warning IONIDE-004 --verbose</FSharpAnalyzersOtherFlags>
104+
<FSharpAnalyzersOtherFlags>--analyzers-path &quot;$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs&quot; --report &quot;$(SarifOutput)$(MSBuildProjectName)-$(TargetFramework).sarif&quot; --code-root $(CodeRoot) --treat-as-warning IONIDE-004 --verbosity d</FSharpAnalyzersOtherFlags>
105105
</PropertyGroup>
106106
</Project>
107107
```

docs/content/Getting Started Writing.fsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ dotnet tool install --global fsharp-analyzers
108108
```
109109
110110
```shell
111-
fsharp-analyzers --project YourProject.fsproj --analyzers-path ./OptionAnalyzer/bin/Release --verbose
111+
fsharp-analyzers --project YourProject.fsproj --analyzers-path ./OptionAnalyzer/bin/Release --verbosity d
112112
```
113113
114114
### Packaging and Distribution

docs/content/Programmatic access.fsx

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The `Client` needs to know what type of analyzer you intend to load: *console* o
1515
(*** hide ***)
1616
#r "../../src/FSharp.Analyzers.Cli/bin/Release/net6.0/FSharp.Analyzers.SDK.dll"
1717
#r "../../src/FSharp.Analyzers.Cli/bin/Release/net6.0/FSharp.Compiler.Service.dll"
18+
#r "../../src/FSharp.Analyzers.Cli/bin/Release/net6.0/Microsoft.Extensions.Logging.Abstractions.dll"
1819
(** *)
1920

2021
open FSharp.Analyzers.SDK

docs/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ F# analyzers are live, real-time, project based plugins that enables to diagnose
1515
2. Run the console application:
1616

1717
```shell
18-
dotnet run --project src\FSharp.Analyzers.Cli\FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbose
18+
dotnet run --project src\FSharp.Analyzers.Cli\FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbosity d
1919
```
2020

2121
You can also set up a run configuration of FSharp.Analyzers.Cli in your favorite IDE using similar arguments. This also allows you to debug FSharp.Analyzers.Cli.
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
module FSharp.Analyzers.Cli.CustomLogging
2+
3+
open System
4+
open System.IO
5+
open System.Runtime.CompilerServices
6+
open Microsoft.Extensions.Logging
7+
open Microsoft.Extensions.Logging.Console
8+
open Microsoft.Extensions.Logging.Abstractions
9+
open Microsoft.Extensions.Options
10+
11+
type CustomOptions() =
12+
inherit ConsoleFormatterOptions()
13+
14+
/// if true: no LogLevel as prefix, colored output according to LogLevel
15+
/// if false: LogLevel as prefix, no colored output
16+
member val UseAnalyzersMsgStyle = false with get, set
17+
18+
type CustomFormatter(options: IOptionsMonitor<CustomOptions>) as this =
19+
inherit ConsoleFormatter("customName")
20+
21+
let mutable optionsReloadToken: IDisposable = null
22+
let mutable formatterOptions = options.CurrentValue
23+
let origColor = Console.ForegroundColor
24+
25+
do optionsReloadToken <- options.OnChange(fun x -> this.ReloadLoggerOptions(x))
26+
27+
member private _.ReloadLoggerOptions(opts: CustomOptions) = formatterOptions <- opts
28+
29+
override this.Write<'TState>
30+
(
31+
logEntry: inref<LogEntry<'TState>>,
32+
_scopeProvider: IExternalScopeProvider,
33+
textWriter: TextWriter
34+
)
35+
=
36+
let message = logEntry.Formatter.Invoke(logEntry.State, logEntry.Exception)
37+
38+
if formatterOptions.UseAnalyzersMsgStyle then
39+
this.SetColor(textWriter, logEntry.LogLevel)
40+
textWriter.WriteLine(message)
41+
this.ResetColor()
42+
else
43+
this.WritePrefix(textWriter, logEntry.LogLevel)
44+
textWriter.WriteLine(message)
45+
46+
member private _.WritePrefix(textWriter: TextWriter, logLevel: LogLevel) =
47+
match logLevel with
48+
| LogLevel.Trace -> textWriter.Write("trace: ")
49+
| LogLevel.Debug -> textWriter.Write("debug: ")
50+
| LogLevel.Information -> textWriter.Write("info: ")
51+
| LogLevel.Warning -> textWriter.Write("warn: ")
52+
| LogLevel.Error -> textWriter.Write("error: ")
53+
| LogLevel.Critical -> textWriter.Write("critical: ")
54+
| _ -> ()
55+
56+
// see https://learn.microsoft.com/en-us/dotnet/core/extensions/console-log-formatter
57+
member private _.SetColor(textWriter: TextWriter, logLevel: LogLevel) =
58+
let color =
59+
match logLevel with
60+
| LogLevel.Error -> "\x1B[1m\x1B[31m" // ConsoleColor.Red
61+
| LogLevel.Warning -> "\x1B[33m" // ConsoleColor.DarkYellow
62+
| LogLevel.Information -> "\x1B[1m\x1B[34m" // ConsoleColor.Blue
63+
| LogLevel.Trace -> "\x1B[1m\x1B[36m" // ConsoleColor.Cyan
64+
| _ -> "\x1B[37m" // ConsoleColor.Gray
65+
66+
textWriter.Write(color)
67+
68+
member private _.ResetColor() = Console.ForegroundColor <- origColor
69+
70+
interface IDisposable with
71+
member _.Dispose() = optionsReloadToken.Dispose()
72+
73+
[<Extension>]
74+
type ConsoleLoggerExtensions =
75+
76+
[<Extension>]
77+
static member AddCustomFormatter(builder: ILoggingBuilder, configure: Action<CustomOptions>) : ILoggingBuilder =
78+
builder
79+
.AddConsole(fun options -> options.FormatterName <- "customName")
80+
.AddConsoleFormatter<CustomFormatter, CustomOptions>(configure)

src/FSharp.Analyzers.Cli/FSharp.Analyzers.Cli.fsproj

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
</PropertyGroup>
1414

1515
<ItemGroup>
16+
<Compile Include="CustomLogging.fs" />
1617
<Compile Include="Program.fs" />
1718
</ItemGroup>
1819

@@ -26,6 +27,7 @@
2627
<PackageReference Include="Microsoft.Build.Locator" />
2728
<PackageReference Include="Microsoft.Build.Tasks.Core" ExcludeAssets="runtime" />
2829
<PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" />
30+
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
2931
<PackageReference Include="Sarif.Sdk" />
3032
</ItemGroup>
3133

0 commit comments

Comments
 (0)