diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index 8d37e28..4deb15b 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -159,7 +159,7 @@ This value should match the version in the props generated by paket If they differ, this means we need to do a restore in order to ensure correct dependencies --> - + true @@ -236,13 +236,16 @@ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) %(PaketReferencesFileLinesInfo.PackageVersion) All - runtime - runtime + runtime + $(ExcludeAssets);contentFiles + $(ExcludeAssets);build;buildMultitargeting;buildTransitive true true @@ -289,14 +292,16 @@ $(MSBuildProjectDirectory)/$(MSBuildProjectFile) true + false + true false - true + true false true false - true + true false - true + true $(PaketIntermediateOutputPath)\$(Configuration) $(PaketIntermediateOutputPath) @@ -314,6 +319,55 @@ + + + PackageLicenseExpressionVersion="$(PackageLicenseExpressionVersion)" + NoDefaultExcludes="$(NoDefaultExcludes)" /> Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Adapters.htm b/docs/coverage/FSharp.Core_Adapters.htm index fdd77d7..de5a9d1 100644 --- a/docs/coverage/FSharp.Core_Adapters.htm +++ b/docs/coverage/FSharp.Core_Adapters.htm @@ -74,7 +74,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\QueryExtensions.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\QueryExtensions.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AllowNullLiteralAttribute.htm b/docs/coverage/FSharp.Core_AllowNullLiteralAttribute.htm index 1690ec3..d5081cd 100644 --- a/docs/coverage/FSharp.Core_AllowNullLiteralAttribute.htm +++ b/docs/coverage/FSharp.Core_AllowNullLiteralAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_1.htm b/docs/coverage/FSharp.Core_AnonymousObject_1.htm index 0240e6d..40fa3b4 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_1.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_1.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_2.htm b/docs/coverage/FSharp.Core_AnonymousObject_2.htm index 976bc1c..b800940 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_2.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_2.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_3.htm b/docs/coverage/FSharp.Core_AnonymousObject_3.htm index 61d0680..69e632d 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_3.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_3.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_4.htm b/docs/coverage/FSharp.Core_AnonymousObject_4.htm index 9b0ac26..d703409 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_4.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_4.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_5.htm b/docs/coverage/FSharp.Core_AnonymousObject_5.htm index bd4ff7c..63975bc 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_5.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_5.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_6.htm b/docs/coverage/FSharp.Core_AnonymousObject_6.htm index 1269afc..aea4882 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_6.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_6.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_7.htm b/docs/coverage/FSharp.Core_AnonymousObject_7.htm index e26f0d8..b83befb 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_7.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_7.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AnonymousObject_8.htm b/docs/coverage/FSharp.Core_AnonymousObject_8.htm index 7481137..0eda3dc 100644 --- a/docs/coverage/FSharp.Core_AnonymousObject_8.htm +++ b/docs/coverage/FSharp.Core_AnonymousObject_8.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\MutableTuple.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Array.htm b/docs/coverage/FSharp.Core_Array.htm index 783473e..8e9d47a 100644 --- a/docs/coverage/FSharp.Core_Array.htm +++ b/docs/coverage/FSharp.Core_Array.htm @@ -59,7 +59,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Array2DModule.htm b/docs/coverage/FSharp.Core_Array2DModule.htm index 67718d8..2e63497 100644 --- a/docs/coverage/FSharp.Core_Array2DModule.htm +++ b/docs/coverage/FSharp.Core_Array2DModule.htm @@ -59,7 +59,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array2.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array2.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Array3DModule.htm b/docs/coverage/FSharp.Core_Array3DModule.htm index 68d7ecd..1d555fa 100644 --- a/docs/coverage/FSharp.Core_Array3DModule.htm +++ b/docs/coverage/FSharp.Core_Array3DModule.htm @@ -48,7 +48,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array3.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array3.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Array4DModule.htm b/docs/coverage/FSharp.Core_Array4DModule.htm index 9ec96a2..12fd7fe 100644 --- a/docs/coverage/FSharp.Core_Array4DModule.htm +++ b/docs/coverage/FSharp.Core_Array4DModule.htm @@ -45,7 +45,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array3.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array3.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ArrayModule.htm b/docs/coverage/FSharp.Core_ArrayModule.htm index a1cfeba..e3f498d 100644 --- a/docs/coverage/FSharp.Core_ArrayModule.htm +++ b/docs/coverage/FSharp.Core_ArrayModule.htm @@ -193,7 +193,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\array.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AsyncActivationAux.htm b/docs/coverage/FSharp.Core_AsyncActivationAux.htm index d4fa2c0..efe809d 100644 --- a/docs/coverage/FSharp.Core_AsyncActivationAux.htm +++ b/docs/coverage/FSharp.Core_AsyncActivationAux.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_AsyncActivationContents_1.htm b/docs/coverage/FSharp.Core_AsyncActivationContents_1.htm index bf090dc..f4e9e50 100644 --- a/docs/coverage/FSharp.Core_AsyncActivationContents_1.htm +++ b/docs/coverage/FSharp.Core_AsyncActivationContents_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_AsyncActivation_1.htm b/docs/coverage/FSharp.Core_AsyncActivation_1.htm index 6819366..af2b2b7 100644 --- a/docs/coverage/FSharp.Core_AsyncActivation_1.htm +++ b/docs/coverage/FSharp.Core_AsyncActivation_1.htm @@ -52,7 +52,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AsyncBuilderImpl.htm b/docs/coverage/FSharp.Core_AsyncBuilderImpl.htm index 03ec3b8..66b60d3 100644 --- a/docs/coverage/FSharp.Core_AsyncBuilderImpl.htm +++ b/docs/coverage/FSharp.Core_AsyncBuilderImpl.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_AsyncHelpers.htm b/docs/coverage/FSharp.Core_AsyncHelpers.htm index 4dd6d19..6b53679 100644 --- a/docs/coverage/FSharp.Core_AsyncHelpers.htm +++ b/docs/coverage/FSharp.Core_AsyncHelpers.htm @@ -51,7 +51,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AsyncPrimitives.htm b/docs/coverage/FSharp.Core_AsyncPrimitives.htm index 7c2ecf3..a7acec6 100644 --- a/docs/coverage/FSharp.Core_AsyncPrimitives.htm +++ b/docs/coverage/FSharp.Core_AsyncPrimitives.htm @@ -162,7 +162,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AsyncResult_1.htm b/docs/coverage/FSharp.Core_AsyncResult_1.htm index a846668..abddc59 100644 --- a/docs/coverage/FSharp.Core_AsyncResult_1.htm +++ b/docs/coverage/FSharp.Core_AsyncResult_1.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AsyncReturn.htm b/docs/coverage/FSharp.Core_AsyncReturn.htm index 6ed404c..a9bc8dc 100644 --- a/docs/coverage/FSharp.Core_AsyncReturn.htm +++ b/docs/coverage/FSharp.Core_AsyncReturn.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AutoOpenAttribute.htm b/docs/coverage/FSharp.Core_AutoOpenAttribute.htm index c509cda..c39b744 100644 --- a/docs/coverage/FSharp.Core_AutoOpenAttribute.htm +++ b/docs/coverage/FSharp.Core_AutoOpenAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_AutoSerializableAttribute.htm b/docs/coverage/FSharp.Core_AutoSerializableAttribute.htm index 3d7d171..3a8bdfc 100644 --- a/docs/coverage/FSharp.Core_AutoSerializableAttribute.htm +++ b/docs/coverage/FSharp.Core_AutoSerializableAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_BasicInlinedOperations.htm b/docs/coverage/FSharp.Core_BasicInlinedOperations.htm index 60dbe9f..b8fc5ee 100644 --- a/docs/coverage/FSharp.Core_BasicInlinedOperations.htm +++ b/docs/coverage/FSharp.Core_BasicInlinedOperations.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_BuildProperties.htm b/docs/coverage/FSharp.Core_BuildProperties.htm index 580aff0..1ee70b7 100644 --- a/docs/coverage/FSharp.Core_BuildProperties.htm +++ b/docs/coverage/FSharp.Core_BuildProperties.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ByRefKinds.htm b/docs/coverage/FSharp.Core_ByRefKinds.htm index 8842e35..b055a5d 100644 --- a/docs/coverage/FSharp.Core_ByRefKinds.htm +++ b/docs/coverage/FSharp.Core_ByRefKinds.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CLIEventAttribute.htm b/docs/coverage/FSharp.Core_CLIEventAttribute.htm index 638a457..301480d 100644 --- a/docs/coverage/FSharp.Core_CLIEventAttribute.htm +++ b/docs/coverage/FSharp.Core_CLIEventAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CLIMutableAttribute.htm b/docs/coverage/FSharp.Core_CLIMutableAttribute.htm index e004bb7..909815f 100644 --- a/docs/coverage/FSharp.Core_CLIMutableAttribute.htm +++ b/docs/coverage/FSharp.Core_CLIMutableAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CachedSeq_1.htm b/docs/coverage/FSharp.Core_CachedSeq_1.htm index b2f5aee..5004ea2 100644 --- a/docs/coverage/FSharp.Core_CachedSeq_1.htm +++ b/docs/coverage/FSharp.Core_CachedSeq_1.htm @@ -40,7 +40,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ClassAttribute.htm b/docs/coverage/FSharp.Core_ClassAttribute.htm index 056536f..481f03a 100644 --- a/docs/coverage/FSharp.Core_ClassAttribute.htm +++ b/docs/coverage/FSharp.Core_ClassAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CommonExtensions.htm b/docs/coverage/FSharp.Core_CommonExtensions.htm index d6bef3a..42f8bad 100644 --- a/docs/coverage/FSharp.Core_CommonExtensions.htm +++ b/docs/coverage/FSharp.Core_CommonExtensions.htm @@ -57,7 +57,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ComparisonConditionalOnAttribute.htm b/docs/coverage/FSharp.Core_ComparisonConditionalOnAttribute.htm index 0a05f64..13837a7 100644 --- a/docs/coverage/FSharp.Core_ComparisonConditionalOnAttribute.htm +++ b/docs/coverage/FSharp.Core_ComparisonConditionalOnAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ComparisonIdentity.htm b/docs/coverage/FSharp.Core_ComparisonIdentity.htm index bc87311..475bb64 100644 --- a/docs/coverage/FSharp.Core_ComparisonIdentity.htm +++ b/docs/coverage/FSharp.Core_ComparisonIdentity.htm @@ -42,7 +42,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\collections.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\collections.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompilationArgumentCountsAttribute.htm b/docs/coverage/FSharp.Core_CompilationArgumentCountsAttribute.htm index 79423cf..63fc3c5 100644 --- a/docs/coverage/FSharp.Core_CompilationArgumentCountsAttribute.htm +++ b/docs/coverage/FSharp.Core_CompilationArgumentCountsAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompilationMappingAttribute.htm b/docs/coverage/FSharp.Core_CompilationMappingAttribute.htm index f9b7a34..57a950c 100644 --- a/docs/coverage/FSharp.Core_CompilationMappingAttribute.htm +++ b/docs/coverage/FSharp.Core_CompilationMappingAttribute.htm @@ -40,7 +40,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompilationRepresentationAttribute.htm b/docs/coverage/FSharp.Core_CompilationRepresentationAttribute.htm index 4bec615..4376677 100644 --- a/docs/coverage/FSharp.Core_CompilationRepresentationAttribute.htm +++ b/docs/coverage/FSharp.Core_CompilationRepresentationAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompilationRepresentationFlags.htm b/docs/coverage/FSharp.Core_CompilationRepresentationFlags.htm index f4e8371..cbabef6 100644 --- a/docs/coverage/FSharp.Core_CompilationRepresentationFlags.htm +++ b/docs/coverage/FSharp.Core_CompilationRepresentationFlags.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_CompilationSourceNameAttribute.htm b/docs/coverage/FSharp.Core_CompilationSourceNameAttribute.htm index 47ca851..6d20267 100644 --- a/docs/coverage/FSharp.Core_CompilationSourceNameAttribute.htm +++ b/docs/coverage/FSharp.Core_CompilationSourceNameAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompiledNameAttribute.htm b/docs/coverage/FSharp.Core_CompiledNameAttribute.htm index 29c7737..d6b4d4a 100644 --- a/docs/coverage/FSharp.Core_CompiledNameAttribute.htm +++ b/docs/coverage/FSharp.Core_CompiledNameAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CompilerMessageAttribute.htm b/docs/coverage/FSharp.Core_CompilerMessageAttribute.htm index 6f67af6..355a469 100644 --- a/docs/coverage/FSharp.Core_CompilerMessageAttribute.htm +++ b/docs/coverage/FSharp.Core_CompilerMessageAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CustomComparisonAttribute.htm b/docs/coverage/FSharp.Core_CustomComparisonAttribute.htm index 3dbc438..c89f908 100644 --- a/docs/coverage/FSharp.Core_CustomComparisonAttribute.htm +++ b/docs/coverage/FSharp.Core_CustomComparisonAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CustomEqualityAttribute.htm b/docs/coverage/FSharp.Core_CustomEqualityAttribute.htm index e737ee0..739b984 100644 --- a/docs/coverage/FSharp.Core_CustomEqualityAttribute.htm +++ b/docs/coverage/FSharp.Core_CustomEqualityAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_CustomOperationAttribute.htm b/docs/coverage/FSharp.Core_CustomOperationAttribute.htm index 3955fdf..9e6bc47 100644 --- a/docs/coverage/FSharp.Core_CustomOperationAttribute.htm +++ b/docs/coverage/FSharp.Core_CustomOperationAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_DefaultAugmentationAttribute.htm b/docs/coverage/FSharp.Core_DefaultAugmentationAttribute.htm index 293c0e8..d194753 100644 --- a/docs/coverage/FSharp.Core_DefaultAugmentationAttribute.htm +++ b/docs/coverage/FSharp.Core_DefaultAugmentationAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_DefaultValueAttribute.htm b/docs/coverage/FSharp.Core_DefaultValueAttribute.htm index fff8582..383d61a 100644 --- a/docs/coverage/FSharp.Core_DefaultValueAttribute.htm +++ b/docs/coverage/FSharp.Core_DefaultValueAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_DerivedPatternsModule.htm b/docs/coverage/FSharp.Core_DerivedPatternsModule.htm index a017e41..e63e406 100644 --- a/docs/coverage/FSharp.Core_DerivedPatternsModule.htm +++ b/docs/coverage/FSharp.Core_DerivedPatternsModule.htm @@ -66,7 +66,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_DetailedExceptions.htm b/docs/coverage/FSharp.Core_DetailedExceptions.htm index 72cdbe4..2e77d0d 100644 --- a/docs/coverage/FSharp.Core_DetailedExceptions.htm +++ b/docs/coverage/FSharp.Core_DetailedExceptions.htm @@ -47,7 +47,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Display.htm b/docs/coverage/FSharp.Core_Display.htm index 509da98..a890cf5 100644 --- a/docs/coverage/FSharp.Core_Display.htm +++ b/docs/coverage/FSharp.Core_Display.htm @@ -136,7 +136,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_DynamicFunction_2.htm b/docs/coverage/FSharp.Core_DynamicFunction_2.htm index 2a62146..a09b6b8 100644 --- a/docs/coverage/FSharp.Core_DynamicFunction_2.htm +++ b/docs/coverage/FSharp.Core_DynamicFunction_2.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_EntryPointAttribute.htm b/docs/coverage/FSharp.Core_EntryPointAttribute.htm index bf5caaa..5e1c074 100644 --- a/docs/coverage/FSharp.Core_EntryPointAttribute.htm +++ b/docs/coverage/FSharp.Core_EntryPointAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_EqualityConditionalOnAttribute.htm b/docs/coverage/FSharp.Core_EqualityConditionalOnAttribute.htm index b498aa8..962b4ba 100644 --- a/docs/coverage/FSharp.Core_EqualityConditionalOnAttribute.htm +++ b/docs/coverage/FSharp.Core_EqualityConditionalOnAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_EventDelegee_1.htm b/docs/coverage/FSharp.Core_EventDelegee_1.htm index b299df0..8dbf7ca 100644 --- a/docs/coverage/FSharp.Core_EventDelegee_1.htm +++ b/docs/coverage/FSharp.Core_EventDelegee_1.htm @@ -45,7 +45,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_EventModule.htm b/docs/coverage/FSharp.Core_EventModule.htm index 521c71c..afeb622 100644 --- a/docs/coverage/FSharp.Core_EventModule.htm +++ b/docs/coverage/FSharp.Core_EventModule.htm @@ -54,7 +54,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\eventmodule.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\eventmodule.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_EventWrapper_2.htm b/docs/coverage/FSharp.Core_EventWrapper_2.htm index fd9b663..281768c 100644 --- a/docs/coverage/FSharp.Core_EventWrapper_2.htm +++ b/docs/coverage/FSharp.Core_EventWrapper_2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ExceptionDispatchInfoHelpers.htm b/docs/coverage/FSharp.Core_ExceptionDispatchInfoHelpers.htm index 4510ec1..4e9dbaa 100644 --- a/docs/coverage/FSharp.Core_ExceptionDispatchInfoHelpers.htm +++ b/docs/coverage/FSharp.Core_ExceptionDispatchInfoHelpers.htm @@ -39,7 +39,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ExperimentalAttribute.htm b/docs/coverage/FSharp.Core_ExperimentalAttribute.htm index 97cb01d..0651f94 100644 --- a/docs/coverage/FSharp.Core_ExperimentalAttribute.htm +++ b/docs/coverage/FSharp.Core_ExperimentalAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ExperimentalAttributeMessages.htm b/docs/coverage/FSharp.Core_ExperimentalAttributeMessages.htm index 1aac167..c2ed6b6 100644 --- a/docs/coverage/FSharp.Core_ExperimentalAttributeMessages.htm +++ b/docs/coverage/FSharp.Core_ExperimentalAttributeMessages.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ExprConstInfo.htm b/docs/coverage/FSharp.Core_ExprConstInfo.htm index caaf2fb..d806b5f 100644 --- a/docs/coverage/FSharp.Core_ExprConstInfo.htm +++ b/docs/coverage/FSharp.Core_ExprConstInfo.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ExprShapeModule.htm b/docs/coverage/FSharp.Core_ExprShapeModule.htm index d62c674..22d4b3c 100644 --- a/docs/coverage/FSharp.Core_ExprShapeModule.htm +++ b/docs/coverage/FSharp.Core_ExprShapeModule.htm @@ -39,7 +39,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ExtraTopLevelOperators.htm b/docs/coverage/FSharp.Core_ExtraTopLevelOperators.htm index 577133a..22875ec 100644 --- a/docs/coverage/FSharp.Core_ExtraTopLevelOperators.htm +++ b/docs/coverage/FSharp.Core_ExtraTopLevelOperators.htm @@ -115,7 +115,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpAsync.htm b/docs/coverage/FSharp.Core_FSharpAsync.htm index ce075a9..8701640 100644 --- a/docs/coverage/FSharp.Core_FSharpAsync.htm +++ b/docs/coverage/FSharp.Core_FSharpAsync.htm @@ -191,7 +191,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpAsyncBuilder.htm b/docs/coverage/FSharp.Core_FSharpAsyncBuilder.htm index deb7741..b033140 100644 --- a/docs/coverage/FSharp.Core_FSharpAsyncBuilder.htm +++ b/docs/coverage/FSharp.Core_FSharpAsyncBuilder.htm @@ -53,7 +53,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpAsyncReplyChannel_1.htm b/docs/coverage/FSharp.Core_FSharpAsyncReplyChannel_1.htm index c8cf04b..c5b02aa 100644 --- a/docs/coverage/FSharp.Core_FSharpAsyncReplyChannel_1.htm +++ b/docs/coverage/FSharp.Core_FSharpAsyncReplyChannel_1.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpAsync_1.htm b/docs/coverage/FSharp.Core_FSharpAsync_1.htm index 14ba00e..d2c3940 100644 --- a/docs/coverage/FSharp.Core_FSharpAsync_1.htm +++ b/docs/coverage/FSharp.Core_FSharpAsync_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_2.htm b/docs/coverage/FSharp.Core_FSharpChoice_2.htm index ad1e758..b9c1c21 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_2.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_3.htm b/docs/coverage/FSharp.Core_FSharpChoice_3.htm index 789e16b..d55d22e 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_3.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_3.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_4.htm b/docs/coverage/FSharp.Core_FSharpChoice_4.htm index a42a9d6..e02a26c 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_4.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_4.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_5.htm b/docs/coverage/FSharp.Core_FSharpChoice_5.htm index 004346b..7b2cef6 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_5.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_5.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_6.htm b/docs/coverage/FSharp.Core_FSharpChoice_6.htm index df2506b..6d4bbd9 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_6.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_6.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpChoice_7.htm b/docs/coverage/FSharp.Core_FSharpChoice_7.htm index f3722fd..518ad71 100644 --- a/docs/coverage/FSharp.Core_FSharpChoice_7.htm +++ b/docs/coverage/FSharp.Core_FSharpChoice_7.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpDelegateEvent_1.htm b/docs/coverage/FSharp.Core_FSharpDelegateEvent_1.htm index 3f951ee..ca70d98 100644 --- a/docs/coverage/FSharp.Core_FSharpDelegateEvent_1.htm +++ b/docs/coverage/FSharp.Core_FSharpDelegateEvent_1.htm @@ -40,7 +40,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpEvent_1.htm b/docs/coverage/FSharp.Core_FSharpEvent_1.htm index 5223031..14e608b 100644 --- a/docs/coverage/FSharp.Core_FSharpEvent_1.htm +++ b/docs/coverage/FSharp.Core_FSharpEvent_1.htm @@ -44,7 +44,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpEvent_2.htm b/docs/coverage/FSharp.Core_FSharpEvent_2.htm index 83f070d..045664c 100644 --- a/docs/coverage/FSharp.Core_FSharpEvent_2.htm +++ b/docs/coverage/FSharp.Core_FSharpEvent_2.htm @@ -44,7 +44,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\event.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpExpr.htm b/docs/coverage/FSharp.Core_FSharpExpr.htm index e2da092..707132f 100644 --- a/docs/coverage/FSharp.Core_FSharpExpr.htm +++ b/docs/coverage/FSharp.Core_FSharpExpr.htm @@ -103,7 +103,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpExpr_1.htm b/docs/coverage/FSharp.Core_FSharpExpr_1.htm index 14e8395..9f70c0a 100644 --- a/docs/coverage/FSharp.Core_FSharpExpr_1.htm +++ b/docs/coverage/FSharp.Core_FSharpExpr_1.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpFunc_2.htm b/docs/coverage/FSharp.Core_FSharpFunc_2.htm index e5a5407..01c3b32 100644 --- a/docs/coverage/FSharp.Core_FSharpFunc_2.htm +++ b/docs/coverage/FSharp.Core_FSharpFunc_2.htm @@ -42,7 +42,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpHandler_1.htm b/docs/coverage/FSharp.Core_FSharpHandler_1.htm index c64a3dd..a84f42f 100644 --- a/docs/coverage/FSharp.Core_FSharpHandler_1.htm +++ b/docs/coverage/FSharp.Core_FSharpHandler_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpInterfaceDataVersionAttribute.htm b/docs/coverage/FSharp.Core_FSharpInterfaceDataVersionAttribute.htm index 104427e..5596c0b 100644 --- a/docs/coverage/FSharp.Core_FSharpInterfaceDataVersionAttribute.htm +++ b/docs/coverage/FSharp.Core_FSharpInterfaceDataVersionAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpList_1.htm b/docs/coverage/FSharp.Core_FSharpList_1.htm index 111a33b..70fe8a0 100644 --- a/docs/coverage/FSharp.Core_FSharpList_1.htm +++ b/docs/coverage/FSharp.Core_FSharpList_1.htm @@ -43,7 +43,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpMailboxProcessor_1.htm b/docs/coverage/FSharp.Core_FSharpMailboxProcessor_1.htm index 65a384e..7c314f9 100644 --- a/docs/coverage/FSharp.Core_FSharpMailboxProcessor_1.htm +++ b/docs/coverage/FSharp.Core_FSharpMailboxProcessor_1.htm @@ -73,7 +73,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpMap_2.htm b/docs/coverage/FSharp.Core_FSharpMap_2.htm index 68e3f20..bb96672 100644 --- a/docs/coverage/FSharp.Core_FSharpMap_2.htm +++ b/docs/coverage/FSharp.Core_FSharpMap_2.htm @@ -88,7 +88,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpOption_1.htm b/docs/coverage/FSharp.Core_FSharpOption_1.htm index aaaf511..1b4f87f 100644 --- a/docs/coverage/FSharp.Core_FSharpOption_1.htm +++ b/docs/coverage/FSharp.Core_FSharpOption_1.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpRef_1.htm b/docs/coverage/FSharp.Core_FSharpRef_1.htm index e033e19..a322b32 100644 --- a/docs/coverage/FSharp.Core_FSharpRef_1.htm +++ b/docs/coverage/FSharp.Core_FSharpRef_1.htm @@ -29,7 +29,7 @@

< Summary

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpReflectionExtensions.htm b/docs/coverage/FSharp.Core_FSharpReflectionExtensions.htm index 9c05dfc..b465b2a 100644 --- a/docs/coverage/FSharp.Core_FSharpReflectionExtensions.htm +++ b/docs/coverage/FSharp.Core_FSharpReflectionExtensions.htm @@ -54,7 +54,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpResult_2.htm b/docs/coverage/FSharp.Core_FSharpResult_2.htm index f04a06f..7f2bb61 100644 --- a/docs/coverage/FSharp.Core_FSharpResult_2.htm +++ b/docs/coverage/FSharp.Core_FSharpResult_2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_FSharpSet_1.htm b/docs/coverage/FSharp.Core_FSharpSet_1.htm index 7388819..d59c010 100644 --- a/docs/coverage/FSharp.Core_FSharpSet_1.htm +++ b/docs/coverage/FSharp.Core_FSharpSet_1.htm @@ -86,7 +86,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpType.htm b/docs/coverage/FSharp.Core_FSharpType.htm index 0ab029c..219d0b8 100644 --- a/docs/coverage/FSharp.Core_FSharpType.htm +++ b/docs/coverage/FSharp.Core_FSharpType.htm @@ -55,7 +55,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpTypeFunc.htm b/docs/coverage/FSharp.Core_FSharpTypeFunc.htm index a713dbf..af0a754 100644 --- a/docs/coverage/FSharp.Core_FSharpTypeFunc.htm +++ b/docs/coverage/FSharp.Core_FSharpTypeFunc.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpValue.htm b/docs/coverage/FSharp.Core_FSharpValue.htm index 68bc818..e0910d4 100644 --- a/docs/coverage/FSharp.Core_FSharpValue.htm +++ b/docs/coverage/FSharp.Core_FSharpValue.htm @@ -60,7 +60,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpValueOption_1.htm b/docs/coverage/FSharp.Core_FSharpValueOption_1.htm index 6eb75cc..ac6a0bb 100644 --- a/docs/coverage/FSharp.Core_FSharpValueOption_1.htm +++ b/docs/coverage/FSharp.Core_FSharpValueOption_1.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FSharpVar.htm b/docs/coverage/FSharp.Core_FSharpVar.htm index 18495d8..bb19677 100644 --- a/docs/coverage/FSharp.Core_FSharpVar.htm +++ b/docs/coverage/FSharp.Core_FSharpVar.htm @@ -43,7 +43,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FormatOptions.htm b/docs/coverage/FSharp.Core_FormatOptions.htm index 03fe9af..3f40eea 100644 --- a/docs/coverage/FSharp.Core_FormatOptions.htm +++ b/docs/coverage/FSharp.Core_FormatOptions.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ForwardDeclarations.htm b/docs/coverage/FSharp.Core_ForwardDeclarations.htm index 70ce135..4a12c4b 100644 --- a/docs/coverage/FSharp.Core_ForwardDeclarations.htm +++ b/docs/coverage/FSharp.Core_ForwardDeclarations.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_FuncConvert.htm b/docs/coverage/FSharp.Core_FuncConvert.htm index 510488a..061c9c4 100644 --- a/docs/coverage/FSharp.Core_FuncConvert.htm +++ b/docs/coverage/FSharp.Core_FuncConvert.htm @@ -73,7 +73,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_GeneralizableValueAttribute.htm b/docs/coverage/FSharp.Core_GeneralizableValueAttribute.htm index ed6da2b..ada3ae8 100644 --- a/docs/coverage/FSharp.Core_GeneralizableValueAttribute.htm +++ b/docs/coverage/FSharp.Core_GeneralizableValueAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_GeneratedSequenceBase_1.htm b/docs/coverage/FSharp.Core_GeneratedSequenceBase_1.htm index 464e240..3c1e411 100644 --- a/docs/coverage/FSharp.Core_GeneratedSequenceBase_1.htm +++ b/docs/coverage/FSharp.Core_GeneratedSequenceBase_1.htm @@ -50,7 +50,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Generator.htm b/docs/coverage/FSharp.Core_Generator.htm index 6a2afe7..fa5b2a1 100644 --- a/docs/coverage/FSharp.Core_Generator.htm +++ b/docs/coverage/FSharp.Core_Generator.htm @@ -57,7 +57,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Grouping_2.htm b/docs/coverage/FSharp.Core_Grouping_2.htm index d20b4c0..5f075db 100644 --- a/docs/coverage/FSharp.Core_Grouping_2.htm +++ b/docs/coverage/FSharp.Core_Grouping_2.htm @@ -39,7 +39,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\QueryExtensions.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\QueryExtensions.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_HashIdentity.htm b/docs/coverage/FSharp.Core_HashIdentity.htm index 47249bb..09e55ee 100644 --- a/docs/coverage/FSharp.Core_HashIdentity.htm +++ b/docs/coverage/FSharp.Core_HashIdentity.htm @@ -51,7 +51,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\collections.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\collections.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Helpers.htm b/docs/coverage/FSharp.Core_Helpers.htm index 206d7f1..02bb094 100644 --- a/docs/coverage/FSharp.Core_Helpers.htm +++ b/docs/coverage/FSharp.Core_Helpers.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Helpers2.htm b/docs/coverage/FSharp.Core_Helpers2.htm index 57a2f19..1e98fa7 100644 --- a/docs/coverage/FSharp.Core_Helpers2.htm +++ b/docs/coverage/FSharp.Core_Helpers2.htm @@ -46,7 +46,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_HighPriority.htm b/docs/coverage/FSharp.Core_HighPriority.htm index a0b179b..086cfad 100644 --- a/docs/coverage/FSharp.Core_HighPriority.htm +++ b/docs/coverage/FSharp.Core_HighPriority.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_IDelegateEvent_1.htm b/docs/coverage/FSharp.Core_IDelegateEvent_1.htm index 56cb47d..3092d5f 100644 --- a/docs/coverage/FSharp.Core_IDelegateEvent_1.htm +++ b/docs/coverage/FSharp.Core_IDelegateEvent_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_IEnumerator.htm b/docs/coverage/FSharp.Core_IEnumerator.htm index 83092b7..e02dd2d 100644 --- a/docs/coverage/FSharp.Core_IEnumerator.htm +++ b/docs/coverage/FSharp.Core_IEnumerator.htm @@ -82,7 +82,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_IEnvironment.htm b/docs/coverage/FSharp.Core_IEnvironment.htm index 4c95801..6c917c7 100644 --- a/docs/coverage/FSharp.Core_IEnvironment.htm +++ b/docs/coverage/FSharp.Core_IEnvironment.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_IEvent_2.htm b/docs/coverage/FSharp.Core_IEvent_2.htm index 33db19d..0b12b67 100644 --- a/docs/coverage/FSharp.Core_IEvent_2.htm +++ b/docs/coverage/FSharp.Core_IEvent_2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_IProvidedNamespace.htm b/docs/coverage/FSharp.Core_IProvidedNamespace.htm index 905e5a5..ed2ab70 100644 --- a/docs/coverage/FSharp.Core_IProvidedNamespace.htm +++ b/docs/coverage/FSharp.Core_IProvidedNamespace.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ITypeProvider.htm b/docs/coverage/FSharp.Core_ITypeProvider.htm index 181bf1b..60f0112 100644 --- a/docs/coverage/FSharp.Core_ITypeProvider.htm +++ b/docs/coverage/FSharp.Core_ITypeProvider.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_ITypeProvider2.htm b/docs/coverage/FSharp.Core_ITypeProvider2.htm index 02a01bc..d58c09c 100644 --- a/docs/coverage/FSharp.Core_ITypeProvider2.htm +++ b/docs/coverage/FSharp.Core_ITypeProvider2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_Impl.htm b/docs/coverage/FSharp.Core_Impl.htm index 1ed7db0..3c48d28 100644 --- a/docs/coverage/FSharp.Core_Impl.htm +++ b/docs/coverage/FSharp.Core_Impl.htm @@ -141,7 +141,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_InterfaceAttribute.htm b/docs/coverage/FSharp.Core_InterfaceAttribute.htm index f1ae262..8e18546 100644 --- a/docs/coverage/FSharp.Core_InterfaceAttribute.htm +++ b/docs/coverage/FSharp.Core_InterfaceAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Internal.htm b/docs/coverage/FSharp.Core_Internal.htm index d9e1613..9a2c935 100644 --- a/docs/coverage/FSharp.Core_Internal.htm +++ b/docs/coverage/FSharp.Core_Internal.htm @@ -92,7 +92,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Joint.htm b/docs/coverage/FSharp.Core_Joint.htm index 076dd9e..4bb4a69 100644 --- a/docs/coverage/FSharp.Core_Joint.htm +++ b/docs/coverage/FSharp.Core_Joint.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_KeyValuePairDebugFriendly_2.htm b/docs/coverage/FSharp.Core_KeyValuePairDebugFriendly_2.htm index b98dee8..bad57bc 100644 --- a/docs/coverage/FSharp.Core_KeyValuePairDebugFriendly_2.htm +++ b/docs/coverage/FSharp.Core_KeyValuePairDebugFriendly_2.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LanguagePrimitives.htm b/docs/coverage/FSharp.Core_LanguagePrimitives.htm index 0c2e0f4..31eb53e 100644 --- a/docs/coverage/FSharp.Core_LanguagePrimitives.htm +++ b/docs/coverage/FSharp.Core_LanguagePrimitives.htm @@ -263,7 +263,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Latch.htm b/docs/coverage/FSharp.Core_Latch.htm index 3c478c8..92c2715 100644 --- a/docs/coverage/FSharp.Core_Latch.htm +++ b/docs/coverage/FSharp.Core_Latch.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Layout.htm b/docs/coverage/FSharp.Core_Layout.htm index e1a9158..d1bf147 100644 --- a/docs/coverage/FSharp.Core_Layout.htm +++ b/docs/coverage/FSharp.Core_Layout.htm @@ -29,7 +29,7 @@

< Summary

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LayoutOps.htm b/docs/coverage/FSharp.Core_LayoutOps.htm index afcb3e7..dfc05b1 100644 --- a/docs/coverage/FSharp.Core_LayoutOps.htm +++ b/docs/coverage/FSharp.Core_LayoutOps.htm @@ -77,7 +77,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LayoutTag.htm b/docs/coverage/FSharp.Core_LayoutTag.htm index 82598be..9732c41 100644 --- a/docs/coverage/FSharp.Core_LayoutTag.htm +++ b/docs/coverage/FSharp.Core_LayoutTag.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_LazyExtensions.htm b/docs/coverage/FSharp.Core_LazyExtensions.htm index 0ed2f62..e235c7d 100644 --- a/docs/coverage/FSharp.Core_LazyExtensions.htm +++ b/docs/coverage/FSharp.Core_LazyExtensions.htm @@ -43,7 +43,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LeafExpressionConverter.htm b/docs/coverage/FSharp.Core_LeafExpressionConverter.htm index 7be280c..e142cce 100644 --- a/docs/coverage/FSharp.Core_LeafExpressionConverter.htm +++ b/docs/coverage/FSharp.Core_LeafExpressionConverter.htm @@ -138,7 +138,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Linq.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Linq.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LinkedSubSource.htm b/docs/coverage/FSharp.Core_LinkedSubSource.htm index 427a63f..c3054d6 100644 --- a/docs/coverage/FSharp.Core_LinkedSubSource.htm +++ b/docs/coverage/FSharp.Core_LinkedSubSource.htm @@ -39,7 +39,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_List.htm b/docs/coverage/FSharp.Core_List.htm index c7a0c77..c016464 100644 --- a/docs/coverage/FSharp.Core_List.htm +++ b/docs/coverage/FSharp.Core_List.htm @@ -117,7 +117,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ListDebugView_1.htm b/docs/coverage/FSharp.Core_ListDebugView_1.htm index 86b3142..b5f322f 100644 --- a/docs/coverage/FSharp.Core_ListDebugView_1.htm +++ b/docs/coverage/FSharp.Core_ListDebugView_1.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ListModule.htm b/docs/coverage/FSharp.Core_ListModule.htm index 10fc7dc..eacd93c 100644 --- a/docs/coverage/FSharp.Core_ListModule.htm +++ b/docs/coverage/FSharp.Core_ListModule.htm @@ -165,7 +165,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\list.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\list.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LiteralAttribute.htm b/docs/coverage/FSharp.Core_LiteralAttribute.htm index bc97fb1..b94e15f 100644 --- a/docs/coverage/FSharp.Core_LiteralAttribute.htm +++ b/docs/coverage/FSharp.Core_LiteralAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_LowPriority.htm b/docs/coverage/FSharp.Core_LowPriority.htm index 5baa0b3..1ac5a46 100644 --- a/docs/coverage/FSharp.Core_LowPriority.htm +++ b/docs/coverage/FSharp.Core_LowPriority.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Mailbox_1.htm b/docs/coverage/FSharp.Core_Mailbox_1.htm index 2baca8c..0c932d6 100644 --- a/docs/coverage/FSharp.Core_Mailbox_1.htm +++ b/docs/coverage/FSharp.Core_Mailbox_1.htm @@ -91,7 +91,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\mailbox.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MapDebugView_2.htm b/docs/coverage/FSharp.Core_MapDebugView_2.htm index 426068a..942a2dc 100644 --- a/docs/coverage/FSharp.Core_MapDebugView_2.htm +++ b/docs/coverage/FSharp.Core_MapDebugView_2.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MapModule.htm b/docs/coverage/FSharp.Core_MapModule.htm index e8ca22e..1241781 100644 --- a/docs/coverage/FSharp.Core_MapModule.htm +++ b/docs/coverage/FSharp.Core_MapModule.htm @@ -65,7 +65,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MapTreeModule.htm b/docs/coverage/FSharp.Core_MapTreeModule.htm index 3a88e7e..2f21faa 100644 --- a/docs/coverage/FSharp.Core_MapTreeModule.htm +++ b/docs/coverage/FSharp.Core_MapTreeModule.htm @@ -94,7 +94,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\map.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MapTree_2.htm b/docs/coverage/FSharp.Core_MapTree_2.htm index 8404efd..ee626de 100644 --- a/docs/coverage/FSharp.Core_MapTree_2.htm +++ b/docs/coverage/FSharp.Core_MapTree_2.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_MatchFailureException.htm b/docs/coverage/FSharp.Core_MatchFailureException.htm index a1ea730..355ae91 100644 --- a/docs/coverage/FSharp.Core_MatchFailureException.htm +++ b/docs/coverage/FSharp.Core_MatchFailureException.htm @@ -29,7 +29,7 @@

< Summary

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MeasureAnnotatedAbbreviationAttribute.htm b/docs/coverage/FSharp.Core_MeasureAnnotatedAbbreviationAttribute.htm index 62be85b..bf52a21 100644 --- a/docs/coverage/FSharp.Core_MeasureAnnotatedAbbreviationAttribute.htm +++ b/docs/coverage/FSharp.Core_MeasureAnnotatedAbbreviationAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MeasureAttribute.htm b/docs/coverage/FSharp.Core_MeasureAttribute.htm index 1878092..6120e89 100644 --- a/docs/coverage/FSharp.Core_MeasureAttribute.htm +++ b/docs/coverage/FSharp.Core_MeasureAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_MeasureInverse_1.htm b/docs/coverage/FSharp.Core_MeasureInverse_1.htm index 104e5a6..fb72794 100644 --- a/docs/coverage/FSharp.Core_MeasureInverse_1.htm +++ b/docs/coverage/FSharp.Core_MeasureInverse_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_MeasureOne.htm b/docs/coverage/FSharp.Core_MeasureOne.htm index ec21bdc..a964fd2 100644 --- a/docs/coverage/FSharp.Core_MeasureOne.htm +++ b/docs/coverage/FSharp.Core_MeasureOne.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_MeasureProduct_2.htm b/docs/coverage/FSharp.Core_MeasureProduct_2.htm index b3c88b1..1bd79d9 100644 --- a/docs/coverage/FSharp.Core_MeasureProduct_2.htm +++ b/docs/coverage/FSharp.Core_MeasureProduct_2.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NativePtrModule.htm b/docs/coverage/FSharp.Core_NativePtrModule.htm index 51ec12f..488ab86 100644 --- a/docs/coverage/FSharp.Core_NativePtrModule.htm +++ b/docs/coverage/FSharp.Core_NativePtrModule.htm @@ -46,7 +46,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\nativeptr.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\nativeptr.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NoComparisonAttribute.htm b/docs/coverage/FSharp.Core_NoComparisonAttribute.htm index 63ec214..495ef56 100644 --- a/docs/coverage/FSharp.Core_NoComparisonAttribute.htm +++ b/docs/coverage/FSharp.Core_NoComparisonAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NoDynamicInvocationAttribute.htm b/docs/coverage/FSharp.Core_NoDynamicInvocationAttribute.htm index 8a740f3..bd185d0 100644 --- a/docs/coverage/FSharp.Core_NoDynamicInvocationAttribute.htm +++ b/docs/coverage/FSharp.Core_NoDynamicInvocationAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NoEqualityAttribute.htm b/docs/coverage/FSharp.Core_NoEqualityAttribute.htm index 645d9d5..be2422f 100644 --- a/docs/coverage/FSharp.Core_NoEqualityAttribute.htm +++ b/docs/coverage/FSharp.Core_NoEqualityAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NullableModule.htm b/docs/coverage/FSharp.Core_NullableModule.htm index 13fb75d..67a91ce 100644 --- a/docs/coverage/FSharp.Core_NullableModule.htm +++ b/docs/coverage/FSharp.Core_NullableModule.htm @@ -77,7 +77,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Nullable.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Nullable.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NullableOperators.htm b/docs/coverage/FSharp.Core_NullableOperators.htm index e6a9815..cdf58e5 100644 --- a/docs/coverage/FSharp.Core_NullableOperators.htm +++ b/docs/coverage/FSharp.Core_NullableOperators.htm @@ -66,7 +66,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Nullable.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Nullable.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_NumericLiterals.htm b/docs/coverage/FSharp.Core_NumericLiterals.htm index d8b0298..067236e 100644 --- a/docs/coverage/FSharp.Core_NumericLiterals.htm +++ b/docs/coverage/FSharp.Core_NumericLiterals.htm @@ -41,7 +41,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\math\z.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\math\z.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ObservableModule.htm b/docs/coverage/FSharp.Core_ObservableModule.htm index 77c4e5f..0cc8d95 100644 --- a/docs/coverage/FSharp.Core_ObservableModule.htm +++ b/docs/coverage/FSharp.Core_ObservableModule.htm @@ -77,7 +77,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\observable.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\observable.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Once.htm b/docs/coverage/FSharp.Core_Once.htm index 4552e53..528f33a 100644 --- a/docs/coverage/FSharp.Core_Once.htm +++ b/docs/coverage/FSharp.Core_Once.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Operators.htm b/docs/coverage/FSharp.Core_Operators.htm index 605e93e..e0e07dd 100644 --- a/docs/coverage/FSharp.Core_Operators.htm +++ b/docs/coverage/FSharp.Core_Operators.htm @@ -729,7 +729,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_OptimizedClosures.htm b/docs/coverage/FSharp.Core_OptimizedClosures.htm index 2fd0314..d76c52a 100644 --- a/docs/coverage/FSharp.Core_OptimizedClosures.htm +++ b/docs/coverage/FSharp.Core_OptimizedClosures.htm @@ -68,7 +68,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_OptionModule.htm b/docs/coverage/FSharp.Core_OptionModule.htm index 8e61f9c..05ffb44 100644 --- a/docs/coverage/FSharp.Core_OptionModule.htm +++ b/docs/coverage/FSharp.Core_OptionModule.htm @@ -60,7 +60,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\option.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\option.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_OptionalArgumentAttribute.htm b/docs/coverage/FSharp.Core_OptionalArgumentAttribute.htm index 7d5ce50..9a4ef26 100644 --- a/docs/coverage/FSharp.Core_OptionalArgumentAttribute.htm +++ b/docs/coverage/FSharp.Core_OptionalArgumentAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PatternsModule.htm b/docs/coverage/FSharp.Core_PatternsModule.htm index dd7bd17..ecb0f8c 100644 --- a/docs/coverage/FSharp.Core_PatternsModule.htm +++ b/docs/coverage/FSharp.Core_PatternsModule.htm @@ -344,7 +344,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PrintfFormat_4.htm b/docs/coverage/FSharp.Core_PrintfFormat_4.htm index 118377b..0af2cb0 100644 --- a/docs/coverage/FSharp.Core_PrintfFormat_4.htm +++ b/docs/coverage/FSharp.Core_PrintfFormat_4.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PrintfFormat_5.htm b/docs/coverage/FSharp.Core_PrintfFormat_5.htm index f417a0a..125e8fa 100644 --- a/docs/coverage/FSharp.Core_PrintfFormat_5.htm +++ b/docs/coverage/FSharp.Core_PrintfFormat_5.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PrintfImpl.htm b/docs/coverage/FSharp.Core_PrintfImpl.htm index 20bb15f..5e5a52d 100644 --- a/docs/coverage/FSharp.Core_PrintfImpl.htm +++ b/docs/coverage/FSharp.Core_PrintfImpl.htm @@ -195,7 +195,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PrintfModule.htm b/docs/coverage/FSharp.Core_PrintfModule.htm index d862b0b..87b65ef 100644 --- a/docs/coverage/FSharp.Core_PrintfModule.htm +++ b/docs/coverage/FSharp.Core_PrintfModule.htm @@ -58,7 +58,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_PrivateListHelpers.htm b/docs/coverage/FSharp.Core_PrivateListHelpers.htm index 4953c96..72b833a 100644 --- a/docs/coverage/FSharp.Core_PrivateListHelpers.htm +++ b/docs/coverage/FSharp.Core_PrivateListHelpers.htm @@ -52,7 +52,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ProjectionParameterAttribute.htm b/docs/coverage/FSharp.Core_ProjectionParameterAttribute.htm index 7396ee5..7f4c581 100644 --- a/docs/coverage/FSharp.Core_ProjectionParameterAttribute.htm +++ b/docs/coverage/FSharp.Core_ProjectionParameterAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_QueryBuilder.htm b/docs/coverage/FSharp.Core_QueryBuilder.htm index 658d5b9..2cb0b64 100644 --- a/docs/coverage/FSharp.Core_QueryBuilder.htm +++ b/docs/coverage/FSharp.Core_QueryBuilder.htm @@ -123,7 +123,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_QueryModule.htm b/docs/coverage/FSharp.Core_QueryModule.htm index 191853c..6364e9d 100644 --- a/docs/coverage/FSharp.Core_QueryModule.htm +++ b/docs/coverage/FSharp.Core_QueryModule.htm @@ -159,7 +159,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_QuerySource_2.htm b/docs/coverage/FSharp.Core_QuerySource_2.htm index 9ee4286..d91f4c9 100644 --- a/docs/coverage/FSharp.Core_QuerySource_2.htm +++ b/docs/coverage/FSharp.Core_QuerySource_2.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\Query.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ReferenceEqualityAttribute.htm b/docs/coverage/FSharp.Core_ReferenceEqualityAttribute.htm index cd2e650..420002b 100644 --- a/docs/coverage/FSharp.Core_ReferenceEqualityAttribute.htm +++ b/docs/coverage/FSharp.Core_ReferenceEqualityAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ReflectUtils.htm b/docs/coverage/FSharp.Core_ReflectUtils.htm index ed72238..33e08f1 100644 --- a/docs/coverage/FSharp.Core_ReflectUtils.htm +++ b/docs/coverage/FSharp.Core_ReflectUtils.htm @@ -43,7 +43,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ReflectedDefinitionAttribute.htm b/docs/coverage/FSharp.Core_ReflectedDefinitionAttribute.htm index 7c83ea4..31cf174 100644 --- a/docs/coverage/FSharp.Core_ReflectedDefinitionAttribute.htm +++ b/docs/coverage/FSharp.Core_ReflectedDefinitionAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ReflectionUtils.htm b/docs/coverage/FSharp.Core_ReflectionUtils.htm index 4f1d4f8..053f5eb 100644 --- a/docs/coverage/FSharp.Core_ReflectionUtils.htm +++ b/docs/coverage/FSharp.Core_ReflectionUtils.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_RequireQualifiedAccessAttribute.htm b/docs/coverage/FSharp.Core_RequireQualifiedAccessAttribute.htm index c68760d..5482b7c 100644 --- a/docs/coverage/FSharp.Core_RequireQualifiedAccessAttribute.htm +++ b/docs/coverage/FSharp.Core_RequireQualifiedAccessAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_RequiresExplicitTypeArgumentsAttribute.htm b/docs/coverage/FSharp.Core_RequiresExplicitTypeArgumentsAttribute.htm index 957d137..b96df11 100644 --- a/docs/coverage/FSharp.Core_RequiresExplicitTypeArgumentsAttribute.htm +++ b/docs/coverage/FSharp.Core_RequiresExplicitTypeArgumentsAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ResultModule.htm b/docs/coverage/FSharp.Core_ResultModule.htm index 152ec3c..61a41c6 100644 --- a/docs/coverage/FSharp.Core_ResultModule.htm +++ b/docs/coverage/FSharp.Core_ResultModule.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\result.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\result.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_RuntimeHelpers.htm b/docs/coverage/FSharp.Core_RuntimeHelpers.htm index f016808..e82bf98 100644 --- a/docs/coverage/FSharp.Core_RuntimeHelpers.htm +++ b/docs/coverage/FSharp.Core_RuntimeHelpers.htm @@ -82,7 +82,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SR.htm b/docs/coverage/FSharp.Core_SR.htm index c3eb1b1..0c28f8d 100644 --- a/docs/coverage/FSharp.Core_SR.htm +++ b/docs/coverage/FSharp.Core_SR.htm @@ -38,7 +38,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\artifacts\obj\FSharp.Core\Release\netstandard2.0\FSCore.fs

File 'F:\workspace\_work\1\s\artifacts\obj\FSharp.Core\Release\netstandard2.0\FSCore.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SealedAttribute.htm b/docs/coverage/FSharp.Core_SealedAttribute.htm index fb9a954..509d682 100644 --- a/docs/coverage/FSharp.Core_SealedAttribute.htm +++ b/docs/coverage/FSharp.Core_SealedAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Seq.htm b/docs/coverage/FSharp.Core_Seq.htm index 60344d1..02f913b 100644 --- a/docs/coverage/FSharp.Core_Seq.htm +++ b/docs/coverage/FSharp.Core_Seq.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SeqModule.htm b/docs/coverage/FSharp.Core_SeqModule.htm index 041044b..cd4ee95 100644 --- a/docs/coverage/FSharp.Core_SeqModule.htm +++ b/docs/coverage/FSharp.Core_SeqModule.htm @@ -238,7 +238,7 @@

F:\workspace\_work\1\s\

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SetDebugView_1.htm b/docs/coverage/FSharp.Core_SetDebugView_1.htm index 69b7157..2f115ed 100644 --- a/docs/coverage/FSharp.Core_SetDebugView_1.htm +++ b/docs/coverage/FSharp.Core_SetDebugView_1.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SetModule.htm b/docs/coverage/FSharp.Core_SetModule.htm index 34cd363..8545351 100644 --- a/docs/coverage/FSharp.Core_SetModule.htm +++ b/docs/coverage/FSharp.Core_SetModule.htm @@ -66,7 +66,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SetTreeModule.htm b/docs/coverage/FSharp.Core_SetTreeModule.htm index e4b4b1b..43a8c1a 100644 --- a/docs/coverage/FSharp.Core_SetTreeModule.htm +++ b/docs/coverage/FSharp.Core_SetTreeModule.htm @@ -89,7 +89,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\set.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_SetTree_1.htm b/docs/coverage/FSharp.Core_SetTree_1.htm index b9e32c7..fc6ba12 100644 --- a/docs/coverage/FSharp.Core_SetTree_1.htm +++ b/docs/coverage/FSharp.Core_SetTree_1.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_SourceConstructFlags.htm b/docs/coverage/FSharp.Core_SourceConstructFlags.htm index 6f5700f..cbeac4e 100644 --- a/docs/coverage/FSharp.Core_SourceConstructFlags.htm +++ b/docs/coverage/FSharp.Core_SourceConstructFlags.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_StringModule.htm b/docs/coverage/FSharp.Core_StringModule.htm index ba604af..2010c48 100644 --- a/docs/coverage/FSharp.Core_StringModule.htm +++ b/docs/coverage/FSharp.Core_StringModule.htm @@ -52,7 +52,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\string.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\string.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_StructAttribute.htm b/docs/coverage/FSharp.Core_StructAttribute.htm index c943736..7d7cbf2 100644 --- a/docs/coverage/FSharp.Core_StructAttribute.htm +++ b/docs/coverage/FSharp.Core_StructAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_StructuralComparisonAttribute.htm b/docs/coverage/FSharp.Core_StructuralComparisonAttribute.htm index c7d900e..7ea6fee 100644 --- a/docs/coverage/FSharp.Core_StructuralComparisonAttribute.htm +++ b/docs/coverage/FSharp.Core_StructuralComparisonAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_StructuralEqualityAttribute.htm b/docs/coverage/FSharp.Core_StructuralEqualityAttribute.htm index 79e572b..0d30149 100644 --- a/docs/coverage/FSharp.Core_StructuralEqualityAttribute.htm +++ b/docs/coverage/FSharp.Core_StructuralEqualityAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_StructuredFormatDisplayAttribute.htm b/docs/coverage/FSharp.Core_StructuredFormatDisplayAttribute.htm index b00c725..7909dd5 100644 --- a/docs/coverage/FSharp.Core_StructuredFormatDisplayAttribute.htm +++ b/docs/coverage/FSharp.Core_StructuredFormatDisplayAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TaggedText.htm b/docs/coverage/FSharp.Core_TaggedText.htm index a1f8858..d5f560e 100644 --- a/docs/coverage/FSharp.Core_TaggedText.htm +++ b/docs/coverage/FSharp.Core_TaggedText.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_TaggedTextOps.htm b/docs/coverage/FSharp.Core_TaggedTextOps.htm index e1162dd..2a07d8a 100644 --- a/docs/coverage/FSharp.Core_TaggedTextOps.htm +++ b/docs/coverage/FSharp.Core_TaggedTextOps.htm @@ -66,7 +66,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\utils\sformat.fs

File 'F:\workspace\_work\1\s\src\utils\sformat.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TaggedTextWriter.htm b/docs/coverage/FSharp.Core_TaggedTextWriter.htm index ed2fb34..ab01bd0 100644 --- a/docs/coverage/FSharp.Core_TaggedTextWriter.htm +++ b/docs/coverage/FSharp.Core_TaggedTextWriter.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_Trampoline.htm b/docs/coverage/FSharp.Core_Trampoline.htm index 5fc6c2d..5741738 100644 --- a/docs/coverage/FSharp.Core_Trampoline.htm +++ b/docs/coverage/FSharp.Core_Trampoline.htm @@ -41,7 +41,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TrampolineHolder.htm b/docs/coverage/FSharp.Core_TrampolineHolder.htm index a1be0b0..e3b7f5c 100644 --- a/docs/coverage/FSharp.Core_TrampolineHolder.htm +++ b/docs/coverage/FSharp.Core_TrampolineHolder.htm @@ -48,7 +48,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Tree.htm b/docs/coverage/FSharp.Core_Tree.htm index b076605..a57099b 100644 --- a/docs/coverage/FSharp.Core_Tree.htm +++ b/docs/coverage/FSharp.Core_Tree.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_TupleUtils.htm b/docs/coverage/FSharp.Core_TupleUtils.htm index 26dc1a7..c5ef7e9 100644 --- a/docs/coverage/FSharp.Core_TupleUtils.htm +++ b/docs/coverage/FSharp.Core_TupleUtils.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_TypeProviderAssemblyAttribute.htm b/docs/coverage/FSharp.Core_TypeProviderAssemblyAttribute.htm index 961235d..199ec24 100644 --- a/docs/coverage/FSharp.Core_TypeProviderAssemblyAttribute.htm +++ b/docs/coverage/FSharp.Core_TypeProviderAssemblyAttribute.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TypeProviderAttribute.htm b/docs/coverage/FSharp.Core_TypeProviderAttribute.htm index 3334ea0..4a6506c 100644 --- a/docs/coverage/FSharp.Core_TypeProviderAttribute.htm +++ b/docs/coverage/FSharp.Core_TypeProviderAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TypeProviderConfig.htm b/docs/coverage/FSharp.Core_TypeProviderConfig.htm index 8f57257..45f6b0b 100644 --- a/docs/coverage/FSharp.Core_TypeProviderConfig.htm +++ b/docs/coverage/FSharp.Core_TypeProviderConfig.htm @@ -37,7 +37,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TypeProviderDefinitionLocationAttribute.htm b/docs/coverage/FSharp.Core_TypeProviderDefinitionLocationAttribute.htm index a9c4b79..c80d1da 100644 --- a/docs/coverage/FSharp.Core_TypeProviderDefinitionLocationAttribute.htm +++ b/docs/coverage/FSharp.Core_TypeProviderDefinitionLocationAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TypeProviderEditorHideMethodsAttribute.htm b/docs/coverage/FSharp.Core_TypeProviderEditorHideMethodsAttribute.htm index 3c73643..5652c2a 100644 --- a/docs/coverage/FSharp.Core_TypeProviderEditorHideMethodsAttribute.htm +++ b/docs/coverage/FSharp.Core_TypeProviderEditorHideMethodsAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_TypeProviderTypeAttributes.htm b/docs/coverage/FSharp.Core_TypeProviderTypeAttributes.htm index 33579bd..4aca56a 100644 --- a/docs/coverage/FSharp.Core_TypeProviderTypeAttributes.htm +++ b/docs/coverage/FSharp.Core_TypeProviderTypeAttributes.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_TypeProviderXmlDocAttribute.htm b/docs/coverage/FSharp.Core_TypeProviderXmlDocAttribute.htm index 6fa752a..a5c98df 100644 --- a/docs/coverage/FSharp.Core_TypeProviderXmlDocAttribute.htm +++ b/docs/coverage/FSharp.Core_TypeProviderXmlDocAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\fslib-extra-pervasives.fs' does not exist (any more).

- +

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_UnionCaseInfo.htm b/docs/coverage/FSharp.Core_UnionCaseInfo.htm index 0562823..59becfc 100644 --- a/docs/coverage/FSharp.Core_UnionCaseInfo.htm +++ b/docs/coverage/FSharp.Core_UnionCaseInfo.htm @@ -44,7 +44,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\reflect.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_Unit.htm b/docs/coverage/FSharp.Core_Unit.htm index 4011463..a853795 100644 --- a/docs/coverage/FSharp.Core_Unit.htm +++ b/docs/coverage/FSharp.Core_Unit.htm @@ -39,7 +39,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_UnverifiableAttribute.htm b/docs/coverage/FSharp.Core_UnverifiableAttribute.htm index 0abf7e8..77be423 100644 --- a/docs/coverage/FSharp.Core_UnverifiableAttribute.htm +++ b/docs/coverage/FSharp.Core_UnverifiableAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ValueAsStaticPropertyAttribute.htm b/docs/coverage/FSharp.Core_ValueAsStaticPropertyAttribute.htm index 3cf1bb1..1af05d4 100644 --- a/docs/coverage/FSharp.Core_ValueAsStaticPropertyAttribute.htm +++ b/docs/coverage/FSharp.Core_ValueAsStaticPropertyAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ValueOption.htm b/docs/coverage/FSharp.Core_ValueOption.htm index 5d2f997..d6d41b7 100644 --- a/docs/coverage/FSharp.Core_ValueOption.htm +++ b/docs/coverage/FSharp.Core_ValueOption.htm @@ -60,7 +60,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\option.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\option.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_VolatileFieldAttribute.htm b/docs/coverage/FSharp.Core_VolatileFieldAttribute.htm index 708ac74..c6919f0 100644 --- a/docs/coverage/FSharp.Core_VolatileFieldAttribute.htm +++ b/docs/coverage/FSharp.Core_VolatileFieldAttribute.htm @@ -36,7 +36,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_WebExtensions.htm b/docs/coverage/FSharp.Core_WebExtensions.htm index bbefd8a..39a50a8 100644 --- a/docs/coverage/FSharp.Core_WebExtensions.htm +++ b/docs/coverage/FSharp.Core_WebExtensions.htm @@ -94,7 +94,7 @@

Metrics

File(s)

F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs

File 'F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs' does not exist (any more).

-
+

Methods/Properties

diff --git a/docs/coverage/FSharp.Core_ampere.htm b/docs/coverage/FSharp.Core_ampere.htm index 828a57f..fdfa4ae 100644 --- a/docs/coverage/FSharp.Core_ampere.htm +++ b/docs/coverage/FSharp.Core_ampere.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

-
+ \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_candela.htm b/docs/coverage/FSharp.Core_candela.htm index 04a62f0..e2cb549 100644 --- a/docs/coverage/FSharp.Core_candela.htm +++ b/docs/coverage/FSharp.Core_candela.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_kelvin.htm b/docs/coverage/FSharp.Core_kelvin.htm index 5615a4e..76857f2 100644 --- a/docs/coverage/FSharp.Core_kelvin.htm +++ b/docs/coverage/FSharp.Core_kelvin.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_kilogram.htm b/docs/coverage/FSharp.Core_kilogram.htm index 0f7d463..fdd3d23 100644 --- a/docs/coverage/FSharp.Core_kilogram.htm +++ b/docs/coverage/FSharp.Core_kilogram.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_metre.htm b/docs/coverage/FSharp.Core_metre.htm index 1002fd5..b8f1cf3 100644 --- a/docs/coverage/FSharp.Core_metre.htm +++ b/docs/coverage/FSharp.Core_metre.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_mole.htm b/docs/coverage/FSharp.Core_mole.htm index 548747f..5336591 100644 --- a/docs/coverage/FSharp.Core_mole.htm +++ b/docs/coverage/FSharp.Core_mole.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FSharp.Core_second.htm b/docs/coverage/FSharp.Core_second.htm index 8dce6d8..e5e5126 100644 --- a/docs/coverage/FSharp.Core_second.htm +++ b/docs/coverage/FSharp.Core_second.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FsLibLog_AssemblyVersionInformation.htm b/docs/coverage/FsLibLog_AssemblyVersionInformation.htm index 81d9bca..4242cc6 100644 --- a/docs/coverage/FsLibLog_AssemblyVersionInformation.htm +++ b/docs/coverage/FsLibLog_AssemblyVersionInformation.htm @@ -28,6 +28,6 @@

< Summary

File(s)

No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).

- + \ No newline at end of file diff --git a/docs/coverage/FsLibLog_LogProvider.htm b/docs/coverage/FsLibLog_LogProvider.htm index 491de01..dd4b643 100644 --- a/docs/coverage/FsLibLog_LogProvider.htm +++ b/docs/coverage/FsLibLog_LogProvider.htm @@ -18,10 +18,10 @@

< Summary

Assembly:FsLibLog File(s):C:\Users\jimmy\Repositories\public\TheAngryByrd\FsLibLog\src\FsLibLog\FsLibLog.fs Covered lines:0 -Uncovered lines:4 -Coverable lines:4 -Total lines:1122 -Line coverage:0% (0 of 4) +Uncovered lines:6 +Coverable lines:6 +Total lines:1233 +Line coverage:0% (0 of 6) Covered branches:0 Total branches:0 @@ -30,9 +30,7 @@

Metrics

- - - +
MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage Crap Score
getLoggerByFunc(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
getLoggerByFunc(...)100%0%0

File(s)

@@ -70,1106 +68,1216 @@

 28    /// Type representing a Log  29    [<NoEquality; NoComparison>]  30    type Log =31        { LogLevel: LogLevel32          Message: MessageThunk33          Exception: exn option34          Parameters: obj list35          AdditionalNamedParameters: ((string * obj * bool) list) }36        static member StartLogLevel(logLevel: LogLevel) =37            { LogLevel = logLevel38              Message = None39              Exception = None40              Parameters = List.empty41              AdditionalNamedParameters = List.empty }4243    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio44    type ILog =45        abstract member Log :  Logger46        abstract member MappedContext :  MappedContext4748#if FABLE_COMPILER49    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)50    // is used instead.51    type Stack<'a>()  =52        let mutable contents = Array.zeroCreate<'a>(2)53        let mutable count = 05455        member buf.Ensure newSize =56            let oldSize = contents.Length57            if newSize > oldSize then58                let old = contents59                contents <- Array.zeroCreate (max newSize (oldSize * 2))60                Array.blit old 0 contents 0 count31        {32            LogLevel: LogLevel33            Message: MessageThunk34            Exception: exn option35            Parameters: obj list36            AdditionalNamedParameters: ((string * obj * bool) list)37        }3839        static member StartLogLevel(logLevel: LogLevel) = {40            LogLevel = logLevel41            Message = None42            Exception = None43            Parameters = List.empty44            AdditionalNamedParameters = List.empty45        }4647    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio48    type ILog =49        abstract member Log: Logger50        abstract member MappedContext: MappedContext5152#if FABLE_COMPILER53    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)54    // is used instead.55    type Stack<'a>() =56        let mutable contents = Array.zeroCreate<'a> (2)57        let mutable count = 05859        member buf.Ensure newSize =60            let oldSize = contents.Length  6162        member buf.Count = count63        member buf.Pop() =64            let item = contents.[count - 1]65            count <- count - 166            item6768        member buf.Peep() = contents.[count - 1]69        member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev70        member buf.Push(x) =71            buf.Ensure(count + 1)72            contents.[count] <- x73            count <- count + 17475        member buf.IsEmpty = (count = 0)76#endif7778    [<AutoOpen>]79    module Inner =80#if !FABLE_COMPILER81        open System.Collections.Generic82#endif8384        /// <summary>85        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.86        /// </summary>87        type DisposableStack() =88            let stack = Stack<IDisposable>()8990            interface IDisposable with91                member __.Dispose() =92                    while stack.Count > 0 do93                        stack.Pop().Dispose()9495            member __.Push(item: IDisposable) = stack.Push item96            member __.Push(items: IDisposable list) = items |> List.iter stack.Push9798            static member Create(items: IDisposable list) =99                let ds = new DisposableStack()100                ds.Push items101                ds102103        type ILog with62            if newSize > oldSize then63                let old = contents64                contents <- Array.zeroCreate (max newSize (oldSize * 2))65                Array.blit old 0 contents 0 count6667        member buf.Count = count6869        member buf.Pop() =70            let item = contents.[count - 1]71            count <- count - 172            item7374        member buf.Peep() = contents.[count - 1]7576        member buf.Top(n) =77            [ for x in contents.[max 0 (count - n) .. count - 1] -> x ]78            |> List.rev7980        member buf.Push(x) =81            buf.Ensure(count + 1)82            contents.[count] <- x83            count <- count + 18485        member buf.IsEmpty = (count = 0)86#endif8788    [<AutoOpen>]89    module Inner =90#if !FABLE_COMPILER91        open System.Collections.Generic92#endif9394        /// <summary>95        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.96        /// </summary>97        type DisposableStack() =98            let stack = Stack<IDisposable>()99100            interface IDisposable with101                member __.Dispose() =102                    while stack.Count > 0 do103                        stack.Pop().Dispose()  104105            /// <summary>106            /// Logs a log107            /// </summary>108            /// <param name="log">The type representing a log message to be logged</param>109            /// <returns><see langword="true"/> if the log message was logged</returns>110            member logger.fromLog(log: Log) =111                use __ =112                    log.AdditionalNamedParameters113                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)114                    // This stack is important, it causes us to unwind as if you have multiple uses in a row115                    |> DisposableStack.Create116117                log.Parameters118                |> List.toArray119                |> logger.Log log.LogLevel log.Message log.Exception120121            /// <summary>122            /// Logs a fatal log message given a log configurer.123            /// </summary>124            /// <param name="logConfig">A function to configure a log</param>125            /// <returns><see langword="true"/>  if the log message was logged</returns>126            member logger.fatal'(logConfig: Log -> Log) =127                Log.StartLogLevel LogLevel.Fatal128                |> logConfig129                |> logger.fromLog130131            /// <summary>132            /// Logs a fatal log message given a log configurer.133            /// </summary>134            /// <param name="logConfig">A function to configure a log</param>135            member logger.fatal(logConfig: Log -> Log) = logger.fatal' logConfig |> ignore136137            /// <summary>138            /// Logs an error log message given a log configurer.139            /// </summary>140            /// <param name="logConfig">A function to configure a log</param>141            /// <returns><see langword="true"/>  if the log message was logged</returns>142            member logger.error'(logConfig: Log -> Log) =143                Log.StartLogLevel LogLevel.Error144                |> logConfig145                |> logger.fromLog146147            /// <summary>148            /// Logs an error log message given a log configurer.149            /// </summary>150            /// <param name="logConfig">A function to configure a log</param>151            member logger.error(logConfig: Log -> Log) = logger.error' logConfig |> ignore152153            /// <summary>154            /// Logs a warn log message given a log configurer.155            /// </summary>156            /// <param name="logConfig">A function to configure a log</param>157            /// <returns><see langword="true"/>  if the log message was logged</returns>158            member logger.warn'(logConfig: Log -> Log) =159                Log.StartLogLevel LogLevel.Warn160                |> logConfig161                |> logger.fromLog162163            /// <summary>164            /// Logs a warn log message given a log configurer.165            /// </summary>166            /// <param name="logConfig">A function to configure a log</param>167            member logger.warn(logConfig: Log -> Log) = logger.warn' logConfig |> ignore168169            /// <summary>170            /// Logs an info log message given a log configurer.171            /// </summary>172            /// <param name="logConfig">A function to configure a log</param>173            /// <returns><see langword="true"/>  if the log message was logged</returns>174            member logger.info'(logConfig: Log -> Log) =175                Log.StartLogLevel LogLevel.Info176                |> logConfig177                |> logger.fromLog178179            /// <summary>180            /// Logs an info log message given a log configurer.181            /// </summary>182            /// <param name="logConfig">A function to configure a log</param>183            member logger.info(logConfig: Log -> Log) = logger.info' logConfig |> ignore184185            /// <summary>186            /// Logs a debug log message given a log configurer.187            /// </summary>188            /// <param name="logConfig">A function to configure a log</param>189            /// <returns><see langword="true"/>  if the log message was logged</returns>190            member logger.debug'(logConfig: Log -> Log) =191                Log.StartLogLevel LogLevel.Debug192                |> logConfig193                |> logger.fromLog194195            /// <summary>196            /// Logs a debug log message given a log configurer.197            /// </summary>198            /// <param name="logConfig">A function to configure a log</param>199            member logger.debug(logConfig: Log -> Log) = logger.debug' logConfig |> ignore200201            /// <summary>202            /// Logs a trace log message given a log configurer.203            /// </summary>204            /// <param name="logConfig">A function to configure a log</param>205            /// <returns><see langword="true"/>  if the log message was logged</returns>206            member logger.trace'(logConfig: Log -> Log) =207                Log.StartLogLevel LogLevel.Trace208                |> logConfig209                |> logger.fromLog210211            /// <summary>212            /// Logs a trace log message given a log configurer.213            /// </summary>214            /// <param name="logConfig">A function to configure a log</param>215            member logger.trace(logConfig: Log -> Log) = logger.trace' logConfig |> ignore216217218    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.219    type ILogProvider =220        abstract member GetLogger : string -> Logger221        abstract member OpenNestedContext : string -> IDisposable222        abstract member OpenMappedContext : string -> obj -> bool -> IDisposable105            member __.Push(item: IDisposable) = stack.Push item106107            member __.Push(items: IDisposable list) =108                items109                |> List.iter stack.Push110111            static member Create(items: IDisposable list) =112                let ds = new DisposableStack()113                ds.Push items114                ds115116        type ILog with117118            /// <summary>119            /// Logs a log120            /// </summary>121            /// <param name="log">The type representing a log message to be logged</param>122            /// <returns><see langword="true"/> if the log message was logged</returns>123            member logger.fromLog(log: Log) =124                use __ =125                    log.AdditionalNamedParameters126                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)127                    // This stack is important, it causes us to unwind as if you have multiple uses in a row128                    |> DisposableStack.Create129130                log.Parameters131                |> List.toArray132                |> logger.Log log.LogLevel log.Message log.Exception133134            /// <summary>135            /// Logs a fatal log message given a log configurer.136            /// </summary>137            /// <param name="logConfig">A function to configure a log</param>138            /// <returns><see langword="true"/>  if the log message was logged</returns>139            member logger.fatal'(logConfig: Log -> Log) =140                Log.StartLogLevel LogLevel.Fatal141                |> logConfig142                |> logger.fromLog143144            /// <summary>145            /// Logs a fatal log message given a log configurer.146            /// </summary>147            /// <param name="logConfig">A function to configure a log</param>148            member logger.fatal(logConfig: Log -> Log) =149                logger.fatal' logConfig150                |> ignore151152            /// <summary>153            /// Logs an error log message given a log configurer.154            /// </summary>155            /// <param name="logConfig">A function to configure a log</param>156            /// <returns><see langword="true"/>  if the log message was logged</returns>157            member logger.error'(logConfig: Log -> Log) =158                Log.StartLogLevel LogLevel.Error159                |> logConfig160                |> logger.fromLog161162            /// <summary>163            /// Logs an error log message given a log configurer.164            /// </summary>165            /// <param name="logConfig">A function to configure a log</param>166            member logger.error(logConfig: Log -> Log) =167                logger.error' logConfig168                |> ignore169170            /// <summary>171            /// Logs a warn log message given a log configurer.172            /// </summary>173            /// <param name="logConfig">A function to configure a log</param>174            /// <returns><see langword="true"/>  if the log message was logged</returns>175            member logger.warn'(logConfig: Log -> Log) =176                Log.StartLogLevel LogLevel.Warn177                |> logConfig178                |> logger.fromLog179180            /// <summary>181            /// Logs a warn log message given a log configurer.182            /// </summary>183            /// <param name="logConfig">A function to configure a log</param>184            member logger.warn(logConfig: Log -> Log) =185                logger.warn' logConfig186                |> ignore187188            /// <summary>189            /// Logs an info log message given a log configurer.190            /// </summary>191            /// <param name="logConfig">A function to configure a log</param>192            /// <returns><see langword="true"/>  if the log message was logged</returns>193            member logger.info'(logConfig: Log -> Log) =194                Log.StartLogLevel LogLevel.Info195                |> logConfig196                |> logger.fromLog197198            /// <summary>199            /// Logs an info log message given a log configurer.200            /// </summary>201            /// <param name="logConfig">A function to configure a log</param>202            member logger.info(logConfig: Log -> Log) =203                logger.info' logConfig204                |> ignore205206            /// <summary>207            /// Logs a debug log message given a log configurer.208            /// </summary>209            /// <param name="logConfig">A function to configure a log</param>210            /// <returns><see langword="true"/>  if the log message was logged</returns>211            member logger.debug'(logConfig: Log -> Log) =212                Log.StartLogLevel LogLevel.Debug213                |> logConfig214                |> logger.fromLog215216            /// <summary>217            /// Logs a debug log message given a log configurer.218            /// </summary>219            /// <param name="logConfig">A function to configure a log</param>220            member logger.debug(logConfig: Log -> Log) =221                logger.debug' logConfig222                |> ignore  223224    module Log =225226        /// <summary>227        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.228        /// </summary>229        /// <param name="message">The message to set for the log.</param>230        /// <param name="log">The log to amend.</param>231        /// <returns>The amended log.</returns>232        let setMessage (message: string) (log: Log) =233            { log with234                  Message = Some(fun () -> message) }235236        /// <summary>237        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con238        /// </summary>239        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>240        /// <param name="log">The log to amend.</param>241        /// <returns>The amended log.</returns>242        let setMessageThunk (messageThunk: unit -> string) (log: Log) =243            { log with Message = Some messageThunk }244245        /// <summary>246        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.247        /// </summary>248        /// <param name="param">The value to add to the log</param>249        /// <param name="log">The log to amend.</param>250        /// <returns>The amended log.</returns>251        let addParameter (param: 'a) (log: Log) =252            { log with253                  Parameters = List.append log.Parameters [ (box param) ] }254255        /// <summary>256        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.257        /// </summary>258        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>259        /// <param name="log">The log to amend.</param>260        /// <returns>The amended log.</returns>261        let addParameters (``params``: obj list) (log: Log) =262            let ``params`` = ``params`` |> List.map box263264            { log with265                  Parameters = log.Parameters @ ``params`` }266267268269        /// <summary>270        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe271        /// This DOES NOT affect the parameters set for a message template.272        /// This is the same calling OpenMappedContext right before logging.224            /// <summary>225            /// Logs a trace log message given a log configurer.226            /// </summary>227            /// <param name="logConfig">A function to configure a log</param>228            /// <returns><see langword="true"/>  if the log message was logged</returns>229            member logger.trace'(logConfig: Log -> Log) =230                Log.StartLogLevel LogLevel.Trace231                |> logConfig232                |> logger.fromLog233234            /// <summary>235            /// Logs a trace log message given a log configurer.236            /// </summary>237            /// <param name="logConfig">A function to configure a log</param>238            member logger.trace(logConfig: Log -> Log) =239                logger.trace' logConfig240                |> ignore241242243    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.244    type ILogProvider =245        abstract member GetLogger: string -> Logger246        abstract member OpenNestedContext: string -> IDisposable247        abstract member OpenMappedContext: string -> obj -> bool -> IDisposable248249    module Log =250251        /// <summary>252        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.253        /// </summary>254        /// <param name="message">The message to set for the log.</param>255        /// <param name="log">The log to amend.</param>256        /// <returns>The amended log.</returns>257        let setMessage (message: string) (log: Log) =258            { log with259                Message = Some(fun () -> message)260            }261262        /// <summary>263        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con264        /// </summary>265        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>266        /// <param name="log">The log to amend.</param>267        /// <returns>The amended log.</returns>268        let setMessageThunk (messageThunk: unit -> string) (log: Log) =269            { log with Message = Some messageThunk }270271        /// <summary>272        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.  273        /// </summary>274        /// <param name="key">The key of the parameter to add to the log.</param>275        /// <param name="value">The value of the parameter to add to the log.</param>276        /// <param name="log">The log to amend.</param>277        /// <returns>The amended log.</returns>278        let addContext (key: string) (value: obj) (log: Log) =279            { log with280                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] }274        /// <param name="param">The value to add to the log</param>275        /// <param name="log">The log to amend.</param>276        /// <returns>The amended log.</returns>277        let addParameter (param: 'a) (log: Log) =278            { log with279                Parameters = List.append log.Parameters [ (box param) ]280            }  281282283        /// <summary>284        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe285        /// This DOES NOT affect the parameters set for a message template.286        /// This is the same calling OpenMappedContext right before logging.287        /// This destructures an object rather than calling `ToString()` on it.288        /// WARNING: Destructring can be expensive.289        /// </summary>290        /// <param name="key">The key of the parameter to add to the log.</param>291        /// <param name="value">The value of the parameter to add to the log.</param>292        /// <param name="log">The log to amend.</param>293        /// <returns>The amended log.</returns>294        let addContextDestructured (key: string) (value: obj) (log: Log) =295            { log with296                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] }297282        /// <summary>283        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.284        /// </summary>285        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>286        /// <param name="log">The log to amend.</param>287        /// <returns>The amended log.</returns>288        let addParameters (``params``: obj list) (log: Log) =289            let ``params`` =290                ``params``291                |> List.map box292293            { log with294                Parameters =295                    log.Parameters296                    @ ``params``297            }  298299        /// <summary>300        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle301        /// </summary>302        /// <param name="exception">The exception to add to the log.</param>303        /// <param name="log">The log to amend.</param>304        /// <returns>The amended log.</returns>305        let addException (``exception``: exn) (log: Log) =306            { log with307                  Exception = Option.ofObj ``exception`` }308309        /// <summary>310        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle311        /// </summary>312        /// <param name="exception">The exception to add to the log.</param>313        /// <param name="log">The log to amend.</param>314        /// <returns>The amended log.</returns>315        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log316317        /// <summary>318        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe319        /// </summary>320        /// <param name="logLevel">The level to set for the log.</param>321        /// <param name="log">The log to amend.</param>322        /// <returns>The amended log.</returns>323        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }324325#if !FABLE_COMPILER326327        let private formatterRegex =328            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)329330        let private isAnObject value =331            Convert.GetTypeCode(value) = TypeCode.Object332333        /// <summary>334        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m335        ///336        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr337        /// </summary>338        /// <param name="message">An interpolated string</param>339        /// <param name="log">The log to amend.</param>340        /// <returns>The amended log.</returns>341        let setMessageInterpolated (message: FormattableString) (log: Log) =342            let mutable messageFormat = message.Format343344            let args =345                formatterRegex.Matches(messageFormat)346                |> Seq.cast<Match>347                |> Seq.map348                    (fun m ->349                        let number = Int32.Parse(m.Groups.["number"].Value)350                        let formatGroup = m.Groups.["format"]351                        let propertyValue = message.GetArgument(number)352                        let propertyName = formatGroup.Value353                        let columnFormatGroup = m.Groups.["columnFormat"]354                        propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length355                        )356            // Reverse the args so we won't change the indexes earlier in the string357            args358            |> Seq.rev359            |> Seq.iter360                (fun (_, _, removeStart, removeLength) ->361                    if removeLength > 0 then362                        messageFormat <- messageFormat.Remove(removeStart, removeLength))299300        /// <summary>301        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe302        /// This DOES NOT affect the parameters set for a message template.303        /// This is the same calling OpenMappedContext right before logging.304        /// </summary>305        /// <param name="key">The key of the parameter to add to the log.</param>306        /// <param name="value">The value of the parameter to add to the log.</param>307        /// <param name="log">The log to amend.</param>308        /// <returns>The amended log.</returns>309        let addContext (key: string) (value: obj) (log: Log) =310            { log with311                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ]312            }313314315        /// <summary>316        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe317        /// This DOES NOT affect the parameters set for a message template.318        /// This is the same calling OpenMappedContext right before logging.319        /// This destructures an object rather than calling `ToString()` on it.320        /// WARNING: Destructring can be expensive.321        /// </summary>322        /// <param name="key">The key of the parameter to add to the log.</param>323        /// <param name="value">The value of the parameter to add to the log.</param>324        /// <param name="log">The log to amend.</param>325        /// <returns>The amended log.</returns>326        let addContextDestructured (key: string) (value: obj) (log: Log) =327            { log with328                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ]329            }330331332        /// <summary>333        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle334        /// </summary>335        /// <param name="exception">The exception to add to the log.</param>336        /// <param name="log">The log to amend.</param>337        /// <returns>The amended log.</returns>338        let addException (``exception``: exn) (log: Log) =339            { log with340                Exception = Option.ofObj ``exception``341            }342343        /// <summary>344        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle345        /// </summary>346        /// <param name="exception">The exception to add to the log.</param>347        /// <param name="log">The log to amend.</param>348        /// <returns>The amended log.</returns>349        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log350351        /// <summary>352        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe353        /// </summary>354        /// <param name="logLevel">The level to set for the log.</param>355        /// <param name="log">The log to amend.</param>356        /// <returns>The amended log.</returns>357        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }358359#if !FABLE_COMPILER360361        let private formatterRegex =362            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)  363364            let namedArgs =365                args366                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")367                |> Seq.toArray368369            messageFormat <-370                messageFormat371                    .Replace("{{", "{{{{")372                    .Replace("}}", "}}}}")373            // Replace numbered args with named args from regex match374            messageFormat <- String.Format(messageFormat, args = namedArgs)375376            let addContexts args (log: Log) =377                let addArgsToContext =378                    (id, args)379                    ||> Seq.fold380                            (fun state (name, value, _, _) ->381                                let contextAdder =382                                    if value |> isAnObject then383                                        addContextDestructured384                                    else385                                        addContext386387                                state >> contextAdder name value)388389                addArgsToContext log390391            log392            |> setMessage messageFormat393            |> addContexts args394395        /// <summary>396        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m397        ///398        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr399        /// </summary>400        /// <param name="message">An interpolated string</param>401        /// <param name="log">The log to amend.</param>402        /// <returns>The amended log.</returns>403        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log404#endif364        let private isAnObject value =365            Convert.GetTypeCode(value) = TypeCode.Object366367        /// <summary>368        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m369        ///370        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr371        /// </summary>372        /// <param name="message">An interpolated string</param>373        /// <param name="log">The log to amend.</param>374        /// <returns>The amended log.</returns>375        let setMessageInterpolated (message: FormattableString) (log: Log) =376            let mutable messageFormat = message.Format377378            let args =379                formatterRegex.Matches(messageFormat)380                |> Seq.cast<Match>381                |> Seq.map (fun m ->382                    let number = Int32.Parse(m.Groups.["number"].Value)383                    let formatGroup = m.Groups.["format"]384                    let propertyValue = message.GetArgument(number)385                    let propertyName = formatGroup.Value386                    let columnFormatGroup = m.Groups.["columnFormat"]387                    propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length388                )389            // Reverse the args so we won't change the indexes earlier in the string390            args391            |> Seq.rev392            |> Seq.iter (fun (_, _, removeStart, removeLength) ->393                if removeLength > 0 then394                    messageFormat <- messageFormat.Remove(removeStart, removeLength)395            )396397            let namedArgs =398                args399                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")400                |> Seq.toArray401402            messageFormat <- messageFormat.Replace("{{", "{{{{").Replace("}}", "}}}}")403            // Replace numbered args with named args from regex match404            messageFormat <- String.Format(messageFormat, args = namedArgs)  405406/// Provides operators to make writing logs more streamlined.407module Operators =408409    /// <summary>410    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.411    /// </summary>412    /// <param name="message">The string of the base message.</param>413    /// <returns>A new Log instance with the specified message.</returns>414    let (!!!) message = Log.setMessage message406            let addContexts args (log: Log) =407                let addArgsToContext =408                    (id, args)409                    ||> Seq.fold (fun state (name, value, _, _) ->410                        let contextAdder =411                            if value |> isAnObject then412                                addContextDestructured413                            else414                                addContext  415416    /// <summary>417    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<418    /// </summary>419    /// <param name="log">The Log to add the parameter to.</param>420    /// <param name="value">The value for the parameter.</param>421    /// <returns>The Log with the added parameter.</returns>422    let (>>!) log value = log >> Log.addParameter value423424    /// <summary>425    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.426    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right427    ///428    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.429    /// </summary>430    /// <param name="log">The log to add the parameter to.</param>431    /// <param name="key">The name for the parameter.</param>432    /// <param name="value">The value for the parameter.</param>433    /// <returns>The amended log with the parameter added.</returns>434    let (>>!-) log (key, value) = log >> Log.addContext key value435436    /// <summary>437    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT438    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling439    ///440    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.441    /// </summary>442    /// <param name="log">The log to add the parameter to.</param>443    /// <param name="key">The name for the parameter.</param>444    /// <param name="value">The value for the parameter.</param>445    /// <returns>The amended log with the parameter added.</returns>446    let (>>!+) log (key, value) =447        log >> Log.addContextDestructured key value448449    /// <summary>450    /// Amends a Log with an exn. Handles nulls.451    ///452    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.453    /// </summary>454    /// <param name="log">The log to add the parameter to.</param>455    /// <param name="e">The exception to add to the log.</param>456    /// <returns>The amended log with the parameter added.</returns>457    let (>>!!) log e = log >> Log.addException e458459460#if !FABLE_COMPILER461module Providers =462    module SerilogProvider =463        open System464        open System.Linq.Expressions465466        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")467        let isAvailable () = getLogManagerType () |> isNull |> not468469        let getPushProperty () =416                        state417                        >> contextAdder name value418                    )419420                addArgsToContext log421422            log423            |> setMessage messageFormat424            |> addContexts args425426        /// <summary>427        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m428        ///429        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr430        /// </summary>431        /// <param name="message">An interpolated string</param>432        /// <param name="log">The log to amend.</param>433        /// <returns>The amended log.</returns>434        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log435#endif436437/// Provides operators to make writing logs more streamlined.438module Operators =439440    /// <summary>441    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.442    /// </summary>443    /// <param name="message">The string of the base message.</param>444    /// <returns>A new Log instance with the specified message.</returns>445    let (!!!) message = Log.setMessage message446447    /// <summary>448    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<449    /// </summary>450    /// <param name="log">The Log to add the parameter to.</param>451    /// <param name="value">The value for the parameter.</param>452    /// <returns>The Log with the added parameter.</returns>453    let (>>!) log value =454        log455        >> Log.addParameter value456457    /// <summary>458    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.459    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right460    ///461    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.462    /// </summary>463    /// <param name="log">The log to add the parameter to.</param>464    /// <param name="key">The name for the parameter.</param>465    /// <param name="value">The value for the parameter.</param>466    /// <returns>The amended log with the parameter added.</returns>467    let (>>!-) log (key, value) =468        log469        >> Log.addContext key value  470471            let ndcContextType =472                Type.GetType("Serilog.Context.LogContext, Serilog")473                |> Option.ofObj474                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))475476            ()477478            let pushPropertyMethod =479                ndcContextType.GetMethod(480                    "PushProperty",481                    [| typedefof<string>482                       typedefof<obj>483                       typedefof<bool> |]484                )485486            let nameParam =487                Expression.Parameter(typedefof<string>, "name")488489            let valueParam =490                Expression.Parameter(typedefof<obj>, "value")491492            let destructureObjectParam =493                Expression.Parameter(typedefof<bool>, "destructureObjects")494495            let pushPropertyMethodCall =496                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)471    /// <summary>472    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT473    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling474    ///475    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.476    /// </summary>477    /// <param name="log">The log to add the parameter to.</param>478    /// <param name="key">The name for the parameter.</param>479    /// <param name="value">The value for the parameter.</param>480    /// <returns>The amended log with the parameter added.</returns>481    let (>>!+) log (key, value) =482        log483        >> Log.addContextDestructured key value484485    /// <summary>486    /// Amends a Log with an exn. Handles nulls.487    ///488    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.489    /// </summary>490    /// <param name="log">The log to add the parameter to.</param>491    /// <param name="e">The exception to add to the log.</param>492    /// <returns>The amended log with the parameter added.</returns>493    let (>>!!) log e =494        log495        >> Log.addException e496  497498            let pushProperty =499                Expression500                    .Lambda<Func<string, obj, bool, IDisposable>>(501                        pushPropertyMethodCall,502                        nameParam,503                        valueParam,504                        destructureObjectParam505                    )506                    .Compile()507508            fun key value destructure -> pushProperty.Invoke(key, value, destructure)509498#if !FABLE_COMPILER499module Providers =500    module SerilogProvider =501        open System502        open System.Linq.Expressions503504        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")505506        let isAvailable () =507            getLogManagerType ()508            |> isNull509            |> not  510511        let getForContextMethodCall () =512            let logManagerType = getLogManagerType ()513514            let method =515                logManagerType.GetMethod(516                    "ForContext",517                    [| typedefof<string>518                       typedefof<obj>519                       typedefof<bool> |]520                )521522            let propertyNameParam =523                Expression.Parameter(typedefof<string>, "propertyName")524525            let valueParam =526                Expression.Parameter(typedefof<obj>, "value")527528            let destructureObjectsParam =529                Expression.Parameter(typedefof<bool>, "destructureObjects")530531            let exrs: Expression [] =532                [| propertyNameParam533                   valueParam534                   destructureObjectsParam |]535536            let methodCall = Expression.Call(null, method, exrs)537538            let func =539                Expression540                    .Lambda<Func<string, obj, bool, obj>>(541                        methodCall,542                        propertyNameParam,543                        valueParam,544                        destructureObjectsParam545                    )546                    .Compile()547548            fun name -> func.Invoke("SourceContext", name, false)511        let getPushProperty () =512513            let ndcContextType =514                Type.GetType("Serilog.Context.LogContext, Serilog")515                |> Option.ofObj516                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))517518            ()519520            let pushPropertyMethod =521                ndcContextType.GetMethod(522                    "PushProperty",523                    [|524                        typedefof<string>525                        typedefof<obj>526                        typedefof<bool>527                    |]528                )529530            let nameParam = Expression.Parameter(typedefof<string>, "name")531532            let valueParam = Expression.Parameter(typedefof<obj>, "value")533534            let destructureObjectParam =535                Expression.Parameter(typedefof<bool>, "destructureObjects")536537            let pushPropertyMethodCall =538                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)539540            let pushProperty =541                Expression542                    .Lambda<Func<string, obj, bool, IDisposable>>(543                        pushPropertyMethodCall,544                        nameParam,545                        valueParam,546                        destructureObjectParam547                    )548                    .Compile()  549550        [<NoEquality; NoComparison>]551        type SerilogGateway =552            { Write: obj -> obj -> string -> obj [] -> unit553              WriteException: obj -> obj -> exn -> string -> obj [] -> unit554              IsEnabled: obj -> obj -> bool555              TranslateLevel: LogLevel -> obj }556            static member Create() =557                let logEventLevelType =558                    Type.GetType("Serilog.Events.LogEventLevel, Serilog")559560                if (logEventLevelType |> isNull) then561                    failwith ("Type Serilog.Events.LogEventLevel was not found.")562563                let debugLevel =564                    Enum.Parse(logEventLevelType, "Debug", false)550            fun key value destructure -> pushProperty.Invoke(key, value, destructure)551552553        let getForContextMethodCall () =554            let logManagerType = getLogManagerType ()555556            let method =557                logManagerType.GetMethod(558                    "ForContext",559                    [|560                        typedefof<string>561                        typedefof<obj>562                        typedefof<bool>563                    |]564                )  565566                let errorLevel =567                    Enum.Parse(logEventLevelType, "Error", false)568569                let fatalLevel =570                    Enum.Parse(logEventLevelType, "Fatal", false)571572                let informationLevel =573                    Enum.Parse(logEventLevelType, "Information", false)574575                let verboseLevel =576                    Enum.Parse(logEventLevelType, "Verbose", false)577578                let warningLevel =579                    Enum.Parse(logEventLevelType, "Warning", false)566            let propertyNameParam = Expression.Parameter(typedefof<string>, "propertyName")567568            let valueParam = Expression.Parameter(typedefof<obj>, "value")569570            let destructureObjectsParam =571                Expression.Parameter(typedefof<bool>, "destructureObjects")572573            let exrs: Expression[] = [|574                propertyNameParam575                valueParam576                destructureObjectsParam577            |]578579            let methodCall = Expression.Call(null, method, exrs)  580581                let translateLevel (level: LogLevel) =582                    match level with583                    | LogLevel.Fatal -> fatalLevel584                    | LogLevel.Error -> errorLevel585                    | LogLevel.Warn -> warningLevel586                    | LogLevel.Info -> informationLevel587                    | LogLevel.Debug -> debugLevel588                    | LogLevel.Trace -> verboseLevel589                    | _ -> debugLevel581            let func =582                Expression583                    .Lambda<Func<string, obj, bool, obj>>(584                        methodCall,585                        propertyNameParam,586                        valueParam,587                        destructureObjectsParam588                    )589                    .Compile()  590591                let loggerType = Type.GetType("Serilog.ILogger, Serilog")591            fun name -> func.Invoke("SourceContext", name, false)  592593                if (loggerType |> isNull) then594                    failwith ("Type Serilog.ILogger was not found.")595596                let isEnabledMethodInfo =597                    loggerType.GetMethod("IsEnabled", [| logEventLevelType |])598599                let instanceParam = Expression.Parameter(typedefof<obj>)600601                let instanceCast =602                    Expression.Convert(instanceParam, loggerType)603604                let levelParam = Expression.Parameter(typedefof<obj>)605606                let levelCast =607                    Expression.Convert(levelParam, logEventLevelType)608609                let isEnabledMethodCall =610                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)611612                let isEnabled =613                    Expression614                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)615                        .Compile()593        [<NoEquality; NoComparison>]594        type SerilogGateway =595            {596                Write: obj -> obj -> string -> obj[] -> unit597                WriteException: obj -> obj -> exn -> string -> obj[] -> unit598                IsEnabled: obj -> obj -> bool599                TranslateLevel: LogLevel -> obj600            }601602            static member Create() =603                let logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog")604605                if606                    (logEventLevelType607                     |> isNull)608                then609                    failwith ("Type Serilog.Events.LogEventLevel was not found.")610611                let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)612613                let errorLevel = Enum.Parse(logEventLevelType, "Error", false)614615                let fatalLevel = Enum.Parse(logEventLevelType, "Fatal", false)  616617                let writeMethodInfo =618                    loggerType.GetMethod(619                        "Write",620                        [| logEventLevelType621                           typedefof<string>622                           typedefof<obj []> |]623                    )624625                let messageParam = Expression.Parameter(typedefof<string>)626                let propertyValuesParam = Expression.Parameter(typedefof<obj []>)627628                let writeMethodExp =629                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)630631                let expression =632                    Expression.Lambda<Action<obj, obj, string, obj []>>(633                        writeMethodExp,634                        instanceParam,635                        levelParam,636                        messageParam,637                        propertyValuesParam638                    )617                let informationLevel = Enum.Parse(logEventLevelType, "Information", false)618619                let verboseLevel = Enum.Parse(logEventLevelType, "Verbose", false)620621                let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)622623                let translateLevel (level: LogLevel) =624                    match level with625                    | LogLevel.Fatal -> fatalLevel626                    | LogLevel.Error -> errorLevel627                    | LogLevel.Warn -> warningLevel628                    | LogLevel.Info -> informationLevel629                    | LogLevel.Debug -> debugLevel630                    | LogLevel.Trace -> verboseLevel631                    | _ -> debugLevel632633                let loggerType = Type.GetType("Serilog.ILogger, Serilog")634635                if (loggerType |> isNull) then636                    failwith ("Type Serilog.ILogger was not found.")637638                let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  639640                let write = expression.Compile()640                let instanceParam = Expression.Parameter(typedefof<obj>)  641642                let writeExceptionMethodInfo =643                    loggerType.GetMethod(644                        "Write",645                        [| logEventLevelType646                           typedefof<exn>647                           typedefof<string>648                           typedefof<obj []> |]649                    )642                let instanceCast = Expression.Convert(instanceParam, loggerType)643644                let levelParam = Expression.Parameter(typedefof<obj>)645646                let levelCast = Expression.Convert(levelParam, logEventLevelType)647648                let isEnabledMethodCall =649                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  650651                let exceptionParam = Expression.Parameter(typedefof<exn>)652653                let writeMethodExp =654                    Expression.Call(655                        instanceCast,656                        writeExceptionMethodInfo,657                        levelCast,658                        exceptionParam,659                        messageParam,660                        propertyValuesParam661                    )662663                let writeException =664                    Expression665                        .Lambda<Action<obj, obj, exn, string, obj []>>(666                            writeMethodExp,667                            instanceParam,668                            levelParam,669                            exceptionParam,670                            messageParam,671                            propertyValuesParam672                        )673                        .Compile()674675                { Write =676                      (fun logger level message formattedParmeters ->677                          write.Invoke(logger, level, message, formattedParmeters))678                  WriteException =679                      fun logger level ex message formattedParmeters ->680                          writeException.Invoke(logger, level, ex, message, formattedParmeters)681                  IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)682                  TranslateLevel = translateLevel }683684        type private SeriLogProvider() =685            let getLoggerByName = getForContextMethodCall ()686            let pushProperty = getPushProperty ()687            let serilogGatewayInit = lazy (SerilogGateway.Create())688689            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =690                let serilogGateway = serilogGatewayInit.Value691                let translatedValue = serilogGateway.TranslateLevel logLevel692693                match messageFunc with694                | None -> serilogGateway.IsEnabled logger translatedValue695                | Some _ when696                    serilogGateway.IsEnabled logger translatedValue697                    |> not698                    ->699                    false700                | Some m ->701                    match ``exception`` with702                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams703                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams704705                    true706707            interface ILogProvider with708                member this.GetLogger(name: string) : Logger = getLoggerByName name |> writeMessage709710                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =711                    pushProperty key value destructure712713                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false714715        let create () = SeriLogProvider() :> ILogProvider716651                let isEnabled =652                    Expression653                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)654                        .Compile()655656                let writeMethodInfo =657                    loggerType.GetMethod(658                        "Write",659                        [|660                            logEventLevelType661                            typedefof<string>662                            typedefof<obj[]>663                        |]664                    )665666                let messageParam = Expression.Parameter(typedefof<string>)667                let propertyValuesParam = Expression.Parameter(typedefof<obj[]>)668669                let writeMethodExp =670                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)671672                let expression =673                    Expression.Lambda<Action<obj, obj, string, obj[]>>(674                        writeMethodExp,675                        instanceParam,676                        levelParam,677                        messageParam,678                        propertyValuesParam679                    )680681                let write = expression.Compile()682683                let writeExceptionMethodInfo =684                    loggerType.GetMethod(685                        "Write",686                        [|687                            logEventLevelType688                            typedefof<exn>689                            typedefof<string>690                            typedefof<obj[]>691                        |]692                    )693694                let exceptionParam = Expression.Parameter(typedefof<exn>)695696                let writeMethodExp =697                    Expression.Call(698                        instanceCast,699                        writeExceptionMethodInfo,700                        levelCast,701                        exceptionParam,702                        messageParam,703                        propertyValuesParam704                    )705706                let writeException =707                    Expression708                        .Lambda<Action<obj, obj, exn, string, obj[]>>(709                            writeMethodExp,710                            instanceParam,711                            levelParam,712                            exceptionParam,713                            messageParam,714                            propertyValuesParam715                        )716                        .Compile()  717718    module MicrosoftExtensionsLoggingProvider =719        open System720        open System.Linq.Expressions721        open System.Reflection722        open System.Collections.Generic723724        type ILoggerFactory = obj725        // This has to be set from usercode for this to light up726        let mutable private  microsoftLoggerFactory : ILoggerFactory option = None727        let setMicrosoftLoggerFactory (factory : ILoggerFactory) = microsoftLoggerFactory <- Option.ofObj factory728729        let getLogFactoryType = lazy(Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Log730        let isAvailable () =731            getLogFactoryType.Value |> isNull |> not732            && microsoftLoggerFactory |> Option.isSome733718                {719                    Write =720                        (fun logger level message formattedParmeters ->721                            write.Invoke(logger, level, message, formattedParmeters)722                        )723                    WriteException =724                        fun logger level ex message formattedParmeters ->725                            writeException.Invoke(logger, level, ex, message, formattedParmeters)726                    IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)727                    TranslateLevel = translateLevel728                }729730        type private SeriLogProvider() =731            let getLoggerByName = getForContextMethodCall ()732            let pushProperty = getPushProperty ()733            let serilogGatewayInit = lazy (SerilogGateway.Create())  734735        type ILogger = obj736        type LoggerName = string737        type MicrosoftLogLevel = obj738        type MessageFormat = string739        type MessageArgs = obj array740741        [<NoEquality; NoComparison>]742        type LoggerFactoryGateway = {743            CreateLogger : ILoggerFactory -> LoggerName -> ILogger744        }745        with746            static member Create() =747                let createLogger =748                    let factoryType = getLogFactoryType.Value749                    let createLoggerMethodInfo =750                        factoryType.GetMethod(751                            "CreateLogger",752                            [|typedefof<string>|])753                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)754                    let nameParam = Expression.Parameter(typedefof<string>)755                    let instanceCast =756                        Expression.Convert(instanceParam, factoryType)757                    let createLoggerMethodExp =758                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)759                    let createLogger =760                        Expression761                            .Lambda<Func<ILoggerFactory,string,ILogger>>(createLoggerMethodExp, instanceParam, nameParam762                            .Compile()763                    createLogger764                    |> FuncConvert.FromFunc765                {766                    CreateLogger = createLogger767                }768769        type LoggerGateway = {770            Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit771            WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit772            IsEnabled: ILogger -> MicrosoftLogLevel -> bool773            TranslateLevel : LogLevel -> MicrosoftLogLevel774            BeginScope : ILogger -> obj -> IDisposable775        } with776            static member Create () =777                let loggerExtensions = Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions778                let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstra779                let logEventLevelType =780                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")781                let instanceParam = Expression.Parameter(typedefof<ILogger>)735            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =736                let serilogGateway = serilogGatewayInit.Value737                let translatedValue = serilogGateway.TranslateLevel logLevel738739                match messageFunc with740                | None -> serilogGateway.IsEnabled logger translatedValue741                | Some _ when742                    serilogGateway.IsEnabled logger translatedValue743                    |> not744                    ->745                    false746                | Some m ->747                    match ``exception`` with748                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams749                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams750751                    true752753            interface ILogProvider with754                member this.GetLogger(name: string) : Logger =755                    getLoggerByName name756                    |> writeMessage757758                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =759                    pushProperty key value destructure760761                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false762763        let create () = SeriLogProvider() :> ILogProvider764765766    module MicrosoftExtensionsLoggingProvider =767        open System768        open System.Linq.Expressions769        open System.Reflection770        open System.Collections.Generic771772        type ILoggerFactory = obj773        // This has to be set from usercode for this to light up774        let mutable private microsoftLoggerFactory: ILoggerFactory option = None775776        let setMicrosoftLoggerFactory (factory: ILoggerFactory) =777            microsoftLoggerFactory <- Option.ofObj factory778779        let getLogFactoryType =780            lazy781                (Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.Abstractions"))  782783                let instanceCast =784                    Expression.Convert(instanceParam, loggerType)785                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)786787                let levelCast = Expression.Convert(levelParam, logEventLevelType)788789                let isEnabled =790                    let isEnabledMethodInfo =791                        loggerType.GetMethod("IsEnabled", [| logEventLevelType |])792                    let isEnabledMethodCall =793                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)794795796                    Expression797                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)798                        .Compile()799                    |> FuncConvert.FromFunc800801                let write, writeError =802                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)803                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)804805                    let write =806                        let writeMethodInfo =807                            loggerExtensions.GetMethod(808                                "Log",809                                BindingFlags.Static ||| BindingFlags.Public,810                                null,811                                [| loggerType812                                   logEventLevelType813                                   typedefof<MessageFormat>814                                   typedefof<MessageArgs> |],815                                null816                            )817818                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, messagePara819820                        let expression =821                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(822                                writeMethodExp,823                                instanceParam,824                                levelParam,825                                messageParam,826                                propertyValuesParam827                            )828                        expression.Compile() |> FuncConvert.FromAction829783        let isAvailable () =784            getLogFactoryType.Value785            |> isNull786            |> not787            && microsoftLoggerFactory788               |> Option.isSome789790791        type ILogger = obj792        type LoggerName = string793        type MicrosoftLogLevel = obj794        type MessageFormat = string795        type MessageArgs = obj array796797        [<NoEquality; NoComparison>]798        type LoggerFactoryGateway =799            {800                CreateLogger: ILoggerFactory -> LoggerName -> ILogger801            }802803            static member Create() =804                let createLogger =805                    let factoryType = getLogFactoryType.Value806807                    let createLoggerMethodInfo =808                        factoryType.GetMethod("CreateLogger", [| typedefof<string> |])809810                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)811                    let nameParam = Expression.Parameter(typedefof<string>)812                    let instanceCast = Expression.Convert(instanceParam, factoryType)813814                    let createLoggerMethodExp =815                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)816817                    let createLogger =818                        Expression819                            .Lambda<Func<ILoggerFactory, string, ILogger>>(820                                createLoggerMethodExp,821                                instanceParam,822                                nameParam823                            )824                            .Compile()825826                    createLogger827                    |> FuncConvert.FromFunc828829                { CreateLogger = createLogger }  830831                    let writeError =832                        let writeMethodInfo =833                            loggerExtensions.GetMethod(834                                "Log",835                                BindingFlags.Static ||| BindingFlags.Public,836                                null,837                                [| loggerType838                                   logEventLevelType839                                   typedefof<exn>840                                   typedefof<MessageFormat>841                                   typedefof<MessageArgs> |],842                                null843844                            )845                        let exnParam = Expression.Parameter(typedefof<exn>)846                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, exnParam, m847848                        let expression =849                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(850                                writeMethodExp,851                                instanceParam,852                                levelParam,853                                exnParam,854                                messageParam,855                                propertyValuesParam856                            )857                        expression.Compile() |> FuncConvert.FromAction858                    write, writeError859860                let translateLevel =831        type LoggerGateway =832            {833                Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit834                WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit835                IsEnabled: ILogger -> MicrosoftLogLevel -> bool836                TranslateLevel: LogLevel -> MicrosoftLogLevel837                BeginScope: ILogger -> obj -> IDisposable838            }839840            static member Create() =841                let loggerExtensions =842                    Type.GetType(843                        "Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions"844                    )845846                let loggerType =847                    Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")848849                let logEventLevelType =850                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")851852                let instanceParam = Expression.Parameter(typedefof<ILogger>)853854                let instanceCast = Expression.Convert(instanceParam, loggerType)855                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)856857                let levelCast = Expression.Convert(levelParam, logEventLevelType)858859                let isEnabled =860                    let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  861862                    let debugLevel =863                        Enum.Parse(logEventLevelType, "Debug", false)862                    let isEnabledMethodCall =863                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  864865                    let errorLevel =866                        Enum.Parse(logEventLevelType, "Error", false)867868                    let criticalLevel =869                        Enum.Parse(logEventLevelType, "Critical", false)865866                    Expression867                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)868                        .Compile()869                    |> FuncConvert.FromFunc  870871                    let informationLevel =872                        Enum.Parse(logEventLevelType, "Information", false)873874                    let traceLevel =875                        Enum.Parse(logEventLevelType, "Trace", false)876877                    let warningLevel =878                        Enum.Parse(logEventLevelType, "Warning", false)879880                    fun (level: LogLevel) ->881                        match level with882                        | LogLevel.Fatal -> criticalLevel883                        | LogLevel.Error -> errorLevel884                        | LogLevel.Warn -> warningLevel885                        | LogLevel.Info -> informationLevel886                        | LogLevel.Debug -> debugLevel887                        | LogLevel.Trace -> traceLevel888                        | _ -> debugLevel889                let beginScope =890                    let beginScopeMethodInfo =891                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)892                    let stateParam = Expression.Parameter(typedefof<obj>)893                    let beginScopeMethodCall =894                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)895896                    Expression897                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)898                        .Compile()899                    |> FuncConvert.FromFunc871                let write, writeError =872                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)873                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)874875                    let write =876                        let writeMethodInfo =877                            loggerExtensions.GetMethod(878                                "Log",879                                BindingFlags.Static880                                ||| BindingFlags.Public,881                                null,882                                [|883                                    loggerType884                                    logEventLevelType885                                    typedefof<MessageFormat>886                                    typedefof<MessageArgs>887                                |],888                                null889                            )890891                        let writeMethodExp =892                            Expression.Call(893                                null,894                                writeMethodInfo,895                                instanceCast,896                                levelCast,897                                messageParam,898                                propertyValuesParam899                            )  900901                {902                    Write = write903                    WriteError = writeError904                    IsEnabled = isEnabled905                    TranslateLevel = translateLevel906                    BeginScope = beginScope907                }908901                        let expression =902                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(903                                writeMethodExp,904                                instanceParam,905                                levelParam,906                                messageParam,907                                propertyValuesParam908                            )  909910        type private MicrosoftProvider() =911            let factoryGateway = lazy(LoggerFactoryGateway.Create())912            let loggerGateway = lazy(LoggerGateway.Create())913            interface ILogProvider with914                member this.GetLogger(name: string) : Logger =915                    match microsoftLoggerFactory with916                    | None ->917                        fun _ _ _ _ -> false918                    | Some factory ->919                        let logger = factoryGateway.Value.CreateLogger factory name920921                        fun logLevel message exn args ->922                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel923                            match message with924                            | Some message ->925                                let message = message ()926                                match exn with927                                | Some ex ->928                                    loggerGateway.Value.WriteError logger microsoftLevel ex message args929                                | None ->930                                    loggerGateway.Value.Write logger microsoftLevel message args931                                true932                            | None ->933                                loggerGateway.Value.IsEnabled logger microsoftLevel934935                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =936                    match microsoftLoggerFactory with937                    | None ->938                        { new IDisposable with member x.Dispose () = ()}939                    | Some factory ->940                        // Create bogus logger that will propagate to a real logger later941                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())942                        // Requires a IEnumerable<KeyValuePair> to make sense943                        // https://nblumhardt.com/2016/11/ilogger-beginscope/944                        [KeyValuePair(key, value)]945                        |> box946                        |> loggerGateway.Value.BeginScope logger947948949                member this.OpenNestedContext(message: string) : IDisposable =950                    match microsoftLoggerFactory with951                    | None ->952                        { new IDisposable with member x.Dispose () = ()}953                    | Some factory ->954                        // Create bogus logger that will propagate to a real logger later955                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())956                        loggerGateway.Value.BeginScope logger (box message)910                        expression.Compile()911                        |> FuncConvert.FromAction912913914                    let writeError =915                        let writeMethodInfo =916                            loggerExtensions.GetMethod(917                                "Log",918                                BindingFlags.Static919                                ||| BindingFlags.Public,920                                null,921                                [|922                                    loggerType923                                    logEventLevelType924                                    typedefof<exn>925                                    typedefof<MessageFormat>926                                    typedefof<MessageArgs>927                                |],928                                null929930                            )931932                        let exnParam = Expression.Parameter(typedefof<exn>)933934                        let writeMethodExp =935                            Expression.Call(936                                null,937                                writeMethodInfo,938                                instanceCast,939                                levelCast,940                                exnParam,941                                messageParam,942                                propertyValuesParam943                            )944945                        let expression =946                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(947                                writeMethodExp,948                                instanceParam,949                                levelParam,950                                exnParam,951                                messageParam,952                                propertyValuesParam953                            )954955                        expression.Compile()956                        |> FuncConvert.FromAction  957958        let create () = MicrosoftProvider() :> ILogProvider958                    write, writeError  959960#endif960                let translateLevel =  961962963module LogProvider =964    open System965    open Types966    #if !FABLE_COMPILER967    open Providers968    #endif969    open System.Diagnostics970    open Microsoft.FSharp.Quotations.Patterns962                    let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)963964                    let errorLevel = Enum.Parse(logEventLevelType, "Error", false)965966                    let criticalLevel = Enum.Parse(logEventLevelType, "Critical", false)967968                    let informationLevel = Enum.Parse(logEventLevelType, "Information", false)969970                    let traceLevel = Enum.Parse(logEventLevelType, "Trace", false)  971972    let mutable private currentLogProvider = None972                    let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)  973974    let private knownProviders =975        [976        #if !FABLE_COMPILER977            (SerilogProvider.isAvailable, SerilogProvider.create)978            (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)979        #endif980        ]981982    /// Greedy search for first available LogProvider. Order of known providers matters.983    let private resolvedLogger =984        lazy985            (knownProviders986             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())987             |> Option.map (fun (_, create) -> create ()))988989    let private noopLogger _ _ _ _ = false990991    let private noopDisposable =992        { new IDisposable with993            member __.Dispose() = () }994995    /// <summary>996    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.997    /// </summary>998    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>999    /// <returns></returns>1000    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider10011002    /// <summary>1003    /// Gets the currently set LogProvider or attempts to find known built in providers1004    /// </summary>1005    /// <returns></returns>1006    let getCurrentLogProvider () =1007        match currentLogProvider with1008        | None -> resolvedLogger.Value1009        | Some p -> Some p974                    fun (level: LogLevel) ->975                        match level with976                        | LogLevel.Fatal -> criticalLevel977                        | LogLevel.Error -> errorLevel978                        | LogLevel.Warn -> warningLevel979                        | LogLevel.Info -> informationLevel980                        | LogLevel.Debug -> debugLevel981                        | LogLevel.Trace -> traceLevel982                        | _ -> debugLevel983984                let beginScope =985                    let beginScopeMethodInfo =986                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)987988                    let stateParam = Expression.Parameter(typedefof<obj>)989990                    let beginScopeMethodCall =991                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)992993                    Expression994                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)995                        .Compile()996                    |> FuncConvert.FromFunc997998                {999                    Write = write1000                    WriteError = writeError1001                    IsEnabled = isEnabled1002                    TranslateLevel = translateLevel1003                    BeginScope = beginScope1004                }100510061007        type private MicrosoftProvider() =1008            let factoryGateway = lazy (LoggerFactoryGateway.Create())1009            let loggerGateway = lazy (LoggerGateway.Create())  10101011    /// <summary>1012    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1013    /// </summary>1014    /// <param name="key">The name of the property.</param>1015    /// <param name="value">The value of the property.</param>1016    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1017    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1018    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1019        let provider = getCurrentLogProvider ()1011            interface ILogProvider with1012                member this.GetLogger(name: string) : Logger =1013                    match microsoftLoggerFactory with1014                    | None -> fun _ _ _ _ -> false1015                    | Some factory ->1016                        let logger = factoryGateway.Value.CreateLogger factory name10171018                        fun logLevel message exn args ->1019                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel  10201021        match provider with1022        | Some p -> p.OpenMappedContext key value destructureObjects1023        | None -> noopDisposable1021                            match message with1022                            | Some message ->1023                                let message = message ()  102410251026    /// <summary>1027    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1028    /// </summary>1029    /// <param name="key">The name of the property.</param>1030    /// <param name="value">The value of the property.</param>1031    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1032    let openMappedContext (key: string) (value: obj) =1033        //TODO: We should try to find out if the value is a primitive1034        openMappedContextDestucturable key value false103510361037    /// <summary>1038    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1039    /// </summary>1040    /// <param name="value">The value of the property</param>1041    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1042    let openNestedContext (value: string) =1043        let provider = getCurrentLogProvider ()10441045        match provider with1046        | Some p -> p.OpenNestedContext value1047        | None -> noopDisposable10481049    /// <summary>1050    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1051    /// </summary>1052    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1053    /// <returns></returns>1054    let getLoggerByName (name: string) =1055        let loggerProvider = getCurrentLogProvider ()10561057        let logFunc =1058            match loggerProvider with1059            | Some loggerProvider -> loggerProvider.GetLogger(name)1060            | None -> noopLogger1025                                match exn with1026                                | Some ex -> loggerGateway.Value.WriteError logger microsoftLevel ex message args1027                                | None -> loggerGateway.Value.Write logger microsoftLevel message args10281029                                true1030                            | None -> loggerGateway.Value.IsEnabled logger microsoftLevel10311032                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =1033                    match microsoftLoggerFactory with1034                    | None ->1035                        { new IDisposable with1036                            member x.Dispose() = ()1037                        }1038                    | Some factory ->1039                        // Create bogus logger that will propagate to a real logger later1040                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1041                        // Requires a IEnumerable<KeyValuePair> to make sense1042                        // https://nblumhardt.com/2016/11/ilogger-beginscope/1043                        [ KeyValuePair(key, value) ]1044                        |> box1045                        |> loggerGateway.Value.BeginScope logger104610471048                member this.OpenNestedContext(message: string) : IDisposable =1049                    match microsoftLoggerFactory with1050                    | None ->1051                        { new IDisposable with1052                            member x.Dispose() = ()1053                        }1054                    | Some factory ->1055                        // Create bogus logger that will propagate to a real logger later1056                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())10571058                        loggerGateway.Value.BeginScope logger (box message)10591060        let create () = MicrosoftProvider() :> ILogProvider  10611062        { new ILog with1063            member x.Log = logFunc1064            member x.MappedContext = openMappedContextDestucturable }10651066    /// <summary>1067    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1068    /// </summary>1069    /// <param name="objectType">The type to generate a logger name from. </param>1070    /// <returns></returns>1071    let getLoggerByType (objectType: Type) = objectType |> string |> getLoggerByName10721073    /// <summary>1074    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1075    /// </summary>1076    /// <typeparam name="'a">The type to generate a name from.</typeparam>1077    /// <returns></returns>1078    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)10791080#if !FABLE_COMPILER1081    let rec private getModuleType =1082        function1083        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1084        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1085        // | Lambda(_, expr) -> getModuleType expr1086        // | ValueWithName(_,_,instance) -> instance1087        | x -> failwithf "Expression is not a property. %A" x10881062#endif106310641065module LogProvider =1066    open System1067    open Types1068#if !FABLE_COMPILER1069    open Providers1070#endif1071    open System.Diagnostics1072    open Microsoft.FSharp.Quotations.Patterns10731074    let mutable private currentLogProvider = None10751076    let private knownProviders = [1077#if !FABLE_COMPILER1078        (SerilogProvider.isAvailable, SerilogProvider.create)1079        (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)1080#endif1081    ]10821083    /// Greedy search for first available LogProvider. Order of known providers matters.1084    let private resolvedLogger =1085        lazy1086            (knownProviders1087             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())1088             |> Option.map (fun (_, create) -> create ()))  10891090    /// <summary>1091    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1092    ///1093    /// It can be utilized like:1094    ///1095    /// <code>1096    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1097    /// </code>1098    ///1099    /// inside a module to get the modules full qualitfied name.1100    /// </summary>1101    /// <param name="quotation">The quotation to generate a logger name from.</param>1102    /// <returns></returns>1103    let getLoggerByQuotation (quotation: Quotations.Expr) =1104        getModuleType quotation |> getLoggerByType110511061107type LogProvider =1108    /// <summary>1109    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1110    /// </summary>1111    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1112    /// <returns></returns>1113    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) = - 01114        let mi = System.Reflection.MethodBase.GetCurrentMethod()1115        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1116        // CallerMemberName gets us the function that actually called it1117        // Splitting off + seems like the best option to get the Fully Qualified Path - 01118        let location = mi.DeclaringType.FullName.Split('+') |> Seq.tryHead |> Option.defaultValue "" - 01119        sprintf "%s.%s" location memberName.Value - 01120        |> LogProvider.getLoggerByName11211122#endif1090    let private noopLogger _ _ _ _ = false10911092    let private noopDisposable =1093        { new IDisposable with1094            member __.Dispose() = ()1095        }10961097    /// <summary>1098    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.1099    /// </summary>1100    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>1101    /// <returns></returns>1102    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider11031104    /// <summary>1105    /// Gets the currently set LogProvider or attempts to find known built in providers1106    /// </summary>1107    /// <returns></returns>1108    let getCurrentLogProvider () =1109        match currentLogProvider with1110        | None -> resolvedLogger.Value1111        | Some p -> Some p11121113    /// <summary>1114    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1115    /// </summary>1116    /// <param name="key">The name of the property.</param>1117    /// <param name="value">The value of the property.</param>1118    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1119    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1120    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1121        let provider = getCurrentLogProvider ()11221123        match provider with1124        | Some p -> p.OpenMappedContext key value destructureObjects1125        | None -> noopDisposable112611271128    /// <summary>1129    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1130    /// </summary>1131    /// <param name="key">The name of the property.</param>1132    /// <param name="value">The value of the property.</param>1133    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1134    let openMappedContext (key: string) (value: obj) =1135        //TODO: We should try to find out if the value is a primitive1136        openMappedContextDestucturable key value false113711381139    /// <summary>1140    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1141    /// </summary>1142    /// <param name="value">The value of the property</param>1143    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1144    let openNestedContext (value: string) =1145        let provider = getCurrentLogProvider ()11461147        match provider with1148        | Some p -> p.OpenNestedContext value1149        | None -> noopDisposable11501151    /// <summary>1152    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1153    /// </summary>1154    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1155    /// <returns></returns>1156    let getLoggerByName (name: string) =1157        let loggerProvider = getCurrentLogProvider ()11581159        let logFunc =1160            match loggerProvider with1161            | Some loggerProvider -> loggerProvider.GetLogger(name)1162            | None -> noopLogger11631164        { new ILog with1165            member x.Log = logFunc1166            member x.MappedContext = openMappedContextDestucturable1167        }11681169    /// <summary>1170    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1171    /// </summary>1172    /// <param name="objectType">The type to generate a logger name from. </param>1173    /// <returns></returns>1174    let getLoggerByType (objectType: Type) =1175        objectType1176        |> string1177        |> getLoggerByName11781179    /// <summary>1180    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1181    /// </summary>1182    /// <typeparam name="'a">The type to generate a name from.</typeparam>1183    /// <returns></returns>1184    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)11851186#if !FABLE_COMPILER1187    let rec private getModuleType =1188        function1189        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1190        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1191        // | Lambda(_, expr) -> getModuleType expr1192        // | ValueWithName(_,_,instance) -> instance1193        | x -> failwithf "Expression is not a property. %A" x119411951196    /// <summary>1197    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1198    ///1199    /// It can be utilized like:1200    ///1201    /// <code>1202    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1203    /// </code>1204    ///1205    /// inside a module to get the modules full qualitfied name.1206    /// </summary>1207    /// <param name="quotation">The quotation to generate a logger name from.</param>1208    /// <returns></returns>1209    let getLoggerByQuotation (quotation: Quotations.Expr) =1210        getModuleType quotation1211        |> getLoggerByType121212131214type LogProvider =1215    /// <summary>1216    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1217    /// </summary>1218    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1219    /// <returns></returns>1220    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) = + 01221        let mi = System.Reflection.MethodBase.GetCurrentMethod()1222        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1223        // CallerMemberName gets us the function that actually called it1224        // Splitting off + seems like the best option to get the Fully Qualified Path1225        let location = + 01226            mi.DeclaringType.FullName.Split('+') + 01227            |> Seq.tryHead + 01228            |> Option.defaultValue ""1229 + 01230        sprintf "%s.%s" location memberName.Value + 01231        |> LogProvider.getLoggerByName12321233#endif - + diff --git a/docs/coverage/FsLibLog_LogProviderModule.htm b/docs/coverage/FsLibLog_LogProviderModule.htm index 68ddf44..040f598 100644 --- a/docs/coverage/FsLibLog_LogProviderModule.htm +++ b/docs/coverage/FsLibLog_LogProviderModule.htm @@ -18,10 +18,10 @@

< Summary

Assembly:FsLibLog File(s):C:\Users\jimmy\Repositories\public\TheAngryByrd\FsLibLog\src\FsLibLog\FsLibLog.fs Covered lines:0 -Uncovered lines:32 -Coverable lines:32 -Total lines:1122 -Line coverage:0% (0 of 32) +Uncovered lines:34 +Coverable lines:34 +Total lines:1233 +Line coverage:0% (0 of 34) Covered branches:0 Total branches:8 Branch coverage:0% (0 of 8) @@ -31,29 +31,23 @@

Metrics

- - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + +
MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage Crap Score
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
noopLogger(...)100%0%0
System.IDisposable.Dispose()100%0%0
setLoggerProvider(...)100%0%0
getCurrentLogProvider()220%0%0
openMappedContextDestucturable(...)220%0%0
openMappedContext(...)100%0%0
openNestedContext(...)220%0%0
getLoggerByName(...)220%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILog.get_Log()100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILog.get_MappedContext()100%0%0
getLoggerByType(...)300%0%0
getLoggerFor()100%0%0
getModuleType(...)200%0%0
getLoggerByQuotation(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
noopLogger(...)100%0%0
System.IDisposable.Dispose()100%0%0
setLoggerProvider(...)100%0%0
getCurrentLogProvider()220%0%0
openMappedContextDestucturable(...)220%0%0
openMappedContext(...)100%0%0
openNestedContext(...)220%0%0
getLoggerByName(...)220%0%0
FsLibLog.Types.ILog.get_Log()100%0%0
FsLibLog.Types.ILog.get_MappedContext()100%0%0
getLoggerByType(...)300%0%0
getLoggerFor()100%0%0
getModuleType(...)200%0%0
getLoggerByQuotation(...)100%0%0

File(s)

@@ -91,1125 +85,1232 @@

 28    /// Type representing a Log  29    [<NoEquality; NoComparison>]  30    type Log =31        { LogLevel: LogLevel32          Message: MessageThunk33          Exception: exn option34          Parameters: obj list35          AdditionalNamedParameters: ((string * obj * bool) list) }36        static member StartLogLevel(logLevel: LogLevel) =37            { LogLevel = logLevel38              Message = None39              Exception = None40              Parameters = List.empty41              AdditionalNamedParameters = List.empty }4243    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio44    type ILog =45        abstract member Log :  Logger46        abstract member MappedContext :  MappedContext4748#if FABLE_COMPILER49    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)50    // is used instead.51    type Stack<'a>()  =52        let mutable contents = Array.zeroCreate<'a>(2)53        let mutable count = 05455        member buf.Ensure newSize =56            let oldSize = contents.Length57            if newSize > oldSize then58                let old = contents59                contents <- Array.zeroCreate (max newSize (oldSize * 2))60                Array.blit old 0 contents 0 count31        {32            LogLevel: LogLevel33            Message: MessageThunk34            Exception: exn option35            Parameters: obj list36            AdditionalNamedParameters: ((string * obj * bool) list)37        }3839        static member StartLogLevel(logLevel: LogLevel) = {40            LogLevel = logLevel41            Message = None42            Exception = None43            Parameters = List.empty44            AdditionalNamedParameters = List.empty45        }4647    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio48    type ILog =49        abstract member Log: Logger50        abstract member MappedContext: MappedContext5152#if FABLE_COMPILER53    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)54    // is used instead.55    type Stack<'a>() =56        let mutable contents = Array.zeroCreate<'a> (2)57        let mutable count = 05859        member buf.Ensure newSize =60            let oldSize = contents.Length  6162        member buf.Count = count63        member buf.Pop() =64            let item = contents.[count - 1]65            count <- count - 166            item6768        member buf.Peep() = contents.[count - 1]69        member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev70        member buf.Push(x) =71            buf.Ensure(count + 1)72            contents.[count] <- x73            count <- count + 17475        member buf.IsEmpty = (count = 0)76#endif7778    [<AutoOpen>]79    module Inner =80#if !FABLE_COMPILER81        open System.Collections.Generic82#endif8384        /// <summary>85        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.86        /// </summary>87        type DisposableStack() =88            let stack = Stack<IDisposable>()8990            interface IDisposable with91                member __.Dispose() =92                    while stack.Count > 0 do93                        stack.Pop().Dispose()9495            member __.Push(item: IDisposable) = stack.Push item96            member __.Push(items: IDisposable list) = items |> List.iter stack.Push9798            static member Create(items: IDisposable list) =99                let ds = new DisposableStack()100                ds.Push items101                ds102103        type ILog with62            if newSize > oldSize then63                let old = contents64                contents <- Array.zeroCreate (max newSize (oldSize * 2))65                Array.blit old 0 contents 0 count6667        member buf.Count = count6869        member buf.Pop() =70            let item = contents.[count - 1]71            count <- count - 172            item7374        member buf.Peep() = contents.[count - 1]7576        member buf.Top(n) =77            [ for x in contents.[max 0 (count - n) .. count - 1] -> x ]78            |> List.rev7980        member buf.Push(x) =81            buf.Ensure(count + 1)82            contents.[count] <- x83            count <- count + 18485        member buf.IsEmpty = (count = 0)86#endif8788    [<AutoOpen>]89    module Inner =90#if !FABLE_COMPILER91        open System.Collections.Generic92#endif9394        /// <summary>95        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.96        /// </summary>97        type DisposableStack() =98            let stack = Stack<IDisposable>()99100            interface IDisposable with101                member __.Dispose() =102                    while stack.Count > 0 do103                        stack.Pop().Dispose()  104105            /// <summary>106            /// Logs a log107            /// </summary>108            /// <param name="log">The type representing a log message to be logged</param>109            /// <returns><see langword="true"/> if the log message was logged</returns>110            member logger.fromLog(log: Log) =111                use __ =112                    log.AdditionalNamedParameters113                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)114                    // This stack is important, it causes us to unwind as if you have multiple uses in a row115                    |> DisposableStack.Create116117                log.Parameters118                |> List.toArray119                |> logger.Log log.LogLevel log.Message log.Exception120121            /// <summary>122            /// Logs a fatal log message given a log configurer.123            /// </summary>124            /// <param name="logConfig">A function to configure a log</param>125            /// <returns><see langword="true"/>  if the log message was logged</returns>126            member logger.fatal'(logConfig: Log -> Log) =127                Log.StartLogLevel LogLevel.Fatal128                |> logConfig129                |> logger.fromLog130131            /// <summary>132            /// Logs a fatal log message given a log configurer.133            /// </summary>134            /// <param name="logConfig">A function to configure a log</param>135            member logger.fatal(logConfig: Log -> Log) = logger.fatal' logConfig |> ignore136137            /// <summary>138            /// Logs an error log message given a log configurer.139            /// </summary>140            /// <param name="logConfig">A function to configure a log</param>141            /// <returns><see langword="true"/>  if the log message was logged</returns>142            member logger.error'(logConfig: Log -> Log) =143                Log.StartLogLevel LogLevel.Error144                |> logConfig145                |> logger.fromLog146147            /// <summary>148            /// Logs an error log message given a log configurer.149            /// </summary>150            /// <param name="logConfig">A function to configure a log</param>151            member logger.error(logConfig: Log -> Log) = logger.error' logConfig |> ignore152153            /// <summary>154            /// Logs a warn log message given a log configurer.155            /// </summary>156            /// <param name="logConfig">A function to configure a log</param>157            /// <returns><see langword="true"/>  if the log message was logged</returns>158            member logger.warn'(logConfig: Log -> Log) =159                Log.StartLogLevel LogLevel.Warn160                |> logConfig161                |> logger.fromLog162163            /// <summary>164            /// Logs a warn log message given a log configurer.165            /// </summary>166            /// <param name="logConfig">A function to configure a log</param>167            member logger.warn(logConfig: Log -> Log) = logger.warn' logConfig |> ignore168169            /// <summary>170            /// Logs an info log message given a log configurer.171            /// </summary>172            /// <param name="logConfig">A function to configure a log</param>173            /// <returns><see langword="true"/>  if the log message was logged</returns>174            member logger.info'(logConfig: Log -> Log) =175                Log.StartLogLevel LogLevel.Info176                |> logConfig177                |> logger.fromLog178179            /// <summary>180            /// Logs an info log message given a log configurer.181            /// </summary>182            /// <param name="logConfig">A function to configure a log</param>183            member logger.info(logConfig: Log -> Log) = logger.info' logConfig |> ignore184185            /// <summary>186            /// Logs a debug log message given a log configurer.187            /// </summary>188            /// <param name="logConfig">A function to configure a log</param>189            /// <returns><see langword="true"/>  if the log message was logged</returns>190            member logger.debug'(logConfig: Log -> Log) =191                Log.StartLogLevel LogLevel.Debug192                |> logConfig193                |> logger.fromLog194195            /// <summary>196            /// Logs a debug log message given a log configurer.197            /// </summary>198            /// <param name="logConfig">A function to configure a log</param>199            member logger.debug(logConfig: Log -> Log) = logger.debug' logConfig |> ignore200201            /// <summary>202            /// Logs a trace log message given a log configurer.203            /// </summary>204            /// <param name="logConfig">A function to configure a log</param>205            /// <returns><see langword="true"/>  if the log message was logged</returns>206            member logger.trace'(logConfig: Log -> Log) =207                Log.StartLogLevel LogLevel.Trace208                |> logConfig209                |> logger.fromLog210211            /// <summary>212            /// Logs a trace log message given a log configurer.213            /// </summary>214            /// <param name="logConfig">A function to configure a log</param>215            member logger.trace(logConfig: Log -> Log) = logger.trace' logConfig |> ignore216217218    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.219    type ILogProvider =220        abstract member GetLogger : string -> Logger221        abstract member OpenNestedContext : string -> IDisposable222        abstract member OpenMappedContext : string -> obj -> bool -> IDisposable105            member __.Push(item: IDisposable) = stack.Push item106107            member __.Push(items: IDisposable list) =108                items109                |> List.iter stack.Push110111            static member Create(items: IDisposable list) =112                let ds = new DisposableStack()113                ds.Push items114                ds115116        type ILog with117118            /// <summary>119            /// Logs a log120            /// </summary>121            /// <param name="log">The type representing a log message to be logged</param>122            /// <returns><see langword="true"/> if the log message was logged</returns>123            member logger.fromLog(log: Log) =124                use __ =125                    log.AdditionalNamedParameters126                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)127                    // This stack is important, it causes us to unwind as if you have multiple uses in a row128                    |> DisposableStack.Create129130                log.Parameters131                |> List.toArray132                |> logger.Log log.LogLevel log.Message log.Exception133134            /// <summary>135            /// Logs a fatal log message given a log configurer.136            /// </summary>137            /// <param name="logConfig">A function to configure a log</param>138            /// <returns><see langword="true"/>  if the log message was logged</returns>139            member logger.fatal'(logConfig: Log -> Log) =140                Log.StartLogLevel LogLevel.Fatal141                |> logConfig142                |> logger.fromLog143144            /// <summary>145            /// Logs a fatal log message given a log configurer.146            /// </summary>147            /// <param name="logConfig">A function to configure a log</param>148            member logger.fatal(logConfig: Log -> Log) =149                logger.fatal' logConfig150                |> ignore151152            /// <summary>153            /// Logs an error log message given a log configurer.154            /// </summary>155            /// <param name="logConfig">A function to configure a log</param>156            /// <returns><see langword="true"/>  if the log message was logged</returns>157            member logger.error'(logConfig: Log -> Log) =158                Log.StartLogLevel LogLevel.Error159                |> logConfig160                |> logger.fromLog161162            /// <summary>163            /// Logs an error log message given a log configurer.164            /// </summary>165            /// <param name="logConfig">A function to configure a log</param>166            member logger.error(logConfig: Log -> Log) =167                logger.error' logConfig168                |> ignore169170            /// <summary>171            /// Logs a warn log message given a log configurer.172            /// </summary>173            /// <param name="logConfig">A function to configure a log</param>174            /// <returns><see langword="true"/>  if the log message was logged</returns>175            member logger.warn'(logConfig: Log -> Log) =176                Log.StartLogLevel LogLevel.Warn177                |> logConfig178                |> logger.fromLog179180            /// <summary>181            /// Logs a warn log message given a log configurer.182            /// </summary>183            /// <param name="logConfig">A function to configure a log</param>184            member logger.warn(logConfig: Log -> Log) =185                logger.warn' logConfig186                |> ignore187188            /// <summary>189            /// Logs an info log message given a log configurer.190            /// </summary>191            /// <param name="logConfig">A function to configure a log</param>192            /// <returns><see langword="true"/>  if the log message was logged</returns>193            member logger.info'(logConfig: Log -> Log) =194                Log.StartLogLevel LogLevel.Info195                |> logConfig196                |> logger.fromLog197198            /// <summary>199            /// Logs an info log message given a log configurer.200            /// </summary>201            /// <param name="logConfig">A function to configure a log</param>202            member logger.info(logConfig: Log -> Log) =203                logger.info' logConfig204                |> ignore205206            /// <summary>207            /// Logs a debug log message given a log configurer.208            /// </summary>209            /// <param name="logConfig">A function to configure a log</param>210            /// <returns><see langword="true"/>  if the log message was logged</returns>211            member logger.debug'(logConfig: Log -> Log) =212                Log.StartLogLevel LogLevel.Debug213                |> logConfig214                |> logger.fromLog215216            /// <summary>217            /// Logs a debug log message given a log configurer.218            /// </summary>219            /// <param name="logConfig">A function to configure a log</param>220            member logger.debug(logConfig: Log -> Log) =221                logger.debug' logConfig222                |> ignore  223224    module Log =225226        /// <summary>227        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.228        /// </summary>229        /// <param name="message">The message to set for the log.</param>230        /// <param name="log">The log to amend.</param>231        /// <returns>The amended log.</returns>232        let setMessage (message: string) (log: Log) =233            { log with234                  Message = Some(fun () -> message) }235236        /// <summary>237        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con238        /// </summary>239        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>240        /// <param name="log">The log to amend.</param>241        /// <returns>The amended log.</returns>242        let setMessageThunk (messageThunk: unit -> string) (log: Log) =243            { log with Message = Some messageThunk }244245        /// <summary>246        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.247        /// </summary>248        /// <param name="param">The value to add to the log</param>249        /// <param name="log">The log to amend.</param>250        /// <returns>The amended log.</returns>251        let addParameter (param: 'a) (log: Log) =252            { log with253                  Parameters = List.append log.Parameters [ (box param) ] }254255        /// <summary>256        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.257        /// </summary>258        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>259        /// <param name="log">The log to amend.</param>260        /// <returns>The amended log.</returns>261        let addParameters (``params``: obj list) (log: Log) =262            let ``params`` = ``params`` |> List.map box263264            { log with265                  Parameters = log.Parameters @ ``params`` }266267268269        /// <summary>270        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe271        /// This DOES NOT affect the parameters set for a message template.272        /// This is the same calling OpenMappedContext right before logging.224            /// <summary>225            /// Logs a trace log message given a log configurer.226            /// </summary>227            /// <param name="logConfig">A function to configure a log</param>228            /// <returns><see langword="true"/>  if the log message was logged</returns>229            member logger.trace'(logConfig: Log -> Log) =230                Log.StartLogLevel LogLevel.Trace231                |> logConfig232                |> logger.fromLog233234            /// <summary>235            /// Logs a trace log message given a log configurer.236            /// </summary>237            /// <param name="logConfig">A function to configure a log</param>238            member logger.trace(logConfig: Log -> Log) =239                logger.trace' logConfig240                |> ignore241242243    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.244    type ILogProvider =245        abstract member GetLogger: string -> Logger246        abstract member OpenNestedContext: string -> IDisposable247        abstract member OpenMappedContext: string -> obj -> bool -> IDisposable248249    module Log =250251        /// <summary>252        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.253        /// </summary>254        /// <param name="message">The message to set for the log.</param>255        /// <param name="log">The log to amend.</param>256        /// <returns>The amended log.</returns>257        let setMessage (message: string) (log: Log) =258            { log with259                Message = Some(fun () -> message)260            }261262        /// <summary>263        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con264        /// </summary>265        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>266        /// <param name="log">The log to amend.</param>267        /// <returns>The amended log.</returns>268        let setMessageThunk (messageThunk: unit -> string) (log: Log) =269            { log with Message = Some messageThunk }270271        /// <summary>272        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.  273        /// </summary>274        /// <param name="key">The key of the parameter to add to the log.</param>275        /// <param name="value">The value of the parameter to add to the log.</param>276        /// <param name="log">The log to amend.</param>277        /// <returns>The amended log.</returns>278        let addContext (key: string) (value: obj) (log: Log) =279            { log with280                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] }274        /// <param name="param">The value to add to the log</param>275        /// <param name="log">The log to amend.</param>276        /// <returns>The amended log.</returns>277        let addParameter (param: 'a) (log: Log) =278            { log with279                Parameters = List.append log.Parameters [ (box param) ]280            }  281282283        /// <summary>284        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe285        /// This DOES NOT affect the parameters set for a message template.286        /// This is the same calling OpenMappedContext right before logging.287        /// This destructures an object rather than calling `ToString()` on it.288        /// WARNING: Destructring can be expensive.289        /// </summary>290        /// <param name="key">The key of the parameter to add to the log.</param>291        /// <param name="value">The value of the parameter to add to the log.</param>292        /// <param name="log">The log to amend.</param>293        /// <returns>The amended log.</returns>294        let addContextDestructured (key: string) (value: obj) (log: Log) =295            { log with296                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] }297282        /// <summary>283        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.284        /// </summary>285        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>286        /// <param name="log">The log to amend.</param>287        /// <returns>The amended log.</returns>288        let addParameters (``params``: obj list) (log: Log) =289            let ``params`` =290                ``params``291                |> List.map box292293            { log with294                Parameters =295                    log.Parameters296                    @ ``params``297            }  298299        /// <summary>300        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle301        /// </summary>302        /// <param name="exception">The exception to add to the log.</param>303        /// <param name="log">The log to amend.</param>304        /// <returns>The amended log.</returns>305        let addException (``exception``: exn) (log: Log) =306            { log with307                  Exception = Option.ofObj ``exception`` }308309        /// <summary>310        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle311        /// </summary>312        /// <param name="exception">The exception to add to the log.</param>313        /// <param name="log">The log to amend.</param>314        /// <returns>The amended log.</returns>315        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log316317        /// <summary>318        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe319        /// </summary>320        /// <param name="logLevel">The level to set for the log.</param>321        /// <param name="log">The log to amend.</param>322        /// <returns>The amended log.</returns>323        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }324325#if !FABLE_COMPILER326327        let private formatterRegex =328            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)329330        let private isAnObject value =331            Convert.GetTypeCode(value) = TypeCode.Object332333        /// <summary>334        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m335        ///336        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr337        /// </summary>338        /// <param name="message">An interpolated string</param>339        /// <param name="log">The log to amend.</param>340        /// <returns>The amended log.</returns>341        let setMessageInterpolated (message: FormattableString) (log: Log) =342            let mutable messageFormat = message.Format343344            let args =345                formatterRegex.Matches(messageFormat)346                |> Seq.cast<Match>347                |> Seq.map348                    (fun m ->349                        let number = Int32.Parse(m.Groups.["number"].Value)350                        let formatGroup = m.Groups.["format"]351                        let propertyValue = message.GetArgument(number)352                        let propertyName = formatGroup.Value353                        let columnFormatGroup = m.Groups.["columnFormat"]354                        propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length355                        )356            // Reverse the args so we won't change the indexes earlier in the string357            args358            |> Seq.rev359            |> Seq.iter360                (fun (_, _, removeStart, removeLength) ->361                    if removeLength > 0 then362                        messageFormat <- messageFormat.Remove(removeStart, removeLength))299300        /// <summary>301        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe302        /// This DOES NOT affect the parameters set for a message template.303        /// This is the same calling OpenMappedContext right before logging.304        /// </summary>305        /// <param name="key">The key of the parameter to add to the log.</param>306        /// <param name="value">The value of the parameter to add to the log.</param>307        /// <param name="log">The log to amend.</param>308        /// <returns>The amended log.</returns>309        let addContext (key: string) (value: obj) (log: Log) =310            { log with311                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ]312            }313314315        /// <summary>316        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe317        /// This DOES NOT affect the parameters set for a message template.318        /// This is the same calling OpenMappedContext right before logging.319        /// This destructures an object rather than calling `ToString()` on it.320        /// WARNING: Destructring can be expensive.321        /// </summary>322        /// <param name="key">The key of the parameter to add to the log.</param>323        /// <param name="value">The value of the parameter to add to the log.</param>324        /// <param name="log">The log to amend.</param>325        /// <returns>The amended log.</returns>326        let addContextDestructured (key: string) (value: obj) (log: Log) =327            { log with328                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ]329            }330331332        /// <summary>333        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle334        /// </summary>335        /// <param name="exception">The exception to add to the log.</param>336        /// <param name="log">The log to amend.</param>337        /// <returns>The amended log.</returns>338        let addException (``exception``: exn) (log: Log) =339            { log with340                Exception = Option.ofObj ``exception``341            }342343        /// <summary>344        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle345        /// </summary>346        /// <param name="exception">The exception to add to the log.</param>347        /// <param name="log">The log to amend.</param>348        /// <returns>The amended log.</returns>349        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log350351        /// <summary>352        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe353        /// </summary>354        /// <param name="logLevel">The level to set for the log.</param>355        /// <param name="log">The log to amend.</param>356        /// <returns>The amended log.</returns>357        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }358359#if !FABLE_COMPILER360361        let private formatterRegex =362            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)  363364            let namedArgs =365                args366                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")367                |> Seq.toArray368369            messageFormat <-370                messageFormat371                    .Replace("{{", "{{{{")372                    .Replace("}}", "}}}}")373            // Replace numbered args with named args from regex match374            messageFormat <- String.Format(messageFormat, args = namedArgs)375376            let addContexts args (log: Log) =377                let addArgsToContext =378                    (id, args)379                    ||> Seq.fold380                            (fun state (name, value, _, _) ->381                                let contextAdder =382                                    if value |> isAnObject then383                                        addContextDestructured384                                    else385                                        addContext386387                                state >> contextAdder name value)388389                addArgsToContext log390391            log392            |> setMessage messageFormat393            |> addContexts args394395        /// <summary>396        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m397        ///398        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr399        /// </summary>400        /// <param name="message">An interpolated string</param>401        /// <param name="log">The log to amend.</param>402        /// <returns>The amended log.</returns>403        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log404#endif364        let private isAnObject value =365            Convert.GetTypeCode(value) = TypeCode.Object366367        /// <summary>368        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m369        ///370        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr371        /// </summary>372        /// <param name="message">An interpolated string</param>373        /// <param name="log">The log to amend.</param>374        /// <returns>The amended log.</returns>375        let setMessageInterpolated (message: FormattableString) (log: Log) =376            let mutable messageFormat = message.Format377378            let args =379                formatterRegex.Matches(messageFormat)380                |> Seq.cast<Match>381                |> Seq.map (fun m ->382                    let number = Int32.Parse(m.Groups.["number"].Value)383                    let formatGroup = m.Groups.["format"]384                    let propertyValue = message.GetArgument(number)385                    let propertyName = formatGroup.Value386                    let columnFormatGroup = m.Groups.["columnFormat"]387                    propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length388                )389            // Reverse the args so we won't change the indexes earlier in the string390            args391            |> Seq.rev392            |> Seq.iter (fun (_, _, removeStart, removeLength) ->393                if removeLength > 0 then394                    messageFormat <- messageFormat.Remove(removeStart, removeLength)395            )396397            let namedArgs =398                args399                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")400                |> Seq.toArray401402            messageFormat <- messageFormat.Replace("{{", "{{{{").Replace("}}", "}}}}")403            // Replace numbered args with named args from regex match404            messageFormat <- String.Format(messageFormat, args = namedArgs)  405406/// Provides operators to make writing logs more streamlined.407module Operators =408409    /// <summary>410    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.411    /// </summary>412    /// <param name="message">The string of the base message.</param>413    /// <returns>A new Log instance with the specified message.</returns>414    let (!!!) message = Log.setMessage message406            let addContexts args (log: Log) =407                let addArgsToContext =408                    (id, args)409                    ||> Seq.fold (fun state (name, value, _, _) ->410                        let contextAdder =411                            if value |> isAnObject then412                                addContextDestructured413                            else414                                addContext  415416    /// <summary>417    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<418    /// </summary>419    /// <param name="log">The Log to add the parameter to.</param>420    /// <param name="value">The value for the parameter.</param>421    /// <returns>The Log with the added parameter.</returns>422    let (>>!) log value = log >> Log.addParameter value423424    /// <summary>425    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.426    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right427    ///428    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.429    /// </summary>430    /// <param name="log">The log to add the parameter to.</param>431    /// <param name="key">The name for the parameter.</param>432    /// <param name="value">The value for the parameter.</param>433    /// <returns>The amended log with the parameter added.</returns>434    let (>>!-) log (key, value) = log >> Log.addContext key value435436    /// <summary>437    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT438    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling439    ///440    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.441    /// </summary>442    /// <param name="log">The log to add the parameter to.</param>443    /// <param name="key">The name for the parameter.</param>444    /// <param name="value">The value for the parameter.</param>445    /// <returns>The amended log with the parameter added.</returns>446    let (>>!+) log (key, value) =447        log >> Log.addContextDestructured key value448449    /// <summary>450    /// Amends a Log with an exn. Handles nulls.451    ///452    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.453    /// </summary>454    /// <param name="log">The log to add the parameter to.</param>455    /// <param name="e">The exception to add to the log.</param>456    /// <returns>The amended log with the parameter added.</returns>457    let (>>!!) log e = log >> Log.addException e458459460#if !FABLE_COMPILER461module Providers =462    module SerilogProvider =463        open System464        open System.Linq.Expressions465466        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")467        let isAvailable () = getLogManagerType () |> isNull |> not468469        let getPushProperty () =416                        state417                        >> contextAdder name value418                    )419420                addArgsToContext log421422            log423            |> setMessage messageFormat424            |> addContexts args425426        /// <summary>427        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m428        ///429        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr430        /// </summary>431        /// <param name="message">An interpolated string</param>432        /// <param name="log">The log to amend.</param>433        /// <returns>The amended log.</returns>434        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log435#endif436437/// Provides operators to make writing logs more streamlined.438module Operators =439440    /// <summary>441    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.442    /// </summary>443    /// <param name="message">The string of the base message.</param>444    /// <returns>A new Log instance with the specified message.</returns>445    let (!!!) message = Log.setMessage message446447    /// <summary>448    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<449    /// </summary>450    /// <param name="log">The Log to add the parameter to.</param>451    /// <param name="value">The value for the parameter.</param>452    /// <returns>The Log with the added parameter.</returns>453    let (>>!) log value =454        log455        >> Log.addParameter value456457    /// <summary>458    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.459    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right460    ///461    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.462    /// </summary>463    /// <param name="log">The log to add the parameter to.</param>464    /// <param name="key">The name for the parameter.</param>465    /// <param name="value">The value for the parameter.</param>466    /// <returns>The amended log with the parameter added.</returns>467    let (>>!-) log (key, value) =468        log469        >> Log.addContext key value  470471            let ndcContextType =472                Type.GetType("Serilog.Context.LogContext, Serilog")473                |> Option.ofObj474                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))475476            ()477478            let pushPropertyMethod =479                ndcContextType.GetMethod(480                    "PushProperty",481                    [| typedefof<string>482                       typedefof<obj>483                       typedefof<bool> |]484                )485486            let nameParam =487                Expression.Parameter(typedefof<string>, "name")488489            let valueParam =490                Expression.Parameter(typedefof<obj>, "value")491492            let destructureObjectParam =493                Expression.Parameter(typedefof<bool>, "destructureObjects")494495            let pushPropertyMethodCall =496                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)471    /// <summary>472    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT473    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling474    ///475    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.476    /// </summary>477    /// <param name="log">The log to add the parameter to.</param>478    /// <param name="key">The name for the parameter.</param>479    /// <param name="value">The value for the parameter.</param>480    /// <returns>The amended log with the parameter added.</returns>481    let (>>!+) log (key, value) =482        log483        >> Log.addContextDestructured key value484485    /// <summary>486    /// Amends a Log with an exn. Handles nulls.487    ///488    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.489    /// </summary>490    /// <param name="log">The log to add the parameter to.</param>491    /// <param name="e">The exception to add to the log.</param>492    /// <returns>The amended log with the parameter added.</returns>493    let (>>!!) log e =494        log495        >> Log.addException e496  497498            let pushProperty =499                Expression500                    .Lambda<Func<string, obj, bool, IDisposable>>(501                        pushPropertyMethodCall,502                        nameParam,503                        valueParam,504                        destructureObjectParam505                    )506                    .Compile()507508            fun key value destructure -> pushProperty.Invoke(key, value, destructure)509498#if !FABLE_COMPILER499module Providers =500    module SerilogProvider =501        open System502        open System.Linq.Expressions503504        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")505506        let isAvailable () =507            getLogManagerType ()508            |> isNull509            |> not  510511        let getForContextMethodCall () =512            let logManagerType = getLogManagerType ()513514            let method =515                logManagerType.GetMethod(516                    "ForContext",517                    [| typedefof<string>518                       typedefof<obj>519                       typedefof<bool> |]520                )521522            let propertyNameParam =523                Expression.Parameter(typedefof<string>, "propertyName")524525            let valueParam =526                Expression.Parameter(typedefof<obj>, "value")527528            let destructureObjectsParam =529                Expression.Parameter(typedefof<bool>, "destructureObjects")530531            let exrs: Expression [] =532                [| propertyNameParam533                   valueParam534                   destructureObjectsParam |]535536            let methodCall = Expression.Call(null, method, exrs)537538            let func =539                Expression540                    .Lambda<Func<string, obj, bool, obj>>(541                        methodCall,542                        propertyNameParam,543                        valueParam,544                        destructureObjectsParam545                    )546                    .Compile()547548            fun name -> func.Invoke("SourceContext", name, false)511        let getPushProperty () =512513            let ndcContextType =514                Type.GetType("Serilog.Context.LogContext, Serilog")515                |> Option.ofObj516                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))517518            ()519520            let pushPropertyMethod =521                ndcContextType.GetMethod(522                    "PushProperty",523                    [|524                        typedefof<string>525                        typedefof<obj>526                        typedefof<bool>527                    |]528                )529530            let nameParam = Expression.Parameter(typedefof<string>, "name")531532            let valueParam = Expression.Parameter(typedefof<obj>, "value")533534            let destructureObjectParam =535                Expression.Parameter(typedefof<bool>, "destructureObjects")536537            let pushPropertyMethodCall =538                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)539540            let pushProperty =541                Expression542                    .Lambda<Func<string, obj, bool, IDisposable>>(543                        pushPropertyMethodCall,544                        nameParam,545                        valueParam,546                        destructureObjectParam547                    )548                    .Compile()  549550        [<NoEquality; NoComparison>]551        type SerilogGateway =552            { Write: obj -> obj -> string -> obj [] -> unit553              WriteException: obj -> obj -> exn -> string -> obj [] -> unit554              IsEnabled: obj -> obj -> bool555              TranslateLevel: LogLevel -> obj }556            static member Create() =557                let logEventLevelType =558                    Type.GetType("Serilog.Events.LogEventLevel, Serilog")559560                if (logEventLevelType |> isNull) then561                    failwith ("Type Serilog.Events.LogEventLevel was not found.")562563                let debugLevel =564                    Enum.Parse(logEventLevelType, "Debug", false)550            fun key value destructure -> pushProperty.Invoke(key, value, destructure)551552553        let getForContextMethodCall () =554            let logManagerType = getLogManagerType ()555556            let method =557                logManagerType.GetMethod(558                    "ForContext",559                    [|560                        typedefof<string>561                        typedefof<obj>562                        typedefof<bool>563                    |]564                )  565566                let errorLevel =567                    Enum.Parse(logEventLevelType, "Error", false)568569                let fatalLevel =570                    Enum.Parse(logEventLevelType, "Fatal", false)571572                let informationLevel =573                    Enum.Parse(logEventLevelType, "Information", false)574575                let verboseLevel =576                    Enum.Parse(logEventLevelType, "Verbose", false)577578                let warningLevel =579                    Enum.Parse(logEventLevelType, "Warning", false)566            let propertyNameParam = Expression.Parameter(typedefof<string>, "propertyName")567568            let valueParam = Expression.Parameter(typedefof<obj>, "value")569570            let destructureObjectsParam =571                Expression.Parameter(typedefof<bool>, "destructureObjects")572573            let exrs: Expression[] = [|574                propertyNameParam575                valueParam576                destructureObjectsParam577            |]578579            let methodCall = Expression.Call(null, method, exrs)  580581                let translateLevel (level: LogLevel) =582                    match level with583                    | LogLevel.Fatal -> fatalLevel584                    | LogLevel.Error -> errorLevel585                    | LogLevel.Warn -> warningLevel586                    | LogLevel.Info -> informationLevel587                    | LogLevel.Debug -> debugLevel588                    | LogLevel.Trace -> verboseLevel589                    | _ -> debugLevel581            let func =582                Expression583                    .Lambda<Func<string, obj, bool, obj>>(584                        methodCall,585                        propertyNameParam,586                        valueParam,587                        destructureObjectsParam588                    )589                    .Compile()  590591                let loggerType = Type.GetType("Serilog.ILogger, Serilog")591            fun name -> func.Invoke("SourceContext", name, false)  592593                if (loggerType |> isNull) then594                    failwith ("Type Serilog.ILogger was not found.")595596                let isEnabledMethodInfo =597                    loggerType.GetMethod("IsEnabled", [| logEventLevelType |])598599                let instanceParam = Expression.Parameter(typedefof<obj>)600601                let instanceCast =602                    Expression.Convert(instanceParam, loggerType)603604                let levelParam = Expression.Parameter(typedefof<obj>)605606                let levelCast =607                    Expression.Convert(levelParam, logEventLevelType)608609                let isEnabledMethodCall =610                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)611612                let isEnabled =613                    Expression614                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)615                        .Compile()593        [<NoEquality; NoComparison>]594        type SerilogGateway =595            {596                Write: obj -> obj -> string -> obj[] -> unit597                WriteException: obj -> obj -> exn -> string -> obj[] -> unit598                IsEnabled: obj -> obj -> bool599                TranslateLevel: LogLevel -> obj600            }601602            static member Create() =603                let logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog")604605                if606                    (logEventLevelType607                     |> isNull)608                then609                    failwith ("Type Serilog.Events.LogEventLevel was not found.")610611                let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)612613                let errorLevel = Enum.Parse(logEventLevelType, "Error", false)614615                let fatalLevel = Enum.Parse(logEventLevelType, "Fatal", false)  616617                let writeMethodInfo =618                    loggerType.GetMethod(619                        "Write",620                        [| logEventLevelType621                           typedefof<string>622                           typedefof<obj []> |]623                    )624625                let messageParam = Expression.Parameter(typedefof<string>)626                let propertyValuesParam = Expression.Parameter(typedefof<obj []>)627628                let writeMethodExp =629                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)630631                let expression =632                    Expression.Lambda<Action<obj, obj, string, obj []>>(633                        writeMethodExp,634                        instanceParam,635                        levelParam,636                        messageParam,637                        propertyValuesParam638                    )617                let informationLevel = Enum.Parse(logEventLevelType, "Information", false)618619                let verboseLevel = Enum.Parse(logEventLevelType, "Verbose", false)620621                let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)622623                let translateLevel (level: LogLevel) =624                    match level with625                    | LogLevel.Fatal -> fatalLevel626                    | LogLevel.Error -> errorLevel627                    | LogLevel.Warn -> warningLevel628                    | LogLevel.Info -> informationLevel629                    | LogLevel.Debug -> debugLevel630                    | LogLevel.Trace -> verboseLevel631                    | _ -> debugLevel632633                let loggerType = Type.GetType("Serilog.ILogger, Serilog")634635                if (loggerType |> isNull) then636                    failwith ("Type Serilog.ILogger was not found.")637638                let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  639640                let write = expression.Compile()640                let instanceParam = Expression.Parameter(typedefof<obj>)  641642                let writeExceptionMethodInfo =643                    loggerType.GetMethod(644                        "Write",645                        [| logEventLevelType646                           typedefof<exn>647                           typedefof<string>648                           typedefof<obj []> |]649                    )642                let instanceCast = Expression.Convert(instanceParam, loggerType)643644                let levelParam = Expression.Parameter(typedefof<obj>)645646                let levelCast = Expression.Convert(levelParam, logEventLevelType)647648                let isEnabledMethodCall =649                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  650651                let exceptionParam = Expression.Parameter(typedefof<exn>)652653                let writeMethodExp =654                    Expression.Call(655                        instanceCast,656                        writeExceptionMethodInfo,657                        levelCast,658                        exceptionParam,659                        messageParam,660                        propertyValuesParam661                    )662663                let writeException =664                    Expression665                        .Lambda<Action<obj, obj, exn, string, obj []>>(666                            writeMethodExp,667                            instanceParam,668                            levelParam,669                            exceptionParam,670                            messageParam,671                            propertyValuesParam672                        )673                        .Compile()674675                { Write =676                      (fun logger level message formattedParmeters ->677                          write.Invoke(logger, level, message, formattedParmeters))678                  WriteException =679                      fun logger level ex message formattedParmeters ->680                          writeException.Invoke(logger, level, ex, message, formattedParmeters)681                  IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)682                  TranslateLevel = translateLevel }683684        type private SeriLogProvider() =685            let getLoggerByName = getForContextMethodCall ()686            let pushProperty = getPushProperty ()687            let serilogGatewayInit = lazy (SerilogGateway.Create())688689            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =690                let serilogGateway = serilogGatewayInit.Value691                let translatedValue = serilogGateway.TranslateLevel logLevel692693                match messageFunc with694                | None -> serilogGateway.IsEnabled logger translatedValue695                | Some _ when696                    serilogGateway.IsEnabled logger translatedValue697                    |> not698                    ->699                    false700                | Some m ->701                    match ``exception`` with702                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams703                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams704705                    true706707            interface ILogProvider with708                member this.GetLogger(name: string) : Logger = getLoggerByName name |> writeMessage709710                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =711                    pushProperty key value destructure712713                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false714715        let create () = SeriLogProvider() :> ILogProvider716651                let isEnabled =652                    Expression653                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)654                        .Compile()655656                let writeMethodInfo =657                    loggerType.GetMethod(658                        "Write",659                        [|660                            logEventLevelType661                            typedefof<string>662                            typedefof<obj[]>663                        |]664                    )665666                let messageParam = Expression.Parameter(typedefof<string>)667                let propertyValuesParam = Expression.Parameter(typedefof<obj[]>)668669                let writeMethodExp =670                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)671672                let expression =673                    Expression.Lambda<Action<obj, obj, string, obj[]>>(674                        writeMethodExp,675                        instanceParam,676                        levelParam,677                        messageParam,678                        propertyValuesParam679                    )680681                let write = expression.Compile()682683                let writeExceptionMethodInfo =684                    loggerType.GetMethod(685                        "Write",686                        [|687                            logEventLevelType688                            typedefof<exn>689                            typedefof<string>690                            typedefof<obj[]>691                        |]692                    )693694                let exceptionParam = Expression.Parameter(typedefof<exn>)695696                let writeMethodExp =697                    Expression.Call(698                        instanceCast,699                        writeExceptionMethodInfo,700                        levelCast,701                        exceptionParam,702                        messageParam,703                        propertyValuesParam704                    )705706                let writeException =707                    Expression708                        .Lambda<Action<obj, obj, exn, string, obj[]>>(709                            writeMethodExp,710                            instanceParam,711                            levelParam,712                            exceptionParam,713                            messageParam,714                            propertyValuesParam715                        )716                        .Compile()  717718    module MicrosoftExtensionsLoggingProvider =719        open System720        open System.Linq.Expressions721        open System.Reflection722        open System.Collections.Generic723724        type ILoggerFactory = obj725        // This has to be set from usercode for this to light up726        let mutable private  microsoftLoggerFactory : ILoggerFactory option = None727        let setMicrosoftLoggerFactory (factory : ILoggerFactory) = microsoftLoggerFactory <- Option.ofObj factory728729        let getLogFactoryType = lazy(Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Log730        let isAvailable () =731            getLogFactoryType.Value |> isNull |> not732            && microsoftLoggerFactory |> Option.isSome733718                {719                    Write =720                        (fun logger level message formattedParmeters ->721                            write.Invoke(logger, level, message, formattedParmeters)722                        )723                    WriteException =724                        fun logger level ex message formattedParmeters ->725                            writeException.Invoke(logger, level, ex, message, formattedParmeters)726                    IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)727                    TranslateLevel = translateLevel728                }729730        type private SeriLogProvider() =731            let getLoggerByName = getForContextMethodCall ()732            let pushProperty = getPushProperty ()733            let serilogGatewayInit = lazy (SerilogGateway.Create())  734735        type ILogger = obj736        type LoggerName = string737        type MicrosoftLogLevel = obj738        type MessageFormat = string739        type MessageArgs = obj array740741        [<NoEquality; NoComparison>]742        type LoggerFactoryGateway = {743            CreateLogger : ILoggerFactory -> LoggerName -> ILogger744        }745        with746            static member Create() =747                let createLogger =748                    let factoryType = getLogFactoryType.Value749                    let createLoggerMethodInfo =750                        factoryType.GetMethod(751                            "CreateLogger",752                            [|typedefof<string>|])753                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)754                    let nameParam = Expression.Parameter(typedefof<string>)755                    let instanceCast =756                        Expression.Convert(instanceParam, factoryType)757                    let createLoggerMethodExp =758                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)759                    let createLogger =760                        Expression761                            .Lambda<Func<ILoggerFactory,string,ILogger>>(createLoggerMethodExp, instanceParam, nameParam762                            .Compile()763                    createLogger764                    |> FuncConvert.FromFunc765                {766                    CreateLogger = createLogger767                }768769        type LoggerGateway = {770            Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit771            WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit772            IsEnabled: ILogger -> MicrosoftLogLevel -> bool773            TranslateLevel : LogLevel -> MicrosoftLogLevel774            BeginScope : ILogger -> obj -> IDisposable775        } with776            static member Create () =777                let loggerExtensions = Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions778                let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstra779                let logEventLevelType =780                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")781                let instanceParam = Expression.Parameter(typedefof<ILogger>)735            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =736                let serilogGateway = serilogGatewayInit.Value737                let translatedValue = serilogGateway.TranslateLevel logLevel738739                match messageFunc with740                | None -> serilogGateway.IsEnabled logger translatedValue741                | Some _ when742                    serilogGateway.IsEnabled logger translatedValue743                    |> not744                    ->745                    false746                | Some m ->747                    match ``exception`` with748                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams749                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams750751                    true752753            interface ILogProvider with754                member this.GetLogger(name: string) : Logger =755                    getLoggerByName name756                    |> writeMessage757758                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =759                    pushProperty key value destructure760761                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false762763        let create () = SeriLogProvider() :> ILogProvider764765766    module MicrosoftExtensionsLoggingProvider =767        open System768        open System.Linq.Expressions769        open System.Reflection770        open System.Collections.Generic771772        type ILoggerFactory = obj773        // This has to be set from usercode for this to light up774        let mutable private microsoftLoggerFactory: ILoggerFactory option = None775776        let setMicrosoftLoggerFactory (factory: ILoggerFactory) =777            microsoftLoggerFactory <- Option.ofObj factory778779        let getLogFactoryType =780            lazy781                (Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.Abstractions"))  782783                let instanceCast =784                    Expression.Convert(instanceParam, loggerType)785                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)786787                let levelCast = Expression.Convert(levelParam, logEventLevelType)788789                let isEnabled =790                    let isEnabledMethodInfo =791                        loggerType.GetMethod("IsEnabled", [| logEventLevelType |])792                    let isEnabledMethodCall =793                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)794795796                    Expression797                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)798                        .Compile()799                    |> FuncConvert.FromFunc800801                let write, writeError =802                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)803                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)804805                    let write =806                        let writeMethodInfo =807                            loggerExtensions.GetMethod(808                                "Log",809                                BindingFlags.Static ||| BindingFlags.Public,810                                null,811                                [| loggerType812                                   logEventLevelType813                                   typedefof<MessageFormat>814                                   typedefof<MessageArgs> |],815                                null816                            )817818                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, messagePara819820                        let expression =821                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(822                                writeMethodExp,823                                instanceParam,824                                levelParam,825                                messageParam,826                                propertyValuesParam827                            )828                        expression.Compile() |> FuncConvert.FromAction829783        let isAvailable () =784            getLogFactoryType.Value785            |> isNull786            |> not787            && microsoftLoggerFactory788               |> Option.isSome789790791        type ILogger = obj792        type LoggerName = string793        type MicrosoftLogLevel = obj794        type MessageFormat = string795        type MessageArgs = obj array796797        [<NoEquality; NoComparison>]798        type LoggerFactoryGateway =799            {800                CreateLogger: ILoggerFactory -> LoggerName -> ILogger801            }802803            static member Create() =804                let createLogger =805                    let factoryType = getLogFactoryType.Value806807                    let createLoggerMethodInfo =808                        factoryType.GetMethod("CreateLogger", [| typedefof<string> |])809810                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)811                    let nameParam = Expression.Parameter(typedefof<string>)812                    let instanceCast = Expression.Convert(instanceParam, factoryType)813814                    let createLoggerMethodExp =815                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)816817                    let createLogger =818                        Expression819                            .Lambda<Func<ILoggerFactory, string, ILogger>>(820                                createLoggerMethodExp,821                                instanceParam,822                                nameParam823                            )824                            .Compile()825826                    createLogger827                    |> FuncConvert.FromFunc828829                { CreateLogger = createLogger }  830831                    let writeError =832                        let writeMethodInfo =833                            loggerExtensions.GetMethod(834                                "Log",835                                BindingFlags.Static ||| BindingFlags.Public,836                                null,837                                [| loggerType838                                   logEventLevelType839                                   typedefof<exn>840                                   typedefof<MessageFormat>841                                   typedefof<MessageArgs> |],842                                null843844                            )845                        let exnParam = Expression.Parameter(typedefof<exn>)846                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, exnParam, m847848                        let expression =849                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(850                                writeMethodExp,851                                instanceParam,852                                levelParam,853                                exnParam,854                                messageParam,855                                propertyValuesParam856                            )857                        expression.Compile() |> FuncConvert.FromAction858                    write, writeError859860                let translateLevel =831        type LoggerGateway =832            {833                Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit834                WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit835                IsEnabled: ILogger -> MicrosoftLogLevel -> bool836                TranslateLevel: LogLevel -> MicrosoftLogLevel837                BeginScope: ILogger -> obj -> IDisposable838            }839840            static member Create() =841                let loggerExtensions =842                    Type.GetType(843                        "Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions"844                    )845846                let loggerType =847                    Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")848849                let logEventLevelType =850                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")851852                let instanceParam = Expression.Parameter(typedefof<ILogger>)853854                let instanceCast = Expression.Convert(instanceParam, loggerType)855                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)856857                let levelCast = Expression.Convert(levelParam, logEventLevelType)858859                let isEnabled =860                    let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  861862                    let debugLevel =863                        Enum.Parse(logEventLevelType, "Debug", false)862                    let isEnabledMethodCall =863                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  864865                    let errorLevel =866                        Enum.Parse(logEventLevelType, "Error", false)867868                    let criticalLevel =869                        Enum.Parse(logEventLevelType, "Critical", false)865866                    Expression867                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)868                        .Compile()869                    |> FuncConvert.FromFunc  870871                    let informationLevel =872                        Enum.Parse(logEventLevelType, "Information", false)873874                    let traceLevel =875                        Enum.Parse(logEventLevelType, "Trace", false)876877                    let warningLevel =878                        Enum.Parse(logEventLevelType, "Warning", false)879880                    fun (level: LogLevel) ->881                        match level with882                        | LogLevel.Fatal -> criticalLevel883                        | LogLevel.Error -> errorLevel884                        | LogLevel.Warn -> warningLevel885                        | LogLevel.Info -> informationLevel886                        | LogLevel.Debug -> debugLevel887                        | LogLevel.Trace -> traceLevel888                        | _ -> debugLevel889                let beginScope =890                    let beginScopeMethodInfo =891                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)892                    let stateParam = Expression.Parameter(typedefof<obj>)893                    let beginScopeMethodCall =894                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)895896                    Expression897                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)898                        .Compile()899                    |> FuncConvert.FromFunc871                let write, writeError =872                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)873                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)874875                    let write =876                        let writeMethodInfo =877                            loggerExtensions.GetMethod(878                                "Log",879                                BindingFlags.Static880                                ||| BindingFlags.Public,881                                null,882                                [|883                                    loggerType884                                    logEventLevelType885                                    typedefof<MessageFormat>886                                    typedefof<MessageArgs>887                                |],888                                null889                            )890891                        let writeMethodExp =892                            Expression.Call(893                                null,894                                writeMethodInfo,895                                instanceCast,896                                levelCast,897                                messageParam,898                                propertyValuesParam899                            )  900901                {902                    Write = write903                    WriteError = writeError904                    IsEnabled = isEnabled905                    TranslateLevel = translateLevel906                    BeginScope = beginScope907                }908901                        let expression =902                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(903                                writeMethodExp,904                                instanceParam,905                                levelParam,906                                messageParam,907                                propertyValuesParam908                            )  909910        type private MicrosoftProvider() =911            let factoryGateway = lazy(LoggerFactoryGateway.Create())912            let loggerGateway = lazy(LoggerGateway.Create())913            interface ILogProvider with914                member this.GetLogger(name: string) : Logger =915                    match microsoftLoggerFactory with916                    | None ->917                        fun _ _ _ _ -> false918                    | Some factory ->919                        let logger = factoryGateway.Value.CreateLogger factory name920921                        fun logLevel message exn args ->922                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel923                            match message with924                            | Some message ->925                                let message = message ()926                                match exn with927                                | Some ex ->928                                    loggerGateway.Value.WriteError logger microsoftLevel ex message args929                                | None ->930                                    loggerGateway.Value.Write logger microsoftLevel message args931                                true932                            | None ->933                                loggerGateway.Value.IsEnabled logger microsoftLevel934935                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =936                    match microsoftLoggerFactory with937                    | None ->938                        { new IDisposable with member x.Dispose () = ()}939                    | Some factory ->940                        // Create bogus logger that will propagate to a real logger later941                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())942                        // Requires a IEnumerable<KeyValuePair> to make sense943                        // https://nblumhardt.com/2016/11/ilogger-beginscope/944                        [KeyValuePair(key, value)]945                        |> box946                        |> loggerGateway.Value.BeginScope logger947948949                member this.OpenNestedContext(message: string) : IDisposable =950                    match microsoftLoggerFactory with951                    | None ->952                        { new IDisposable with member x.Dispose () = ()}953                    | Some factory ->954                        // Create bogus logger that will propagate to a real logger later955                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())956                        loggerGateway.Value.BeginScope logger (box message)910                        expression.Compile()911                        |> FuncConvert.FromAction912913914                    let writeError =915                        let writeMethodInfo =916                            loggerExtensions.GetMethod(917                                "Log",918                                BindingFlags.Static919                                ||| BindingFlags.Public,920                                null,921                                [|922                                    loggerType923                                    logEventLevelType924                                    typedefof<exn>925                                    typedefof<MessageFormat>926                                    typedefof<MessageArgs>927                                |],928                                null929930                            )931932                        let exnParam = Expression.Parameter(typedefof<exn>)933934                        let writeMethodExp =935                            Expression.Call(936                                null,937                                writeMethodInfo,938                                instanceCast,939                                levelCast,940                                exnParam,941                                messageParam,942                                propertyValuesParam943                            )944945                        let expression =946                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(947                                writeMethodExp,948                                instanceParam,949                                levelParam,950                                exnParam,951                                messageParam,952                                propertyValuesParam953                            )954955                        expression.Compile()956                        |> FuncConvert.FromAction  957958        let create () = MicrosoftProvider() :> ILogProvider958                    write, writeError  959960#endif960                let translateLevel =  961962963module LogProvider =964    open System965    open Types966    #if !FABLE_COMPILER967    open Providers968    #endif969    open System.Diagnostics970    open Microsoft.FSharp.Quotations.Patterns962                    let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)963964                    let errorLevel = Enum.Parse(logEventLevelType, "Error", false)965966                    let criticalLevel = Enum.Parse(logEventLevelType, "Critical", false)967968                    let informationLevel = Enum.Parse(logEventLevelType, "Information", false)969970                    let traceLevel = Enum.Parse(logEventLevelType, "Trace", false)  971972    let mutable private currentLogProvider = None972                    let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)  973974    let private knownProviders =975        [976        #if !FABLE_COMPILER - 0977            (SerilogProvider.isAvailable, SerilogProvider.create) - 0978            (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)979        #endif980        ]981982    /// Greedy search for first available LogProvider. Order of known providers matters.983    let private resolvedLogger =984        lazy - 0985            (knownProviders - 0986             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ()) - 0987             |> Option.map (fun (_, create) -> create ()))988 - 0989    let private noopLogger _ _ _ _ = false990991    let private noopDisposable =992        { new IDisposable with - 0993            member __.Dispose() = () }994995    /// <summary>996    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.997    /// </summary>998    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>999    /// <returns></returns> - 01000    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider10011002    /// <summary>1003    /// Gets the currently set LogProvider or attempts to find known built in providers1004    /// </summary>1005    /// <returns></returns>1006    let getCurrentLogProvider () = - 01007        match currentLogProvider with - 01008        | None -> resolvedLogger.Value - 01009        | Some p -> Some p974                    fun (level: LogLevel) ->975                        match level with976                        | LogLevel.Fatal -> criticalLevel977                        | LogLevel.Error -> errorLevel978                        | LogLevel.Warn -> warningLevel979                        | LogLevel.Info -> informationLevel980                        | LogLevel.Debug -> debugLevel981                        | LogLevel.Trace -> traceLevel982                        | _ -> debugLevel983984                let beginScope =985                    let beginScopeMethodInfo =986                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)987988                    let stateParam = Expression.Parameter(typedefof<obj>)989990                    let beginScopeMethodCall =991                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)992993                    Expression994                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)995                        .Compile()996                    |> FuncConvert.FromFunc997998                {999                    Write = write1000                    WriteError = writeError1001                    IsEnabled = isEnabled1002                    TranslateLevel = translateLevel1003                    BeginScope = beginScope1004                }100510061007        type private MicrosoftProvider() =1008            let factoryGateway = lazy (LoggerFactoryGateway.Create())1009            let loggerGateway = lazy (LoggerGateway.Create())  10101011    /// <summary>1012    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1013    /// </summary>1014    /// <param name="key">The name of the property.</param>1015    /// <param name="value">The value of the property.</param>1016    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1017    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1018    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) = - 01019        let provider = getCurrentLogProvider ()1011            interface ILogProvider with1012                member this.GetLogger(name: string) : Logger =1013                    match microsoftLoggerFactory with1014                    | None -> fun _ _ _ _ -> false1015                    | Some factory ->1016                        let logger = factoryGateway.Value.CreateLogger factory name10171018                        fun logLevel message exn args ->1019                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel  1020 - 01021        match provider with - 01022        | Some p -> p.OpenMappedContext key value destructureObjects - 01023        | None -> noopDisposable1021                            match message with1022                            | Some message ->1023                                let message = message ()  102410251026    /// <summary>1027    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1028    /// </summary>1029    /// <param name="key">The name of the property.</param>1030    /// <param name="value">The value of the property.</param>1031    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1032    let openMappedContext (key: string) (value: obj) =1033        //TODO: We should try to find out if the value is a primitive - 01034        openMappedContextDestucturable key value false103510361037    /// <summary>1038    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1039    /// </summary>1040    /// <param name="value">The value of the property</param>1041    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1042    let openNestedContext (value: string) = - 01043        let provider = getCurrentLogProvider ()1044 - 01045        match provider with - 01046        | Some p -> p.OpenNestedContext value - 01047        | None -> noopDisposable10481049    /// <summary>1050    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1051    /// </summary>1052    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1053    /// <returns></returns>1054    let getLoggerByName (name: string) = - 01055        let loggerProvider = getCurrentLogProvider ()10561057        let logFunc = - 01058            match loggerProvider with - 01059            | Some loggerProvider -> loggerProvider.GetLogger(name) - 01060            | None -> noopLogger1025                                match exn with1026                                | Some ex -> loggerGateway.Value.WriteError logger microsoftLevel ex message args1027                                | None -> loggerGateway.Value.Write logger microsoftLevel message args10281029                                true1030                            | None -> loggerGateway.Value.IsEnabled logger microsoftLevel10311032                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =1033                    match microsoftLoggerFactory with1034                    | None ->1035                        { new IDisposable with1036                            member x.Dispose() = ()1037                        }1038                    | Some factory ->1039                        // Create bogus logger that will propagate to a real logger later1040                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1041                        // Requires a IEnumerable<KeyValuePair> to make sense1042                        // https://nblumhardt.com/2016/11/ilogger-beginscope/1043                        [ KeyValuePair(key, value) ]1044                        |> box1045                        |> loggerGateway.Value.BeginScope logger104610471048                member this.OpenNestedContext(message: string) : IDisposable =1049                    match microsoftLoggerFactory with1050                    | None ->1051                        { new IDisposable with1052                            member x.Dispose() = ()1053                        }1054                    | Some factory ->1055                        // Create bogus logger that will propagate to a real logger later1056                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())10571058                        loggerGateway.Value.BeginScope logger (box message)10591060        let create () = MicrosoftProvider() :> ILogProvider  1061 - 01062        { new ILog with - 01063            member x.Log = logFunc - 01064            member x.MappedContext = openMappedContextDestucturable }10651066    /// <summary>1067    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1068    /// </summary>1069    /// <param name="objectType">The type to generate a logger name from. </param>1070    /// <returns></returns> - 01071    let getLoggerByType (objectType: Type) = objectType |> string |> getLoggerByName10721073    /// <summary>1074    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1075    /// </summary>1076    /// <typeparam name="'a">The type to generate a name from.</typeparam>1077    /// <returns></returns> - 01078    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)10791080#if !FABLE_COMPILER1081    let rec private getModuleType =1082        function - 01083        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1084        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1085        // | Lambda(_, expr) -> getModuleType expr1086        // | ValueWithName(_,_,instance) -> instance - 01087        | x -> failwithf "Expression is not a property. %A" x10881062#endif106310641065module LogProvider =1066    open System1067    open Types1068#if !FABLE_COMPILER1069    open Providers1070#endif1071    open System.Diagnostics1072    open Microsoft.FSharp.Quotations.Patterns10731074    let mutable private currentLogProvider = None10751076    let private knownProviders = [1077#if !FABLE_COMPILER1078        (SerilogProvider.isAvailable, SerilogProvider.create)1079        (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)1080#endif1081    ]10821083    /// Greedy search for first available LogProvider. Order of known providers matters.1084    let private resolvedLogger =1085        lazy + 01086            (knownProviders + 01087             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ()) + 01088             |> Option.map (fun (_, create) -> create ()))  10891090    /// <summary>1091    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1092    ///1093    /// It can be utilized like:1094    ///1095    /// <code>1096    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1097    /// </code>1098    ///1099    /// inside a module to get the modules full qualitfied name.1100    /// </summary>1101    /// <param name="quotation">The quotation to generate a logger name from.</param>1102    /// <returns></returns>1103    let getLoggerByQuotation (quotation: Quotations.Expr) = - 01104        getModuleType quotation |> getLoggerByType110511061107type LogProvider =1108    /// <summary>1109    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1110    /// </summary>1111    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1112    /// <returns></returns>1113    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1114        let mi = System.Reflection.MethodBase.GetCurrentMethod()1115        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1116        // CallerMemberName gets us the function that actually called it1117        // Splitting off + seems like the best option to get the Fully Qualified Path1118        let location = mi.DeclaringType.FullName.Split('+') |> Seq.tryHead |> Option.defaultValue ""1119        sprintf "%s.%s" location memberName.Value1120        |> LogProvider.getLoggerByName11211122#endif + 01090    let private noopLogger _ _ _ _ = false10911092    let private noopDisposable =1093        { new IDisposable with + 01094            member __.Dispose() = ()1095        }10961097    /// <summary>1098    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.1099    /// </summary>1100    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>1101    /// <returns></returns> + 01102    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider11031104    /// <summary>1105    /// Gets the currently set LogProvider or attempts to find known built in providers1106    /// </summary>1107    /// <returns></returns>1108    let getCurrentLogProvider () = + 01109        match currentLogProvider with + 01110        | None -> resolvedLogger.Value + 01111        | Some p -> Some p11121113    /// <summary>1114    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1115    /// </summary>1116    /// <param name="key">The name of the property.</param>1117    /// <param name="value">The value of the property.</param>1118    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1119    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1120    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) = + 01121        let provider = getCurrentLogProvider ()1122 + 01123        match provider with + 01124        | Some p -> p.OpenMappedContext key value destructureObjects + 01125        | None -> noopDisposable112611271128    /// <summary>1129    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1130    /// </summary>1131    /// <param name="key">The name of the property.</param>1132    /// <param name="value">The value of the property.</param>1133    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1134    let openMappedContext (key: string) (value: obj) =1135        //TODO: We should try to find out if the value is a primitive + 01136        openMappedContextDestucturable key value false113711381139    /// <summary>1140    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1141    /// </summary>1142    /// <param name="value">The value of the property</param>1143    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1144    let openNestedContext (value: string) = + 01145        let provider = getCurrentLogProvider ()1146 + 01147        match provider with + 01148        | Some p -> p.OpenNestedContext value + 01149        | None -> noopDisposable11501151    /// <summary>1152    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1153    /// </summary>1154    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1155    /// <returns></returns>1156    let getLoggerByName (name: string) = + 01157        let loggerProvider = getCurrentLogProvider ()11581159        let logFunc = + 01160            match loggerProvider with + 01161            | Some loggerProvider -> loggerProvider.GetLogger(name) + 01162            | None -> noopLogger1163 + 01164        { new ILog with + 01165            member x.Log = logFunc + 01166            member x.MappedContext = openMappedContextDestucturable + 01167        }11681169    /// <summary>1170    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1171    /// </summary>1172    /// <param name="objectType">The type to generate a logger name from. </param>1173    /// <returns></returns>1174    let getLoggerByType (objectType: Type) = + 01175        objectType + 01176        |> string + 01177        |> getLoggerByName11781179    /// <summary>1180    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1181    /// </summary>1182    /// <typeparam name="'a">The type to generate a name from.</typeparam>1183    /// <returns></returns> + 01184    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)11851186#if !FABLE_COMPILER1187    let rec private getModuleType =1188        function + 01189        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1190        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1191        // | Lambda(_, expr) -> getModuleType expr1192        // | ValueWithName(_,_,instance) -> instance + 01193        | x -> failwithf "Expression is not a property. %A" x119411951196    /// <summary>1197    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1198    ///1199    /// It can be utilized like:1200    ///1201    /// <code>1202    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1203    /// </code>1204    ///1205    /// inside a module to get the modules full qualitfied name.1206    /// </summary>1207    /// <param name="quotation">The quotation to generate a logger name from.</param>1208    /// <returns></returns>1209    let getLoggerByQuotation (quotation: Quotations.Expr) = + 01210        getModuleType quotation + 01211        |> getLoggerByType121212131214type LogProvider =1215    /// <summary>1216    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1217    /// </summary>1218    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1219    /// <returns></returns>1220    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1221        let mi = System.Reflection.MethodBase.GetCurrentMethod()1222        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1223        // CallerMemberName gets us the function that actually called it1224        // Splitting off + seems like the best option to get the Fully Qualified Path1225        let location =1226            mi.DeclaringType.FullName.Split('+')1227            |> Seq.tryHead1228            |> Option.defaultValue ""12291230        sprintf "%s.%s" location memberName.Value1231        |> LogProvider.getLoggerByName12321233#endif - +

Methods/Properties

-Invoke(Microsoft.FSharp.Core.Unit)
-Invoke(Microsoft.FSharp.Core.Unit)
-Invoke(Microsoft.FSharp.Core.Unit)
-Invoke(System.Tuple`2<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.Boolean>,Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,FsLibLog.Types/ILogProvider>>)
-Invoke(System.Tuple`2<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.Boolean>,Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,FsLibLog.Types/ILogProvider>>)
-noopLogger(a,b,c,d)
-System.IDisposable.Dispose()
-setLoggerProvider(FsLibLog.Types/ILogProvider)
-getCurrentLogProvider()
-openMappedContextDestucturable(System.String,System.Object,System.Boolean)
-openMappedContext(System.String,System.Object)
-openNestedContext(System.String)
-getLoggerByName(System.String)
-Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
-FsLibLog.Types.ILog.get_Log()
-Invoke(System.String,System.Object,System.Boolean)
-FsLibLog.Types.ILog.get_MappedContext()
-getLoggerByType(System.Type)
-getLoggerFor()
-getModuleType(Microsoft.FSharp.Quotations.FSharpExpr)
-getLoggerByQuotation(Microsoft.FSharp.Quotations.FSharpExpr)
+Invoke(Microsoft.FSharp.Core.Unit)
+Invoke(System.Tuple`2<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.Boolean>,Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,FsLibLog.Types/ILogProvider>>)
+Invoke(System.Tuple`2<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.Boolean>,Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,FsLibLog.Types/ILogProvider>>)
+noopLogger(a,b,c,d)
+System.IDisposable.Dispose()
+setLoggerProvider(FsLibLog.Types/ILogProvider)
+getCurrentLogProvider()
+openMappedContextDestucturable(System.String,System.Object,System.Boolean)
+openMappedContext(System.String,System.Object)
+openNestedContext(System.String)
+getLoggerByName(System.String)
+FsLibLog.Types.ILog.get_Log()
+FsLibLog.Types.ILog.get_MappedContext()
+getLoggerByType(System.Type)
+getLoggerFor()
+getModuleType(Microsoft.FSharp.Quotations.FSharpExpr)
+getLoggerByQuotation(Microsoft.FSharp.Quotations.FSharpExpr)

diff --git a/docs/coverage/FsLibLog_Operators.htm b/docs/coverage/FsLibLog_Operators.htm index 343015e..1416207 100644 --- a/docs/coverage/FsLibLog_Operators.htm +++ b/docs/coverage/FsLibLog_Operators.htm @@ -18,10 +18,10 @@

< Summary

Assembly:FsLibLog File(s):C:\Users\jimmy\Repositories\public\TheAngryByrd\FsLibLog\src\FsLibLog\FsLibLog.fs Covered lines:0 -Uncovered lines:5 -Coverable lines:5 -Total lines:1122 -Line coverage:0% (0 of 5) +Uncovered lines:9 +Coverable lines:9 +Total lines:1233 +Line coverage:0% (0 of 9) Covered branches:0 Total branches:0 @@ -30,20 +30,11 @@

Metrics

- - - - - - - - - - - - - - + + + + +
MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage Crap Score
op_BangBangBang(...)100%0%0
Invoke(...)100%0%0
op_GreaterGreaterBang(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
op_GreaterGreaterBangMinus(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
op_GreaterGreaterBangPlus(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
op_GreaterGreaterBangBang(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
op_BangBangBang(...)100%0%0
op_GreaterGreaterBang(...)100%0%0
op_GreaterGreaterBangMinus(...)100%0%0
op_GreaterGreaterBangPlus(...)100%0%0
op_GreaterGreaterBangBang(...)100%0%0

File(s)

@@ -81,1118 +72,1220 @@

 28    /// Type representing a Log  29    [<NoEquality; NoComparison>]  30    type Log =31        { LogLevel: LogLevel32          Message: MessageThunk33          Exception: exn option34          Parameters: obj list35          AdditionalNamedParameters: ((string * obj * bool) list) }36        static member StartLogLevel(logLevel: LogLevel) =37            { LogLevel = logLevel38              Message = None39              Exception = None40              Parameters = List.empty41              AdditionalNamedParameters = List.empty }4243    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio44    type ILog =45        abstract member Log :  Logger46        abstract member MappedContext :  MappedContext4748#if FABLE_COMPILER49    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)50    // is used instead.51    type Stack<'a>()  =52        let mutable contents = Array.zeroCreate<'a>(2)53        let mutable count = 05455        member buf.Ensure newSize =56            let oldSize = contents.Length57            if newSize > oldSize then58                let old = contents59                contents <- Array.zeroCreate (max newSize (oldSize * 2))60                Array.blit old 0 contents 0 count31        {32            LogLevel: LogLevel33            Message: MessageThunk34            Exception: exn option35            Parameters: obj list36            AdditionalNamedParameters: ((string * obj * bool) list)37        }3839        static member StartLogLevel(logLevel: LogLevel) = {40            LogLevel = logLevel41            Message = None42            Exception = None43            Parameters = List.empty44            AdditionalNamedParameters = List.empty45        }4647    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio48    type ILog =49        abstract member Log: Logger50        abstract member MappedContext: MappedContext5152#if FABLE_COMPILER53    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)54    // is used instead.55    type Stack<'a>() =56        let mutable contents = Array.zeroCreate<'a> (2)57        let mutable count = 05859        member buf.Ensure newSize =60            let oldSize = contents.Length  6162        member buf.Count = count63        member buf.Pop() =64            let item = contents.[count - 1]65            count <- count - 166            item6768        member buf.Peep() = contents.[count - 1]69        member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev70        member buf.Push(x) =71            buf.Ensure(count + 1)72            contents.[count] <- x73            count <- count + 17475        member buf.IsEmpty = (count = 0)76#endif7778    [<AutoOpen>]79    module Inner =80#if !FABLE_COMPILER81        open System.Collections.Generic82#endif8384        /// <summary>85        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.86        /// </summary>87        type DisposableStack() =88            let stack = Stack<IDisposable>()8990            interface IDisposable with91                member __.Dispose() =92                    while stack.Count > 0 do93                        stack.Pop().Dispose()9495            member __.Push(item: IDisposable) = stack.Push item96            member __.Push(items: IDisposable list) = items |> List.iter stack.Push9798            static member Create(items: IDisposable list) =99                let ds = new DisposableStack()100                ds.Push items101                ds102103        type ILog with62            if newSize > oldSize then63                let old = contents64                contents <- Array.zeroCreate (max newSize (oldSize * 2))65                Array.blit old 0 contents 0 count6667        member buf.Count = count6869        member buf.Pop() =70            let item = contents.[count - 1]71            count <- count - 172            item7374        member buf.Peep() = contents.[count - 1]7576        member buf.Top(n) =77            [ for x in contents.[max 0 (count - n) .. count - 1] -> x ]78            |> List.rev7980        member buf.Push(x) =81            buf.Ensure(count + 1)82            contents.[count] <- x83            count <- count + 18485        member buf.IsEmpty = (count = 0)86#endif8788    [<AutoOpen>]89    module Inner =90#if !FABLE_COMPILER91        open System.Collections.Generic92#endif9394        /// <summary>95        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.96        /// </summary>97        type DisposableStack() =98            let stack = Stack<IDisposable>()99100            interface IDisposable with101                member __.Dispose() =102                    while stack.Count > 0 do103                        stack.Pop().Dispose()  104105            /// <summary>106            /// Logs a log107            /// </summary>108            /// <param name="log">The type representing a log message to be logged</param>109            /// <returns><see langword="true"/> if the log message was logged</returns>110            member logger.fromLog(log: Log) =111                use __ =112                    log.AdditionalNamedParameters113                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)114                    // This stack is important, it causes us to unwind as if you have multiple uses in a row115                    |> DisposableStack.Create116117                log.Parameters118                |> List.toArray119                |> logger.Log log.LogLevel log.Message log.Exception120121            /// <summary>122            /// Logs a fatal log message given a log configurer.123            /// </summary>124            /// <param name="logConfig">A function to configure a log</param>125            /// <returns><see langword="true"/>  if the log message was logged</returns>126            member logger.fatal'(logConfig: Log -> Log) =127                Log.StartLogLevel LogLevel.Fatal128                |> logConfig129                |> logger.fromLog130131            /// <summary>132            /// Logs a fatal log message given a log configurer.133            /// </summary>134            /// <param name="logConfig">A function to configure a log</param>135            member logger.fatal(logConfig: Log -> Log) = logger.fatal' logConfig |> ignore136137            /// <summary>138            /// Logs an error log message given a log configurer.139            /// </summary>140            /// <param name="logConfig">A function to configure a log</param>141            /// <returns><see langword="true"/>  if the log message was logged</returns>142            member logger.error'(logConfig: Log -> Log) =143                Log.StartLogLevel LogLevel.Error144                |> logConfig145                |> logger.fromLog146147            /// <summary>148            /// Logs an error log message given a log configurer.149            /// </summary>150            /// <param name="logConfig">A function to configure a log</param>151            member logger.error(logConfig: Log -> Log) = logger.error' logConfig |> ignore152153            /// <summary>154            /// Logs a warn log message given a log configurer.155            /// </summary>156            /// <param name="logConfig">A function to configure a log</param>157            /// <returns><see langword="true"/>  if the log message was logged</returns>158            member logger.warn'(logConfig: Log -> Log) =159                Log.StartLogLevel LogLevel.Warn160                |> logConfig161                |> logger.fromLog162163            /// <summary>164            /// Logs a warn log message given a log configurer.165            /// </summary>166            /// <param name="logConfig">A function to configure a log</param>167            member logger.warn(logConfig: Log -> Log) = logger.warn' logConfig |> ignore168169            /// <summary>170            /// Logs an info log message given a log configurer.171            /// </summary>172            /// <param name="logConfig">A function to configure a log</param>173            /// <returns><see langword="true"/>  if the log message was logged</returns>174            member logger.info'(logConfig: Log -> Log) =175                Log.StartLogLevel LogLevel.Info176                |> logConfig177                |> logger.fromLog178179            /// <summary>180            /// Logs an info log message given a log configurer.181            /// </summary>182            /// <param name="logConfig">A function to configure a log</param>183            member logger.info(logConfig: Log -> Log) = logger.info' logConfig |> ignore184185            /// <summary>186            /// Logs a debug log message given a log configurer.187            /// </summary>188            /// <param name="logConfig">A function to configure a log</param>189            /// <returns><see langword="true"/>  if the log message was logged</returns>190            member logger.debug'(logConfig: Log -> Log) =191                Log.StartLogLevel LogLevel.Debug192                |> logConfig193                |> logger.fromLog194195            /// <summary>196            /// Logs a debug log message given a log configurer.197            /// </summary>198            /// <param name="logConfig">A function to configure a log</param>199            member logger.debug(logConfig: Log -> Log) = logger.debug' logConfig |> ignore200201            /// <summary>202            /// Logs a trace log message given a log configurer.203            /// </summary>204            /// <param name="logConfig">A function to configure a log</param>205            /// <returns><see langword="true"/>  if the log message was logged</returns>206            member logger.trace'(logConfig: Log -> Log) =207                Log.StartLogLevel LogLevel.Trace208                |> logConfig209                |> logger.fromLog210211            /// <summary>212            /// Logs a trace log message given a log configurer.213            /// </summary>214            /// <param name="logConfig">A function to configure a log</param>215            member logger.trace(logConfig: Log -> Log) = logger.trace' logConfig |> ignore216217218    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.219    type ILogProvider =220        abstract member GetLogger : string -> Logger221        abstract member OpenNestedContext : string -> IDisposable222        abstract member OpenMappedContext : string -> obj -> bool -> IDisposable105            member __.Push(item: IDisposable) = stack.Push item106107            member __.Push(items: IDisposable list) =108                items109                |> List.iter stack.Push110111            static member Create(items: IDisposable list) =112                let ds = new DisposableStack()113                ds.Push items114                ds115116        type ILog with117118            /// <summary>119            /// Logs a log120            /// </summary>121            /// <param name="log">The type representing a log message to be logged</param>122            /// <returns><see langword="true"/> if the log message was logged</returns>123            member logger.fromLog(log: Log) =124                use __ =125                    log.AdditionalNamedParameters126                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)127                    // This stack is important, it causes us to unwind as if you have multiple uses in a row128                    |> DisposableStack.Create129130                log.Parameters131                |> List.toArray132                |> logger.Log log.LogLevel log.Message log.Exception133134            /// <summary>135            /// Logs a fatal log message given a log configurer.136            /// </summary>137            /// <param name="logConfig">A function to configure a log</param>138            /// <returns><see langword="true"/>  if the log message was logged</returns>139            member logger.fatal'(logConfig: Log -> Log) =140                Log.StartLogLevel LogLevel.Fatal141                |> logConfig142                |> logger.fromLog143144            /// <summary>145            /// Logs a fatal log message given a log configurer.146            /// </summary>147            /// <param name="logConfig">A function to configure a log</param>148            member logger.fatal(logConfig: Log -> Log) =149                logger.fatal' logConfig150                |> ignore151152            /// <summary>153            /// Logs an error log message given a log configurer.154            /// </summary>155            /// <param name="logConfig">A function to configure a log</param>156            /// <returns><see langword="true"/>  if the log message was logged</returns>157            member logger.error'(logConfig: Log -> Log) =158                Log.StartLogLevel LogLevel.Error159                |> logConfig160                |> logger.fromLog161162            /// <summary>163            /// Logs an error log message given a log configurer.164            /// </summary>165            /// <param name="logConfig">A function to configure a log</param>166            member logger.error(logConfig: Log -> Log) =167                logger.error' logConfig168                |> ignore169170            /// <summary>171            /// Logs a warn log message given a log configurer.172            /// </summary>173            /// <param name="logConfig">A function to configure a log</param>174            /// <returns><see langword="true"/>  if the log message was logged</returns>175            member logger.warn'(logConfig: Log -> Log) =176                Log.StartLogLevel LogLevel.Warn177                |> logConfig178                |> logger.fromLog179180            /// <summary>181            /// Logs a warn log message given a log configurer.182            /// </summary>183            /// <param name="logConfig">A function to configure a log</param>184            member logger.warn(logConfig: Log -> Log) =185                logger.warn' logConfig186                |> ignore187188            /// <summary>189            /// Logs an info log message given a log configurer.190            /// </summary>191            /// <param name="logConfig">A function to configure a log</param>192            /// <returns><see langword="true"/>  if the log message was logged</returns>193            member logger.info'(logConfig: Log -> Log) =194                Log.StartLogLevel LogLevel.Info195                |> logConfig196                |> logger.fromLog197198            /// <summary>199            /// Logs an info log message given a log configurer.200            /// </summary>201            /// <param name="logConfig">A function to configure a log</param>202            member logger.info(logConfig: Log -> Log) =203                logger.info' logConfig204                |> ignore205206            /// <summary>207            /// Logs a debug log message given a log configurer.208            /// </summary>209            /// <param name="logConfig">A function to configure a log</param>210            /// <returns><see langword="true"/>  if the log message was logged</returns>211            member logger.debug'(logConfig: Log -> Log) =212                Log.StartLogLevel LogLevel.Debug213                |> logConfig214                |> logger.fromLog215216            /// <summary>217            /// Logs a debug log message given a log configurer.218            /// </summary>219            /// <param name="logConfig">A function to configure a log</param>220            member logger.debug(logConfig: Log -> Log) =221                logger.debug' logConfig222                |> ignore  223224    module Log =225226        /// <summary>227        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.228        /// </summary>229        /// <param name="message">The message to set for the log.</param>230        /// <param name="log">The log to amend.</param>231        /// <returns>The amended log.</returns>232        let setMessage (message: string) (log: Log) =233            { log with234                  Message = Some(fun () -> message) }235236        /// <summary>237        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con238        /// </summary>239        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>240        /// <param name="log">The log to amend.</param>241        /// <returns>The amended log.</returns>242        let setMessageThunk (messageThunk: unit -> string) (log: Log) =243            { log with Message = Some messageThunk }244245        /// <summary>246        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.247        /// </summary>248        /// <param name="param">The value to add to the log</param>249        /// <param name="log">The log to amend.</param>250        /// <returns>The amended log.</returns>251        let addParameter (param: 'a) (log: Log) =252            { log with253                  Parameters = List.append log.Parameters [ (box param) ] }254255        /// <summary>256        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.257        /// </summary>258        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>259        /// <param name="log">The log to amend.</param>260        /// <returns>The amended log.</returns>261        let addParameters (``params``: obj list) (log: Log) =262            let ``params`` = ``params`` |> List.map box263264            { log with265                  Parameters = log.Parameters @ ``params`` }266267268269        /// <summary>270        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe271        /// This DOES NOT affect the parameters set for a message template.272        /// This is the same calling OpenMappedContext right before logging.224            /// <summary>225            /// Logs a trace log message given a log configurer.226            /// </summary>227            /// <param name="logConfig">A function to configure a log</param>228            /// <returns><see langword="true"/>  if the log message was logged</returns>229            member logger.trace'(logConfig: Log -> Log) =230                Log.StartLogLevel LogLevel.Trace231                |> logConfig232                |> logger.fromLog233234            /// <summary>235            /// Logs a trace log message given a log configurer.236            /// </summary>237            /// <param name="logConfig">A function to configure a log</param>238            member logger.trace(logConfig: Log -> Log) =239                logger.trace' logConfig240                |> ignore241242243    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.244    type ILogProvider =245        abstract member GetLogger: string -> Logger246        abstract member OpenNestedContext: string -> IDisposable247        abstract member OpenMappedContext: string -> obj -> bool -> IDisposable248249    module Log =250251        /// <summary>252        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.253        /// </summary>254        /// <param name="message">The message to set for the log.</param>255        /// <param name="log">The log to amend.</param>256        /// <returns>The amended log.</returns>257        let setMessage (message: string) (log: Log) =258            { log with259                Message = Some(fun () -> message)260            }261262        /// <summary>263        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con264        /// </summary>265        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>266        /// <param name="log">The log to amend.</param>267        /// <returns>The amended log.</returns>268        let setMessageThunk (messageThunk: unit -> string) (log: Log) =269            { log with Message = Some messageThunk }270271        /// <summary>272        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.  273        /// </summary>274        /// <param name="key">The key of the parameter to add to the log.</param>275        /// <param name="value">The value of the parameter to add to the log.</param>276        /// <param name="log">The log to amend.</param>277        /// <returns>The amended log.</returns>278        let addContext (key: string) (value: obj) (log: Log) =279            { log with280                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] }274        /// <param name="param">The value to add to the log</param>275        /// <param name="log">The log to amend.</param>276        /// <returns>The amended log.</returns>277        let addParameter (param: 'a) (log: Log) =278            { log with279                Parameters = List.append log.Parameters [ (box param) ]280            }  281282283        /// <summary>284        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe285        /// This DOES NOT affect the parameters set for a message template.286        /// This is the same calling OpenMappedContext right before logging.287        /// This destructures an object rather than calling `ToString()` on it.288        /// WARNING: Destructring can be expensive.289        /// </summary>290        /// <param name="key">The key of the parameter to add to the log.</param>291        /// <param name="value">The value of the parameter to add to the log.</param>292        /// <param name="log">The log to amend.</param>293        /// <returns>The amended log.</returns>294        let addContextDestructured (key: string) (value: obj) (log: Log) =295            { log with296                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] }297282        /// <summary>283        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.284        /// </summary>285        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>286        /// <param name="log">The log to amend.</param>287        /// <returns>The amended log.</returns>288        let addParameters (``params``: obj list) (log: Log) =289            let ``params`` =290                ``params``291                |> List.map box292293            { log with294                Parameters =295                    log.Parameters296                    @ ``params``297            }  298299        /// <summary>300        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle301        /// </summary>302        /// <param name="exception">The exception to add to the log.</param>303        /// <param name="log">The log to amend.</param>304        /// <returns>The amended log.</returns>305        let addException (``exception``: exn) (log: Log) =306            { log with307                  Exception = Option.ofObj ``exception`` }308309        /// <summary>310        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle311        /// </summary>312        /// <param name="exception">The exception to add to the log.</param>313        /// <param name="log">The log to amend.</param>314        /// <returns>The amended log.</returns>315        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log316317        /// <summary>318        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe319        /// </summary>320        /// <param name="logLevel">The level to set for the log.</param>321        /// <param name="log">The log to amend.</param>322        /// <returns>The amended log.</returns>323        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }324325#if !FABLE_COMPILER326327        let private formatterRegex =328            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)329330        let private isAnObject value =331            Convert.GetTypeCode(value) = TypeCode.Object332333        /// <summary>334        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m335        ///336        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr337        /// </summary>338        /// <param name="message">An interpolated string</param>339        /// <param name="log">The log to amend.</param>340        /// <returns>The amended log.</returns>341        let setMessageInterpolated (message: FormattableString) (log: Log) =342            let mutable messageFormat = message.Format343344            let args =345                formatterRegex.Matches(messageFormat)346                |> Seq.cast<Match>347                |> Seq.map348                    (fun m ->349                        let number = Int32.Parse(m.Groups.["number"].Value)350                        let formatGroup = m.Groups.["format"]351                        let propertyValue = message.GetArgument(number)352                        let propertyName = formatGroup.Value353                        let columnFormatGroup = m.Groups.["columnFormat"]354                        propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length355                        )356            // Reverse the args so we won't change the indexes earlier in the string357            args358            |> Seq.rev359            |> Seq.iter360                (fun (_, _, removeStart, removeLength) ->361                    if removeLength > 0 then362                        messageFormat <- messageFormat.Remove(removeStart, removeLength))299300        /// <summary>301        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe302        /// This DOES NOT affect the parameters set for a message template.303        /// This is the same calling OpenMappedContext right before logging.304        /// </summary>305        /// <param name="key">The key of the parameter to add to the log.</param>306        /// <param name="value">The value of the parameter to add to the log.</param>307        /// <param name="log">The log to amend.</param>308        /// <returns>The amended log.</returns>309        let addContext (key: string) (value: obj) (log: Log) =310            { log with311                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ]312            }313314315        /// <summary>316        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe317        /// This DOES NOT affect the parameters set for a message template.318        /// This is the same calling OpenMappedContext right before logging.319        /// This destructures an object rather than calling `ToString()` on it.320        /// WARNING: Destructring can be expensive.321        /// </summary>322        /// <param name="key">The key of the parameter to add to the log.</param>323        /// <param name="value">The value of the parameter to add to the log.</param>324        /// <param name="log">The log to amend.</param>325        /// <returns>The amended log.</returns>326        let addContextDestructured (key: string) (value: obj) (log: Log) =327            { log with328                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ]329            }330331332        /// <summary>333        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle334        /// </summary>335        /// <param name="exception">The exception to add to the log.</param>336        /// <param name="log">The log to amend.</param>337        /// <returns>The amended log.</returns>338        let addException (``exception``: exn) (log: Log) =339            { log with340                Exception = Option.ofObj ``exception``341            }342343        /// <summary>344        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle345        /// </summary>346        /// <param name="exception">The exception to add to the log.</param>347        /// <param name="log">The log to amend.</param>348        /// <returns>The amended log.</returns>349        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log350351        /// <summary>352        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe353        /// </summary>354        /// <param name="logLevel">The level to set for the log.</param>355        /// <param name="log">The log to amend.</param>356        /// <returns>The amended log.</returns>357        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }358359#if !FABLE_COMPILER360361        let private formatterRegex =362            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)  363364            let namedArgs =365                args366                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")367                |> Seq.toArray368369            messageFormat <-370                messageFormat371                    .Replace("{{", "{{{{")372                    .Replace("}}", "}}}}")373            // Replace numbered args with named args from regex match374            messageFormat <- String.Format(messageFormat, args = namedArgs)375376            let addContexts args (log: Log) =377                let addArgsToContext =378                    (id, args)379                    ||> Seq.fold380                            (fun state (name, value, _, _) ->381                                let contextAdder =382                                    if value |> isAnObject then383                                        addContextDestructured384                                    else385                                        addContext386387                                state >> contextAdder name value)388389                addArgsToContext log390391            log392            |> setMessage messageFormat393            |> addContexts args394395        /// <summary>396        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m397        ///398        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr399        /// </summary>400        /// <param name="message">An interpolated string</param>401        /// <param name="log">The log to amend.</param>402        /// <returns>The amended log.</returns>403        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log404#endif364        let private isAnObject value =365            Convert.GetTypeCode(value) = TypeCode.Object366367        /// <summary>368        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m369        ///370        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr371        /// </summary>372        /// <param name="message">An interpolated string</param>373        /// <param name="log">The log to amend.</param>374        /// <returns>The amended log.</returns>375        let setMessageInterpolated (message: FormattableString) (log: Log) =376            let mutable messageFormat = message.Format377378            let args =379                formatterRegex.Matches(messageFormat)380                |> Seq.cast<Match>381                |> Seq.map (fun m ->382                    let number = Int32.Parse(m.Groups.["number"].Value)383                    let formatGroup = m.Groups.["format"]384                    let propertyValue = message.GetArgument(number)385                    let propertyName = formatGroup.Value386                    let columnFormatGroup = m.Groups.["columnFormat"]387                    propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length388                )389            // Reverse the args so we won't change the indexes earlier in the string390            args391            |> Seq.rev392            |> Seq.iter (fun (_, _, removeStart, removeLength) ->393                if removeLength > 0 then394                    messageFormat <- messageFormat.Remove(removeStart, removeLength)395            )396397            let namedArgs =398                args399                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")400                |> Seq.toArray401402            messageFormat <- messageFormat.Replace("{{", "{{{{").Replace("}}", "}}}}")403            // Replace numbered args with named args from regex match404            messageFormat <- String.Format(messageFormat, args = namedArgs)  405406/// Provides operators to make writing logs more streamlined.407module Operators =408409    /// <summary>410    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.411    /// </summary>412    /// <param name="message">The string of the base message.</param>413    /// <returns>A new Log instance with the specified message.</returns> - 0414    let (!!!) message = Log.setMessage message406            let addContexts args (log: Log) =407                let addArgsToContext =408                    (id, args)409                    ||> Seq.fold (fun state (name, value, _, _) ->410                        let contextAdder =411                            if value |> isAnObject then412                                addContextDestructured413                            else414                                addContext  415416    /// <summary>417    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<418    /// </summary>419    /// <param name="log">The Log to add the parameter to.</param>420    /// <param name="value">The value for the parameter.</param>421    /// <returns>The Log with the added parameter.</returns> - 0422    let (>>!) log value = log >> Log.addParameter value423424    /// <summary>425    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.426    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right427    ///428    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.429    /// </summary>430    /// <param name="log">The log to add the parameter to.</param>431    /// <param name="key">The name for the parameter.</param>432    /// <param name="value">The value for the parameter.</param>433    /// <returns>The amended log with the parameter added.</returns> - 0434    let (>>!-) log (key, value) = log >> Log.addContext key value435436    /// <summary>437    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT438    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling439    ///440    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.441    /// </summary>442    /// <param name="log">The log to add the parameter to.</param>443    /// <param name="key">The name for the parameter.</param>444    /// <param name="value">The value for the parameter.</param>445    /// <returns>The amended log with the parameter added.</returns>446    let (>>!+) log (key, value) = - 0447        log >> Log.addContextDestructured key value448449    /// <summary>450    /// Amends a Log with an exn. Handles nulls.451    ///452    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.453    /// </summary>454    /// <param name="log">The log to add the parameter to.</param>455    /// <param name="e">The exception to add to the log.</param>456    /// <returns>The amended log with the parameter added.</returns> - 0457    let (>>!!) log e = log >> Log.addException e458459460#if !FABLE_COMPILER461module Providers =462    module SerilogProvider =463        open System464        open System.Linq.Expressions465466        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")467        let isAvailable () = getLogManagerType () |> isNull |> not468469        let getPushProperty () =416                        state417                        >> contextAdder name value418                    )419420                addArgsToContext log421422            log423            |> setMessage messageFormat424            |> addContexts args425426        /// <summary>427        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m428        ///429        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr430        /// </summary>431        /// <param name="message">An interpolated string</param>432        /// <param name="log">The log to amend.</param>433        /// <returns>The amended log.</returns>434        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log435#endif436437/// Provides operators to make writing logs more streamlined.438module Operators =439440    /// <summary>441    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.442    /// </summary>443    /// <param name="message">The string of the base message.</param>444    /// <returns>A new Log instance with the specified message.</returns> + 0445    let (!!!) message = Log.setMessage message446447    /// <summary>448    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<449    /// </summary>450    /// <param name="log">The Log to add the parameter to.</param>451    /// <param name="value">The value for the parameter.</param>452    /// <returns>The Log with the added parameter.</returns>453    let (>>!) log value = + 0454        log + 0455        >> Log.addParameter value456457    /// <summary>458    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.459    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right460    ///461    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.462    /// </summary>463    /// <param name="log">The log to add the parameter to.</param>464    /// <param name="key">The name for the parameter.</param>465    /// <param name="value">The value for the parameter.</param>466    /// <returns>The amended log with the parameter added.</returns>467    let (>>!-) log (key, value) = + 0468        log + 0469        >> Log.addContext key value  470471            let ndcContextType =472                Type.GetType("Serilog.Context.LogContext, Serilog")473                |> Option.ofObj474                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))475476            ()477478            let pushPropertyMethod =479                ndcContextType.GetMethod(480                    "PushProperty",481                    [| typedefof<string>482                       typedefof<obj>483                       typedefof<bool> |]484                )485486            let nameParam =487                Expression.Parameter(typedefof<string>, "name")488489            let valueParam =490                Expression.Parameter(typedefof<obj>, "value")491492            let destructureObjectParam =493                Expression.Parameter(typedefof<bool>, "destructureObjects")494495            let pushPropertyMethodCall =496                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)471    /// <summary>472    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT473    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling474    ///475    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.476    /// </summary>477    /// <param name="log">The log to add the parameter to.</param>478    /// <param name="key">The name for the parameter.</param>479    /// <param name="value">The value for the parameter.</param>480    /// <returns>The amended log with the parameter added.</returns>481    let (>>!+) log (key, value) = + 0482        log + 0483        >> Log.addContextDestructured key value484485    /// <summary>486    /// Amends a Log with an exn. Handles nulls.487    ///488    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.489    /// </summary>490    /// <param name="log">The log to add the parameter to.</param>491    /// <param name="e">The exception to add to the log.</param>492    /// <returns>The amended log with the parameter added.</returns>493    let (>>!!) log e = + 0494        log + 0495        >> Log.addException e496  497498            let pushProperty =499                Expression500                    .Lambda<Func<string, obj, bool, IDisposable>>(501                        pushPropertyMethodCall,502                        nameParam,503                        valueParam,504                        destructureObjectParam505                    )506                    .Compile()507508            fun key value destructure -> pushProperty.Invoke(key, value, destructure)509498#if !FABLE_COMPILER499module Providers =500    module SerilogProvider =501        open System502        open System.Linq.Expressions503504        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")505506        let isAvailable () =507            getLogManagerType ()508            |> isNull509            |> not  510511        let getForContextMethodCall () =512            let logManagerType = getLogManagerType ()513514            let method =515                logManagerType.GetMethod(516                    "ForContext",517                    [| typedefof<string>518                       typedefof<obj>519                       typedefof<bool> |]520                )521522            let propertyNameParam =523                Expression.Parameter(typedefof<string>, "propertyName")524525            let valueParam =526                Expression.Parameter(typedefof<obj>, "value")527528            let destructureObjectsParam =529                Expression.Parameter(typedefof<bool>, "destructureObjects")530531            let exrs: Expression [] =532                [| propertyNameParam533                   valueParam534                   destructureObjectsParam |]535536            let methodCall = Expression.Call(null, method, exrs)537538            let func =539                Expression540                    .Lambda<Func<string, obj, bool, obj>>(541                        methodCall,542                        propertyNameParam,543                        valueParam,544                        destructureObjectsParam545                    )546                    .Compile()547548            fun name -> func.Invoke("SourceContext", name, false)511        let getPushProperty () =512513            let ndcContextType =514                Type.GetType("Serilog.Context.LogContext, Serilog")515                |> Option.ofObj516                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))517518            ()519520            let pushPropertyMethod =521                ndcContextType.GetMethod(522                    "PushProperty",523                    [|524                        typedefof<string>525                        typedefof<obj>526                        typedefof<bool>527                    |]528                )529530            let nameParam = Expression.Parameter(typedefof<string>, "name")531532            let valueParam = Expression.Parameter(typedefof<obj>, "value")533534            let destructureObjectParam =535                Expression.Parameter(typedefof<bool>, "destructureObjects")536537            let pushPropertyMethodCall =538                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)539540            let pushProperty =541                Expression542                    .Lambda<Func<string, obj, bool, IDisposable>>(543                        pushPropertyMethodCall,544                        nameParam,545                        valueParam,546                        destructureObjectParam547                    )548                    .Compile()  549550        [<NoEquality; NoComparison>]551        type SerilogGateway =552            { Write: obj -> obj -> string -> obj [] -> unit553              WriteException: obj -> obj -> exn -> string -> obj [] -> unit554              IsEnabled: obj -> obj -> bool555              TranslateLevel: LogLevel -> obj }556            static member Create() =557                let logEventLevelType =558                    Type.GetType("Serilog.Events.LogEventLevel, Serilog")559560                if (logEventLevelType |> isNull) then561                    failwith ("Type Serilog.Events.LogEventLevel was not found.")562563                let debugLevel =564                    Enum.Parse(logEventLevelType, "Debug", false)550            fun key value destructure -> pushProperty.Invoke(key, value, destructure)551552553        let getForContextMethodCall () =554            let logManagerType = getLogManagerType ()555556            let method =557                logManagerType.GetMethod(558                    "ForContext",559                    [|560                        typedefof<string>561                        typedefof<obj>562                        typedefof<bool>563                    |]564                )  565566                let errorLevel =567                    Enum.Parse(logEventLevelType, "Error", false)568569                let fatalLevel =570                    Enum.Parse(logEventLevelType, "Fatal", false)571572                let informationLevel =573                    Enum.Parse(logEventLevelType, "Information", false)574575                let verboseLevel =576                    Enum.Parse(logEventLevelType, "Verbose", false)577578                let warningLevel =579                    Enum.Parse(logEventLevelType, "Warning", false)566            let propertyNameParam = Expression.Parameter(typedefof<string>, "propertyName")567568            let valueParam = Expression.Parameter(typedefof<obj>, "value")569570            let destructureObjectsParam =571                Expression.Parameter(typedefof<bool>, "destructureObjects")572573            let exrs: Expression[] = [|574                propertyNameParam575                valueParam576                destructureObjectsParam577            |]578579            let methodCall = Expression.Call(null, method, exrs)  580581                let translateLevel (level: LogLevel) =582                    match level with583                    | LogLevel.Fatal -> fatalLevel584                    | LogLevel.Error -> errorLevel585                    | LogLevel.Warn -> warningLevel586                    | LogLevel.Info -> informationLevel587                    | LogLevel.Debug -> debugLevel588                    | LogLevel.Trace -> verboseLevel589                    | _ -> debugLevel581            let func =582                Expression583                    .Lambda<Func<string, obj, bool, obj>>(584                        methodCall,585                        propertyNameParam,586                        valueParam,587                        destructureObjectsParam588                    )589                    .Compile()  590591                let loggerType = Type.GetType("Serilog.ILogger, Serilog")591            fun name -> func.Invoke("SourceContext", name, false)  592593                if (loggerType |> isNull) then594                    failwith ("Type Serilog.ILogger was not found.")595596                let isEnabledMethodInfo =597                    loggerType.GetMethod("IsEnabled", [| logEventLevelType |])598599                let instanceParam = Expression.Parameter(typedefof<obj>)600601                let instanceCast =602                    Expression.Convert(instanceParam, loggerType)603604                let levelParam = Expression.Parameter(typedefof<obj>)605606                let levelCast =607                    Expression.Convert(levelParam, logEventLevelType)608609                let isEnabledMethodCall =610                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)611612                let isEnabled =613                    Expression614                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)615                        .Compile()593        [<NoEquality; NoComparison>]594        type SerilogGateway =595            {596                Write: obj -> obj -> string -> obj[] -> unit597                WriteException: obj -> obj -> exn -> string -> obj[] -> unit598                IsEnabled: obj -> obj -> bool599                TranslateLevel: LogLevel -> obj600            }601602            static member Create() =603                let logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog")604605                if606                    (logEventLevelType607                     |> isNull)608                then609                    failwith ("Type Serilog.Events.LogEventLevel was not found.")610611                let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)612613                let errorLevel = Enum.Parse(logEventLevelType, "Error", false)614615                let fatalLevel = Enum.Parse(logEventLevelType, "Fatal", false)  616617                let writeMethodInfo =618                    loggerType.GetMethod(619                        "Write",620                        [| logEventLevelType621                           typedefof<string>622                           typedefof<obj []> |]623                    )624625                let messageParam = Expression.Parameter(typedefof<string>)626                let propertyValuesParam = Expression.Parameter(typedefof<obj []>)627628                let writeMethodExp =629                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)630631                let expression =632                    Expression.Lambda<Action<obj, obj, string, obj []>>(633                        writeMethodExp,634                        instanceParam,635                        levelParam,636                        messageParam,637                        propertyValuesParam638                    )617                let informationLevel = Enum.Parse(logEventLevelType, "Information", false)618619                let verboseLevel = Enum.Parse(logEventLevelType, "Verbose", false)620621                let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)622623                let translateLevel (level: LogLevel) =624                    match level with625                    | LogLevel.Fatal -> fatalLevel626                    | LogLevel.Error -> errorLevel627                    | LogLevel.Warn -> warningLevel628                    | LogLevel.Info -> informationLevel629                    | LogLevel.Debug -> debugLevel630                    | LogLevel.Trace -> verboseLevel631                    | _ -> debugLevel632633                let loggerType = Type.GetType("Serilog.ILogger, Serilog")634635                if (loggerType |> isNull) then636                    failwith ("Type Serilog.ILogger was not found.")637638                let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  639640                let write = expression.Compile()640                let instanceParam = Expression.Parameter(typedefof<obj>)  641642                let writeExceptionMethodInfo =643                    loggerType.GetMethod(644                        "Write",645                        [| logEventLevelType646                           typedefof<exn>647                           typedefof<string>648                           typedefof<obj []> |]649                    )642                let instanceCast = Expression.Convert(instanceParam, loggerType)643644                let levelParam = Expression.Parameter(typedefof<obj>)645646                let levelCast = Expression.Convert(levelParam, logEventLevelType)647648                let isEnabledMethodCall =649                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  650651                let exceptionParam = Expression.Parameter(typedefof<exn>)652653                let writeMethodExp =654                    Expression.Call(655                        instanceCast,656                        writeExceptionMethodInfo,657                        levelCast,658                        exceptionParam,659                        messageParam,660                        propertyValuesParam661                    )662663                let writeException =664                    Expression665                        .Lambda<Action<obj, obj, exn, string, obj []>>(666                            writeMethodExp,667                            instanceParam,668                            levelParam,669                            exceptionParam,670                            messageParam,671                            propertyValuesParam672                        )673                        .Compile()674675                { Write =676                      (fun logger level message formattedParmeters ->677                          write.Invoke(logger, level, message, formattedParmeters))678                  WriteException =679                      fun logger level ex message formattedParmeters ->680                          writeException.Invoke(logger, level, ex, message, formattedParmeters)681                  IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)682                  TranslateLevel = translateLevel }683684        type private SeriLogProvider() =685            let getLoggerByName = getForContextMethodCall ()686            let pushProperty = getPushProperty ()687            let serilogGatewayInit = lazy (SerilogGateway.Create())688689            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =690                let serilogGateway = serilogGatewayInit.Value691                let translatedValue = serilogGateway.TranslateLevel logLevel692693                match messageFunc with694                | None -> serilogGateway.IsEnabled logger translatedValue695                | Some _ when696                    serilogGateway.IsEnabled logger translatedValue697                    |> not698                    ->699                    false700                | Some m ->701                    match ``exception`` with702                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams703                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams704705                    true706707            interface ILogProvider with708                member this.GetLogger(name: string) : Logger = getLoggerByName name |> writeMessage709710                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =711                    pushProperty key value destructure712713                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false714715        let create () = SeriLogProvider() :> ILogProvider716651                let isEnabled =652                    Expression653                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)654                        .Compile()655656                let writeMethodInfo =657                    loggerType.GetMethod(658                        "Write",659                        [|660                            logEventLevelType661                            typedefof<string>662                            typedefof<obj[]>663                        |]664                    )665666                let messageParam = Expression.Parameter(typedefof<string>)667                let propertyValuesParam = Expression.Parameter(typedefof<obj[]>)668669                let writeMethodExp =670                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)671672                let expression =673                    Expression.Lambda<Action<obj, obj, string, obj[]>>(674                        writeMethodExp,675                        instanceParam,676                        levelParam,677                        messageParam,678                        propertyValuesParam679                    )680681                let write = expression.Compile()682683                let writeExceptionMethodInfo =684                    loggerType.GetMethod(685                        "Write",686                        [|687                            logEventLevelType688                            typedefof<exn>689                            typedefof<string>690                            typedefof<obj[]>691                        |]692                    )693694                let exceptionParam = Expression.Parameter(typedefof<exn>)695696                let writeMethodExp =697                    Expression.Call(698                        instanceCast,699                        writeExceptionMethodInfo,700                        levelCast,701                        exceptionParam,702                        messageParam,703                        propertyValuesParam704                    )705706                let writeException =707                    Expression708                        .Lambda<Action<obj, obj, exn, string, obj[]>>(709                            writeMethodExp,710                            instanceParam,711                            levelParam,712                            exceptionParam,713                            messageParam,714                            propertyValuesParam715                        )716                        .Compile()  717718    module MicrosoftExtensionsLoggingProvider =719        open System720        open System.Linq.Expressions721        open System.Reflection722        open System.Collections.Generic723724        type ILoggerFactory = obj725        // This has to be set from usercode for this to light up726        let mutable private  microsoftLoggerFactory : ILoggerFactory option = None727        let setMicrosoftLoggerFactory (factory : ILoggerFactory) = microsoftLoggerFactory <- Option.ofObj factory728729        let getLogFactoryType = lazy(Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Log730        let isAvailable () =731            getLogFactoryType.Value |> isNull |> not732            && microsoftLoggerFactory |> Option.isSome733718                {719                    Write =720                        (fun logger level message formattedParmeters ->721                            write.Invoke(logger, level, message, formattedParmeters)722                        )723                    WriteException =724                        fun logger level ex message formattedParmeters ->725                            writeException.Invoke(logger, level, ex, message, formattedParmeters)726                    IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)727                    TranslateLevel = translateLevel728                }729730        type private SeriLogProvider() =731            let getLoggerByName = getForContextMethodCall ()732            let pushProperty = getPushProperty ()733            let serilogGatewayInit = lazy (SerilogGateway.Create())  734735        type ILogger = obj736        type LoggerName = string737        type MicrosoftLogLevel = obj738        type MessageFormat = string739        type MessageArgs = obj array740741        [<NoEquality; NoComparison>]742        type LoggerFactoryGateway = {743            CreateLogger : ILoggerFactory -> LoggerName -> ILogger744        }745        with746            static member Create() =747                let createLogger =748                    let factoryType = getLogFactoryType.Value749                    let createLoggerMethodInfo =750                        factoryType.GetMethod(751                            "CreateLogger",752                            [|typedefof<string>|])753                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)754                    let nameParam = Expression.Parameter(typedefof<string>)755                    let instanceCast =756                        Expression.Convert(instanceParam, factoryType)757                    let createLoggerMethodExp =758                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)759                    let createLogger =760                        Expression761                            .Lambda<Func<ILoggerFactory,string,ILogger>>(createLoggerMethodExp, instanceParam, nameParam762                            .Compile()763                    createLogger764                    |> FuncConvert.FromFunc765                {766                    CreateLogger = createLogger767                }768769        type LoggerGateway = {770            Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit771            WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit772            IsEnabled: ILogger -> MicrosoftLogLevel -> bool773            TranslateLevel : LogLevel -> MicrosoftLogLevel774            BeginScope : ILogger -> obj -> IDisposable775        } with776            static member Create () =777                let loggerExtensions = Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions778                let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstra779                let logEventLevelType =780                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")781                let instanceParam = Expression.Parameter(typedefof<ILogger>)735            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =736                let serilogGateway = serilogGatewayInit.Value737                let translatedValue = serilogGateway.TranslateLevel logLevel738739                match messageFunc with740                | None -> serilogGateway.IsEnabled logger translatedValue741                | Some _ when742                    serilogGateway.IsEnabled logger translatedValue743                    |> not744                    ->745                    false746                | Some m ->747                    match ``exception`` with748                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams749                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams750751                    true752753            interface ILogProvider with754                member this.GetLogger(name: string) : Logger =755                    getLoggerByName name756                    |> writeMessage757758                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =759                    pushProperty key value destructure760761                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false762763        let create () = SeriLogProvider() :> ILogProvider764765766    module MicrosoftExtensionsLoggingProvider =767        open System768        open System.Linq.Expressions769        open System.Reflection770        open System.Collections.Generic771772        type ILoggerFactory = obj773        // This has to be set from usercode for this to light up774        let mutable private microsoftLoggerFactory: ILoggerFactory option = None775776        let setMicrosoftLoggerFactory (factory: ILoggerFactory) =777            microsoftLoggerFactory <- Option.ofObj factory778779        let getLogFactoryType =780            lazy781                (Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.Abstractions"))  782783                let instanceCast =784                    Expression.Convert(instanceParam, loggerType)785                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)786787                let levelCast = Expression.Convert(levelParam, logEventLevelType)788789                let isEnabled =790                    let isEnabledMethodInfo =791                        loggerType.GetMethod("IsEnabled", [| logEventLevelType |])792                    let isEnabledMethodCall =793                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)794795796                    Expression797                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)798                        .Compile()799                    |> FuncConvert.FromFunc800801                let write, writeError =802                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)803                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)804805                    let write =806                        let writeMethodInfo =807                            loggerExtensions.GetMethod(808                                "Log",809                                BindingFlags.Static ||| BindingFlags.Public,810                                null,811                                [| loggerType812                                   logEventLevelType813                                   typedefof<MessageFormat>814                                   typedefof<MessageArgs> |],815                                null816                            )817818                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, messagePara819820                        let expression =821                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(822                                writeMethodExp,823                                instanceParam,824                                levelParam,825                                messageParam,826                                propertyValuesParam827                            )828                        expression.Compile() |> FuncConvert.FromAction829783        let isAvailable () =784            getLogFactoryType.Value785            |> isNull786            |> not787            && microsoftLoggerFactory788               |> Option.isSome789790791        type ILogger = obj792        type LoggerName = string793        type MicrosoftLogLevel = obj794        type MessageFormat = string795        type MessageArgs = obj array796797        [<NoEquality; NoComparison>]798        type LoggerFactoryGateway =799            {800                CreateLogger: ILoggerFactory -> LoggerName -> ILogger801            }802803            static member Create() =804                let createLogger =805                    let factoryType = getLogFactoryType.Value806807                    let createLoggerMethodInfo =808                        factoryType.GetMethod("CreateLogger", [| typedefof<string> |])809810                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)811                    let nameParam = Expression.Parameter(typedefof<string>)812                    let instanceCast = Expression.Convert(instanceParam, factoryType)813814                    let createLoggerMethodExp =815                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)816817                    let createLogger =818                        Expression819                            .Lambda<Func<ILoggerFactory, string, ILogger>>(820                                createLoggerMethodExp,821                                instanceParam,822                                nameParam823                            )824                            .Compile()825826                    createLogger827                    |> FuncConvert.FromFunc828829                { CreateLogger = createLogger }  830831                    let writeError =832                        let writeMethodInfo =833                            loggerExtensions.GetMethod(834                                "Log",835                                BindingFlags.Static ||| BindingFlags.Public,836                                null,837                                [| loggerType838                                   logEventLevelType839                                   typedefof<exn>840                                   typedefof<MessageFormat>841                                   typedefof<MessageArgs> |],842                                null843844                            )845                        let exnParam = Expression.Parameter(typedefof<exn>)846                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, exnParam, m847848                        let expression =849                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(850                                writeMethodExp,851                                instanceParam,852                                levelParam,853                                exnParam,854                                messageParam,855                                propertyValuesParam856                            )857                        expression.Compile() |> FuncConvert.FromAction858                    write, writeError859860                let translateLevel =831        type LoggerGateway =832            {833                Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit834                WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit835                IsEnabled: ILogger -> MicrosoftLogLevel -> bool836                TranslateLevel: LogLevel -> MicrosoftLogLevel837                BeginScope: ILogger -> obj -> IDisposable838            }839840            static member Create() =841                let loggerExtensions =842                    Type.GetType(843                        "Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions"844                    )845846                let loggerType =847                    Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")848849                let logEventLevelType =850                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")851852                let instanceParam = Expression.Parameter(typedefof<ILogger>)853854                let instanceCast = Expression.Convert(instanceParam, loggerType)855                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)856857                let levelCast = Expression.Convert(levelParam, logEventLevelType)858859                let isEnabled =860                    let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  861862                    let debugLevel =863                        Enum.Parse(logEventLevelType, "Debug", false)862                    let isEnabledMethodCall =863                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  864865                    let errorLevel =866                        Enum.Parse(logEventLevelType, "Error", false)867868                    let criticalLevel =869                        Enum.Parse(logEventLevelType, "Critical", false)865866                    Expression867                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)868                        .Compile()869                    |> FuncConvert.FromFunc  870871                    let informationLevel =872                        Enum.Parse(logEventLevelType, "Information", false)873874                    let traceLevel =875                        Enum.Parse(logEventLevelType, "Trace", false)876877                    let warningLevel =878                        Enum.Parse(logEventLevelType, "Warning", false)879880                    fun (level: LogLevel) ->881                        match level with882                        | LogLevel.Fatal -> criticalLevel883                        | LogLevel.Error -> errorLevel884                        | LogLevel.Warn -> warningLevel885                        | LogLevel.Info -> informationLevel886                        | LogLevel.Debug -> debugLevel887                        | LogLevel.Trace -> traceLevel888                        | _ -> debugLevel889                let beginScope =890                    let beginScopeMethodInfo =891                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)892                    let stateParam = Expression.Parameter(typedefof<obj>)893                    let beginScopeMethodCall =894                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)895896                    Expression897                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)898                        .Compile()899                    |> FuncConvert.FromFunc871                let write, writeError =872                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)873                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)874875                    let write =876                        let writeMethodInfo =877                            loggerExtensions.GetMethod(878                                "Log",879                                BindingFlags.Static880                                ||| BindingFlags.Public,881                                null,882                                [|883                                    loggerType884                                    logEventLevelType885                                    typedefof<MessageFormat>886                                    typedefof<MessageArgs>887                                |],888                                null889                            )890891                        let writeMethodExp =892                            Expression.Call(893                                null,894                                writeMethodInfo,895                                instanceCast,896                                levelCast,897                                messageParam,898                                propertyValuesParam899                            )  900901                {902                    Write = write903                    WriteError = writeError904                    IsEnabled = isEnabled905                    TranslateLevel = translateLevel906                    BeginScope = beginScope907                }908901                        let expression =902                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(903                                writeMethodExp,904                                instanceParam,905                                levelParam,906                                messageParam,907                                propertyValuesParam908                            )  909910        type private MicrosoftProvider() =911            let factoryGateway = lazy(LoggerFactoryGateway.Create())912            let loggerGateway = lazy(LoggerGateway.Create())913            interface ILogProvider with914                member this.GetLogger(name: string) : Logger =915                    match microsoftLoggerFactory with916                    | None ->917                        fun _ _ _ _ -> false918                    | Some factory ->919                        let logger = factoryGateway.Value.CreateLogger factory name920921                        fun logLevel message exn args ->922                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel923                            match message with924                            | Some message ->925                                let message = message ()926                                match exn with927                                | Some ex ->928                                    loggerGateway.Value.WriteError logger microsoftLevel ex message args929                                | None ->930                                    loggerGateway.Value.Write logger microsoftLevel message args931                                true932                            | None ->933                                loggerGateway.Value.IsEnabled logger microsoftLevel934935                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =936                    match microsoftLoggerFactory with937                    | None ->938                        { new IDisposable with member x.Dispose () = ()}939                    | Some factory ->940                        // Create bogus logger that will propagate to a real logger later941                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())942                        // Requires a IEnumerable<KeyValuePair> to make sense943                        // https://nblumhardt.com/2016/11/ilogger-beginscope/944                        [KeyValuePair(key, value)]945                        |> box946                        |> loggerGateway.Value.BeginScope logger947948949                member this.OpenNestedContext(message: string) : IDisposable =950                    match microsoftLoggerFactory with951                    | None ->952                        { new IDisposable with member x.Dispose () = ()}953                    | Some factory ->954                        // Create bogus logger that will propagate to a real logger later955                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())956                        loggerGateway.Value.BeginScope logger (box message)910                        expression.Compile()911                        |> FuncConvert.FromAction912913914                    let writeError =915                        let writeMethodInfo =916                            loggerExtensions.GetMethod(917                                "Log",918                                BindingFlags.Static919                                ||| BindingFlags.Public,920                                null,921                                [|922                                    loggerType923                                    logEventLevelType924                                    typedefof<exn>925                                    typedefof<MessageFormat>926                                    typedefof<MessageArgs>927                                |],928                                null929930                            )931932                        let exnParam = Expression.Parameter(typedefof<exn>)933934                        let writeMethodExp =935                            Expression.Call(936                                null,937                                writeMethodInfo,938                                instanceCast,939                                levelCast,940                                exnParam,941                                messageParam,942                                propertyValuesParam943                            )944945                        let expression =946                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(947                                writeMethodExp,948                                instanceParam,949                                levelParam,950                                exnParam,951                                messageParam,952                                propertyValuesParam953                            )954955                        expression.Compile()956                        |> FuncConvert.FromAction  957958        let create () = MicrosoftProvider() :> ILogProvider958                    write, writeError  959960#endif960                let translateLevel =  961962963module LogProvider =964    open System965    open Types966    #if !FABLE_COMPILER967    open Providers968    #endif969    open System.Diagnostics970    open Microsoft.FSharp.Quotations.Patterns962                    let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)963964                    let errorLevel = Enum.Parse(logEventLevelType, "Error", false)965966                    let criticalLevel = Enum.Parse(logEventLevelType, "Critical", false)967968                    let informationLevel = Enum.Parse(logEventLevelType, "Information", false)969970                    let traceLevel = Enum.Parse(logEventLevelType, "Trace", false)  971972    let mutable private currentLogProvider = None972                    let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)  973974    let private knownProviders =975        [976        #if !FABLE_COMPILER977            (SerilogProvider.isAvailable, SerilogProvider.create)978            (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)979        #endif980        ]981982    /// Greedy search for first available LogProvider. Order of known providers matters.983    let private resolvedLogger =984        lazy985            (knownProviders986             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())987             |> Option.map (fun (_, create) -> create ()))988989    let private noopLogger _ _ _ _ = false990991    let private noopDisposable =992        { new IDisposable with993            member __.Dispose() = () }994995    /// <summary>996    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.997    /// </summary>998    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>999    /// <returns></returns>1000    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider10011002    /// <summary>1003    /// Gets the currently set LogProvider or attempts to find known built in providers1004    /// </summary>1005    /// <returns></returns>1006    let getCurrentLogProvider () =1007        match currentLogProvider with1008        | None -> resolvedLogger.Value1009        | Some p -> Some p974                    fun (level: LogLevel) ->975                        match level with976                        | LogLevel.Fatal -> criticalLevel977                        | LogLevel.Error -> errorLevel978                        | LogLevel.Warn -> warningLevel979                        | LogLevel.Info -> informationLevel980                        | LogLevel.Debug -> debugLevel981                        | LogLevel.Trace -> traceLevel982                        | _ -> debugLevel983984                let beginScope =985                    let beginScopeMethodInfo =986                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)987988                    let stateParam = Expression.Parameter(typedefof<obj>)989990                    let beginScopeMethodCall =991                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)992993                    Expression994                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)995                        .Compile()996                    |> FuncConvert.FromFunc997998                {999                    Write = write1000                    WriteError = writeError1001                    IsEnabled = isEnabled1002                    TranslateLevel = translateLevel1003                    BeginScope = beginScope1004                }100510061007        type private MicrosoftProvider() =1008            let factoryGateway = lazy (LoggerFactoryGateway.Create())1009            let loggerGateway = lazy (LoggerGateway.Create())  10101011    /// <summary>1012    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1013    /// </summary>1014    /// <param name="key">The name of the property.</param>1015    /// <param name="value">The value of the property.</param>1016    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1017    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1018    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1019        let provider = getCurrentLogProvider ()1011            interface ILogProvider with1012                member this.GetLogger(name: string) : Logger =1013                    match microsoftLoggerFactory with1014                    | None -> fun _ _ _ _ -> false1015                    | Some factory ->1016                        let logger = factoryGateway.Value.CreateLogger factory name10171018                        fun logLevel message exn args ->1019                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel  10201021        match provider with1022        | Some p -> p.OpenMappedContext key value destructureObjects1023        | None -> noopDisposable1021                            match message with1022                            | Some message ->1023                                let message = message ()  102410251026    /// <summary>1027    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1028    /// </summary>1029    /// <param name="key">The name of the property.</param>1030    /// <param name="value">The value of the property.</param>1031    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1032    let openMappedContext (key: string) (value: obj) =1033        //TODO: We should try to find out if the value is a primitive1034        openMappedContextDestucturable key value false103510361037    /// <summary>1038    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1039    /// </summary>1040    /// <param name="value">The value of the property</param>1041    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1042    let openNestedContext (value: string) =1043        let provider = getCurrentLogProvider ()10441045        match provider with1046        | Some p -> p.OpenNestedContext value1047        | None -> noopDisposable10481049    /// <summary>1050    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1051    /// </summary>1052    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1053    /// <returns></returns>1054    let getLoggerByName (name: string) =1055        let loggerProvider = getCurrentLogProvider ()10561057        let logFunc =1058            match loggerProvider with1059            | Some loggerProvider -> loggerProvider.GetLogger(name)1060            | None -> noopLogger1025                                match exn with1026                                | Some ex -> loggerGateway.Value.WriteError logger microsoftLevel ex message args1027                                | None -> loggerGateway.Value.Write logger microsoftLevel message args10281029                                true1030                            | None -> loggerGateway.Value.IsEnabled logger microsoftLevel10311032                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =1033                    match microsoftLoggerFactory with1034                    | None ->1035                        { new IDisposable with1036                            member x.Dispose() = ()1037                        }1038                    | Some factory ->1039                        // Create bogus logger that will propagate to a real logger later1040                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1041                        // Requires a IEnumerable<KeyValuePair> to make sense1042                        // https://nblumhardt.com/2016/11/ilogger-beginscope/1043                        [ KeyValuePair(key, value) ]1044                        |> box1045                        |> loggerGateway.Value.BeginScope logger104610471048                member this.OpenNestedContext(message: string) : IDisposable =1049                    match microsoftLoggerFactory with1050                    | None ->1051                        { new IDisposable with1052                            member x.Dispose() = ()1053                        }1054                    | Some factory ->1055                        // Create bogus logger that will propagate to a real logger later1056                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())10571058                        loggerGateway.Value.BeginScope logger (box message)10591060        let create () = MicrosoftProvider() :> ILogProvider  10611062        { new ILog with1063            member x.Log = logFunc1064            member x.MappedContext = openMappedContextDestucturable }10651066    /// <summary>1067    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1068    /// </summary>1069    /// <param name="objectType">The type to generate a logger name from. </param>1070    /// <returns></returns>1071    let getLoggerByType (objectType: Type) = objectType |> string |> getLoggerByName10721073    /// <summary>1074    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1075    /// </summary>1076    /// <typeparam name="'a">The type to generate a name from.</typeparam>1077    /// <returns></returns>1078    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)10791080#if !FABLE_COMPILER1081    let rec private getModuleType =1082        function1083        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1084        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1085        // | Lambda(_, expr) -> getModuleType expr1086        // | ValueWithName(_,_,instance) -> instance1087        | x -> failwithf "Expression is not a property. %A" x10881062#endif106310641065module LogProvider =1066    open System1067    open Types1068#if !FABLE_COMPILER1069    open Providers1070#endif1071    open System.Diagnostics1072    open Microsoft.FSharp.Quotations.Patterns10731074    let mutable private currentLogProvider = None10751076    let private knownProviders = [1077#if !FABLE_COMPILER1078        (SerilogProvider.isAvailable, SerilogProvider.create)1079        (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)1080#endif1081    ]10821083    /// Greedy search for first available LogProvider. Order of known providers matters.1084    let private resolvedLogger =1085        lazy1086            (knownProviders1087             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())1088             |> Option.map (fun (_, create) -> create ()))  10891090    /// <summary>1091    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1092    ///1093    /// It can be utilized like:1094    ///1095    /// <code>1096    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1097    /// </code>1098    ///1099    /// inside a module to get the modules full qualitfied name.1100    /// </summary>1101    /// <param name="quotation">The quotation to generate a logger name from.</param>1102    /// <returns></returns>1103    let getLoggerByQuotation (quotation: Quotations.Expr) =1104        getModuleType quotation |> getLoggerByType110511061107type LogProvider =1108    /// <summary>1109    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1110    /// </summary>1111    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1112    /// <returns></returns>1113    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1114        let mi = System.Reflection.MethodBase.GetCurrentMethod()1115        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1116        // CallerMemberName gets us the function that actually called it1117        // Splitting off + seems like the best option to get the Fully Qualified Path1118        let location = mi.DeclaringType.FullName.Split('+') |> Seq.tryHead |> Option.defaultValue ""1119        sprintf "%s.%s" location memberName.Value1120        |> LogProvider.getLoggerByName11211122#endif1090    let private noopLogger _ _ _ _ = false10911092    let private noopDisposable =1093        { new IDisposable with1094            member __.Dispose() = ()1095        }10961097    /// <summary>1098    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.1099    /// </summary>1100    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>1101    /// <returns></returns>1102    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider11031104    /// <summary>1105    /// Gets the currently set LogProvider or attempts to find known built in providers1106    /// </summary>1107    /// <returns></returns>1108    let getCurrentLogProvider () =1109        match currentLogProvider with1110        | None -> resolvedLogger.Value1111        | Some p -> Some p11121113    /// <summary>1114    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1115    /// </summary>1116    /// <param name="key">The name of the property.</param>1117    /// <param name="value">The value of the property.</param>1118    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1119    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1120    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1121        let provider = getCurrentLogProvider ()11221123        match provider with1124        | Some p -> p.OpenMappedContext key value destructureObjects1125        | None -> noopDisposable112611271128    /// <summary>1129    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1130    /// </summary>1131    /// <param name="key">The name of the property.</param>1132    /// <param name="value">The value of the property.</param>1133    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1134    let openMappedContext (key: string) (value: obj) =1135        //TODO: We should try to find out if the value is a primitive1136        openMappedContextDestucturable key value false113711381139    /// <summary>1140    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1141    /// </summary>1142    /// <param name="value">The value of the property</param>1143    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1144    let openNestedContext (value: string) =1145        let provider = getCurrentLogProvider ()11461147        match provider with1148        | Some p -> p.OpenNestedContext value1149        | None -> noopDisposable11501151    /// <summary>1152    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1153    /// </summary>1154    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1155    /// <returns></returns>1156    let getLoggerByName (name: string) =1157        let loggerProvider = getCurrentLogProvider ()11581159        let logFunc =1160            match loggerProvider with1161            | Some loggerProvider -> loggerProvider.GetLogger(name)1162            | None -> noopLogger11631164        { new ILog with1165            member x.Log = logFunc1166            member x.MappedContext = openMappedContextDestucturable1167        }11681169    /// <summary>1170    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1171    /// </summary>1172    /// <param name="objectType">The type to generate a logger name from. </param>1173    /// <returns></returns>1174    let getLoggerByType (objectType: Type) =1175        objectType1176        |> string1177        |> getLoggerByName11781179    /// <summary>1180    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1181    /// </summary>1182    /// <typeparam name="'a">The type to generate a name from.</typeparam>1183    /// <returns></returns>1184    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)11851186#if !FABLE_COMPILER1187    let rec private getModuleType =1188        function1189        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1190        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1191        // | Lambda(_, expr) -> getModuleType expr1192        // | ValueWithName(_,_,instance) -> instance1193        | x -> failwithf "Expression is not a property. %A" x119411951196    /// <summary>1197    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1198    ///1199    /// It can be utilized like:1200    ///1201    /// <code>1202    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1203    /// </code>1204    ///1205    /// inside a module to get the modules full qualitfied name.1206    /// </summary>1207    /// <param name="quotation">The quotation to generate a logger name from.</param>1208    /// <returns></returns>1209    let getLoggerByQuotation (quotation: Quotations.Expr) =1210        getModuleType quotation1211        |> getLoggerByType121212131214type LogProvider =1215    /// <summary>1216    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1217    /// </summary>1218    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1219    /// <returns></returns>1220    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1221        let mi = System.Reflection.MethodBase.GetCurrentMethod()1222        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1223        // CallerMemberName gets us the function that actually called it1224        // Splitting off + seems like the best option to get the Fully Qualified Path1225        let location =1226            mi.DeclaringType.FullName.Split('+')1227            |> Seq.tryHead1228            |> Option.defaultValue ""12291230        sprintf "%s.%s" location memberName.Value1231        |> LogProvider.getLoggerByName12321233#endif - + diff --git a/docs/coverage/FsLibLog_Providers.htm b/docs/coverage/FsLibLog_Providers.htm index 805209a..f0cde07 100644 --- a/docs/coverage/FsLibLog_Providers.htm +++ b/docs/coverage/FsLibLog_Providers.htm @@ -18,62 +18,54 @@

< Summary

Assembly:FsLibLog File(s):C:\Users\jimmy\Repositories\public\TheAngryByrd\FsLibLog\src\FsLibLog\FsLibLog.fs Covered lines:0 -Uncovered lines:321 -Coverable lines:321 -Total lines:1122 -Line coverage:0% (0 of 321) +Uncovered lines:342 +Coverable lines:342 +Total lines:1233 +Line coverage:0% (0 of 342) Covered branches:0 -Total branches:28 -Branch coverage:0% (0 of 28) +Total branches:26 +Branch coverage:0% (0 of 26)

Metrics

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage Crap Score
getLogManagerType()100%0%0
isAvailable()200%0%0
getPushProperty()700%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
getForContextMethodCall()700%0%0
Invoke(...)100%0%0
Create()1540%0%0
Invoke(...)870%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
.ctor()100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILogProvider.GetLogger(...)100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILogProvider.OpenMappedContext(...)100%0%0
FsLibLog.Types.ILogProvider.OpenNestedContext(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
create()100%0%0
setMicrosoftLoggerFactory(...)100%0%0
Invoke(...)100%0%0
Create()400%0%0
Invoke(...)100%0%0
Create()1300%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)870%0%0
Invoke(...)100%0%0
.ctor()100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILogProvider.GetLogger(...)220%0%0
Invoke(...)100%0%0
Invoke(...)340%0%0
FsLibLog.Types.ILogProvider.OpenMappedContext(...)220%0%0
System.IDisposable.Dispose()100%0%0
FsLibLog.Types.ILogProvider.OpenNestedContext(...)220%0%0
System.IDisposable.Dispose()100%0%0
create()100%0%0
getLogManagerType()100%0%0
isAvailable()200%0%0
getPushProperty()700%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
getForContextMethodCall()700%0%0
Invoke(...)100%0%0
Create()1340%0%0
Invoke(...)870%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
.ctor()100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILogProvider.GetLogger(...)100%0%0
FsLibLog.Types.ILogProvider.OpenMappedContext(...)100%0%0
FsLibLog.Types.ILogProvider.OpenNestedContext(...)100%0%0
create()100%0%0
setMicrosoftLoggerFactory(...)100%0%0
Invoke(...)100%0%0
isAvailable()200%0%0
Create()400%0%0
Create()1300%0%0
Invoke(...)870%0%0
.ctor()100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
FsLibLog.Types.ILogProvider.GetLogger(...)200%0%0
Invoke(...)100%0%0
Invoke(...)340%0%0
FsLibLog.Types.ILogProvider.OpenMappedContext(...)220%0%0
System.IDisposable.Dispose()100%0%0
FsLibLog.Types.ILogProvider.OpenNestedContext(...)220%0%0
System.IDisposable.Dispose()100%0%0
create()100%0%0

File(s)

@@ -111,1146 +103,1250 @@

 28    /// Type representing a Log  29    [<NoEquality; NoComparison>]  30    type Log =31        { LogLevel: LogLevel32          Message: MessageThunk33          Exception: exn option34          Parameters: obj list35          AdditionalNamedParameters: ((string * obj * bool) list) }36        static member StartLogLevel(logLevel: LogLevel) =37            { LogLevel = logLevel38              Message = None39              Exception = None40              Parameters = List.empty41              AdditionalNamedParameters = List.empty }4243    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio44    type ILog =45        abstract member Log :  Logger46        abstract member MappedContext :  MappedContext4748#if FABLE_COMPILER49    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)50    // is used instead.51    type Stack<'a>()  =52        let mutable contents = Array.zeroCreate<'a>(2)53        let mutable count = 05455        member buf.Ensure newSize =56            let oldSize = contents.Length57            if newSize > oldSize then58                let old = contents59                contents <- Array.zeroCreate (max newSize (oldSize * 2))60                Array.blit old 0 contents 0 count31        {32            LogLevel: LogLevel33            Message: MessageThunk34            Exception: exn option35            Parameters: obj list36            AdditionalNamedParameters: ((string * obj * bool) list)37        }3839        static member StartLogLevel(logLevel: LogLevel) = {40            LogLevel = logLevel41            Message = None42            Exception = None43            Parameters = List.empty44            AdditionalNamedParameters = List.empty45        }4647    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio48    type ILog =49        abstract member Log: Logger50        abstract member MappedContext: MappedContext5152#if FABLE_COMPILER53    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)54    // is used instead.55    type Stack<'a>() =56        let mutable contents = Array.zeroCreate<'a> (2)57        let mutable count = 05859        member buf.Ensure newSize =60            let oldSize = contents.Length  6162        member buf.Count = count63        member buf.Pop() =64            let item = contents.[count - 1]65            count <- count - 166            item6768        member buf.Peep() = contents.[count - 1]69        member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev70        member buf.Push(x) =71            buf.Ensure(count + 1)72            contents.[count] <- x73            count <- count + 17475        member buf.IsEmpty = (count = 0)76#endif7778    [<AutoOpen>]79    module Inner =80#if !FABLE_COMPILER81        open System.Collections.Generic82#endif8384        /// <summary>85        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.86        /// </summary>87        type DisposableStack() =88            let stack = Stack<IDisposable>()8990            interface IDisposable with91                member __.Dispose() =92                    while stack.Count > 0 do93                        stack.Pop().Dispose()9495            member __.Push(item: IDisposable) = stack.Push item96            member __.Push(items: IDisposable list) = items |> List.iter stack.Push9798            static member Create(items: IDisposable list) =99                let ds = new DisposableStack()100                ds.Push items101                ds102103        type ILog with62            if newSize > oldSize then63                let old = contents64                contents <- Array.zeroCreate (max newSize (oldSize * 2))65                Array.blit old 0 contents 0 count6667        member buf.Count = count6869        member buf.Pop() =70            let item = contents.[count - 1]71            count <- count - 172            item7374        member buf.Peep() = contents.[count - 1]7576        member buf.Top(n) =77            [ for x in contents.[max 0 (count - n) .. count - 1] -> x ]78            |> List.rev7980        member buf.Push(x) =81            buf.Ensure(count + 1)82            contents.[count] <- x83            count <- count + 18485        member buf.IsEmpty = (count = 0)86#endif8788    [<AutoOpen>]89    module Inner =90#if !FABLE_COMPILER91        open System.Collections.Generic92#endif9394        /// <summary>95        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.96        /// </summary>97        type DisposableStack() =98            let stack = Stack<IDisposable>()99100            interface IDisposable with101                member __.Dispose() =102                    while stack.Count > 0 do103                        stack.Pop().Dispose()  104105            /// <summary>106            /// Logs a log107            /// </summary>108            /// <param name="log">The type representing a log message to be logged</param>109            /// <returns><see langword="true"/> if the log message was logged</returns>110            member logger.fromLog(log: Log) =111                use __ =112                    log.AdditionalNamedParameters113                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)114                    // This stack is important, it causes us to unwind as if you have multiple uses in a row115                    |> DisposableStack.Create116117                log.Parameters118                |> List.toArray119                |> logger.Log log.LogLevel log.Message log.Exception120121            /// <summary>122            /// Logs a fatal log message given a log configurer.123            /// </summary>124            /// <param name="logConfig">A function to configure a log</param>125            /// <returns><see langword="true"/>  if the log message was logged</returns>126            member logger.fatal'(logConfig: Log -> Log) =127                Log.StartLogLevel LogLevel.Fatal128                |> logConfig129                |> logger.fromLog130131            /// <summary>132            /// Logs a fatal log message given a log configurer.133            /// </summary>134            /// <param name="logConfig">A function to configure a log</param>135            member logger.fatal(logConfig: Log -> Log) = logger.fatal' logConfig |> ignore136137            /// <summary>138            /// Logs an error log message given a log configurer.139            /// </summary>140            /// <param name="logConfig">A function to configure a log</param>141            /// <returns><see langword="true"/>  if the log message was logged</returns>142            member logger.error'(logConfig: Log -> Log) =143                Log.StartLogLevel LogLevel.Error144                |> logConfig145                |> logger.fromLog146147            /// <summary>148            /// Logs an error log message given a log configurer.149            /// </summary>150            /// <param name="logConfig">A function to configure a log</param>151            member logger.error(logConfig: Log -> Log) = logger.error' logConfig |> ignore152153            /// <summary>154            /// Logs a warn log message given a log configurer.155            /// </summary>156            /// <param name="logConfig">A function to configure a log</param>157            /// <returns><see langword="true"/>  if the log message was logged</returns>158            member logger.warn'(logConfig: Log -> Log) =159                Log.StartLogLevel LogLevel.Warn160                |> logConfig161                |> logger.fromLog162163            /// <summary>164            /// Logs a warn log message given a log configurer.165            /// </summary>166            /// <param name="logConfig">A function to configure a log</param>167            member logger.warn(logConfig: Log -> Log) = logger.warn' logConfig |> ignore168169            /// <summary>170            /// Logs an info log message given a log configurer.171            /// </summary>172            /// <param name="logConfig">A function to configure a log</param>173            /// <returns><see langword="true"/>  if the log message was logged</returns>174            member logger.info'(logConfig: Log -> Log) =175                Log.StartLogLevel LogLevel.Info176                |> logConfig177                |> logger.fromLog178179            /// <summary>180            /// Logs an info log message given a log configurer.181            /// </summary>182            /// <param name="logConfig">A function to configure a log</param>183            member logger.info(logConfig: Log -> Log) = logger.info' logConfig |> ignore184185            /// <summary>186            /// Logs a debug log message given a log configurer.187            /// </summary>188            /// <param name="logConfig">A function to configure a log</param>189            /// <returns><see langword="true"/>  if the log message was logged</returns>190            member logger.debug'(logConfig: Log -> Log) =191                Log.StartLogLevel LogLevel.Debug192                |> logConfig193                |> logger.fromLog194195            /// <summary>196            /// Logs a debug log message given a log configurer.197            /// </summary>198            /// <param name="logConfig">A function to configure a log</param>199            member logger.debug(logConfig: Log -> Log) = logger.debug' logConfig |> ignore200201            /// <summary>202            /// Logs a trace log message given a log configurer.203            /// </summary>204            /// <param name="logConfig">A function to configure a log</param>205            /// <returns><see langword="true"/>  if the log message was logged</returns>206            member logger.trace'(logConfig: Log -> Log) =207                Log.StartLogLevel LogLevel.Trace208                |> logConfig209                |> logger.fromLog210211            /// <summary>212            /// Logs a trace log message given a log configurer.213            /// </summary>214            /// <param name="logConfig">A function to configure a log</param>215            member logger.trace(logConfig: Log -> Log) = logger.trace' logConfig |> ignore216217218    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.219    type ILogProvider =220        abstract member GetLogger : string -> Logger221        abstract member OpenNestedContext : string -> IDisposable222        abstract member OpenMappedContext : string -> obj -> bool -> IDisposable105            member __.Push(item: IDisposable) = stack.Push item106107            member __.Push(items: IDisposable list) =108                items109                |> List.iter stack.Push110111            static member Create(items: IDisposable list) =112                let ds = new DisposableStack()113                ds.Push items114                ds115116        type ILog with117118            /// <summary>119            /// Logs a log120            /// </summary>121            /// <param name="log">The type representing a log message to be logged</param>122            /// <returns><see langword="true"/> if the log message was logged</returns>123            member logger.fromLog(log: Log) =124                use __ =125                    log.AdditionalNamedParameters126                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure)127                    // This stack is important, it causes us to unwind as if you have multiple uses in a row128                    |> DisposableStack.Create129130                log.Parameters131                |> List.toArray132                |> logger.Log log.LogLevel log.Message log.Exception133134            /// <summary>135            /// Logs a fatal log message given a log configurer.136            /// </summary>137            /// <param name="logConfig">A function to configure a log</param>138            /// <returns><see langword="true"/>  if the log message was logged</returns>139            member logger.fatal'(logConfig: Log -> Log) =140                Log.StartLogLevel LogLevel.Fatal141                |> logConfig142                |> logger.fromLog143144            /// <summary>145            /// Logs a fatal log message given a log configurer.146            /// </summary>147            /// <param name="logConfig">A function to configure a log</param>148            member logger.fatal(logConfig: Log -> Log) =149                logger.fatal' logConfig150                |> ignore151152            /// <summary>153            /// Logs an error log message given a log configurer.154            /// </summary>155            /// <param name="logConfig">A function to configure a log</param>156            /// <returns><see langword="true"/>  if the log message was logged</returns>157            member logger.error'(logConfig: Log -> Log) =158                Log.StartLogLevel LogLevel.Error159                |> logConfig160                |> logger.fromLog161162            /// <summary>163            /// Logs an error log message given a log configurer.164            /// </summary>165            /// <param name="logConfig">A function to configure a log</param>166            member logger.error(logConfig: Log -> Log) =167                logger.error' logConfig168                |> ignore169170            /// <summary>171            /// Logs a warn log message given a log configurer.172            /// </summary>173            /// <param name="logConfig">A function to configure a log</param>174            /// <returns><see langword="true"/>  if the log message was logged</returns>175            member logger.warn'(logConfig: Log -> Log) =176                Log.StartLogLevel LogLevel.Warn177                |> logConfig178                |> logger.fromLog179180            /// <summary>181            /// Logs a warn log message given a log configurer.182            /// </summary>183            /// <param name="logConfig">A function to configure a log</param>184            member logger.warn(logConfig: Log -> Log) =185                logger.warn' logConfig186                |> ignore187188            /// <summary>189            /// Logs an info log message given a log configurer.190            /// </summary>191            /// <param name="logConfig">A function to configure a log</param>192            /// <returns><see langword="true"/>  if the log message was logged</returns>193            member logger.info'(logConfig: Log -> Log) =194                Log.StartLogLevel LogLevel.Info195                |> logConfig196                |> logger.fromLog197198            /// <summary>199            /// Logs an info log message given a log configurer.200            /// </summary>201            /// <param name="logConfig">A function to configure a log</param>202            member logger.info(logConfig: Log -> Log) =203                logger.info' logConfig204                |> ignore205206            /// <summary>207            /// Logs a debug log message given a log configurer.208            /// </summary>209            /// <param name="logConfig">A function to configure a log</param>210            /// <returns><see langword="true"/>  if the log message was logged</returns>211            member logger.debug'(logConfig: Log -> Log) =212                Log.StartLogLevel LogLevel.Debug213                |> logConfig214                |> logger.fromLog215216            /// <summary>217            /// Logs a debug log message given a log configurer.218            /// </summary>219            /// <param name="logConfig">A function to configure a log</param>220            member logger.debug(logConfig: Log -> Log) =221                logger.debug' logConfig222                |> ignore  223224    module Log =225226        /// <summary>227        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.228        /// </summary>229        /// <param name="message">The message to set for the log.</param>230        /// <param name="log">The log to amend.</param>231        /// <returns>The amended log.</returns>232        let setMessage (message: string) (log: Log) =233            { log with234                  Message = Some(fun () -> message) }235236        /// <summary>237        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con238        /// </summary>239        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>240        /// <param name="log">The log to amend.</param>241        /// <returns>The amended log.</returns>242        let setMessageThunk (messageThunk: unit -> string) (log: Log) =243            { log with Message = Some messageThunk }244245        /// <summary>246        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.247        /// </summary>248        /// <param name="param">The value to add to the log</param>249        /// <param name="log">The log to amend.</param>250        /// <returns>The amended log.</returns>251        let addParameter (param: 'a) (log: Log) =252            { log with253                  Parameters = List.append log.Parameters [ (box param) ] }254255        /// <summary>256        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.257        /// </summary>258        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>259        /// <param name="log">The log to amend.</param>260        /// <returns>The amended log.</returns>261        let addParameters (``params``: obj list) (log: Log) =262            let ``params`` = ``params`` |> List.map box263264            { log with265                  Parameters = log.Parameters @ ``params`` }266267268269        /// <summary>270        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe271        /// This DOES NOT affect the parameters set for a message template.272        /// This is the same calling OpenMappedContext right before logging.224            /// <summary>225            /// Logs a trace log message given a log configurer.226            /// </summary>227            /// <param name="logConfig">A function to configure a log</param>228            /// <returns><see langword="true"/>  if the log message was logged</returns>229            member logger.trace'(logConfig: Log -> Log) =230                Log.StartLogLevel LogLevel.Trace231                |> logConfig232                |> logger.fromLog233234            /// <summary>235            /// Logs a trace log message given a log configurer.236            /// </summary>237            /// <param name="logConfig">A function to configure a log</param>238            member logger.trace(logConfig: Log -> Log) =239                logger.trace' logConfig240                |> ignore241242243    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.244    type ILogProvider =245        abstract member GetLogger: string -> Logger246        abstract member OpenNestedContext: string -> IDisposable247        abstract member OpenMappedContext: string -> obj -> bool -> IDisposable248249    module Log =250251        /// <summary>252        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.253        /// </summary>254        /// <param name="message">The message to set for the log.</param>255        /// <param name="log">The log to amend.</param>256        /// <returns>The amended log.</returns>257        let setMessage (message: string) (log: Log) =258            { log with259                Message = Some(fun () -> message)260            }261262        /// <summary>263        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con264        /// </summary>265        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>266        /// <param name="log">The log to amend.</param>267        /// <returns>The amended log.</returns>268        let setMessageThunk (messageThunk: unit -> string) (log: Log) =269            { log with Message = Some messageThunk }270271        /// <summary>272        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.  273        /// </summary>274        /// <param name="key">The key of the parameter to add to the log.</param>275        /// <param name="value">The value of the parameter to add to the log.</param>276        /// <param name="log">The log to amend.</param>277        /// <returns>The amended log.</returns>278        let addContext (key: string) (value: obj) (log: Log) =279            { log with280                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] }274        /// <param name="param">The value to add to the log</param>275        /// <param name="log">The log to amend.</param>276        /// <returns>The amended log.</returns>277        let addParameter (param: 'a) (log: Log) =278            { log with279                Parameters = List.append log.Parameters [ (box param) ]280            }  281282283        /// <summary>284        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe285        /// This DOES NOT affect the parameters set for a message template.286        /// This is the same calling OpenMappedContext right before logging.287        /// This destructures an object rather than calling `ToString()` on it.288        /// WARNING: Destructring can be expensive.289        /// </summary>290        /// <param name="key">The key of the parameter to add to the log.</param>291        /// <param name="value">The value of the parameter to add to the log.</param>292        /// <param name="log">The log to amend.</param>293        /// <returns>The amended log.</returns>294        let addContextDestructured (key: string) (value: obj) (log: Log) =295            { log with296                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] }297282        /// <summary>283        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.284        /// </summary>285        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>286        /// <param name="log">The log to amend.</param>287        /// <returns>The amended log.</returns>288        let addParameters (``params``: obj list) (log: Log) =289            let ``params`` =290                ``params``291                |> List.map box292293            { log with294                Parameters =295                    log.Parameters296                    @ ``params``297            }  298299        /// <summary>300        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle301        /// </summary>302        /// <param name="exception">The exception to add to the log.</param>303        /// <param name="log">The log to amend.</param>304        /// <returns>The amended log.</returns>305        let addException (``exception``: exn) (log: Log) =306            { log with307                  Exception = Option.ofObj ``exception`` }308309        /// <summary>310        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle311        /// </summary>312        /// <param name="exception">The exception to add to the log.</param>313        /// <param name="log">The log to amend.</param>314        /// <returns>The amended log.</returns>315        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log316317        /// <summary>318        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe319        /// </summary>320        /// <param name="logLevel">The level to set for the log.</param>321        /// <param name="log">The log to amend.</param>322        /// <returns>The amended log.</returns>323        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }324325#if !FABLE_COMPILER326327        let private formatterRegex =328            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)329330        let private isAnObject value =331            Convert.GetTypeCode(value) = TypeCode.Object332333        /// <summary>334        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m335        ///336        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr337        /// </summary>338        /// <param name="message">An interpolated string</param>339        /// <param name="log">The log to amend.</param>340        /// <returns>The amended log.</returns>341        let setMessageInterpolated (message: FormattableString) (log: Log) =342            let mutable messageFormat = message.Format343344            let args =345                formatterRegex.Matches(messageFormat)346                |> Seq.cast<Match>347                |> Seq.map348                    (fun m ->349                        let number = Int32.Parse(m.Groups.["number"].Value)350                        let formatGroup = m.Groups.["format"]351                        let propertyValue = message.GetArgument(number)352                        let propertyName = formatGroup.Value353                        let columnFormatGroup = m.Groups.["columnFormat"]354                        propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length355                        )356            // Reverse the args so we won't change the indexes earlier in the string357            args358            |> Seq.rev359            |> Seq.iter360                (fun (_, _, removeStart, removeLength) ->361                    if removeLength > 0 then362                        messageFormat <- messageFormat.Remove(removeStart, removeLength))299300        /// <summary>301        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe302        /// This DOES NOT affect the parameters set for a message template.303        /// This is the same calling OpenMappedContext right before logging.304        /// </summary>305        /// <param name="key">The key of the parameter to add to the log.</param>306        /// <param name="value">The value of the parameter to add to the log.</param>307        /// <param name="log">The log to amend.</param>308        /// <returns>The amended log.</returns>309        let addContext (key: string) (value: obj) (log: Log) =310            { log with311                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ]312            }313314315        /// <summary>316        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe317        /// This DOES NOT affect the parameters set for a message template.318        /// This is the same calling OpenMappedContext right before logging.319        /// This destructures an object rather than calling `ToString()` on it.320        /// WARNING: Destructring can be expensive.321        /// </summary>322        /// <param name="key">The key of the parameter to add to the log.</param>323        /// <param name="value">The value of the parameter to add to the log.</param>324        /// <param name="log">The log to amend.</param>325        /// <returns>The amended log.</returns>326        let addContextDestructured (key: string) (value: obj) (log: Log) =327            { log with328                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ]329            }330331332        /// <summary>333        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle334        /// </summary>335        /// <param name="exception">The exception to add to the log.</param>336        /// <param name="log">The log to amend.</param>337        /// <returns>The amended log.</returns>338        let addException (``exception``: exn) (log: Log) =339            { log with340                Exception = Option.ofObj ``exception``341            }342343        /// <summary>344        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle345        /// </summary>346        /// <param name="exception">The exception to add to the log.</param>347        /// <param name="log">The log to amend.</param>348        /// <returns>The amended log.</returns>349        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log350351        /// <summary>352        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe353        /// </summary>354        /// <param name="logLevel">The level to set for the log.</param>355        /// <param name="log">The log to amend.</param>356        /// <returns>The amended log.</returns>357        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }358359#if !FABLE_COMPILER360361        let private formatterRegex =362            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)  363364            let namedArgs =365                args366                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")367                |> Seq.toArray368369            messageFormat <-370                messageFormat371                    .Replace("{{", "{{{{")372                    .Replace("}}", "}}}}")373            // Replace numbered args with named args from regex match374            messageFormat <- String.Format(messageFormat, args = namedArgs)375376            let addContexts args (log: Log) =377                let addArgsToContext =378                    (id, args)379                    ||> Seq.fold380                            (fun state (name, value, _, _) ->381                                let contextAdder =382                                    if value |> isAnObject then383                                        addContextDestructured384                                    else385                                        addContext386387                                state >> contextAdder name value)388389                addArgsToContext log390391            log392            |> setMessage messageFormat393            |> addContexts args394395        /// <summary>396        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m397        ///398        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr399        /// </summary>400        /// <param name="message">An interpolated string</param>401        /// <param name="log">The log to amend.</param>402        /// <returns>The amended log.</returns>403        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log404#endif364        let private isAnObject value =365            Convert.GetTypeCode(value) = TypeCode.Object366367        /// <summary>368        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m369        ///370        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr371        /// </summary>372        /// <param name="message">An interpolated string</param>373        /// <param name="log">The log to amend.</param>374        /// <returns>The amended log.</returns>375        let setMessageInterpolated (message: FormattableString) (log: Log) =376            let mutable messageFormat = message.Format377378            let args =379                formatterRegex.Matches(messageFormat)380                |> Seq.cast<Match>381                |> Seq.map (fun m ->382                    let number = Int32.Parse(m.Groups.["number"].Value)383                    let formatGroup = m.Groups.["format"]384                    let propertyValue = message.GetArgument(number)385                    let propertyName = formatGroup.Value386                    let columnFormatGroup = m.Groups.["columnFormat"]387                    propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length388                )389            // Reverse the args so we won't change the indexes earlier in the string390            args391            |> Seq.rev392            |> Seq.iter (fun (_, _, removeStart, removeLength) ->393                if removeLength > 0 then394                    messageFormat <- messageFormat.Remove(removeStart, removeLength)395            )396397            let namedArgs =398                args399                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}")400                |> Seq.toArray401402            messageFormat <- messageFormat.Replace("{{", "{{{{").Replace("}}", "}}}}")403            // Replace numbered args with named args from regex match404            messageFormat <- String.Format(messageFormat, args = namedArgs)  405406/// Provides operators to make writing logs more streamlined.407module Operators =408409    /// <summary>410    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.411    /// </summary>412    /// <param name="message">The string of the base message.</param>413    /// <returns>A new Log instance with the specified message.</returns>414    let (!!!) message = Log.setMessage message406            let addContexts args (log: Log) =407                let addArgsToContext =408                    (id, args)409                    ||> Seq.fold (fun state (name, value, _, _) ->410                        let contextAdder =411                            if value |> isAnObject then412                                addContextDestructured413                            else414                                addContext  415416    /// <summary>417    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<418    /// </summary>419    /// <param name="log">The Log to add the parameter to.</param>420    /// <param name="value">The value for the parameter.</param>421    /// <returns>The Log with the added parameter.</returns>422    let (>>!) log value = log >> Log.addParameter value423424    /// <summary>425    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.426    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right427    ///428    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.429    /// </summary>430    /// <param name="log">The log to add the parameter to.</param>431    /// <param name="key">The name for the parameter.</param>432    /// <param name="value">The value for the parameter.</param>433    /// <returns>The amended log with the parameter added.</returns>434    let (>>!-) log (key, value) = log >> Log.addContext key value435436    /// <summary>437    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT438    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling439    ///440    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.441    /// </summary>442    /// <param name="log">The log to add the parameter to.</param>443    /// <param name="key">The name for the parameter.</param>444    /// <param name="value">The value for the parameter.</param>445    /// <returns>The amended log with the parameter added.</returns>446    let (>>!+) log (key, value) =447        log >> Log.addContextDestructured key value448449    /// <summary>450    /// Amends a Log with an exn. Handles nulls.451    ///452    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.453    /// </summary>454    /// <param name="log">The log to add the parameter to.</param>455    /// <param name="e">The exception to add to the log.</param>456    /// <returns>The amended log with the parameter added.</returns>457    let (>>!!) log e = log >> Log.addException e458459460#if !FABLE_COMPILER461module Providers =462    module SerilogProvider =463        open System464        open System.Linq.Expressions465 - 0466        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog") - 0467        let isAvailable () = getLogManagerType () |> isNull |> not468469        let getPushProperty () =416                        state417                        >> contextAdder name value418                    )419420                addArgsToContext log421422            log423            |> setMessage messageFormat424            |> addContexts args425426        /// <summary>427        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m428        ///429        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr430        /// </summary>431        /// <param name="message">An interpolated string</param>432        /// <param name="log">The log to amend.</param>433        /// <returns>The amended log.</returns>434        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log435#endif436437/// Provides operators to make writing logs more streamlined.438module Operators =439440    /// <summary>441    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.442    /// </summary>443    /// <param name="message">The string of the base message.</param>444    /// <returns>A new Log instance with the specified message.</returns>445    let (!!!) message = Log.setMessage message446447    /// <summary>448    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<449    /// </summary>450    /// <param name="log">The Log to add the parameter to.</param>451    /// <param name="value">The value for the parameter.</param>452    /// <returns>The Log with the added parameter.</returns>453    let (>>!) log value =454        log455        >> Log.addParameter value456457    /// <summary>458    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.459    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right460    ///461    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.462    /// </summary>463    /// <param name="log">The log to add the parameter to.</param>464    /// <param name="key">The name for the parameter.</param>465    /// <param name="value">The value for the parameter.</param>466    /// <returns>The amended log with the parameter added.</returns>467    let (>>!-) log (key, value) =468        log469        >> Log.addContext key value  470 - 0471            let ndcContextType = - 0472                Type.GetType("Serilog.Context.LogContext, Serilog") - 0473                |> Option.ofObj - 0474                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))475476            ()477 - 0478            let pushPropertyMethod = - 0479                ndcContextType.GetMethod( - 0480                    "PushProperty", - 0481                    [| typedefof<string> - 0482                       typedefof<obj> - 0483                       typedefof<bool> |] - 0484                )485 - 0486            let nameParam = - 0487                Expression.Parameter(typedefof<string>, "name")488 - 0489            let valueParam = - 0490                Expression.Parameter(typedefof<obj>, "value")491 - 0492            let destructureObjectParam = - 0493                Expression.Parameter(typedefof<bool>, "destructureObjects")494 - 0495            let pushPropertyMethodCall = - 0496                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)471    /// <summary>472    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT473    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling474    ///475    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.476    /// </summary>477    /// <param name="log">The log to add the parameter to.</param>478    /// <param name="key">The name for the parameter.</param>479    /// <param name="value">The value for the parameter.</param>480    /// <returns>The amended log with the parameter added.</returns>481    let (>>!+) log (key, value) =482        log483        >> Log.addContextDestructured key value484485    /// <summary>486    /// Amends a Log with an exn. Handles nulls.487    ///488    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.489    /// </summary>490    /// <param name="log">The log to add the parameter to.</param>491    /// <param name="e">The exception to add to the log.</param>492    /// <returns>The amended log with the parameter added.</returns>493    let (>>!!) log e =494        log495        >> Log.addException e496  497 - 0498            let pushProperty = - 0499                Expression - 0500                    .Lambda<Func<string, obj, bool, IDisposable>>( - 0501                        pushPropertyMethodCall, - 0502                        nameParam, - 0503                        valueParam, - 0504                        destructureObjectParam - 0505                    ) - 0506                    .Compile()507 - 0508            fun key value destructure -> pushProperty.Invoke(key, value, destructure)509498#if !FABLE_COMPILER499module Providers =500    module SerilogProvider =501        open System502        open System.Linq.Expressions503 + 0504        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")505506        let isAvailable () = + 0507            getLogManagerType () + 0508            |> isNull + 0509            |> not  510511        let getForContextMethodCall () = - 0512            let logManagerType = getLogManagerType ()513 - 0514            let method = - 0515                logManagerType.GetMethod( - 0516                    "ForContext", - 0517                    [| typedefof<string> - 0518                       typedefof<obj> - 0519                       typedefof<bool> |] - 0520                )521 - 0522            let propertyNameParam = - 0523                Expression.Parameter(typedefof<string>, "propertyName")524 - 0525            let valueParam = - 0526                Expression.Parameter(typedefof<obj>, "value")527 - 0528            let destructureObjectsParam = - 0529                Expression.Parameter(typedefof<bool>, "destructureObjects")530 - 0531            let exrs: Expression [] = - 0532                [| propertyNameParam - 0533                   valueParam - 0534                   destructureObjectsParam |]535 - 0536            let methodCall = Expression.Call(null, method, exrs)537 - 0538            let func = - 0539                Expression - 0540                    .Lambda<Func<string, obj, bool, obj>>( - 0541                        methodCall, - 0542                        propertyNameParam, - 0543                        valueParam, - 0544                        destructureObjectsParam - 0545                    ) - 0546                    .Compile()547 - 0548            fun name -> func.Invoke("SourceContext", name, false)511        let getPushProperty () =512513            let ndcContextType = + 0514                Type.GetType("Serilog.Context.LogContext, Serilog") + 0515                |> Option.ofObj + 0516                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))517518            ()519 + 0520            let pushPropertyMethod = + 0521                ndcContextType.GetMethod( + 0522                    "PushProperty", + 0523                    [| + 0524                        typedefof<string> + 0525                        typedefof<obj> + 0526                        typedefof<bool> + 0527                    |] + 0528                )529 + 0530            let nameParam = Expression.Parameter(typedefof<string>, "name")531 + 0532            let valueParam = Expression.Parameter(typedefof<obj>, "value")533 + 0534            let destructureObjectParam = + 0535                Expression.Parameter(typedefof<bool>, "destructureObjects")536 + 0537            let pushPropertyMethodCall = + 0538                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)539 + 0540            let pushProperty = + 0541                Expression + 0542                    .Lambda<Func<string, obj, bool, IDisposable>>( + 0543                        pushPropertyMethodCall, + 0544                        nameParam, + 0545                        valueParam, + 0546                        destructureObjectParam + 0547                    ) + 0548                    .Compile()  549550        [<NoEquality; NoComparison>]551        type SerilogGateway =552            { Write: obj -> obj -> string -> obj [] -> unit553              WriteException: obj -> obj -> exn -> string -> obj [] -> unit554              IsEnabled: obj -> obj -> bool555              TranslateLevel: LogLevel -> obj }556            static member Create() = - 0557                let logEventLevelType = - 0558                    Type.GetType("Serilog.Events.LogEventLevel, Serilog")559 - 0560                if (logEventLevelType |> isNull) then - 0561                    failwith ("Type Serilog.Events.LogEventLevel was not found.")562 - 0563                let debugLevel = - 0564                    Enum.Parse(logEventLevelType, "Debug", false) + 0550            fun key value destructure -> pushProperty.Invoke(key, value, destructure)551552553        let getForContextMethodCall () = + 0554            let logManagerType = getLogManagerType ()555 + 0556            let method = + 0557                logManagerType.GetMethod( + 0558                    "ForContext", + 0559                    [| + 0560                        typedefof<string> + 0561                        typedefof<obj> + 0562                        typedefof<bool> + 0563                    |] + 0564                )  565 - 0566                let errorLevel = - 0567                    Enum.Parse(logEventLevelType, "Error", false)568 - 0569                let fatalLevel = - 0570                    Enum.Parse(logEventLevelType, "Fatal", false)571 - 0572                let informationLevel = - 0573                    Enum.Parse(logEventLevelType, "Information", false)574 - 0575                let verboseLevel = - 0576                    Enum.Parse(logEventLevelType, "Verbose", false)577 - 0578                let warningLevel = - 0579                    Enum.Parse(logEventLevelType, "Warning", false) + 0566            let propertyNameParam = Expression.Parameter(typedefof<string>, "propertyName")567 + 0568            let valueParam = Expression.Parameter(typedefof<obj>, "value")569 + 0570            let destructureObjectsParam = + 0571                Expression.Parameter(typedefof<bool>, "destructureObjects")572 + 0573            let exrs: Expression[] = [| + 0574                propertyNameParam + 0575                valueParam + 0576                destructureObjectsParam + 0577            |]578 + 0579            let methodCall = Expression.Call(null, method, exrs)  580581                let translateLevel (level: LogLevel) = - 0582                    match level with - 0583                    | LogLevel.Fatal -> fatalLevel - 0584                    | LogLevel.Error -> errorLevel - 0585                    | LogLevel.Warn -> warningLevel - 0586                    | LogLevel.Info -> informationLevel - 0587                    | LogLevel.Debug -> debugLevel - 0588                    | LogLevel.Trace -> verboseLevel - 0589                    | _ -> debugLevel + 0581            let func = + 0582                Expression + 0583                    .Lambda<Func<string, obj, bool, obj>>( + 0584                        methodCall, + 0585                        propertyNameParam, + 0586                        valueParam, + 0587                        destructureObjectsParam + 0588                    ) + 0589                    .Compile()  590 - 0591                let loggerType = Type.GetType("Serilog.ILogger, Serilog") + 0591            fun name -> func.Invoke("SourceContext", name, false)  592 - 0593                if (loggerType |> isNull) then - 0594                    failwith ("Type Serilog.ILogger was not found.")595 - 0596                let isEnabledMethodInfo = - 0597                    loggerType.GetMethod("IsEnabled", [| logEventLevelType |])598 - 0599                let instanceParam = Expression.Parameter(typedefof<obj>)600 - 0601                let instanceCast = - 0602                    Expression.Convert(instanceParam, loggerType)603 - 0604                let levelParam = Expression.Parameter(typedefof<obj>)605 - 0606                let levelCast = - 0607                    Expression.Convert(levelParam, logEventLevelType)608 - 0609                let isEnabledMethodCall = - 0610                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)611 - 0612                let isEnabled = - 0613                    Expression - 0614                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam) - 0615                        .Compile()593        [<NoEquality; NoComparison>]594        type SerilogGateway =595            {596                Write: obj -> obj -> string -> obj[] -> unit597                WriteException: obj -> obj -> exn -> string -> obj[] -> unit598                IsEnabled: obj -> obj -> bool599                TranslateLevel: LogLevel -> obj600            }601602            static member Create() = + 0603                let logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog")604 + 0605                if + 0606                    (logEventLevelType + 0607                     |> isNull) + 0608                then + 0609                    failwith ("Type Serilog.Events.LogEventLevel was not found.")610 + 0611                let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)612 + 0613                let errorLevel = Enum.Parse(logEventLevelType, "Error", false)614 + 0615                let fatalLevel = Enum.Parse(logEventLevelType, "Fatal", false)  616 - 0617                let writeMethodInfo = - 0618                    loggerType.GetMethod( - 0619                        "Write", - 0620                        [| logEventLevelType - 0621                           typedefof<string> - 0622                           typedefof<obj []> |] - 0623                    )624 - 0625                let messageParam = Expression.Parameter(typedefof<string>) - 0626                let propertyValuesParam = Expression.Parameter(typedefof<obj []>)627 - 0628                let writeMethodExp = - 0629                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)630 - 0631                let expression = - 0632                    Expression.Lambda<Action<obj, obj, string, obj []>>( - 0633                        writeMethodExp, - 0634                        instanceParam, - 0635                        levelParam, - 0636                        messageParam, - 0637                        propertyValuesParam - 0638                    ) + 0617                let informationLevel = Enum.Parse(logEventLevelType, "Information", false)618 + 0619                let verboseLevel = Enum.Parse(logEventLevelType, "Verbose", false)620 + 0621                let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)622623                let translateLevel (level: LogLevel) = + 0624                    match level with + 0625                    | LogLevel.Fatal -> fatalLevel + 0626                    | LogLevel.Error -> errorLevel + 0627                    | LogLevel.Warn -> warningLevel + 0628                    | LogLevel.Info -> informationLevel + 0629                    | LogLevel.Debug -> debugLevel + 0630                    | LogLevel.Trace -> verboseLevel + 0631                    | _ -> debugLevel632 + 0633                let loggerType = Type.GetType("Serilog.ILogger, Serilog")634 + 0635                if (loggerType |> isNull) then + 0636                    failwith ("Type Serilog.ILogger was not found.")637 + 0638                let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  639 - 0640                let write = expression.Compile() + 0640                let instanceParam = Expression.Parameter(typedefof<obj>)  641 - 0642                let writeExceptionMethodInfo = - 0643                    loggerType.GetMethod( - 0644                        "Write", - 0645                        [| logEventLevelType - 0646                           typedefof<exn> - 0647                           typedefof<string> - 0648                           typedefof<obj []> |] - 0649                    ) + 0642                let instanceCast = Expression.Convert(instanceParam, loggerType)643 + 0644                let levelParam = Expression.Parameter(typedefof<obj>)645 + 0646                let levelCast = Expression.Convert(levelParam, logEventLevelType)647 + 0648                let isEnabledMethodCall = + 0649                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  650 - 0651                let exceptionParam = Expression.Parameter(typedefof<exn>)652 - 0653                let writeMethodExp = - 0654                    Expression.Call( - 0655                        instanceCast, - 0656                        writeExceptionMethodInfo, - 0657                        levelCast, - 0658                        exceptionParam, - 0659                        messageParam, - 0660                        propertyValuesParam - 0661                    )662 - 0663                let writeException = - 0664                    Expression - 0665                        .Lambda<Action<obj, obj, exn, string, obj []>>( - 0666                            writeMethodExp, - 0667                            instanceParam, - 0668                            levelParam, - 0669                            exceptionParam, - 0670                            messageParam, - 0671                            propertyValuesParam - 0672                        ) - 0673                        .Compile()674 - 0675                { Write = - 0676                      (fun logger level message formattedParmeters -> - 0677                          write.Invoke(logger, level, message, formattedParmeters)) - 0678                  WriteException = - 0679                      fun logger level ex message formattedParmeters -> - 0680                          writeException.Invoke(logger, level, ex, message, formattedParmeters) - 0681                  IsEnabled = fun logger level -> isEnabled.Invoke(logger, level) - 0682                  TranslateLevel = translateLevel }683 - 0684        type private SeriLogProvider() = - 0685            let getLoggerByName = getForContextMethodCall () - 0686            let pushProperty = getPushProperty () - 0687            let serilogGatewayInit = lazy (SerilogGateway.Create())688689            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =690                let serilogGateway = serilogGatewayInit.Value691                let translatedValue = serilogGateway.TranslateLevel logLevel692693                match messageFunc with694                | None -> serilogGateway.IsEnabled logger translatedValue695                | Some _ when696                    serilogGateway.IsEnabled logger translatedValue697                    |> not698                    ->699                    false700                | Some m ->701                    match ``exception`` with702                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams703                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams704705                    true706707            interface ILogProvider with - 0708                member this.GetLogger(name: string) : Logger = getLoggerByName name |> writeMessage709710                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable = - 0711                    pushProperty key value destructure712 - 0713                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false714 - 0715        let create () = SeriLogProvider() :> ILogProvider716 + 0651                let isEnabled = + 0652                    Expression + 0653                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam) + 0654                        .Compile()655 + 0656                let writeMethodInfo = + 0657                    loggerType.GetMethod( + 0658                        "Write", + 0659                        [| + 0660                            logEventLevelType + 0661                            typedefof<string> + 0662                            typedefof<obj[]> + 0663                        |] + 0664                    )665 + 0666                let messageParam = Expression.Parameter(typedefof<string>) + 0667                let propertyValuesParam = Expression.Parameter(typedefof<obj[]>)668 + 0669                let writeMethodExp = + 0670                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)671 + 0672                let expression = + 0673                    Expression.Lambda<Action<obj, obj, string, obj[]>>( + 0674                        writeMethodExp, + 0675                        instanceParam, + 0676                        levelParam, + 0677                        messageParam, + 0678                        propertyValuesParam + 0679                    )680 + 0681                let write = expression.Compile()682 + 0683                let writeExceptionMethodInfo = + 0684                    loggerType.GetMethod( + 0685                        "Write", + 0686                        [| + 0687                            logEventLevelType + 0688                            typedefof<exn> + 0689                            typedefof<string> + 0690                            typedefof<obj[]> + 0691                        |] + 0692                    )693 + 0694                let exceptionParam = Expression.Parameter(typedefof<exn>)695 + 0696                let writeMethodExp = + 0697                    Expression.Call( + 0698                        instanceCast, + 0699                        writeExceptionMethodInfo, + 0700                        levelCast, + 0701                        exceptionParam, + 0702                        messageParam, + 0703                        propertyValuesParam + 0704                    )705 + 0706                let writeException = + 0707                    Expression + 0708                        .Lambda<Action<obj, obj, exn, string, obj[]>>( + 0709                            writeMethodExp, + 0710                            instanceParam, + 0711                            levelParam, + 0712                            exceptionParam, + 0713                            messageParam, + 0714                            propertyValuesParam + 0715                        ) + 0716                        .Compile()  717718    module MicrosoftExtensionsLoggingProvider =719        open System720        open System.Linq.Expressions721        open System.Reflection722        open System.Collections.Generic723724        type ILoggerFactory = obj725        // This has to be set from usercode for this to light up726        let mutable private  microsoftLoggerFactory : ILoggerFactory option = None - 0727        let setMicrosoftLoggerFactory (factory : ILoggerFactory) = microsoftLoggerFactory <- Option.ofObj factory728 - 0729        let getLogFactoryType = lazy(Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Log730        let isAvailable () =731            getLogFactoryType.Value |> isNull |> not732            && microsoftLoggerFactory |> Option.isSome733 + 0718                { + 0719                    Write = + 0720                        (fun logger level message formattedParmeters -> + 0721                            write.Invoke(logger, level, message, formattedParmeters) + 0722                        ) + 0723                    WriteException = + 0724                        fun logger level ex message formattedParmeters -> + 0725                            writeException.Invoke(logger, level, ex, message, formattedParmeters) + 0726                    IsEnabled = fun logger level -> isEnabled.Invoke(logger, level) + 0727                    TranslateLevel = translateLevel + 0728                }729730        type private SeriLogProvider() = + 0731            let getLoggerByName = getForContextMethodCall () + 0732            let pushProperty = getPushProperty () + 0733            let serilogGatewayInit = lazy (SerilogGateway.Create())  734735        type ILogger = obj736        type LoggerName = string737        type MicrosoftLogLevel = obj738        type MessageFormat = string739        type MessageArgs = obj array740741        [<NoEquality; NoComparison>]742        type LoggerFactoryGateway = {743            CreateLogger : ILoggerFactory -> LoggerName -> ILogger744        }745        with746            static member Create() =747                let createLogger = - 0748                    let factoryType = getLogFactoryType.Value - 0749                    let createLoggerMethodInfo = - 0750                        factoryType.GetMethod( - 0751                            "CreateLogger", - 0752                            [|typedefof<string>|]) - 0753                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>) - 0754                    let nameParam = Expression.Parameter(typedefof<string>) - 0755                    let instanceCast = - 0756                        Expression.Convert(instanceParam, factoryType) - 0757                    let createLoggerMethodExp = - 0758                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam) - 0759                    let createLogger = - 0760                        Expression - 0761                            .Lambda<Func<ILoggerFactory,string,ILogger>>(createLoggerMethodExp, instanceParam, nameParam - 0762                            .Compile() - 0763                    createLogger - 0764                    |> FuncConvert.FromFunc - 0765                { - 0766                    CreateLogger = createLogger - 0767                }768769        type LoggerGateway = {770            Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit771            WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit772            IsEnabled: ILogger -> MicrosoftLogLevel -> bool773            TranslateLevel : LogLevel -> MicrosoftLogLevel774            BeginScope : ILogger -> obj -> IDisposable775        } with776            static member Create () = - 0777                let loggerExtensions = Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions - 0778                let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstra - 0779                let logEventLevelType = - 0780                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions") - 0781                let instanceParam = Expression.Parameter(typedefof<ILogger>)735            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =736                let serilogGateway = serilogGatewayInit.Value737                let translatedValue = serilogGateway.TranslateLevel logLevel738739                match messageFunc with740                | None -> serilogGateway.IsEnabled logger translatedValue741                | Some _ when742                    serilogGateway.IsEnabled logger translatedValue743                    |> not744                    ->745                    false746                | Some m ->747                    match ``exception`` with748                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams749                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams750751                    true752753            interface ILogProvider with754                member this.GetLogger(name: string) : Logger = + 0755                    getLoggerByName name + 0756                    |> writeMessage757758                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable = + 0759                    pushProperty key value destructure760 + 0761                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false762 + 0763        let create () = SeriLogProvider() :> ILogProvider764765766    module MicrosoftExtensionsLoggingProvider =767        open System768        open System.Linq.Expressions769        open System.Reflection770        open System.Collections.Generic771772        type ILoggerFactory = obj773        // This has to be set from usercode for this to light up774        let mutable private microsoftLoggerFactory: ILoggerFactory option = None775776        let setMicrosoftLoggerFactory (factory: ILoggerFactory) = + 0777            microsoftLoggerFactory <- Option.ofObj factory778779        let getLogFactoryType =780            lazy + 0781                (Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.Abstractions"))  782 - 0783                let instanceCast = - 0784                    Expression.Convert(instanceParam, loggerType) - 0785                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)786 - 0787                let levelCast = Expression.Convert(levelParam, logEventLevelType)788789                let isEnabled = - 0790                    let isEnabledMethodInfo = - 0791                        loggerType.GetMethod("IsEnabled", [| logEventLevelType |]) - 0792                    let isEnabledMethodCall = - 0793                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)794795 - 0796                    Expression - 0797                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam) - 0798                        .Compile() - 0799                    |> FuncConvert.FromFunc800801                let write, writeError = - 0802                    let messageParam = Expression.Parameter(typedefof<MessageFormat>) - 0803                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)804805                    let write = - 0806                        let writeMethodInfo = - 0807                            loggerExtensions.GetMethod( - 0808                                "Log", - 0809                                BindingFlags.Static ||| BindingFlags.Public, - 0810                                null, - 0811                                [| loggerType - 0812                                   logEventLevelType - 0813                                   typedefof<MessageFormat> - 0814                                   typedefof<MessageArgs> |], - 0815                                null - 0816                            )817 - 0818                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, messagePara819 - 0820                        let expression = - 0821                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>( - 0822                                writeMethodExp, - 0823                                instanceParam, - 0824                                levelParam, - 0825                                messageParam, - 0826                                propertyValuesParam - 0827                            ) - 0828                        expression.Compile() |> FuncConvert.FromAction829783        let isAvailable () =784            getLogFactoryType.Value785            |> isNull786            |> not + 0787            && microsoftLoggerFactory + 0788               |> Option.isSome789790791        type ILogger = obj792        type LoggerName = string793        type MicrosoftLogLevel = obj794        type MessageFormat = string795        type MessageArgs = obj array796797        [<NoEquality; NoComparison>]798        type LoggerFactoryGateway =799            {800                CreateLogger: ILoggerFactory -> LoggerName -> ILogger801            }802803            static member Create() =804                let createLogger = + 0805                    let factoryType = getLogFactoryType.Value806 + 0807                    let createLoggerMethodInfo = + 0808                        factoryType.GetMethod("CreateLogger", [| typedefof<string> |])809 + 0810                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>) + 0811                    let nameParam = Expression.Parameter(typedefof<string>) + 0812                    let instanceCast = Expression.Convert(instanceParam, factoryType)813 + 0814                    let createLoggerMethodExp = + 0815                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)816 + 0817                    let createLogger = + 0818                        Expression + 0819                            .Lambda<Func<ILoggerFactory, string, ILogger>>( + 0820                                createLoggerMethodExp, + 0821                                instanceParam, + 0822                                nameParam + 0823                            ) + 0824                            .Compile()825 + 0826                    createLogger + 0827                    |> FuncConvert.FromFunc828 + 0829                { CreateLogger = createLogger }  830831                    let writeError = - 0832                        let writeMethodInfo = - 0833                            loggerExtensions.GetMethod( - 0834                                "Log", - 0835                                BindingFlags.Static ||| BindingFlags.Public, - 0836                                null, - 0837                                [| loggerType - 0838                                   logEventLevelType - 0839                                   typedefof<exn> - 0840                                   typedefof<MessageFormat> - 0841                                   typedefof<MessageArgs> |], - 0842                                null - 0843 - 0844                            ) - 0845                        let exnParam = Expression.Parameter(typedefof<exn>) - 0846                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, exnParam, m847 - 0848                        let expression = - 0849                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>( - 0850                                writeMethodExp, - 0851                                instanceParam, - 0852                                levelParam, - 0853                                exnParam, - 0854                                messageParam, - 0855                                propertyValuesParam - 0856                            ) - 0857                        expression.Compile() |> FuncConvert.FromAction - 0858                    write, writeError859860                let translateLevel =831        type LoggerGateway =832            {833                Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit834                WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit835                IsEnabled: ILogger -> MicrosoftLogLevel -> bool836                TranslateLevel: LogLevel -> MicrosoftLogLevel837                BeginScope: ILogger -> obj -> IDisposable838            }839840            static member Create() = + 0841                let loggerExtensions = + 0842                    Type.GetType( + 0843                        "Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions" + 0844                    )845 + 0846                let loggerType = + 0847                    Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")848 + 0849                let logEventLevelType = + 0850                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")851 + 0852                let instanceParam = Expression.Parameter(typedefof<ILogger>)853 + 0854                let instanceCast = Expression.Convert(instanceParam, loggerType) + 0855                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)856 + 0857                let levelCast = Expression.Convert(levelParam, logEventLevelType)858859                let isEnabled = + 0860                    let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  861 - 0862                    let debugLevel = - 0863                        Enum.Parse(logEventLevelType, "Debug", false) + 0862                    let isEnabledMethodCall = + 0863                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  864 - 0865                    let errorLevel = - 0866                        Enum.Parse(logEventLevelType, "Error", false)867 - 0868                    let criticalLevel = - 0869                        Enum.Parse(logEventLevelType, "Critical", false)865 + 0866                    Expression + 0867                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam) + 0868                        .Compile() + 0869                    |> FuncConvert.FromFunc  870 - 0871                    let informationLevel = - 0872                        Enum.Parse(logEventLevelType, "Information", false)873 - 0874                    let traceLevel = - 0875                        Enum.Parse(logEventLevelType, "Trace", false)876 - 0877                    let warningLevel = - 0878                        Enum.Parse(logEventLevelType, "Warning", false)879 - 0880                    fun (level: LogLevel) -> - 0881                        match level with - 0882                        | LogLevel.Fatal -> criticalLevel - 0883                        | LogLevel.Error -> errorLevel - 0884                        | LogLevel.Warn -> warningLevel - 0885                        | LogLevel.Info -> informationLevel - 0886                        | LogLevel.Debug -> debugLevel - 0887                        | LogLevel.Trace -> traceLevel - 0888                        | _ -> debugLevel889                let beginScope = - 0890                    let beginScopeMethodInfo = - 0891                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>) - 0892                    let stateParam = Expression.Parameter(typedefof<obj>) - 0893                    let beginScopeMethodCall = - 0894                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)895 - 0896                    Expression - 0897                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam) - 0898                        .Compile() - 0899                    |> FuncConvert.FromFunc871                let write, writeError = + 0872                    let messageParam = Expression.Parameter(typedefof<MessageFormat>) + 0873                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)874875                    let write = + 0876                        let writeMethodInfo = + 0877                            loggerExtensions.GetMethod( + 0878                                "Log", + 0879                                BindingFlags.Static + 0880                                ||| BindingFlags.Public, + 0881                                null, + 0882                                [| + 0883                                    loggerType + 0884                                    logEventLevelType + 0885                                    typedefof<MessageFormat> + 0886                                    typedefof<MessageArgs> + 0887                                |], + 0888                                null + 0889                            )890 + 0891                        let writeMethodExp = + 0892                            Expression.Call( + 0893                                null, + 0894                                writeMethodInfo, + 0895                                instanceCast, + 0896                                levelCast, + 0897                                messageParam, + 0898                                propertyValuesParam + 0899                            )  900 - 0901                { - 0902                    Write = write - 0903                    WriteError = writeError - 0904                    IsEnabled = isEnabled - 0905                    TranslateLevel = translateLevel - 0906                    BeginScope = beginScope - 0907                }908 + 0901                        let expression = + 0902                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>( + 0903                                writeMethodExp, + 0904                                instanceParam, + 0905                                levelParam, + 0906                                messageParam, + 0907                                propertyValuesParam + 0908                            )  909 - 0910        type private MicrosoftProvider() = - 0911            let factoryGateway = lazy(LoggerFactoryGateway.Create()) - 0912            let loggerGateway = lazy(LoggerGateway.Create())913            interface ILogProvider with914                member this.GetLogger(name: string) : Logger = - 0915                    match microsoftLoggerFactory with916                    | None -> - 0917                        fun _ _ _ _ -> false918                    | Some factory -> - 0919                        let logger = factoryGateway.Value.CreateLogger factory name920 - 0921                        fun logLevel message exn args -> - 0922                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel - 0923                            match message with - 0924                            | Some message -> - 0925                                let message = message () - 0926                                match exn with - 0927                                | Some ex -> - 0928                                    loggerGateway.Value.WriteError logger microsoftLevel ex message args - 0929                                | None -> - 0930                                    loggerGateway.Value.Write logger microsoftLevel message args - 0931                                true - 0932                            | None -> - 0933                                loggerGateway.Value.IsEnabled logger microsoftLevel934935                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable = - 0936                    match microsoftLoggerFactory with937                    | None -> - 0938                        { new IDisposable with member x.Dispose () = ()}939                    | Some factory ->940                        // Create bogus logger that will propagate to a real logger later - 0941                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())942                        // Requires a IEnumerable<KeyValuePair> to make sense943                        // https://nblumhardt.com/2016/11/ilogger-beginscope/ - 0944                        [KeyValuePair(key, value)] - 0945                        |> box - 0946                        |> loggerGateway.Value.BeginScope logger947948949                member this.OpenNestedContext(message: string) : IDisposable = - 0950                    match microsoftLoggerFactory with951                    | None -> - 0952                        { new IDisposable with member x.Dispose () = ()}953                    | Some factory ->954                        // Create bogus logger that will propagate to a real logger later - 0955                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString()) - 0956                        loggerGateway.Value.BeginScope logger (box message) + 0910                        expression.Compile() + 0911                        |> FuncConvert.FromAction912913914                    let writeError = + 0915                        let writeMethodInfo = + 0916                            loggerExtensions.GetMethod( + 0917                                "Log", + 0918                                BindingFlags.Static + 0919                                ||| BindingFlags.Public, + 0920                                null, + 0921                                [| + 0922                                    loggerType + 0923                                    logEventLevelType + 0924                                    typedefof<exn> + 0925                                    typedefof<MessageFormat> + 0926                                    typedefof<MessageArgs> + 0927                                |], + 0928                                null + 0929 + 0930                            )931 + 0932                        let exnParam = Expression.Parameter(typedefof<exn>)933 + 0934                        let writeMethodExp = + 0935                            Expression.Call( + 0936                                null, + 0937                                writeMethodInfo, + 0938                                instanceCast, + 0939                                levelCast, + 0940                                exnParam, + 0941                                messageParam, + 0942                                propertyValuesParam + 0943                            )944 + 0945                        let expression = + 0946                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>( + 0947                                writeMethodExp, + 0948                                instanceParam, + 0949                                levelParam, + 0950                                exnParam, + 0951                                messageParam, + 0952                                propertyValuesParam + 0953                            )954 + 0955                        expression.Compile() + 0956                        |> FuncConvert.FromAction  957 - 0958        let create () = MicrosoftProvider() :> ILogProvider + 0958                    write, writeError  959960#endif960                let translateLevel =  961962963module LogProvider =964    open System965    open Types966    #if !FABLE_COMPILER967    open Providers968    #endif969    open System.Diagnostics970    open Microsoft.FSharp.Quotations.Patterns + 0962                    let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)963 + 0964                    let errorLevel = Enum.Parse(logEventLevelType, "Error", false)965 + 0966                    let criticalLevel = Enum.Parse(logEventLevelType, "Critical", false)967 + 0968                    let informationLevel = Enum.Parse(logEventLevelType, "Information", false)969 + 0970                    let traceLevel = Enum.Parse(logEventLevelType, "Trace", false)  971972    let mutable private currentLogProvider = None + 0972                    let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)  973974    let private knownProviders =975        [976        #if !FABLE_COMPILER977            (SerilogProvider.isAvailable, SerilogProvider.create)978            (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)979        #endif980        ]981982    /// Greedy search for first available LogProvider. Order of known providers matters.983    let private resolvedLogger =984        lazy985            (knownProviders986             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())987             |> Option.map (fun (_, create) -> create ()))988989    let private noopLogger _ _ _ _ = false990991    let private noopDisposable =992        { new IDisposable with993            member __.Dispose() = () }994995    /// <summary>996    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.997    /// </summary>998    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>999    /// <returns></returns>1000    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider10011002    /// <summary>1003    /// Gets the currently set LogProvider or attempts to find known built in providers1004    /// </summary>1005    /// <returns></returns>1006    let getCurrentLogProvider () =1007        match currentLogProvider with1008        | None -> resolvedLogger.Value1009        | Some p -> Some p974                    fun (level: LogLevel) -> + 0975                        match level with + 0976                        | LogLevel.Fatal -> criticalLevel + 0977                        | LogLevel.Error -> errorLevel + 0978                        | LogLevel.Warn -> warningLevel + 0979                        | LogLevel.Info -> informationLevel + 0980                        | LogLevel.Debug -> debugLevel + 0981                        | LogLevel.Trace -> traceLevel + 0982                        | _ -> debugLevel983984                let beginScope = + 0985                    let beginScopeMethodInfo = + 0986                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)987 + 0988                    let stateParam = Expression.Parameter(typedefof<obj>)989 + 0990                    let beginScopeMethodCall = + 0991                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)992 + 0993                    Expression + 0994                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam) + 0995                        .Compile() + 0996                    |> FuncConvert.FromFunc997 + 0998                { + 0999                    Write = write + 01000                    WriteError = writeError + 01001                    IsEnabled = isEnabled + 01002                    TranslateLevel = translateLevel + 01003                    BeginScope = beginScope + 01004                }100510061007        type private MicrosoftProvider() = + 01008            let factoryGateway = lazy (LoggerFactoryGateway.Create()) + 01009            let loggerGateway = lazy (LoggerGateway.Create())  10101011    /// <summary>1012    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1013    /// </summary>1014    /// <param name="key">The name of the property.</param>1015    /// <param name="value">The value of the property.</param>1016    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1017    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1018    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1019        let provider = getCurrentLogProvider ()1011            interface ILogProvider with1012                member this.GetLogger(name: string) : Logger = + 01013                    match microsoftLoggerFactory with + 01014                    | None -> fun _ _ _ _ -> false1015                    | Some factory -> + 01016                        let logger = factoryGateway.Value.CreateLogger factory name10171018                        fun logLevel message exn args -> + 01019                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel  10201021        match provider with1022        | Some p -> p.OpenMappedContext key value destructureObjects1023        | None -> noopDisposable + 01021                            match message with1022                            | Some message -> + 01023                                let message = message ()  102410251026    /// <summary>1027    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1028    /// </summary>1029    /// <param name="key">The name of the property.</param>1030    /// <param name="value">The value of the property.</param>1031    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1032    let openMappedContext (key: string) (value: obj) =1033        //TODO: We should try to find out if the value is a primitive1034        openMappedContextDestucturable key value false103510361037    /// <summary>1038    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1039    /// </summary>1040    /// <param name="value">The value of the property</param>1041    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1042    let openNestedContext (value: string) =1043        let provider = getCurrentLogProvider ()10441045        match provider with1046        | Some p -> p.OpenNestedContext value1047        | None -> noopDisposable10481049    /// <summary>1050    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1051    /// </summary>1052    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1053    /// <returns></returns>1054    let getLoggerByName (name: string) =1055        let loggerProvider = getCurrentLogProvider ()10561057        let logFunc =1058            match loggerProvider with1059            | Some loggerProvider -> loggerProvider.GetLogger(name)1060            | None -> noopLogger + 01025                                match exn with + 01026                                | Some ex -> loggerGateway.Value.WriteError logger microsoftLevel ex message args + 01027                                | None -> loggerGateway.Value.Write logger microsoftLevel message args1028 + 01029                                true + 01030                            | None -> loggerGateway.Value.IsEnabled logger microsoftLevel10311032                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable = + 01033                    match microsoftLoggerFactory with1034                    | None -> + 01035                        { new IDisposable with + 01036                            member x.Dispose() = () + 01037                        }1038                    | Some factory ->1039                        // Create bogus logger that will propagate to a real logger later + 01040                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1041                        // Requires a IEnumerable<KeyValuePair> to make sense1042                        // https://nblumhardt.com/2016/11/ilogger-beginscope/ + 01043                        [ KeyValuePair(key, value) ] + 01044                        |> box + 01045                        |> loggerGateway.Value.BeginScope logger104610471048                member this.OpenNestedContext(message: string) : IDisposable = + 01049                    match microsoftLoggerFactory with1050                    | None -> + 01051                        { new IDisposable with + 01052                            member x.Dispose() = () + 01053                        }1054                    | Some factory ->1055                        // Create bogus logger that will propagate to a real logger later + 01056                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1057 + 01058                        loggerGateway.Value.BeginScope logger (box message)1059 + 01060        let create () = MicrosoftProvider() :> ILogProvider  10611062        { new ILog with1063            member x.Log = logFunc1064            member x.MappedContext = openMappedContextDestucturable }10651066    /// <summary>1067    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1068    /// </summary>1069    /// <param name="objectType">The type to generate a logger name from. </param>1070    /// <returns></returns>1071    let getLoggerByType (objectType: Type) = objectType |> string |> getLoggerByName10721073    /// <summary>1074    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1075    /// </summary>1076    /// <typeparam name="'a">The type to generate a name from.</typeparam>1077    /// <returns></returns>1078    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)10791080#if !FABLE_COMPILER1081    let rec private getModuleType =1082        function1083        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1084        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1085        // | Lambda(_, expr) -> getModuleType expr1086        // | ValueWithName(_,_,instance) -> instance1087        | x -> failwithf "Expression is not a property. %A" x10881062#endif106310641065module LogProvider =1066    open System1067    open Types1068#if !FABLE_COMPILER1069    open Providers1070#endif1071    open System.Diagnostics1072    open Microsoft.FSharp.Quotations.Patterns10731074    let mutable private currentLogProvider = None10751076    let private knownProviders = [1077#if !FABLE_COMPILER1078        (SerilogProvider.isAvailable, SerilogProvider.create)1079        (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)1080#endif1081    ]10821083    /// Greedy search for first available LogProvider. Order of known providers matters.1084    let private resolvedLogger =1085        lazy1086            (knownProviders1087             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())1088             |> Option.map (fun (_, create) -> create ()))  10891090    /// <summary>1091    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1092    ///1093    /// It can be utilized like:1094    ///1095    /// <code>1096    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1097    /// </code>1098    ///1099    /// inside a module to get the modules full qualitfied name.1100    /// </summary>1101    /// <param name="quotation">The quotation to generate a logger name from.</param>1102    /// <returns></returns>1103    let getLoggerByQuotation (quotation: Quotations.Expr) =1104        getModuleType quotation |> getLoggerByType110511061107type LogProvider =1108    /// <summary>1109    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1110    /// </summary>1111    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1112    /// <returns></returns>1113    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1114        let mi = System.Reflection.MethodBase.GetCurrentMethod()1115        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1116        // CallerMemberName gets us the function that actually called it1117        // Splitting off + seems like the best option to get the Fully Qualified Path1118        let location = mi.DeclaringType.FullName.Split('+') |> Seq.tryHead |> Option.defaultValue ""1119        sprintf "%s.%s" location memberName.Value1120        |> LogProvider.getLoggerByName11211122#endif1090    let private noopLogger _ _ _ _ = false10911092    let private noopDisposable =1093        { new IDisposable with1094            member __.Dispose() = ()1095        }10961097    /// <summary>1098    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.1099    /// </summary>1100    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>1101    /// <returns></returns>1102    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider11031104    /// <summary>1105    /// Gets the currently set LogProvider or attempts to find known built in providers1106    /// </summary>1107    /// <returns></returns>1108    let getCurrentLogProvider () =1109        match currentLogProvider with1110        | None -> resolvedLogger.Value1111        | Some p -> Some p11121113    /// <summary>1114    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1115    /// </summary>1116    /// <param name="key">The name of the property.</param>1117    /// <param name="value">The value of the property.</param>1118    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1119    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1120    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1121        let provider = getCurrentLogProvider ()11221123        match provider with1124        | Some p -> p.OpenMappedContext key value destructureObjects1125        | None -> noopDisposable112611271128    /// <summary>1129    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1130    /// </summary>1131    /// <param name="key">The name of the property.</param>1132    /// <param name="value">The value of the property.</param>1133    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1134    let openMappedContext (key: string) (value: obj) =1135        //TODO: We should try to find out if the value is a primitive1136        openMappedContextDestucturable key value false113711381139    /// <summary>1140    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1141    /// </summary>1142    /// <param name="value">The value of the property</param>1143    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1144    let openNestedContext (value: string) =1145        let provider = getCurrentLogProvider ()11461147        match provider with1148        | Some p -> p.OpenNestedContext value1149        | None -> noopDisposable11501151    /// <summary>1152    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1153    /// </summary>1154    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1155    /// <returns></returns>1156    let getLoggerByName (name: string) =1157        let loggerProvider = getCurrentLogProvider ()11581159        let logFunc =1160            match loggerProvider with1161            | Some loggerProvider -> loggerProvider.GetLogger(name)1162            | None -> noopLogger11631164        { new ILog with1165            member x.Log = logFunc1166            member x.MappedContext = openMappedContextDestucturable1167        }11681169    /// <summary>1170    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1171    /// </summary>1172    /// <param name="objectType">The type to generate a logger name from. </param>1173    /// <returns></returns>1174    let getLoggerByType (objectType: Type) =1175        objectType1176        |> string1177        |> getLoggerByName11781179    /// <summary>1180    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1181    /// </summary>1182    /// <typeparam name="'a">The type to generate a name from.</typeparam>1183    /// <returns></returns>1184    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)11851186#if !FABLE_COMPILER1187    let rec private getModuleType =1188        function1189        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1190        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1191        // | Lambda(_, expr) -> getModuleType expr1192        // | ValueWithName(_,_,instance) -> instance1193        | x -> failwithf "Expression is not a property. %A" x119411951196    /// <summary>1197    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1198    ///1199    /// It can be utilized like:1200    ///1201    /// <code>1202    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1203    /// </code>1204    ///1205    /// inside a module to get the modules full qualitfied name.1206    /// </summary>1207    /// <param name="quotation">The quotation to generate a logger name from.</param>1208    /// <returns></returns>1209    let getLoggerByQuotation (quotation: Quotations.Expr) =1210        getModuleType quotation1211        |> getLoggerByType121212131214type LogProvider =1215    /// <summary>1216    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1217    /// </summary>1218    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1219    /// <returns></returns>1220    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1221        let mi = System.Reflection.MethodBase.GetCurrentMethod()1222        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1223        // CallerMemberName gets us the function that actually called it1224        // Splitting off + seems like the best option to get the Fully Qualified Path1225        let location =1226            mi.DeclaringType.FullName.Split('+')1227            |> Seq.tryHead1228            |> Option.defaultValue ""12291230        sprintf "%s.%s" location memberName.Value1231        |> LogProvider.getLoggerByName12321233#endif - +

Methods/Properties

-getLogManagerType()
-isAvailable()
-getPushProperty()
-Invoke(Microsoft.FSharp.Core.Unit)
-Invoke(System.String,a,System.Boolean)
-getForContextMethodCall()
-Invoke(a)
-Create()
-Invoke(FsLibLog.Types/LogLevel)
-Invoke(System.Object,System.Object,System.String,System.Object[])
-Invoke(System.Object,System.Object,System.Exception,System.String,System.Object[])
-Invoke(System.Object,System.Object)
-.ctor()
-Invoke(Microsoft.FSharp.Core.Unit)
-FsLibLog.Types.ILogProvider.GetLogger(System.String)
-Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
-FsLibLog.Types.ILogProvider.OpenMappedContext(System.String,System.Object,System.Boolean)
-FsLibLog.Types.ILogProvider.OpenNestedContext(System.String)
-Invoke(System.Boolean)
-Invoke(System.String)
-create()
-setMicrosoftLoggerFactory(System.Object)
-Invoke(Microsoft.FSharp.Core.Unit)
-Create()
-Invoke(System.Object,System.String)
-Create()
-Invoke(System.Object,System.Object)
-Invoke(System.Object,System.Object,System.String,System.Object[])
-Invoke(System.Object,System.Object,System.Exception,System.String,System.Object[])
-Invoke(FsLibLog.Types/LogLevel)
-Invoke(System.Object,System.Object)
-.ctor()
-Invoke(Microsoft.FSharp.Core.Unit)
-Invoke(Microsoft.FSharp.Core.Unit)
-FsLibLog.Types.ILogProvider.GetLogger(System.String)
-Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
-Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
-FsLibLog.Types.ILogProvider.OpenMappedContext(System.String,System.Object,System.Boolean)
-System.IDisposable.Dispose()
-FsLibLog.Types.ILogProvider.OpenNestedContext(System.String)
-System.IDisposable.Dispose()
-create()
+getLogManagerType()
+isAvailable()
+getPushProperty()
+Invoke(Microsoft.FSharp.Core.Unit)
+Invoke(System.String,a,System.Boolean)
+getForContextMethodCall()
+Invoke(a)
+Create()
+Invoke(FsLibLog.Types/LogLevel)
+Invoke(System.Object,System.Object,System.String,System.Object[])
+Invoke(System.Object,System.Object,System.Exception,System.String,System.Object[])
+Invoke(System.Object,System.Object)
+.ctor()
+Invoke(Microsoft.FSharp.Core.Unit)
+FsLibLog.Types.ILogProvider.GetLogger(System.String)
+FsLibLog.Types.ILogProvider.OpenMappedContext(System.String,System.Object,System.Boolean)
+FsLibLog.Types.ILogProvider.OpenNestedContext(System.String)
+create()
+setMicrosoftLoggerFactory(System.Object)
+Invoke(Microsoft.FSharp.Core.Unit)
+isAvailable()
+Create()
+Create()
+Invoke(FsLibLog.Types/LogLevel)
+.ctor()
+Invoke(Microsoft.FSharp.Core.Unit)
+Invoke(Microsoft.FSharp.Core.Unit)
+FsLibLog.Types.ILogProvider.GetLogger(System.String)
+Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
+Invoke(FsLibLog.Types/LogLevel,Microsoft.FSharp.Core.FSharpOption`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>>,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>,System.Object[])
+FsLibLog.Types.ILogProvider.OpenMappedContext(System.String,System.Object,System.Boolean)
+System.IDisposable.Dispose()
+FsLibLog.Types.ILogProvider.OpenNestedContext(System.String)
+System.IDisposable.Dispose()
+create()

diff --git a/docs/coverage/FsLibLog_Types.htm b/docs/coverage/FsLibLog_Types.htm index 13ea44e..1f832c3 100644 --- a/docs/coverage/FsLibLog_Types.htm +++ b/docs/coverage/FsLibLog_Types.htm @@ -18,63 +18,57 @@

< Summary

Assembly:FsLibLog File(s):C:\Users\jimmy\Repositories\public\TheAngryByrd\FsLibLog\src\FsLibLog\FsLibLog.fs Covered lines:0 -Uncovered lines:107 -Coverable lines:107 -Total lines:1122 -Line coverage:0% (0 of 107) +Uncovered lines:111 +Coverable lines:111 +Total lines:1233 +Line coverage:0% (0 of 111) Covered branches:0 -Total branches:8 -Branch coverage:0% (0 of 8) +Total branches:6 +Branch coverage:0% (0 of 6)

Metrics

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage Crap Score
StartLogLevel(...)100%0%0
.ctor()100%0%0
System.IDisposable.Dispose()220%0%0
Push(...)100%0%0
Push(...)220%0%0
Invoke(...)100%0%0
Create(...)100%0%0
ILog.fromLog(...)200%0%0
Invoke(...)100%0%0
ILog.fatal'(...)100%0%0
ILog.fatal(...)100%0%0
ILog.error'(...)100%0%0
ILog.error(...)100%0%0
ILog.warn'(...)100%0%0
ILog.warn(...)100%0%0
ILog.info'(...)100%0%0
ILog.info(...)100%0%0
ILog.debug'(...)100%0%0
ILog.debug(...)100%0%0
ILog.trace'(...)100%0%0
ILog.trace(...)100%0%0
setMessage(...)100%0%0
Invoke(...)100%0%0
setMessageThunk(...)100%0%0
addParameter(...)100%0%0
addParameters(...)100%0%0
Invoke(...)100%0%0
addContext(...)100%0%0
addContextDestructured(...)100%0%0
addException(...)100%0%0
addExn(...)100%0%0
setLogLevel(...)100%0%0
isAnObject(...)100%0%0
setMessageInterpolated(...)100%0%0
Invoke(...)100%0%0
Invoke(...)220%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)220%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
Invoke(...)100%0%0
setMessageI(...)100%0%0
StartLogLevel(...)100%0%0
.ctor()100%0%0
System.IDisposable.Dispose()220%0%0
Push(...)100%0%0
Push(...)200%0%0
Create(...)100%0%0
ILog.fromLog(...)200%0%0
Invoke(...)100%0%0
ILog.fatal'(...)100%0%0
ILog.fatal(...)100%0%0
ILog.error'(...)100%0%0
ILog.error(...)100%0%0
ILog.warn'(...)100%0%0
ILog.warn(...)100%0%0
ILog.info'(...)100%0%0
ILog.info(...)100%0%0
ILog.debug'(...)100%0%0
ILog.debug(...)100%0%0
ILog.trace'(...)100%0%0
ILog.trace(...)100%0%0
setMessage(...)100%0%0
Invoke(...)100%0%0
setMessageThunk(...)100%0%0
addParameter(...)100%0%0
addParameters(...)100%0%0
addContext(...)100%0%0
addContextDestructured(...)100%0%0
addException(...)100%0%0
addExn(...)100%0%0
setLogLevel(...)100%0%0
isAnObject(...)100%0%0
setMessageInterpolated(...)100%0%0
Invoke(...)100%0%0
Invoke(...)220%0%0
Invoke(...)100%0%0
Invoke(...)220%0%0
Invoke(...)100%0%0
setMessageI(...)100%0%0

File(s)

@@ -112,1148 +106,1253 @@

 28    /// Type representing a Log  29    [<NoEquality; NoComparison>]  30    type Log =31        { LogLevel: LogLevel32          Message: MessageThunk33          Exception: exn option34          Parameters: obj list35          AdditionalNamedParameters: ((string * obj * bool) list) }36        static member StartLogLevel(logLevel: LogLevel) = - 037            { LogLevel = logLevel - 038              Message = None - 039              Exception = None - 040              Parameters = List.empty - 041              AdditionalNamedParameters = List.empty }4243    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio44    type ILog =45        abstract member Log :  Logger46        abstract member MappedContext :  MappedContext4748#if FABLE_COMPILER49    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)50    // is used instead.51    type Stack<'a>()  =52        let mutable contents = Array.zeroCreate<'a>(2)53        let mutable count = 05455        member buf.Ensure newSize =56            let oldSize = contents.Length57            if newSize > oldSize then58                let old = contents59                contents <- Array.zeroCreate (max newSize (oldSize * 2))60                Array.blit old 0 contents 0 count31        {32            LogLevel: LogLevel33            Message: MessageThunk34            Exception: exn option35            Parameters: obj list36            AdditionalNamedParameters: ((string * obj * bool) list)37        }38 + 039        static member StartLogLevel(logLevel: LogLevel) = { + 040            LogLevel = logLevel + 041            Message = None + 042            Exception = None + 043            Parameters = List.empty + 044            AdditionalNamedParameters = List.empty + 045        }4647    /// An interface wrapper for a<see cref="T:FsLibLog.Types.Logger">Logger</see>. Useful when using depedency injectio48    type ILog =49        abstract member Log: Logger50        abstract member MappedContext: MappedContext5152#if FABLE_COMPILER53    // Fable doesn't support System.Collections.Generic.Stack, so this implementation (from FCS)54    // is used instead.55    type Stack<'a>() =56        let mutable contents = Array.zeroCreate<'a> (2)57        let mutable count = 05859        member buf.Ensure newSize =60            let oldSize = contents.Length  6162        member buf.Count = count63        member buf.Pop() =64            let item = contents.[count - 1]65            count <- count - 166            item6768        member buf.Peep() = contents.[count - 1]69        member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev70        member buf.Push(x) =71            buf.Ensure(count + 1)72            contents.[count] <- x73            count <- count + 17475        member buf.IsEmpty = (count = 0)76#endif7778    [<AutoOpen>]79    module Inner =80#if !FABLE_COMPILER81        open System.Collections.Generic82#endif8384        /// <summary>85        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.86        /// </summary> - 087        type DisposableStack() = - 088            let stack = Stack<IDisposable>()8990            interface IDisposable with91                member __.Dispose() = - 092                    while stack.Count > 0 do - 093                        stack.Pop().Dispose()94 - 095            member __.Push(item: IDisposable) = stack.Push item - 096            member __.Push(items: IDisposable list) = items |> List.iter stack.Push9798            static member Create(items: IDisposable list) = - 099                let ds = new DisposableStack() - 0100                ds.Push items - 0101                ds102103        type ILog with62            if newSize > oldSize then63                let old = contents64                contents <- Array.zeroCreate (max newSize (oldSize * 2))65                Array.blit old 0 contents 0 count6667        member buf.Count = count6869        member buf.Pop() =70            let item = contents.[count - 1]71            count <- count - 172            item7374        member buf.Peep() = contents.[count - 1]7576        member buf.Top(n) =77            [ for x in contents.[max 0 (count - n) .. count - 1] -> x ]78            |> List.rev7980        member buf.Push(x) =81            buf.Ensure(count + 1)82            contents.[count] <- x83            count <- count + 18485        member buf.IsEmpty = (count = 0)86#endif8788    [<AutoOpen>]89    module Inner =90#if !FABLE_COMPILER91        open System.Collections.Generic92#endif9394        /// <summary>95        /// DisposableStack on Dispose will call dispose on items appended to its stack in Last In First Out.96        /// </summary>97        type DisposableStack() = + 098            let stack = Stack<IDisposable>()99100            interface IDisposable with101                member __.Dispose() = + 0102                    while stack.Count > 0 do + 0103                        stack.Pop().Dispose()  104105            /// <summary>106            /// Logs a log107            /// </summary>108            /// <param name="log">The type representing a log message to be logged</param>109            /// <returns><see langword="true"/> if the log message was logged</returns>110            member logger.fromLog(log: Log) = - 0111                use __ = - 0112                    log.AdditionalNamedParameters - 0113                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure) - 0114                    // This stack is important, it causes us to unwind as if you have multiple uses in a row - 0115                    |> DisposableStack.Create116 - 0117                log.Parameters - 0118                |> List.toArray - 0119                |> logger.Log log.LogLevel log.Message log.Exception120121            /// <summary>122            /// Logs a fatal log message given a log configurer.123            /// </summary>124            /// <param name="logConfig">A function to configure a log</param>125            /// <returns><see langword="true"/>  if the log message was logged</returns>126            member logger.fatal'(logConfig: Log -> Log) = - 0127                Log.StartLogLevel LogLevel.Fatal - 0128                |> logConfig - 0129                |> logger.fromLog130131            /// <summary>132            /// Logs a fatal log message given a log configurer.133            /// </summary>134            /// <param name="logConfig">A function to configure a log</param> - 0135            member logger.fatal(logConfig: Log -> Log) = logger.fatal' logConfig |> ignore136137            /// <summary>138            /// Logs an error log message given a log configurer.139            /// </summary>140            /// <param name="logConfig">A function to configure a log</param>141            /// <returns><see langword="true"/>  if the log message was logged</returns>142            member logger.error'(logConfig: Log -> Log) = - 0143                Log.StartLogLevel LogLevel.Error - 0144                |> logConfig - 0145                |> logger.fromLog146147            /// <summary>148            /// Logs an error log message given a log configurer.149            /// </summary>150            /// <param name="logConfig">A function to configure a log</param> - 0151            member logger.error(logConfig: Log -> Log) = logger.error' logConfig |> ignore152153            /// <summary>154            /// Logs a warn log message given a log configurer.155            /// </summary>156            /// <param name="logConfig">A function to configure a log</param>157            /// <returns><see langword="true"/>  if the log message was logged</returns>158            member logger.warn'(logConfig: Log -> Log) = - 0159                Log.StartLogLevel LogLevel.Warn - 0160                |> logConfig - 0161                |> logger.fromLog162163            /// <summary>164            /// Logs a warn log message given a log configurer.165            /// </summary>166            /// <param name="logConfig">A function to configure a log</param> - 0167            member logger.warn(logConfig: Log -> Log) = logger.warn' logConfig |> ignore168169            /// <summary>170            /// Logs an info log message given a log configurer.171            /// </summary>172            /// <param name="logConfig">A function to configure a log</param>173            /// <returns><see langword="true"/>  if the log message was logged</returns>174            member logger.info'(logConfig: Log -> Log) = - 0175                Log.StartLogLevel LogLevel.Info - 0176                |> logConfig - 0177                |> logger.fromLog178179            /// <summary>180            /// Logs an info log message given a log configurer.181            /// </summary>182            /// <param name="logConfig">A function to configure a log</param> - 0183            member logger.info(logConfig: Log -> Log) = logger.info' logConfig |> ignore184185            /// <summary>186            /// Logs a debug log message given a log configurer.187            /// </summary>188            /// <param name="logConfig">A function to configure a log</param>189            /// <returns><see langword="true"/>  if the log message was logged</returns>190            member logger.debug'(logConfig: Log -> Log) = - 0191                Log.StartLogLevel LogLevel.Debug - 0192                |> logConfig - 0193                |> logger.fromLog194195            /// <summary>196            /// Logs a debug log message given a log configurer.197            /// </summary>198            /// <param name="logConfig">A function to configure a log</param> - 0199            member logger.debug(logConfig: Log -> Log) = logger.debug' logConfig |> ignore200201            /// <summary>202            /// Logs a trace log message given a log configurer.203            /// </summary>204            /// <param name="logConfig">A function to configure a log</param>205            /// <returns><see langword="true"/>  if the log message was logged</returns>206            member logger.trace'(logConfig: Log -> Log) = - 0207                Log.StartLogLevel LogLevel.Trace - 0208                |> logConfig - 0209                |> logger.fromLog210211            /// <summary>212            /// Logs a trace log message given a log configurer.213            /// </summary>214            /// <param name="logConfig">A function to configure a log</param> - 0215            member logger.trace(logConfig: Log -> Log) = logger.trace' logConfig |> ignore216217218    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.219    type ILogProvider =220        abstract member GetLogger : string -> Logger221        abstract member OpenNestedContext : string -> IDisposable222        abstract member OpenMappedContext : string -> obj -> bool -> IDisposable + 0105            member __.Push(item: IDisposable) = stack.Push item106107            member __.Push(items: IDisposable list) = + 0108                items + 0109                |> List.iter stack.Push110111            static member Create(items: IDisposable list) = + 0112                let ds = new DisposableStack() + 0113                ds.Push items + 0114                ds115116        type ILog with117118            /// <summary>119            /// Logs a log120            /// </summary>121            /// <param name="log">The type representing a log message to be logged</param>122            /// <returns><see langword="true"/> if the log message was logged</returns>123            member logger.fromLog(log: Log) =124                use __ = + 0125                    log.AdditionalNamedParameters + 0126                    |> List.map (fun (key, value, destructure) -> logger.MappedContext key value destructure) + 0127                    // This stack is important, it causes us to unwind as if you have multiple uses in a row + 0128                    |> DisposableStack.Create129 + 0130                log.Parameters + 0131                |> List.toArray + 0132                |> logger.Log log.LogLevel log.Message log.Exception133134            /// <summary>135            /// Logs a fatal log message given a log configurer.136            /// </summary>137            /// <param name="logConfig">A function to configure a log</param>138            /// <returns><see langword="true"/>  if the log message was logged</returns>139            member logger.fatal'(logConfig: Log -> Log) = + 0140                Log.StartLogLevel LogLevel.Fatal + 0141                |> logConfig + 0142                |> logger.fromLog143144            /// <summary>145            /// Logs a fatal log message given a log configurer.146            /// </summary>147            /// <param name="logConfig">A function to configure a log</param>148            member logger.fatal(logConfig: Log -> Log) = + 0149                logger.fatal' logConfig + 0150                |> ignore151152            /// <summary>153            /// Logs an error log message given a log configurer.154            /// </summary>155            /// <param name="logConfig">A function to configure a log</param>156            /// <returns><see langword="true"/>  if the log message was logged</returns>157            member logger.error'(logConfig: Log -> Log) = + 0158                Log.StartLogLevel LogLevel.Error + 0159                |> logConfig + 0160                |> logger.fromLog161162            /// <summary>163            /// Logs an error log message given a log configurer.164            /// </summary>165            /// <param name="logConfig">A function to configure a log</param>166            member logger.error(logConfig: Log -> Log) = + 0167                logger.error' logConfig + 0168                |> ignore169170            /// <summary>171            /// Logs a warn log message given a log configurer.172            /// </summary>173            /// <param name="logConfig">A function to configure a log</param>174            /// <returns><see langword="true"/>  if the log message was logged</returns>175            member logger.warn'(logConfig: Log -> Log) = + 0176                Log.StartLogLevel LogLevel.Warn + 0177                |> logConfig + 0178                |> logger.fromLog179180            /// <summary>181            /// Logs a warn log message given a log configurer.182            /// </summary>183            /// <param name="logConfig">A function to configure a log</param>184            member logger.warn(logConfig: Log -> Log) = + 0185                logger.warn' logConfig + 0186                |> ignore187188            /// <summary>189            /// Logs an info log message given a log configurer.190            /// </summary>191            /// <param name="logConfig">A function to configure a log</param>192            /// <returns><see langword="true"/>  if the log message was logged</returns>193            member logger.info'(logConfig: Log -> Log) = + 0194                Log.StartLogLevel LogLevel.Info + 0195                |> logConfig + 0196                |> logger.fromLog197198            /// <summary>199            /// Logs an info log message given a log configurer.200            /// </summary>201            /// <param name="logConfig">A function to configure a log</param>202            member logger.info(logConfig: Log -> Log) = + 0203                logger.info' logConfig + 0204                |> ignore205206            /// <summary>207            /// Logs a debug log message given a log configurer.208            /// </summary>209            /// <param name="logConfig">A function to configure a log</param>210            /// <returns><see langword="true"/>  if the log message was logged</returns>211            member logger.debug'(logConfig: Log -> Log) = + 0212                Log.StartLogLevel LogLevel.Debug + 0213                |> logConfig + 0214                |> logger.fromLog215216            /// <summary>217            /// Logs a debug log message given a log configurer.218            /// </summary>219            /// <param name="logConfig">A function to configure a log</param>220            member logger.debug(logConfig: Log -> Log) = + 0221                logger.debug' logConfig + 0222                |> ignore  223224    module Log =225226        /// <summary>227        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.228        /// </summary>229        /// <param name="message">The message to set for the log.</param>230        /// <param name="log">The log to amend.</param>231        /// <returns>The amended log.</returns>232        let setMessage (message: string) (log: Log) = - 0233            { log with - 0234                  Message = Some(fun () -> message) }235236        /// <summary>237        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con238        /// </summary>239        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>240        /// <param name="log">The log to amend.</param>241        /// <returns>The amended log.</returns>242        let setMessageThunk (messageThunk: unit -> string) (log: Log) = - 0243            { log with Message = Some messageThunk }244245        /// <summary>246        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.247        /// </summary>248        /// <param name="param">The value to add to the log</param>249        /// <param name="log">The log to amend.</param>250        /// <returns>The amended log.</returns>251        let addParameter (param: 'a) (log: Log) = - 0252            { log with - 0253                  Parameters = List.append log.Parameters [ (box param) ] }254255        /// <summary>256        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.257        /// </summary>258        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>259        /// <param name="log">The log to amend.</param>260        /// <returns>The amended log.</returns>261        let addParameters (``params``: obj list) (log: Log) = - 0262            let ``params`` = ``params`` |> List.map box263 - 0264            { log with - 0265                  Parameters = log.Parameters @ ``params`` }266267268269        /// <summary>270        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe271        /// This DOES NOT affect the parameters set for a message template.272        /// This is the same calling OpenMappedContext right before logging.224            /// <summary>225            /// Logs a trace log message given a log configurer.226            /// </summary>227            /// <param name="logConfig">A function to configure a log</param>228            /// <returns><see langword="true"/>  if the log message was logged</returns>229            member logger.trace'(logConfig: Log -> Log) = + 0230                Log.StartLogLevel LogLevel.Trace + 0231                |> logConfig + 0232                |> logger.fromLog233234            /// <summary>235            /// Logs a trace log message given a log configurer.236            /// </summary>237            /// <param name="logConfig">A function to configure a log</param>238            member logger.trace(logConfig: Log -> Log) = + 0239                logger.trace' logConfig + 0240                |> ignore241242243    /// An interface for retrieving a concrete logger such as Serilog, Nlog, etc.244    type ILogProvider =245        abstract member GetLogger: string -> Logger246        abstract member OpenNestedContext: string -> IDisposable247        abstract member OpenMappedContext: string -> obj -> bool -> IDisposable248249    module Log =250251        /// <summary>252        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message.253        /// </summary>254        /// <param name="message">The message to set for the log.</param>255        /// <param name="log">The log to amend.</param>256        /// <returns>The amended log.</returns>257        let setMessage (message: string) (log: Log) = + 0258            { log with + 0259                Message = Some(fun () -> message) + 0260            }261262        /// <summary>263        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a message thunk.  Useful for "expensive" string con264        /// </summary>265        /// <param name="messageThunk">The function that generates a message to add to a Log.</param>266        /// <param name="log">The log to amend.</param>267        /// <returns>The amended log.</returns>268        let setMessageThunk (messageThunk: unit -> string) (log: Log) = + 0269            { log with Message = Some messageThunk }270271        /// <summary>272        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a parameter.  273        /// </summary>274        /// <param name="key">The key of the parameter to add to the log.</param>275        /// <param name="value">The value of the parameter to add to the log.</param>276        /// <param name="log">The log to amend.</param>277        /// <returns>The amended log.</returns>278        let addContext (key: string) (value: obj) (log: Log) = - 0279            { log with - 0280                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] }274        /// <param name="param">The value to add to the log</param>275        /// <param name="log">The log to amend.</param>276        /// <returns>The amended log.</returns>277        let addParameter (param: 'a) (log: Log) = + 0278            { log with + 0279                Parameters = List.append log.Parameters [ (box param) ] + 0280            }  281282283        /// <summary>284        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe285        /// This DOES NOT affect the parameters set for a message template.286        /// This is the same calling OpenMappedContext right before logging.287        /// This destructures an object rather than calling `ToString()` on it.288        /// WARNING: Destructring can be expensive.289        /// </summary>290        /// <param name="key">The key of the parameter to add to the log.</param>291        /// <param name="value">The value of the parameter to add to the log.</param>292        /// <param name="log">The log to amend.</param>293        /// <returns>The amended log.</returns>294        let addContextDestructured (key: string) (value: obj) (log: Log) = - 0295            { log with - 0296                  AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] }297282        /// <summary>283        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a list of parameters.284        /// </summary>285        /// <param name="params">The values to add to the log, in the form of an `obj list`.</param>286        /// <param name="log">The log to amend.</param>287        /// <returns>The amended log.</returns>288        let addParameters (``params``: obj list) (log: Log) =289            let ``params`` = + 0290                ``params`` + 0291                |> List.map box292 + 0293            { log with + 0294                Parameters = + 0295                    log.Parameters + 0296                    @ ``params`` + 0297            }  298299        /// <summary>300        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle301        /// </summary>302        /// <param name="exception">The exception to add to the log.</param>303        /// <param name="log">The log to amend.</param>304        /// <returns>The amended log.</returns>305        let addException (``exception``: exn) (log: Log) = - 0306            { log with - 0307                  Exception = Option.ofObj ``exception`` }308309        /// <summary>310        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle311        /// </summary>312        /// <param name="exception">The exception to add to the log.</param>313        /// <param name="log">The log to amend.</param>314        /// <returns>The amended log.</returns> - 0315        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log316317        /// <summary>318        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe319        /// </summary>320        /// <param name="logLevel">The level to set for the log.</param>321        /// <param name="log">The log to amend.</param>322        /// <returns>The amended log.</returns> - 0323        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }324325#if !FABLE_COMPILER326327        let private formatterRegex =328            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)329330        let private isAnObject value = - 0331            Convert.GetTypeCode(value) = TypeCode.Object332333        /// <summary>334        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m335        ///336        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr337        /// </summary>338        /// <param name="message">An interpolated string</param>339        /// <param name="log">The log to amend.</param>340        /// <returns>The amended log.</returns>341        let setMessageInterpolated (message: FormattableString) (log: Log) = - 0342            let mutable messageFormat = message.Format343 - 0344            let args = - 0345                formatterRegex.Matches(messageFormat) - 0346                |> Seq.cast<Match> - 0347                |> Seq.map - 0348                    (fun m -> - 0349                        let number = Int32.Parse(m.Groups.["number"].Value) - 0350                        let formatGroup = m.Groups.["format"] - 0351                        let propertyValue = message.GetArgument(number) - 0352                        let propertyName = formatGroup.Value - 0353                        let columnFormatGroup = m.Groups.["columnFormat"] - 0354                        propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length - 0355                        )356            // Reverse the args so we won't change the indexes earlier in the string - 0357            args - 0358            |> Seq.rev - 0359            |> Seq.iter - 0360                (fun (_, _, removeStart, removeLength) -> - 0361                    if removeLength > 0 then - 0362                        messageFormat <- messageFormat.Remove(removeStart, removeLength))299300        /// <summary>301        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe302        /// This DOES NOT affect the parameters set for a message template.303        /// This is the same calling OpenMappedContext right before logging.304        /// </summary>305        /// <param name="key">The key of the parameter to add to the log.</param>306        /// <param name="value">The value of the parameter to add to the log.</param>307        /// <param name="log">The log to amend.</param>308        /// <returns>The amended log.</returns>309        let addContext (key: string) (value: obj) (log: Log) = + 0310            { log with + 0311                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), false ] + 0312            }313314315        /// <summary>316        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with additional named parameters for context. This helpe317        /// This DOES NOT affect the parameters set for a message template.318        /// This is the same calling OpenMappedContext right before logging.319        /// This destructures an object rather than calling `ToString()` on it.320        /// WARNING: Destructring can be expensive.321        /// </summary>322        /// <param name="key">The key of the parameter to add to the log.</param>323        /// <param name="value">The value of the parameter to add to the log.</param>324        /// <param name="log">The log to amend.</param>325        /// <returns>The amended log.</returns>326        let addContextDestructured (key: string) (value: obj) (log: Log) = + 0327            { log with + 0328                AdditionalNamedParameters = List.append log.AdditionalNamedParameters [ key, (box value), true ] + 0329            }330331332        /// <summary>333        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle334        /// </summary>335        /// <param name="exception">The exception to add to the log.</param>336        /// <param name="log">The log to amend.</param>337        /// <returns>The amended log.</returns>338        let addException (``exception``: exn) (log: Log) = + 0339            { log with + 0340                Exception = Option.ofObj ``exception`` + 0341            }342343        /// <summary>344        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with an <see cref="T:System.Exception">exn</see>. Handle345        /// </summary>346        /// <param name="exception">The exception to add to the log.</param>347        /// <param name="log">The log to amend.</param>348        /// <returns>The amended log.</returns> + 0349        let addExn (``exception``: exn) (log: Log) = addException ``exception`` log350351        /// <summary>352        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given <see cref="T:FsLibLog.Types.LogLevel">LogLe353        /// </summary>354        /// <param name="logLevel">The level to set for the log.</param>355        /// <param name="log">The log to amend.</param>356        /// <returns>The amended log.</returns> + 0357        let setLogLevel (logLevel: LogLevel) (log: Log) = { log with LogLevel = logLevel }358359#if !FABLE_COMPILER360361        let private formatterRegex =362            Regex(@"(?<!{){(?<number>\d+)(?<columnFormat>:(?<format>[^}]+))?}(?!})", RegexOptions.Compiled)  363 - 0364            let namedArgs = - 0365                args - 0366                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}") - 0367                |> Seq.toArray368 - 0369            messageFormat <- - 0370                messageFormat - 0371                    .Replace("{{", "{{{{") - 0372                    .Replace("}}", "}}}}")373            // Replace numbered args with named args from regex match - 0374            messageFormat <- String.Format(messageFormat, args = namedArgs)375376            let addContexts args (log: Log) = - 0377                let addArgsToContext = - 0378                    (id, args) - 0379                    ||> Seq.fold - 0380                            (fun state (name, value, _, _) -> - 0381                                let contextAdder = - 0382                                    if value |> isAnObject then - 0383                                        addContextDestructured - 0384                                    else - 0385                                        addContext - 0386 - 0387                                state >> contextAdder name value)388 - 0389                addArgsToContext log390 - 0391            log - 0392            |> setMessage messageFormat - 0393            |> addContexts args394395        /// <summary>396        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m397        ///398        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr399        /// </summary>400        /// <param name="message">An interpolated string</param>401        /// <param name="log">The log to amend.</param>402        /// <returns>The amended log.</returns> - 0403        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log404#endif364        let private isAnObject value = + 0365            Convert.GetTypeCode(value) = TypeCode.Object366367        /// <summary>368        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m369        ///370        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr371        /// </summary>372        /// <param name="message">An interpolated string</param>373        /// <param name="log">The log to amend.</param>374        /// <returns>The amended log.</returns>375        let setMessageInterpolated (message: FormattableString) (log: Log) = + 0376            let mutable messageFormat = message.Format377378            let args = + 0379                formatterRegex.Matches(messageFormat) + 0380                |> Seq.cast<Match> + 0381                |> Seq.map (fun m -> + 0382                    let number = Int32.Parse(m.Groups.["number"].Value) + 0383                    let formatGroup = m.Groups.["format"] + 0384                    let propertyValue = message.GetArgument(number) + 0385                    let propertyName = formatGroup.Value + 0386                    let columnFormatGroup = m.Groups.["columnFormat"] + 0387                    propertyName, propertyValue, columnFormatGroup.Index, columnFormatGroup.Length + 0388                )389            // Reverse the args so we won't change the indexes earlier in the string + 0390            args + 0391            |> Seq.rev + 0392            |> Seq.iter (fun (_, _, removeStart, removeLength) -> + 0393                if removeLength > 0 then + 0394                    messageFormat <- messageFormat.Remove(removeStart, removeLength) + 0395            )396397            let namedArgs = + 0398                args + 0399                |> Seq.map (fun (name, _, _, _) -> box $"{{{name}}}") + 0400                |> Seq.toArray401 + 0402            messageFormat <- messageFormat.Replace("{{", "{{{{").Replace("}}", "}}}}")403            // Replace numbered args with named args from regex match + 0404            messageFormat <- String.Format(messageFormat, args = namedArgs)  405406/// Provides operators to make writing logs more streamlined.407module Operators =408409    /// <summary>410    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.411    /// </summary>412    /// <param name="message">The string of the base message.</param>413    /// <returns>A new Log instance with the specified message.</returns>414    let (!!!) message = Log.setMessage message406            let addContexts args (log: Log) =407                let addArgsToContext =408                    (id, args)409                    ||> Seq.fold (fun state (name, value, _, _) ->410                        let contextAdder = + 0411                            if value |> isAnObject then + 0412                                addContextDestructured413                            else + 0414                                addContext  415416    /// <summary>417    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<418    /// </summary>419    /// <param name="log">The Log to add the parameter to.</param>420    /// <param name="value">The value for the parameter.</param>421    /// <returns>The Log with the added parameter.</returns>422    let (>>!) log value = log >> Log.addParameter value423424    /// <summary>425    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.426    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right427    ///428    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.429    /// </summary>430    /// <param name="log">The log to add the parameter to.</param>431    /// <param name="key">The name for the parameter.</param>432    /// <param name="value">The value for the parameter.</param>433    /// <returns>The amended log with the parameter added.</returns>434    let (>>!-) log (key, value) = log >> Log.addContext key value435436    /// <summary>437    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT438    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling439    ///440    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.441    /// </summary>442    /// <param name="log">The log to add the parameter to.</param>443    /// <param name="key">The name for the parameter.</param>444    /// <param name="value">The value for the parameter.</param>445    /// <returns>The amended log with the parameter added.</returns>446    let (>>!+) log (key, value) =447        log >> Log.addContextDestructured key value448449    /// <summary>450    /// Amends a Log with an exn. Handles nulls.451    ///452    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.453    /// </summary>454    /// <param name="log">The log to add the parameter to.</param>455    /// <param name="e">The exception to add to the log.</param>456    /// <returns>The amended log with the parameter added.</returns>457    let (>>!!) log e = log >> Log.addException e458459460#if !FABLE_COMPILER461module Providers =462    module SerilogProvider =463        open System464        open System.Linq.Expressions465466        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")467        let isAvailable () = getLogManagerType () |> isNull |> not468469        let getPushProperty () = + 0416                        state + 0417                        >> contextAdder name value418                    )419 + 0420                addArgsToContext log421 + 0422            log + 0423            |> setMessage messageFormat + 0424            |> addContexts args425426        /// <summary>427        /// Amends a <see cref="T:FsLibLog.Types.Log">Log</see> with a given interpolated string. This will generate a m428        ///429        /// This would be equivalent of calling <code>(setMessage "I want to log {MyLogVariableName}" >> addContextDestr430        /// </summary>431        /// <param name="message">An interpolated string</param>432        /// <param name="log">The log to amend.</param>433        /// <returns>The amended log.</returns> + 0434        let setMessageI (message: FormattableString) (log: Log) = setMessageInterpolated message log435#endif436437/// Provides operators to make writing logs more streamlined.438module Operators =439440    /// <summary>441    /// Amend a log with a message. Wrapper for <see cref="M:FsLibLog.Types.LogModule.setMessage">Log.setMessage</see>.442    /// </summary>443    /// <param name="message">The string of the base message.</param>444    /// <returns>A new Log instance with the specified message.</returns>445    let (!!!) message = Log.setMessage message446447    /// <summary>448    /// Amends a log with a parameter. Wrapper for <see cref="M:FsLibLog.Types.LogModule.addParameter">Log.addParameter<449    /// </summary>450    /// <param name="log">The Log to add the parameter to.</param>451    /// <param name="value">The value for the parameter.</param>452    /// <returns>The Log with the added parameter.</returns>453    let (>>!) log value =454        log455        >> Log.addParameter value456457    /// <summary>458    /// Amends a Log with additional named parameters for context. This helper adds more context to a log.459    /// This DOES NOT affect the parameters set for a message template. This is the same calling OpenMappedContext right460    ///461    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContext">Log.addContext</see>.462    /// </summary>463    /// <param name="log">The log to add the parameter to.</param>464    /// <param name="key">The name for the parameter.</param>465    /// <param name="value">The value for the parameter.</param>466    /// <returns>The amended log with the parameter added.</returns>467    let (>>!-) log (key, value) =468        log469        >> Log.addContext key value  470471            let ndcContextType =472                Type.GetType("Serilog.Context.LogContext, Serilog")473                |> Option.ofObj474                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))475476            ()477478            let pushPropertyMethod =479                ndcContextType.GetMethod(480                    "PushProperty",481                    [| typedefof<string>482                       typedefof<obj>483                       typedefof<bool> |]484                )485486            let nameParam =487                Expression.Parameter(typedefof<string>, "name")488489            let valueParam =490                Expression.Parameter(typedefof<obj>, "value")491492            let destructureObjectParam =493                Expression.Parameter(typedefof<bool>, "destructureObjects")494495            let pushPropertyMethodCall =496                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)471    /// <summary>472    /// Amends a Log with additional named parameters for context. This helper adds more context to a log. This DOES NOT473    /// This is the same calling OpenMappedContext right before logging. This destructures an object rather than calling474    ///475    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addContextDestructured">Log.addContextDestructured</see>.476    /// </summary>477    /// <param name="log">The log to add the parameter to.</param>478    /// <param name="key">The name for the parameter.</param>479    /// <param name="value">The value for the parameter.</param>480    /// <returns>The amended log with the parameter added.</returns>481    let (>>!+) log (key, value) =482        log483        >> Log.addContextDestructured key value484485    /// <summary>486    /// Amends a Log with an exn. Handles nulls.487    ///488    /// Wrapper for <see cref="M:FsLibLog.Types.LogModule.addException">Log.addException</see>.489    /// </summary>490    /// <param name="log">The log to add the parameter to.</param>491    /// <param name="e">The exception to add to the log.</param>492    /// <returns>The amended log with the parameter added.</returns>493    let (>>!!) log e =494        log495        >> Log.addException e496  497498            let pushProperty =499                Expression500                    .Lambda<Func<string, obj, bool, IDisposable>>(501                        pushPropertyMethodCall,502                        nameParam,503                        valueParam,504                        destructureObjectParam505                    )506                    .Compile()507508            fun key value destructure -> pushProperty.Invoke(key, value, destructure)509498#if !FABLE_COMPILER499module Providers =500    module SerilogProvider =501        open System502        open System.Linq.Expressions503504        let getLogManagerType () = Type.GetType("Serilog.Log, Serilog")505506        let isAvailable () =507            getLogManagerType ()508            |> isNull509            |> not  510511        let getForContextMethodCall () =512            let logManagerType = getLogManagerType ()513514            let method =515                logManagerType.GetMethod(516                    "ForContext",517                    [| typedefof<string>518                       typedefof<obj>519                       typedefof<bool> |]520                )521522            let propertyNameParam =523                Expression.Parameter(typedefof<string>, "propertyName")524525            let valueParam =526                Expression.Parameter(typedefof<obj>, "value")527528            let destructureObjectsParam =529                Expression.Parameter(typedefof<bool>, "destructureObjects")530531            let exrs: Expression [] =532                [| propertyNameParam533                   valueParam534                   destructureObjectsParam |]535536            let methodCall = Expression.Call(null, method, exrs)537538            let func =539                Expression540                    .Lambda<Func<string, obj, bool, obj>>(541                        methodCall,542                        propertyNameParam,543                        valueParam,544                        destructureObjectsParam545                    )546                    .Compile()547548            fun name -> func.Invoke("SourceContext", name, false)511        let getPushProperty () =512513            let ndcContextType =514                Type.GetType("Serilog.Context.LogContext, Serilog")515                |> Option.ofObj516                |> Option.defaultWith (fun () -> Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"))517518            ()519520            let pushPropertyMethod =521                ndcContextType.GetMethod(522                    "PushProperty",523                    [|524                        typedefof<string>525                        typedefof<obj>526                        typedefof<bool>527                    |]528                )529530            let nameParam = Expression.Parameter(typedefof<string>, "name")531532            let valueParam = Expression.Parameter(typedefof<obj>, "value")533534            let destructureObjectParam =535                Expression.Parameter(typedefof<bool>, "destructureObjects")536537            let pushPropertyMethodCall =538                Expression.Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam)539540            let pushProperty =541                Expression542                    .Lambda<Func<string, obj, bool, IDisposable>>(543                        pushPropertyMethodCall,544                        nameParam,545                        valueParam,546                        destructureObjectParam547                    )548                    .Compile()  549550        [<NoEquality; NoComparison>]551        type SerilogGateway =552            { Write: obj -> obj -> string -> obj [] -> unit553              WriteException: obj -> obj -> exn -> string -> obj [] -> unit554              IsEnabled: obj -> obj -> bool555              TranslateLevel: LogLevel -> obj }556            static member Create() =557                let logEventLevelType =558                    Type.GetType("Serilog.Events.LogEventLevel, Serilog")559560                if (logEventLevelType |> isNull) then561                    failwith ("Type Serilog.Events.LogEventLevel was not found.")562563                let debugLevel =564                    Enum.Parse(logEventLevelType, "Debug", false)550            fun key value destructure -> pushProperty.Invoke(key, value, destructure)551552553        let getForContextMethodCall () =554            let logManagerType = getLogManagerType ()555556            let method =557                logManagerType.GetMethod(558                    "ForContext",559                    [|560                        typedefof<string>561                        typedefof<obj>562                        typedefof<bool>563                    |]564                )  565566                let errorLevel =567                    Enum.Parse(logEventLevelType, "Error", false)568569                let fatalLevel =570                    Enum.Parse(logEventLevelType, "Fatal", false)571572                let informationLevel =573                    Enum.Parse(logEventLevelType, "Information", false)574575                let verboseLevel =576                    Enum.Parse(logEventLevelType, "Verbose", false)577578                let warningLevel =579                    Enum.Parse(logEventLevelType, "Warning", false)566            let propertyNameParam = Expression.Parameter(typedefof<string>, "propertyName")567568            let valueParam = Expression.Parameter(typedefof<obj>, "value")569570            let destructureObjectsParam =571                Expression.Parameter(typedefof<bool>, "destructureObjects")572573            let exrs: Expression[] = [|574                propertyNameParam575                valueParam576                destructureObjectsParam577            |]578579            let methodCall = Expression.Call(null, method, exrs)  580581                let translateLevel (level: LogLevel) =582                    match level with583                    | LogLevel.Fatal -> fatalLevel584                    | LogLevel.Error -> errorLevel585                    | LogLevel.Warn -> warningLevel586                    | LogLevel.Info -> informationLevel587                    | LogLevel.Debug -> debugLevel588                    | LogLevel.Trace -> verboseLevel589                    | _ -> debugLevel581            let func =582                Expression583                    .Lambda<Func<string, obj, bool, obj>>(584                        methodCall,585                        propertyNameParam,586                        valueParam,587                        destructureObjectsParam588                    )589                    .Compile()  590591                let loggerType = Type.GetType("Serilog.ILogger, Serilog")591            fun name -> func.Invoke("SourceContext", name, false)  592593                if (loggerType |> isNull) then594                    failwith ("Type Serilog.ILogger was not found.")595596                let isEnabledMethodInfo =597                    loggerType.GetMethod("IsEnabled", [| logEventLevelType |])598599                let instanceParam = Expression.Parameter(typedefof<obj>)600601                let instanceCast =602                    Expression.Convert(instanceParam, loggerType)603604                let levelParam = Expression.Parameter(typedefof<obj>)605606                let levelCast =607                    Expression.Convert(levelParam, logEventLevelType)608609                let isEnabledMethodCall =610                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)611612                let isEnabled =613                    Expression614                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)615                        .Compile()593        [<NoEquality; NoComparison>]594        type SerilogGateway =595            {596                Write: obj -> obj -> string -> obj[] -> unit597                WriteException: obj -> obj -> exn -> string -> obj[] -> unit598                IsEnabled: obj -> obj -> bool599                TranslateLevel: LogLevel -> obj600            }601602            static member Create() =603                let logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog")604605                if606                    (logEventLevelType607                     |> isNull)608                then609                    failwith ("Type Serilog.Events.LogEventLevel was not found.")610611                let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)612613                let errorLevel = Enum.Parse(logEventLevelType, "Error", false)614615                let fatalLevel = Enum.Parse(logEventLevelType, "Fatal", false)  616617                let writeMethodInfo =618                    loggerType.GetMethod(619                        "Write",620                        [| logEventLevelType621                           typedefof<string>622                           typedefof<obj []> |]623                    )624625                let messageParam = Expression.Parameter(typedefof<string>)626                let propertyValuesParam = Expression.Parameter(typedefof<obj []>)627628                let writeMethodExp =629                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)630631                let expression =632                    Expression.Lambda<Action<obj, obj, string, obj []>>(633                        writeMethodExp,634                        instanceParam,635                        levelParam,636                        messageParam,637                        propertyValuesParam638                    )617                let informationLevel = Enum.Parse(logEventLevelType, "Information", false)618619                let verboseLevel = Enum.Parse(logEventLevelType, "Verbose", false)620621                let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)622623                let translateLevel (level: LogLevel) =624                    match level with625                    | LogLevel.Fatal -> fatalLevel626                    | LogLevel.Error -> errorLevel627                    | LogLevel.Warn -> warningLevel628                    | LogLevel.Info -> informationLevel629                    | LogLevel.Debug -> debugLevel630                    | LogLevel.Trace -> verboseLevel631                    | _ -> debugLevel632633                let loggerType = Type.GetType("Serilog.ILogger, Serilog")634635                if (loggerType |> isNull) then636                    failwith ("Type Serilog.ILogger was not found.")637638                let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  639640                let write = expression.Compile()640                let instanceParam = Expression.Parameter(typedefof<obj>)  641642                let writeExceptionMethodInfo =643                    loggerType.GetMethod(644                        "Write",645                        [| logEventLevelType646                           typedefof<exn>647                           typedefof<string>648                           typedefof<obj []> |]649                    )642                let instanceCast = Expression.Convert(instanceParam, loggerType)643644                let levelParam = Expression.Parameter(typedefof<obj>)645646                let levelCast = Expression.Convert(levelParam, logEventLevelType)647648                let isEnabledMethodCall =649                    Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  650651                let exceptionParam = Expression.Parameter(typedefof<exn>)652653                let writeMethodExp =654                    Expression.Call(655                        instanceCast,656                        writeExceptionMethodInfo,657                        levelCast,658                        exceptionParam,659                        messageParam,660                        propertyValuesParam661                    )662663                let writeException =664                    Expression665                        .Lambda<Action<obj, obj, exn, string, obj []>>(666                            writeMethodExp,667                            instanceParam,668                            levelParam,669                            exceptionParam,670                            messageParam,671                            propertyValuesParam672                        )673                        .Compile()674675                { Write =676                      (fun logger level message formattedParmeters ->677                          write.Invoke(logger, level, message, formattedParmeters))678                  WriteException =679                      fun logger level ex message formattedParmeters ->680                          writeException.Invoke(logger, level, ex, message, formattedParmeters)681                  IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)682                  TranslateLevel = translateLevel }683684        type private SeriLogProvider() =685            let getLoggerByName = getForContextMethodCall ()686            let pushProperty = getPushProperty ()687            let serilogGatewayInit = lazy (SerilogGateway.Create())688689            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =690                let serilogGateway = serilogGatewayInit.Value691                let translatedValue = serilogGateway.TranslateLevel logLevel692693                match messageFunc with694                | None -> serilogGateway.IsEnabled logger translatedValue695                | Some _ when696                    serilogGateway.IsEnabled logger translatedValue697                    |> not698                    ->699                    false700                | Some m ->701                    match ``exception`` with702                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams703                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams704705                    true706707            interface ILogProvider with708                member this.GetLogger(name: string) : Logger = getLoggerByName name |> writeMessage709710                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =711                    pushProperty key value destructure712713                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false714715        let create () = SeriLogProvider() :> ILogProvider716651                let isEnabled =652                    Expression653                        .Lambda<Func<obj, obj, bool>>(isEnabledMethodCall, instanceParam, levelParam)654                        .Compile()655656                let writeMethodInfo =657                    loggerType.GetMethod(658                        "Write",659                        [|660                            logEventLevelType661                            typedefof<string>662                            typedefof<obj[]>663                        |]664                    )665666                let messageParam = Expression.Parameter(typedefof<string>)667                let propertyValuesParam = Expression.Parameter(typedefof<obj[]>)668669                let writeMethodExp =670                    Expression.Call(instanceCast, writeMethodInfo, levelCast, messageParam, propertyValuesParam)671672                let expression =673                    Expression.Lambda<Action<obj, obj, string, obj[]>>(674                        writeMethodExp,675                        instanceParam,676                        levelParam,677                        messageParam,678                        propertyValuesParam679                    )680681                let write = expression.Compile()682683                let writeExceptionMethodInfo =684                    loggerType.GetMethod(685                        "Write",686                        [|687                            logEventLevelType688                            typedefof<exn>689                            typedefof<string>690                            typedefof<obj[]>691                        |]692                    )693694                let exceptionParam = Expression.Parameter(typedefof<exn>)695696                let writeMethodExp =697                    Expression.Call(698                        instanceCast,699                        writeExceptionMethodInfo,700                        levelCast,701                        exceptionParam,702                        messageParam,703                        propertyValuesParam704                    )705706                let writeException =707                    Expression708                        .Lambda<Action<obj, obj, exn, string, obj[]>>(709                            writeMethodExp,710                            instanceParam,711                            levelParam,712                            exceptionParam,713                            messageParam,714                            propertyValuesParam715                        )716                        .Compile()  717718    module MicrosoftExtensionsLoggingProvider =719        open System720        open System.Linq.Expressions721        open System.Reflection722        open System.Collections.Generic723724        type ILoggerFactory = obj725        // This has to be set from usercode for this to light up726        let mutable private  microsoftLoggerFactory : ILoggerFactory option = None727        let setMicrosoftLoggerFactory (factory : ILoggerFactory) = microsoftLoggerFactory <- Option.ofObj factory728729        let getLogFactoryType = lazy(Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Log730        let isAvailable () =731            getLogFactoryType.Value |> isNull |> not732            && microsoftLoggerFactory |> Option.isSome733718                {719                    Write =720                        (fun logger level message formattedParmeters ->721                            write.Invoke(logger, level, message, formattedParmeters)722                        )723                    WriteException =724                        fun logger level ex message formattedParmeters ->725                            writeException.Invoke(logger, level, ex, message, formattedParmeters)726                    IsEnabled = fun logger level -> isEnabled.Invoke(logger, level)727                    TranslateLevel = translateLevel728                }729730        type private SeriLogProvider() =731            let getLoggerByName = getForContextMethodCall ()732            let pushProperty = getPushProperty ()733            let serilogGatewayInit = lazy (SerilogGateway.Create())  734735        type ILogger = obj736        type LoggerName = string737        type MicrosoftLogLevel = obj738        type MessageFormat = string739        type MessageArgs = obj array740741        [<NoEquality; NoComparison>]742        type LoggerFactoryGateway = {743            CreateLogger : ILoggerFactory -> LoggerName -> ILogger744        }745        with746            static member Create() =747                let createLogger =748                    let factoryType = getLogFactoryType.Value749                    let createLoggerMethodInfo =750                        factoryType.GetMethod(751                            "CreateLogger",752                            [|typedefof<string>|])753                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)754                    let nameParam = Expression.Parameter(typedefof<string>)755                    let instanceCast =756                        Expression.Convert(instanceParam, factoryType)757                    let createLoggerMethodExp =758                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)759                    let createLogger =760                        Expression761                            .Lambda<Func<ILoggerFactory,string,ILogger>>(createLoggerMethodExp, instanceParam, nameParam762                            .Compile()763                    createLogger764                    |> FuncConvert.FromFunc765                {766                    CreateLogger = createLogger767                }768769        type LoggerGateway = {770            Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit771            WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit772            IsEnabled: ILogger -> MicrosoftLogLevel -> bool773            TranslateLevel : LogLevel -> MicrosoftLogLevel774            BeginScope : ILogger -> obj -> IDisposable775        } with776            static member Create () =777                let loggerExtensions = Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions778                let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstra779                let logEventLevelType =780                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")781                let instanceParam = Expression.Parameter(typedefof<ILogger>)735            let writeMessage logger logLevel (messageFunc: MessageThunk) ``exception`` formatParams =736                let serilogGateway = serilogGatewayInit.Value737                let translatedValue = serilogGateway.TranslateLevel logLevel738739                match messageFunc with740                | None -> serilogGateway.IsEnabled logger translatedValue741                | Some _ when742                    serilogGateway.IsEnabled logger translatedValue743                    |> not744                    ->745                    false746                | Some m ->747                    match ``exception`` with748                    | Some ex -> serilogGateway.WriteException logger translatedValue ex (m ()) formatParams749                    | None -> serilogGateway.Write logger translatedValue (m ()) formatParams750751                    true752753            interface ILogProvider with754                member this.GetLogger(name: string) : Logger =755                    getLoggerByName name756                    |> writeMessage757758                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =759                    pushProperty key value destructure760761                member this.OpenNestedContext(message: string) : IDisposable = pushProperty "NDC" message false762763        let create () = SeriLogProvider() :> ILogProvider764765766    module MicrosoftExtensionsLoggingProvider =767        open System768        open System.Linq.Expressions769        open System.Reflection770        open System.Collections.Generic771772        type ILoggerFactory = obj773        // This has to be set from usercode for this to light up774        let mutable private microsoftLoggerFactory: ILoggerFactory option = None775776        let setMicrosoftLoggerFactory (factory: ILoggerFactory) =777            microsoftLoggerFactory <- Option.ofObj factory778779        let getLogFactoryType =780            lazy781                (Type.GetType("Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.Abstractions"))  782783                let instanceCast =784                    Expression.Convert(instanceParam, loggerType)785                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)786787                let levelCast = Expression.Convert(levelParam, logEventLevelType)788789                let isEnabled =790                    let isEnabledMethodInfo =791                        loggerType.GetMethod("IsEnabled", [| logEventLevelType |])792                    let isEnabledMethodCall =793                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)794795796                    Expression797                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)798                        .Compile()799                    |> FuncConvert.FromFunc800801                let write, writeError =802                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)803                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)804805                    let write =806                        let writeMethodInfo =807                            loggerExtensions.GetMethod(808                                "Log",809                                BindingFlags.Static ||| BindingFlags.Public,810                                null,811                                [| loggerType812                                   logEventLevelType813                                   typedefof<MessageFormat>814                                   typedefof<MessageArgs> |],815                                null816                            )817818                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, messagePara819820                        let expression =821                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(822                                writeMethodExp,823                                instanceParam,824                                levelParam,825                                messageParam,826                                propertyValuesParam827                            )828                        expression.Compile() |> FuncConvert.FromAction829783        let isAvailable () =784            getLogFactoryType.Value785            |> isNull786            |> not787            && microsoftLoggerFactory788               |> Option.isSome789790791        type ILogger = obj792        type LoggerName = string793        type MicrosoftLogLevel = obj794        type MessageFormat = string795        type MessageArgs = obj array796797        [<NoEquality; NoComparison>]798        type LoggerFactoryGateway =799            {800                CreateLogger: ILoggerFactory -> LoggerName -> ILogger801            }802803            static member Create() =804                let createLogger =805                    let factoryType = getLogFactoryType.Value806807                    let createLoggerMethodInfo =808                        factoryType.GetMethod("CreateLogger", [| typedefof<string> |])809810                    let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)811                    let nameParam = Expression.Parameter(typedefof<string>)812                    let instanceCast = Expression.Convert(instanceParam, factoryType)813814                    let createLoggerMethodExp =815                        Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)816817                    let createLogger =818                        Expression819                            .Lambda<Func<ILoggerFactory, string, ILogger>>(820                                createLoggerMethodExp,821                                instanceParam,822                                nameParam823                            )824                            .Compile()825826                    createLogger827                    |> FuncConvert.FromFunc828829                { CreateLogger = createLogger }  830831                    let writeError =832                        let writeMethodInfo =833                            loggerExtensions.GetMethod(834                                "Log",835                                BindingFlags.Static ||| BindingFlags.Public,836                                null,837                                [| loggerType838                                   logEventLevelType839                                   typedefof<exn>840                                   typedefof<MessageFormat>841                                   typedefof<MessageArgs> |],842                                null843844                            )845                        let exnParam = Expression.Parameter(typedefof<exn>)846                        let writeMethodExp = Expression.Call(null, writeMethodInfo, instanceCast, levelCast, exnParam, m847848                        let expression =849                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(850                                writeMethodExp,851                                instanceParam,852                                levelParam,853                                exnParam,854                                messageParam,855                                propertyValuesParam856                            )857                        expression.Compile() |> FuncConvert.FromAction858                    write, writeError859860                let translateLevel =831        type LoggerGateway =832            {833                Write: ILogger -> MicrosoftLogLevel -> MessageFormat -> MessageArgs -> unit834                WriteError: ILogger -> MicrosoftLogLevel -> exn -> MessageFormat -> MessageArgs -> unit835                IsEnabled: ILogger -> MicrosoftLogLevel -> bool836                TranslateLevel: LogLevel -> MicrosoftLogLevel837                BeginScope: ILogger -> obj -> IDisposable838            }839840            static member Create() =841                let loggerExtensions =842                    Type.GetType(843                        "Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions"844                    )845846                let loggerType =847                    Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")848849                let logEventLevelType =850                    Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")851852                let instanceParam = Expression.Parameter(typedefof<ILogger>)853854                let instanceCast = Expression.Convert(instanceParam, loggerType)855                let levelParam = Expression.Parameter(typedefof<MicrosoftLogLevel>)856857                let levelCast = Expression.Convert(levelParam, logEventLevelType)858859                let isEnabled =860                    let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])  861862                    let debugLevel =863                        Enum.Parse(logEventLevelType, "Debug", false)862                    let isEnabledMethodCall =863                        Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)  864865                    let errorLevel =866                        Enum.Parse(logEventLevelType, "Error", false)867868                    let criticalLevel =869                        Enum.Parse(logEventLevelType, "Critical", false)865866                    Expression867                        .Lambda<Func<ILogger, MicrosoftLogLevel, bool>>(isEnabledMethodCall, instanceParam, levelParam)868                        .Compile()869                    |> FuncConvert.FromFunc  870871                    let informationLevel =872                        Enum.Parse(logEventLevelType, "Information", false)873874                    let traceLevel =875                        Enum.Parse(logEventLevelType, "Trace", false)876877                    let warningLevel =878                        Enum.Parse(logEventLevelType, "Warning", false)879880                    fun (level: LogLevel) ->881                        match level with882                        | LogLevel.Fatal -> criticalLevel883                        | LogLevel.Error -> errorLevel884                        | LogLevel.Warn -> warningLevel885                        | LogLevel.Info -> informationLevel886                        | LogLevel.Debug -> debugLevel887                        | LogLevel.Trace -> traceLevel888                        | _ -> debugLevel889                let beginScope =890                    let beginScopeMethodInfo =891                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)892                    let stateParam = Expression.Parameter(typedefof<obj>)893                    let beginScopeMethodCall =894                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)895896                    Expression897                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)898                        .Compile()899                    |> FuncConvert.FromFunc871                let write, writeError =872                    let messageParam = Expression.Parameter(typedefof<MessageFormat>)873                    let propertyValuesParam = Expression.Parameter(typedefof<MessageArgs>)874875                    let write =876                        let writeMethodInfo =877                            loggerExtensions.GetMethod(878                                "Log",879                                BindingFlags.Static880                                ||| BindingFlags.Public,881                                null,882                                [|883                                    loggerType884                                    logEventLevelType885                                    typedefof<MessageFormat>886                                    typedefof<MessageArgs>887                                |],888                                null889                            )890891                        let writeMethodExp =892                            Expression.Call(893                                null,894                                writeMethodInfo,895                                instanceCast,896                                levelCast,897                                messageParam,898                                propertyValuesParam899                            )  900901                {902                    Write = write903                    WriteError = writeError904                    IsEnabled = isEnabled905                    TranslateLevel = translateLevel906                    BeginScope = beginScope907                }908901                        let expression =902                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, MessageFormat, MessageArgs>>(903                                writeMethodExp,904                                instanceParam,905                                levelParam,906                                messageParam,907                                propertyValuesParam908                            )  909910        type private MicrosoftProvider() =911            let factoryGateway = lazy(LoggerFactoryGateway.Create())912            let loggerGateway = lazy(LoggerGateway.Create())913            interface ILogProvider with914                member this.GetLogger(name: string) : Logger =915                    match microsoftLoggerFactory with916                    | None ->917                        fun _ _ _ _ -> false918                    | Some factory ->919                        let logger = factoryGateway.Value.CreateLogger factory name920921                        fun logLevel message exn args ->922                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel923                            match message with924                            | Some message ->925                                let message = message ()926                                match exn with927                                | Some ex ->928                                    loggerGateway.Value.WriteError logger microsoftLevel ex message args929                                | None ->930                                    loggerGateway.Value.Write logger microsoftLevel message args931                                true932                            | None ->933                                loggerGateway.Value.IsEnabled logger microsoftLevel934935                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =936                    match microsoftLoggerFactory with937                    | None ->938                        { new IDisposable with member x.Dispose () = ()}939                    | Some factory ->940                        // Create bogus logger that will propagate to a real logger later941                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())942                        // Requires a IEnumerable<KeyValuePair> to make sense943                        // https://nblumhardt.com/2016/11/ilogger-beginscope/944                        [KeyValuePair(key, value)]945                        |> box946                        |> loggerGateway.Value.BeginScope logger947948949                member this.OpenNestedContext(message: string) : IDisposable =950                    match microsoftLoggerFactory with951                    | None ->952                        { new IDisposable with member x.Dispose () = ()}953                    | Some factory ->954                        // Create bogus logger that will propagate to a real logger later955                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())956                        loggerGateway.Value.BeginScope logger (box message)910                        expression.Compile()911                        |> FuncConvert.FromAction912913914                    let writeError =915                        let writeMethodInfo =916                            loggerExtensions.GetMethod(917                                "Log",918                                BindingFlags.Static919                                ||| BindingFlags.Public,920                                null,921                                [|922                                    loggerType923                                    logEventLevelType924                                    typedefof<exn>925                                    typedefof<MessageFormat>926                                    typedefof<MessageArgs>927                                |],928                                null929930                            )931932                        let exnParam = Expression.Parameter(typedefof<exn>)933934                        let writeMethodExp =935                            Expression.Call(936                                null,937                                writeMethodInfo,938                                instanceCast,939                                levelCast,940                                exnParam,941                                messageParam,942                                propertyValuesParam943                            )944945                        let expression =946                            Expression.Lambda<Action<ILogger, MicrosoftLogLevel, exn, MessageFormat, MessageArgs>>(947                                writeMethodExp,948                                instanceParam,949                                levelParam,950                                exnParam,951                                messageParam,952                                propertyValuesParam953                            )954955                        expression.Compile()956                        |> FuncConvert.FromAction  957958        let create () = MicrosoftProvider() :> ILogProvider958                    write, writeError  959960#endif960                let translateLevel =  961962963module LogProvider =964    open System965    open Types966    #if !FABLE_COMPILER967    open Providers968    #endif969    open System.Diagnostics970    open Microsoft.FSharp.Quotations.Patterns962                    let debugLevel = Enum.Parse(logEventLevelType, "Debug", false)963964                    let errorLevel = Enum.Parse(logEventLevelType, "Error", false)965966                    let criticalLevel = Enum.Parse(logEventLevelType, "Critical", false)967968                    let informationLevel = Enum.Parse(logEventLevelType, "Information", false)969970                    let traceLevel = Enum.Parse(logEventLevelType, "Trace", false)  971972    let mutable private currentLogProvider = None972                    let warningLevel = Enum.Parse(logEventLevelType, "Warning", false)  973974    let private knownProviders =975        [976        #if !FABLE_COMPILER977            (SerilogProvider.isAvailable, SerilogProvider.create)978            (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)979        #endif980        ]981982    /// Greedy search for first available LogProvider. Order of known providers matters.983    let private resolvedLogger =984        lazy985            (knownProviders986             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())987             |> Option.map (fun (_, create) -> create ()))988989    let private noopLogger _ _ _ _ = false990991    let private noopDisposable =992        { new IDisposable with993            member __.Dispose() = () }994995    /// <summary>996    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.997    /// </summary>998    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>999    /// <returns></returns>1000    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider10011002    /// <summary>1003    /// Gets the currently set LogProvider or attempts to find known built in providers1004    /// </summary>1005    /// <returns></returns>1006    let getCurrentLogProvider () =1007        match currentLogProvider with1008        | None -> resolvedLogger.Value1009        | Some p -> Some p974                    fun (level: LogLevel) ->975                        match level with976                        | LogLevel.Fatal -> criticalLevel977                        | LogLevel.Error -> errorLevel978                        | LogLevel.Warn -> warningLevel979                        | LogLevel.Info -> informationLevel980                        | LogLevel.Debug -> debugLevel981                        | LogLevel.Trace -> traceLevel982                        | _ -> debugLevel983984                let beginScope =985                    let beginScopeMethodInfo =986                        loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)987988                    let stateParam = Expression.Parameter(typedefof<obj>)989990                    let beginScopeMethodCall =991                        Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)992993                    Expression994                        .Lambda<Func<ILogger, obj, IDisposable>>(beginScopeMethodCall, instanceParam, stateParam)995                        .Compile()996                    |> FuncConvert.FromFunc997998                {999                    Write = write1000                    WriteError = writeError1001                    IsEnabled = isEnabled1002                    TranslateLevel = translateLevel1003                    BeginScope = beginScope1004                }100510061007        type private MicrosoftProvider() =1008            let factoryGateway = lazy (LoggerFactoryGateway.Create())1009            let loggerGateway = lazy (LoggerGateway.Create())  10101011    /// <summary>1012    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1013    /// </summary>1014    /// <param name="key">The name of the property.</param>1015    /// <param name="value">The value of the property.</param>1016    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1017    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1018    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1019        let provider = getCurrentLogProvider ()1011            interface ILogProvider with1012                member this.GetLogger(name: string) : Logger =1013                    match microsoftLoggerFactory with1014                    | None -> fun _ _ _ _ -> false1015                    | Some factory ->1016                        let logger = factoryGateway.Value.CreateLogger factory name10171018                        fun logLevel message exn args ->1019                            let microsoftLevel = loggerGateway.Value.TranslateLevel logLevel  10201021        match provider with1022        | Some p -> p.OpenMappedContext key value destructureObjects1023        | None -> noopDisposable1021                            match message with1022                            | Some message ->1023                                let message = message ()  102410251026    /// <summary>1027    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1028    /// </summary>1029    /// <param name="key">The name of the property.</param>1030    /// <param name="value">The value of the property.</param>1031    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1032    let openMappedContext (key: string) (value: obj) =1033        //TODO: We should try to find out if the value is a primitive1034        openMappedContextDestucturable key value false103510361037    /// <summary>1038    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1039    /// </summary>1040    /// <param name="value">The value of the property</param>1041    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1042    let openNestedContext (value: string) =1043        let provider = getCurrentLogProvider ()10441045        match provider with1046        | Some p -> p.OpenNestedContext value1047        | None -> noopDisposable10481049    /// <summary>1050    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1051    /// </summary>1052    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1053    /// <returns></returns>1054    let getLoggerByName (name: string) =1055        let loggerProvider = getCurrentLogProvider ()10561057        let logFunc =1058            match loggerProvider with1059            | Some loggerProvider -> loggerProvider.GetLogger(name)1060            | None -> noopLogger1025                                match exn with1026                                | Some ex -> loggerGateway.Value.WriteError logger microsoftLevel ex message args1027                                | None -> loggerGateway.Value.Write logger microsoftLevel message args10281029                                true1030                            | None -> loggerGateway.Value.IsEnabled logger microsoftLevel10311032                member this.OpenMappedContext (key: string) (value: obj) (destructure: bool) : IDisposable =1033                    match microsoftLoggerFactory with1034                    | None ->1035                        { new IDisposable with1036                            member x.Dispose() = ()1037                        }1038                    | Some factory ->1039                        // Create bogus logger that will propagate to a real logger later1040                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())1041                        // Requires a IEnumerable<KeyValuePair> to make sense1042                        // https://nblumhardt.com/2016/11/ilogger-beginscope/1043                        [ KeyValuePair(key, value) ]1044                        |> box1045                        |> loggerGateway.Value.BeginScope logger104610471048                member this.OpenNestedContext(message: string) : IDisposable =1049                    match microsoftLoggerFactory with1050                    | None ->1051                        { new IDisposable with1052                            member x.Dispose() = ()1053                        }1054                    | Some factory ->1055                        // Create bogus logger that will propagate to a real logger later1056                        let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())10571058                        loggerGateway.Value.BeginScope logger (box message)10591060        let create () = MicrosoftProvider() :> ILogProvider  10611062        { new ILog with1063            member x.Log = logFunc1064            member x.MappedContext = openMappedContextDestucturable }10651066    /// <summary>1067    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1068    /// </summary>1069    /// <param name="objectType">The type to generate a logger name from. </param>1070    /// <returns></returns>1071    let getLoggerByType (objectType: Type) = objectType |> string |> getLoggerByName10721073    /// <summary>1074    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1075    /// </summary>1076    /// <typeparam name="'a">The type to generate a name from.</typeparam>1077    /// <returns></returns>1078    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)10791080#if !FABLE_COMPILER1081    let rec private getModuleType =1082        function1083        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1084        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1085        // | Lambda(_, expr) -> getModuleType expr1086        // | ValueWithName(_,_,instance) -> instance1087        | x -> failwithf "Expression is not a property. %A" x10881062#endif106310641065module LogProvider =1066    open System1067    open Types1068#if !FABLE_COMPILER1069    open Providers1070#endif1071    open System.Diagnostics1072    open Microsoft.FSharp.Quotations.Patterns10731074    let mutable private currentLogProvider = None10751076    let private knownProviders = [1077#if !FABLE_COMPILER1078        (SerilogProvider.isAvailable, SerilogProvider.create)1079        (MicrosoftExtensionsLoggingProvider.isAvailable, MicrosoftExtensionsLoggingProvider.create)1080#endif1081    ]10821083    /// Greedy search for first available LogProvider. Order of known providers matters.1084    let private resolvedLogger =1085        lazy1086            (knownProviders1087             |> Seq.tryFind (fun (isAvailable, _) -> isAvailable ())1088             |> Option.map (fun (_, create) -> create ()))  10891090    /// <summary>1091    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1092    ///1093    /// It can be utilized like:1094    ///1095    /// <code>1096    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1097    /// </code>1098    ///1099    /// inside a module to get the modules full qualitfied name.1100    /// </summary>1101    /// <param name="quotation">The quotation to generate a logger name from.</param>1102    /// <returns></returns>1103    let getLoggerByQuotation (quotation: Quotations.Expr) =1104        getModuleType quotation |> getLoggerByType110511061107type LogProvider =1108    /// <summary>1109    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1110    /// </summary>1111    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1112    /// <returns></returns>1113    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1114        let mi = System.Reflection.MethodBase.GetCurrentMethod()1115        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1116        // CallerMemberName gets us the function that actually called it1117        // Splitting off + seems like the best option to get the Fully Qualified Path1118        let location = mi.DeclaringType.FullName.Split('+') |> Seq.tryHead |> Option.defaultValue ""1119        sprintf "%s.%s" location memberName.Value1120        |> LogProvider.getLoggerByName11211122#endif1090    let private noopLogger _ _ _ _ = false10911092    let private noopDisposable =1093        { new IDisposable with1094            member __.Dispose() = ()1095        }10961097    /// <summary>1098    /// Allows custom override when a <c>getLogger</c> function searches for a LogProvider.1099    /// </summary>1100    /// <param name="logProvider">The <see cref="M:FsLibLog.Types.ILogProvider"/> to set</param>1101    /// <returns></returns>1102    let setLoggerProvider (logProvider: ILogProvider) = currentLogProvider <- Some logProvider11031104    /// <summary>1105    /// Gets the currently set LogProvider or attempts to find known built in providers1106    /// </summary>1107    /// <returns></returns>1108    let getCurrentLogProvider () =1109        match currentLogProvider with1110        | None -> resolvedLogger.Value1111        | Some p -> Some p11121113    /// <summary>1114    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope.1115    /// </summary>1116    /// <param name="key">The name of the property.</param>1117    /// <param name="value">The value of the property.</param>1118    /// <param name="destructureObjects">If true, and the value is a non-primitive, non-array type, then the value will 1119    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1120    let openMappedContextDestucturable (key: string) (value: obj) (destructureObjects: bool) =1121        let provider = getCurrentLogProvider ()11221123        match provider with1124        | Some p -> p.OpenMappedContext key value destructureObjects1125        | None -> noopDisposable112611271128    /// <summary>1129    /// Opens a mapped diagnostic context.  This will allow you to set additional parameters to a log given a scope. Set1130    /// </summary>1131    /// <param name="key">The name of the property.</param>1132    /// <param name="value">The value of the property.</param>1133    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1134    let openMappedContext (key: string) (value: obj) =1135        //TODO: We should try to find out if the value is a primitive1136        openMappedContextDestucturable key value false113711381139    /// <summary>1140    /// Opens a nested diagnostic context.  This will allow you to set additional parameters to a log given a scope.1141    /// </summary>1142    /// <param name="value">The value of the property</param>1143    /// <returns>An IDisposable upon disposing will remove this value from a loggers scope</returns>1144    let openNestedContext (value: string) =1145        let provider = getCurrentLogProvider ()11461147        match provider with1148        | Some p -> p.OpenNestedContext value1149        | None -> noopDisposable11501151    /// <summary>1152    /// Creates a logger given a <see cref="T:System.String">string</see>. This will attempt to retrieve any loggers set1153    /// </summary>1154    /// <param name="name">A name to give a logger. This can help you identify the location of where the log occurred up1155    /// <returns></returns>1156    let getLoggerByName (name: string) =1157        let loggerProvider = getCurrentLogProvider ()11581159        let logFunc =1160            match loggerProvider with1161            | Some loggerProvider -> loggerProvider.GetLogger(name)1162            | None -> noopLogger11631164        { new ILog with1165            member x.Log = logFunc1166            member x.MappedContext = openMappedContextDestucturable1167        }11681169    /// <summary>1170    /// Creates a logger given a <see cref="T:System.Type">Type</see>.  This will attempt to retrieve any loggers set wi1171    /// </summary>1172    /// <param name="objectType">The type to generate a logger name from. </param>1173    /// <returns></returns>1174    let getLoggerByType (objectType: Type) =1175        objectType1176        |> string1177        |> getLoggerByName11781179    /// <summary>1180    /// Creates a logger given a <c>'a</c> type. This will attempt to retrieve any loggers set with <see cref="M:FsLibLo1181    /// </summary>1182    /// <typeparam name="'a">The type to generate a name from.</typeparam>1183    /// <returns></returns>1184    let inline getLoggerFor<'a> () = getLoggerByType (typeof<'a>)11851186#if !FABLE_COMPILER1187    let rec private getModuleType =1188        function1189        | PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType1190        // | Call (_, methInfo, _) -> sprintf "%s.%s" methInfo.DeclaringType.FullName methInfo.Name1191        // | Lambda(_, expr) -> getModuleType expr1192        // | ValueWithName(_,_,instance) -> instance1193        | x -> failwithf "Expression is not a property. %A" x119411951196    /// <summary>1197    /// Creates a logger given a Quotations.Expr type. This is only useful for module level declarations. It uses the De1198    ///1199    /// It can be utilized like:1200    ///1201    /// <code>1202    /// let rec logger = LogProvider.getLoggerByQuotation &lt;@ logger @&gt;1203    /// </code>1204    ///1205    /// inside a module to get the modules full qualitfied name.1206    /// </summary>1207    /// <param name="quotation">The quotation to generate a logger name from.</param>1208    /// <returns></returns>1209    let getLoggerByQuotation (quotation: Quotations.Expr) =1210        getModuleType quotation1211        |> getLoggerByType121212131214type LogProvider =1215    /// <summary>1216    /// Creates a logger based on `Reflection.MethodBase.GetCurrentMethod().FullName` and `CallerMemberName`. This is on1217    /// </summary>1218    /// <param name="memberName">Do not pass anything to this parameter to get `CallerMemberName` to work.</param>1219    /// <returns></returns>1220    static member inline getLoggerByFunc([<System.Runtime.CompilerServices.CallerMemberName>] ?memberName: string) =1221        let mi = System.Reflection.MethodBase.GetCurrentMethod()1222        // When we're in a CE we get something like `WebBackend.App+thingsToCall2@130`.1223        // CallerMemberName gets us the function that actually called it1224        // Splitting off + seems like the best option to get the Fully Qualified Path1225        let location =1226            mi.DeclaringType.FullName.Split('+')1227            |> Seq.tryHead1228            |> Option.defaultValue ""12291230        sprintf "%s.%s" location memberName.Value1231        |> LogProvider.getLoggerByName12321233#endif - +

Methods/Properties

-StartLogLevel(FsLibLog.Types/LogLevel)
-.ctor()
-System.IDisposable.Dispose()
-Push(System.IDisposable)
-Push(Microsoft.FSharp.Collections.FSharpList`1<System.IDisposable>)
-Invoke(System.IDisposable)
-Create(Microsoft.FSharp.Collections.FSharpList`1<System.IDisposable>)
-ILog.fromLog(FsLibLog.Types/ILog,FsLibLog.Types/Log)
-Invoke(System.Tuple`3<System.String,System.Object,System.Boolean>)
-ILog.fatal'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.fatal(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.error'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.error(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.warn'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.warn(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.info'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.info(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.debug'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.debug(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.trace'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-ILog.trace(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
-setMessage(System.String,FsLibLog.Types/Log)
-Invoke(Microsoft.FSharp.Core.Unit)
-setMessageThunk(Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>,FsLibLog.Types/Log)
-addParameter(a,FsLibLog.Types/Log)
-addParameters(Microsoft.FSharp.Collections.FSharpList`1<System.Object>,FsLibLog.Types/Log)
-Invoke(System.Object)
-addContext(System.String,System.Object,FsLibLog.Types/Log)
-addContextDestructured(System.String,System.Object,FsLibLog.Types/Log)
-addException(System.Exception,FsLibLog.Types/Log)
-addExn(System.Exception,FsLibLog.Types/Log)
-setLogLevel(FsLibLog.Types/LogLevel,FsLibLog.Types/Log)
-isAnObject(a)
-setMessageInterpolated(System.FormattableString,FsLibLog.Types/Log)
-Invoke(System.Text.RegularExpressions.Match)
-Invoke(System.Tuple`4<System.String,System.Object,System.Int32,System.Int32>)
-Invoke(System.Tuple`4<System.String,System.Object,System.Int32,System.Int32>)
-Invoke(System.Collections.Generic.IEnumerable`1<System.Tuple`4<System.String,a,b,c>>,FsLibLog.Types/Log)
-Invoke(FsLibLog.Types/Log)
-Invoke(Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>,System.Tuple`4<System.String,a,b,c>)
-Invoke(System.String,a,FsLibLog.Types/Log)
-Invoke(System.String,a,FsLibLog.Types/Log)
-Invoke(FsLibLog.Types/Log)
-setMessageI(System.FormattableString,FsLibLog.Types/Log)
+StartLogLevel(FsLibLog.Types/LogLevel)
+.ctor()
+System.IDisposable.Dispose()
+Push(System.IDisposable)
+Push(Microsoft.FSharp.Collections.FSharpList`1<System.IDisposable>)
+Create(Microsoft.FSharp.Collections.FSharpList`1<System.IDisposable>)
+ILog.fromLog(FsLibLog.Types/ILog,FsLibLog.Types/Log)
+Invoke(System.Tuple`3<System.String,System.Object,System.Boolean>)
+ILog.fatal'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.fatal(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.error'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.error(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.warn'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.warn(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.info'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.info(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.debug'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.debug(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.trace'(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+ILog.trace(FsLibLog.Types/ILog,Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>)
+setMessage(System.String,FsLibLog.Types/Log)
+Invoke(Microsoft.FSharp.Core.Unit)
+setMessageThunk(Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.String>,FsLibLog.Types/Log)
+addParameter(a,FsLibLog.Types/Log)
+addParameters(Microsoft.FSharp.Collections.FSharpList`1<System.Object>,FsLibLog.Types/Log)
+addContext(System.String,System.Object,FsLibLog.Types/Log)
+addContextDestructured(System.String,System.Object,FsLibLog.Types/Log)
+addException(System.Exception,FsLibLog.Types/Log)
+addExn(System.Exception,FsLibLog.Types/Log)
+setLogLevel(FsLibLog.Types/LogLevel,FsLibLog.Types/Log)
+isAnObject(a)
+setMessageInterpolated(System.FormattableString,FsLibLog.Types/Log)
+Invoke(System.Text.RegularExpressions.Match)
+Invoke(System.Tuple`4<System.String,System.Object,System.Int32,System.Int32>)
+Invoke(System.Tuple`4<System.String,System.Object,System.Int32,System.Int32>)
+Invoke(Microsoft.FSharp.Core.FSharpFunc`2<FsLibLog.Types/Log,FsLibLog.Types/Log>,System.Tuple`4<System.String,a,b,c>)
+Invoke(FsLibLog.Types/Log)
+setMessageI(System.FormattableString,FsLibLog.Types/Log)

diff --git a/docs/coverage/index.htm b/docs/coverage/index.htm index bfe4566..6baf42a 100644 --- a/docs/coverage/index.htm +++ b/docs/coverage/index.htm @@ -14,19 +14,19 @@

Summary

-Generated on:9/17/2022 - 5:27:01 PM +Generated on:9/17/2022 - 6:01:04 PM Parser:OpenCoverParser Assemblies:2 Classes:220 Files:33 Covered lines:533 -Uncovered lines:10529 -Coverable lines:11062 -Total lines:1122 -Line coverage:4.8% (533 of 11062) +Uncovered lines:10562 +Coverable lines:11095 +Total lines:1233 +Line coverage:4.8% (533 of 11095) Covered branches:151 -Total branches:9096 -Branch coverage:1.6% (151 of 9096) +Total branches:9092 +Branch coverage:1.6% (151 of 9092)

Risk Hotspots

@@ -422,16 +422,16 @@

Coverage

Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedText0000
 
 
Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedTextOps0303000%
 
0%
 
Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedTextWriter0000
 
 
-FsLibLog046946956100%
 
0%
 
-FsLibLog.LogProvider04411220%
 
 
-FsLibLog.LogProviderModule0323211220%
 
0%
 
-FsLibLog.Operators05511220%
 
 
-FsLibLog.Providers032132111220%
 
0%
 
-FsLibLog.Types010710711220%
 
0%
 
+FsLibLog050250261650%
 
0%
 
+FsLibLog.LogProvider06612330%
 
 
+FsLibLog.LogProviderModule0343412330%
 
0%
 
+FsLibLog.Operators09912330%
 
 
+FsLibLog.Providers034234212330%
 
0%
 
+FsLibLog.Types011111112330%
 
0%
 
System.AssemblyVersionInformation0000
 
 
- + \ No newline at end of file diff --git a/docs/coverage/main.js b/docs/coverage/main.js index 03076fa..b875574 100644 --- a/docs/coverage/main.js +++ b/docs/coverage/main.js @@ -442,11 +442,11 @@ var assemblies = [ { "name": "FsLibLog", "classes": [ - { "name": "FsLibLog.LogProvider", "rp": "FsLibLog_LogProvider.htm", "cl": 0, "ucl": 4, "cal": 4, "tl": 1122, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 0, "lch": [], "bch": [], "hc": [] }, - { "name": "FsLibLog.LogProviderModule", "rp": "FsLibLog_LogProviderModule.htm", "cl": 0, "ucl": 32, "cal": 32, "tl": 1122, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 8, "lch": [], "bch": [], "hc": [] }, - { "name": "FsLibLog.Operators", "rp": "FsLibLog_Operators.htm", "cl": 0, "ucl": 5, "cal": 5, "tl": 1122, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 0, "lch": [], "bch": [], "hc": [] }, - { "name": "FsLibLog.Providers", "rp": "FsLibLog_Providers.htm", "cl": 0, "ucl": 321, "cal": 321, "tl": 1122, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 28, "lch": [], "bch": [], "hc": [] }, - { "name": "FsLibLog.Types", "rp": "FsLibLog_Types.htm", "cl": 0, "ucl": 107, "cal": 107, "tl": 1122, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 8, "lch": [], "bch": [], "hc": [] }, + { "name": "FsLibLog.LogProvider", "rp": "FsLibLog_LogProvider.htm", "cl": 0, "ucl": 6, "cal": 6, "tl": 1233, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 0, "lch": [], "bch": [], "hc": [] }, + { "name": "FsLibLog.LogProviderModule", "rp": "FsLibLog_LogProviderModule.htm", "cl": 0, "ucl": 34, "cal": 34, "tl": 1233, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 8, "lch": [], "bch": [], "hc": [] }, + { "name": "FsLibLog.Operators", "rp": "FsLibLog_Operators.htm", "cl": 0, "ucl": 9, "cal": 9, "tl": 1233, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 0, "lch": [], "bch": [], "hc": [] }, + { "name": "FsLibLog.Providers", "rp": "FsLibLog_Providers.htm", "cl": 0, "ucl": 342, "cal": 342, "tl": 1233, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 26, "lch": [], "bch": [], "hc": [] }, + { "name": "FsLibLog.Types", "rp": "FsLibLog_Types.htm", "cl": 0, "ucl": 111, "cal": 111, "tl": 1233, "ct": "LineCoverage", "mc": "-", "cb": 0, "tb": 6, "lch": [], "bch": [], "hc": [] }, { "name": "System.AssemblyVersionInformation", "rp": "FsLibLog_AssemblyVersionInformation.htm", "cl": 0, "ucl": 0, "cal": 0, "tl": 0, "ct": "MethodCoverage", "mc": "-", "cb": 0, "tb": 0, "lch": [], "bch": [], "hc": [] }, ]}, ];