anchor.diff:  module LanguageService =
       let ax =  Node.require.Invoke "axios" |>  unbox<Axios.AxiosStatic>
   
  -    let logRequests =
  +    let logRequestsToConsole =
           try
               workspace.getConfiguration().get("FSharp.logLanguageServiceRequestsToConsole", false)
           with
           | _ -> false
  +
  +    let logRequestsToOutputWindow =
  +        try
  +            workspace.getConfiguration().get("FSharp.logLanguageServiceRequestsToOutputWindow", false)
  +        with
  +        | _ -> false
  +
  +    // Always log to the logger, and let it decide where/if to write the message
  +    let log =
  +        let channel = if logRequestsToOutputWindow then Some (window.createOutputChannel "F# Language Service") else None
  +        ConsoleAndOutputChannelLogger(Some "IONIDE-FSAC", INF, channel, logRequestsToConsole)
   
       let genPort () =
           let r = JS.Math.random ()
  
positive.code:                 // Wait until FsAC sends the 'listener started' magic string until
                  // we inform the caller that it's ready to accept requests.
                  let isStartedMessage = (n.ToString().Contains(": listener started in"))
                  if isStartedMessage then
                      Browser.console.log ("[IONIDE-FSAC-SIG] started message?", isStartedMessage)
                      service <- Some child
                      resolve child
                  else
                     Browser.console.log (n.ToString())
              )
              |> Process.onErrorOutput (fun n ->
                  Browser.console.error (n.ToString())
                  reject ()
              )
              |> Process.onError (fun e ->
                  Browser.console.error (e.ToString())
                  reject ()
              )
              |> ignore
  
negative.code: 
      let mutable private service : child_process_types.ChildProcess option =  None
  
      let request<'a, 'b> (ep: string) id  (obj : 'a) =       
          log.Debug ("REQUEST  : %s, Request=%j", ep, obj)
  
          // At the INFO level, it's nice to see only the key data to get an overview of
          // what's happening, without being bombarded with too much detail
          if JS.isDefined (obj?FileName) then
              log.Info ("REQUEST  : %s, FileName=%j", ep, obj?FileName)
          else if JS.isDefined (obj?Symbol) then
              log.Info ("REQUEST  : %s, Symbol=%j", ep, obj?Symbol)
          else
              log.Info ("REQUEST  : %s", ep)
  
          ax.post (ep, obj)
          |> Promise.onFail (fun r ->
              log.Error ("FAILED   : %s, Failure=%j Data=%j", ep, r.ToString(), obj)
              null |> unbox
          )
          |> Promise.map(fun r ->
              try
                  let res = (r.data |> unbox<string[]>).[id] |> JS.JSON.parse |> unbox<'b>
                  log.Info ("RESPONSE : %s, Kind=%s", ep, res?Kind)
                  log.Debug ("RESPONSE : %s, Kind=%s, Data=%j", ep, res?Kind, res?Data)
                  if res?Kind |> unbox = "error" || res?Kind |> unbox = "info" then null |> unbox
                  else res
              with
              | ex ->
                  log.Error ("RESPONSE : %s, Failure=%j, Data=%j", ep, ex.ToString(), obj)
                  null |> unbox
          )
  
  