Skip to content

Commit

Permalink
more logging pls
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAngryByrd committed Mar 30, 2023
1 parent cd7c7ee commit 4c5b40a
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 23 deletions.
5 changes: 4 additions & 1 deletion build/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ let init args =
Target.create "Build" (fun _ -> DotNet.build id "")

let testTFM tfm =
exec "dotnet" $"test --blame --blame-hang-timeout 2m --no-build --framework {tfm} --logger trx --logger GitHubActions -c Release .\\test\\Ionide.ProjInfo.Tests\\Ionide.ProjInfo.Tests.fsproj" "."
exec
"dotnet"
$"test --blame --blame-hang-timeout 2m --no-build --framework {tfm} --logger trx --logger GitHubActions -c Release -v n .\\test\\Ionide.ProjInfo.Tests\\Ionide.ProjInfo.Tests.fsproj -- Expecto.debug=true Expecto.parallel=false"
"."
|> ignore

Target.create "Test" DoNothing
Expand Down
10 changes: 9 additions & 1 deletion src/Ionide.ProjInfo/FsLibLog.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// As of commit 599e765db64ba5bcde23a589f427453c52fdb132
// As of commit 1fe15c95c008567db63e00e823ca8768155e85c6
namespace Ionide.ProjInfo.Logging

open System.Text.RegularExpressions
Expand Down Expand Up @@ -772,10 +772,13 @@ module Providers =
static member Create() =
let createLogger =
let factoryType = getLogFactoryType.Value

let createLoggerMethodInfo = factoryType.GetMethod("CreateLogger", [| typedefof<string> |])

let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)
let nameParam = Expression.Parameter(typedefof<string>)
let instanceCast = Expression.Convert(instanceParam, factoryType)

let createLoggerMethodExp = Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)

let createLogger =
Expand All @@ -801,7 +804,9 @@ module Providers =
Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions")

let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")

let logEventLevelType = Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")

let instanceParam = Expression.Parameter(typedefof<ILogger>)

let instanceCast = Expression.Convert(instanceParam, loggerType)
Expand All @@ -811,6 +816,7 @@ module Providers =

let isEnabled =
let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])

let isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)


Expand Down Expand Up @@ -907,6 +913,7 @@ module Providers =
let beginScopeMethodInfo = loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)

let stateParam = Expression.Parameter(typedefof<obj>)

let beginScopeMethodCall = Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)

Expression
Expand Down Expand Up @@ -973,6 +980,7 @@ module Providers =
| Some factory ->
// Create bogus logger that will propagate to a real logger later
let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())

loggerGateway.Value.BeginScope logger (box message)

let create () = MicrosoftProvider() :> ILogProvider
Expand Down
47 changes: 38 additions & 9 deletions src/Ionide.ProjInfo/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ type BinaryLogGeneration =
/// </summary>
module ProjectLoader =


type LoadedProject = internal LoadedProject of ProjectInstance

[<RequireQualifiedAccess>]
Expand All @@ -337,11 +338,14 @@ module ProjectLoader =
| Success of LoadedProject
| Error of string

let internal logger (writer: StringWriter) =
let internal stringWriterLogger (writer: StringWriter) =
{ new ILogger with
member this.Initialize(eventSource: IEventSource) : unit =
// eventSource.ErrorRaised.Add(fun t -> writer.WriteLine t.Message) //Only log errors
eventSource.AnyEventRaised.Add(fun t -> writer.WriteLine t.Message)
eventSource.AnyEventRaised.Add(fun t ->
let message = t.Message
writer.WriteLine message
)

member this.Parameters: string = ""

Expand All @@ -355,6 +359,28 @@ module ProjectLoader =
with set (v: LoggerVerbosity): unit = ()
}


let msBuildToLogProvider () =
let msBuildLogger = LogProvider.getLoggerByName "MsBuild"

{ new ILogger with
member this.Initialize(eventSource: IEventSource) : unit =
eventSource.ErrorRaised.Add(fun t -> msBuildLogger.error (Log.setMessage t.Message))
eventSource.WarningRaised.Add(fun t -> msBuildLogger.warn (Log.setMessage t.Message))

eventSource.AnyEventRaised.Add(fun t -> msBuildLogger.info (Log.setMessage t.Message))

member this.Parameters
with get (): string = ""
and set (v: string): unit = ()

member this.Shutdown() : unit = ()

member this.Verbosity
with get (): LoggerVerbosity = LoggerVerbosity.Diagnostic
and set (v: LoggerVerbosity): unit = ()
}

let getTfm (path: string) readingProps isLegacyFrameworkProj =
let pi = ProjectInstance(path, globalProperties = readingProps, toolsVersion = null)

Expand All @@ -379,15 +405,19 @@ module ProjectLoader =
Some tfm

let createLoggers (paths: string seq) (binaryLogs: BinaryLogGeneration) (sw: StringWriter) =
let logger = logger (sw)
let swLogger = stringWriterLogger (sw)
let msbuildLogger = msBuildToLogProvider ()

let logFilePath (dir: DirectoryInfo, projectPath: string) =
let projectFileName = Path.GetFileName projectPath
let logFileName = Path.ChangeExtension(projectFileName, ".binlog")
Path.Combine(dir.FullName, logFileName)

match binaryLogs with
| BinaryLogGeneration.Off -> [ logger ]
| BinaryLogGeneration.Off -> [
swLogger
msbuildLogger
]
| BinaryLogGeneration.Within dir ->
let loggers =
paths
Expand All @@ -397,7 +427,8 @@ module ProjectLoader =
)

[
logger
msbuildLogger
swLogger
yield! loggers
]

Expand Down Expand Up @@ -851,6 +882,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (stri
let (ToolsPath toolsPath) = toolsPath
let globalProperties = defaultArg globalProperties []
let logger = LogProvider.getLoggerFor<WorkspaceLoaderViaProjectGraph> ()

let loadingNotification = new Event<Types.WorkspaceProjectState>()

let handleProjectGraphFailures f =
Expand Down Expand Up @@ -1041,10 +1073,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (stri

allProjectOptions
|> Seq.iter (fun po ->
logger.info (
Log.setMessage "Project loaded {project}"
>> Log.addContextDestructured "project" po.ProjectFileName
)
logger.info (Log.setMessageI $"Project loaded {po.ProjectFileName:project}")

loadingNotification.Trigger(
WorkspaceProjectState.Loaded(
Expand Down
86 changes: 86 additions & 0 deletions test/Ionide.ProjInfo.Tests/FsLibLog.Expecto.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace FsLibLog.Providers.Expecto

open System
open Ionide.ProjInfo.Logging

module EMsg = Expecto.Logging.Message
type ELL = Expecto.Logging.LogLevel

module internal Helpers =
let addExnOpt exOpt msg =
match exOpt with
| None -> msg
| Some ex ->
msg
|> EMsg.addExn ex

let addValues (items: obj[]) msg =
(msg,
items
|> Seq.mapi (fun i item -> i, item))
||> Seq.fold (fun msg (i, item) ->
msg
|> EMsg.setField (string i) item
)

let getLogLevel: LogLevel -> Expecto.Logging.LogLevel =
function
| LogLevel.Debug -> ELL.Debug
| LogLevel.Error -> ELL.Error
| LogLevel.Fatal -> ELL.Fatal
| LogLevel.Info -> ELL.Info
| LogLevel.Trace -> ELL.Verbose
| LogLevel.Warn -> ELL.Warn
| _ -> ELL.Warn

open Helpers

// Naive implementation, not that important, just need logging to actually work
type ExpectoLogProvider() =
let propertyStack = System.Collections.Generic.Stack<string * obj>()


let addProp key value =
propertyStack.Push(key, value)

{ new IDisposable with
member __.Dispose() =
propertyStack.Pop()
|> ignore
}

interface ILogProvider with
override __.GetLogger(name: string) : Logger =
let logger = Expecto.Logging.Log.create name

fun ll mt exnOpt values ->
match mt with
| Some f ->
let ll = getLogLevel ll

logger.log
ll
(fun ll ->
let message = f ()
let mutable msg = Expecto.Logging.Message.eventX message ll

for (propertyName, propertyValue) in (Seq.rev propertyStack) do
msg <- Expecto.Logging.Message.setField propertyName propertyValue msg

match exnOpt with
| None -> msg
| Some ex ->
msg
|> Expecto.Logging.Message.addExn ex
|> addValues values
)
|> Async.RunSynchronously

true
| None -> false

override __.OpenMappedContext (key: string) (value: obj) (b: bool) = addProp key value
override __.OpenNestedContext name = addProp "NDC" name

module ExpectoLogProvider =
let create () = ExpectoLogProvider() :> ILogProvider
10 changes: 3 additions & 7 deletions test/Ionide.ProjInfo.Tests/Ionide.ProjInfo.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="FsLibLog.Expecto.fs" />
<Compile Include="FileUtils.fs" />
<Compile Include="TestAssets.fs" />
<Compile Include="Tests.fs" />
Expand All @@ -20,17 +21,12 @@
<ProjectReference
Include="..\..\src\Ionide.ProjInfo.ProjectSystem\Ionide.ProjInfo.ProjectSystem.fsproj" />
</ItemGroup>

<!-- This is a workaround for the test framework using Microsoft.Build dependencies and our
project uses it's own set of Microsoft.Build dependencies which causes loading conflicts -->
<Target
Name="PostBuild"
AfterTargets="PostBuildEvent">
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Copy
SourceFiles="$([System.IO.Directory]::GetParent($(BundledRuntimeIdentifierGraphFile)))\NuGet.Frameworks.dll"
DestinationFolder="$(OutputPath)"
ContinueOnError="false" />
DestinationFolder="$(OutputPath)" ContinueOnError="false" />
</Target>

<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
3 changes: 3 additions & 0 deletions test/Ionide.ProjInfo.Tests/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ open Ionide.ProjInfo.ProjectSystem
open Expecto
open Expecto.Impl
open Expecto.Logging
open FsLibLog.Providers.Expecto

let toolsPath = Init.init (IO.DirectoryInfo Environment.CurrentDirectory) None

[<Tests>]
let tests = Tests.tests toolsPath

Ionide.ProjInfo.Logging.LogProvider.setLoggerProvider (ExpectoLogProvider())


[<EntryPoint>]
let main argv =
Expand Down
6 changes: 1 addition & 5 deletions test/Ionide.ProjInfo.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -821,11 +821,7 @@ let testParseSln toolsPath =
let p = InspectSln.tryParseSln (slnPath)

()
// Expect.isTrue
// (match p with
// | Ok _ -> true
// | Result.Error _ -> false)
// "expected successful parse"
Expect.isOk p "expected successful parse"

// let actualProjects =
// InspectSln.loadingBuildOrder (
Expand Down

0 comments on commit 4c5b40a

Please sign in to comment.