1- namespace Microsoft.VisualStudio.FSharp.Editor.Logging
1+ namespace Microsoft.VisualStudio.FSharp.Editor.DebugHelpers
22
33open System
44open System.Diagnostics
5- open System.ComponentModel .Composition
65open Microsoft.VisualStudio .Shell
76open Microsoft.VisualStudio .Shell .Interop
8- open Microsoft.VisualStudio .FSharp .Editor
97
108open FSharp.Compiler .Diagnostics
119
@@ -32,75 +30,57 @@ module Config =
3230open Config
3331open System.Diagnostics .Metrics
3432open System.Text
33+ open Microsoft.VisualStudio .Threading
3534
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 =
9636
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
9846
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
10055
10156 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
10484
10585 let logMsg msg = log LogType.Message msg
10686 let logInfo msg = log LogType.Info msg
@@ -145,7 +125,7 @@ module FSharpServiceTelemetry =
145125 ActivitySamplingResult.AllData
146126 else
147127 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}" )
149129 )
150130
151131 ActivitySource.AddActivityListener( listener)
0 commit comments