1
- namespace Microsoft.VisualStudio.FSharp.Editor.Logging
1
+ namespace Microsoft.VisualStudio.FSharp.Editor.DebugHelpers
2
2
3
3
open System
4
4
open System.Diagnostics
5
- open System.ComponentModel .Composition
6
5
open Microsoft.VisualStudio .Shell
7
6
open Microsoft.VisualStudio .Shell .Interop
8
- open Microsoft.VisualStudio .FSharp .Editor
9
7
10
8
open FSharp.Compiler .Diagnostics
11
9
@@ -32,75 +30,57 @@ module Config =
32
30
open Config
33
31
open System.Diagnostics .Metrics
34
32
open System.Text
33
+ open Microsoft.VisualStudio .Threading
35
34
36
- [<Export>]
37
- type Logger [<ImportingConstructor>] ([< Import ( typeof <SVsServiceProvider> )>] serviceProvider : IServiceProvider ) =
38
- let outputWindow =
39
- serviceProvider.GetService< SVsOutputWindow, IVsOutputWindow>() |> Option.ofObj
40
-
41
- let createPane () =
42
- outputWindow
43
- |> Option.iter ( fun x ->
44
- x.CreatePane( ref fsharpOutputGuid, " F# Language Service" , Convert.ToInt32 true , Convert.ToInt32 false )
45
- |> ignore)
46
-
47
- do createPane ()
48
-
49
- let getPane () =
50
- match outputWindow |> Option.map ( fun x -> x.GetPane( ref fsharpOutputGuid)) with
51
- | Some( 0 , pane) ->
52
- pane.Activate() |> ignore
53
- Some pane
54
- | _ -> None
55
-
56
- static let mutable globalServiceProvider : IServiceProvider option = None
57
-
58
- static member GlobalServiceProvider
59
- with get () =
60
- globalServiceProvider
61
- |> Option.defaultValue ( ServiceProvider.GlobalProvider :> IServiceProvider)
62
- and set v = globalServiceProvider <- Some v
63
-
64
- member _.FSharpLoggingPane =
65
- getPane ()
66
- |> function
67
- | Some pane -> Some pane
68
- | None ->
69
- createPane ()
70
- getPane ()
71
-
72
- member self.Log ( msgType : LogType , msg : string ) =
73
- let time = DateTime.Now.ToString( " hh:mm:ss tt" )
74
-
75
- match self.FSharpLoggingPane, msgType with
76
- | None, _ -> ()
77
- | Some pane, LogType.Message ->
78
- String.Format( " [{0}{1}] {2}{3}" , " " , time, msg, Environment.NewLine)
79
- |> pane.OutputString
80
- |> ignore
81
- | Some pane, LogType.Info ->
82
- String.Format( " [{0}{1}] {2}{3}" , " INFO " , time, msg, Environment.NewLine)
83
- |> pane.OutputString
84
- |> ignore
85
- | Some pane, LogType.Warn ->
86
- String.Format( " [{0}{1}] {2}{3}" , " WARN " , time, msg, Environment.NewLine)
87
- |> pane.OutputString
88
- |> ignore
89
- | Some pane, LogType.Error ->
90
- String.Format( " [{0}{1}] {2}{3}" , " ERROR " , time, msg, Environment.NewLine)
91
- |> pane.OutputString
92
- |> ignore
93
-
94
- [<AutoOpen>]
95
- module Logging =
35
+ module FSharpOutputPane =
96
36
97
- let inline debug msg = Printf.kprintf Debug.WriteLine msg
37
+ let private pane =
38
+ AsyncLazy(
39
+ fun () ->
40
+ task {
41
+ do ! ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync()
42
+ let! window = AsyncServiceProvider.GlobalProvider.GetServiceAsync< SVsOutputWindow, IVsOutputWindow>()
43
+
44
+ window.CreatePane( ref fsharpOutputGuid, " F# Language Service" , Convert.ToInt32 true , Convert.ToInt32 false )
45
+ |> ignore
98
46
99
- let private logger = lazy Logger( Logger.GlobalServiceProvider)
47
+ match window.GetPane( ref fsharpOutputGuid) with
48
+ | 0 , pane -> return pane
49
+ | _ -> return failwith " Could not get F# output pane"
50
+ }
51
+ , ThreadHelper.JoinableTaskFactory
52
+ )
53
+
54
+ let inline debug msg = Printf.kprintf Debug.WriteLine msg
100
55
101
56
let private log logType msg =
102
- logger.Value.Log( logType, msg)
103
- System.Diagnostics.Trace.TraceInformation( msg)
57
+ task {
58
+ System.Diagnostics.Trace.TraceInformation( msg)
59
+ let time = DateTime.Now.ToString( " hh:mm:ss tt" )
60
+
61
+ let! pane = pane.GetValueAsync()
62
+
63
+ do ! ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync()
64
+
65
+ match logType with
66
+ | LogType.Message ->
67
+ String.Format( " [{0}{1}] {2}{3}" , " " , time, msg, Environment.NewLine)
68
+ |> pane.OutputStringThreadSafe
69
+ |> ignore
70
+ | LogType.Info ->
71
+ String.Format( " [{0}{1}] {2}{3}" , " INFO " , time, msg, Environment.NewLine)
72
+ |> pane.OutputStringThreadSafe
73
+ |> ignore
74
+ | LogType.Warn ->
75
+ String.Format( " [{0}{1}] {2}{3}" , " WARN " , time, msg, Environment.NewLine)
76
+ |> pane.OutputStringThreadSafe
77
+ |> ignore
78
+ | LogType.Error ->
79
+ String.Format( " [{0}{1}] {2}{3}" , " ERROR " , time, msg, Environment.NewLine)
80
+ |> pane.OutputStringThreadSafe
81
+ |> ignore
82
+ }
83
+ |> ignore
104
84
105
85
let logMsg msg = log LogType.Message msg
106
86
let logInfo msg = log LogType.Info msg
@@ -145,7 +125,7 @@ module FSharpServiceTelemetry =
145
125
ActivitySamplingResult.AllData
146
126
else
147
127
ActivitySamplingResult.None),
148
- ActivityStarted = ( fun a -> logMsg $" {indent a}{a.OperationName} {collectTags a}" )
128
+ ActivityStarted = ( fun a -> FSharpOutputPane. logMsg $" {indent a}{a.OperationName} {collectTags a}" )
149
129
)
150
130
151
131
ActivitySource.AddActivityListener( listener)
0 commit comments