How do I stop NCalc from writing to the console?

626 Views Asked by At

I'm using NCalc to do mathematical evaluations in a Console application. It keeps spewing tons of information to the console (Specifically when the Evaluate() function is executed). I was unable to find documentation to stop this. For example:

MyApp.exe Information: 0 : Expression added to cache: 18.855520754*45.5445916666667/100
MyApp.exe Information: 0 : Information: 0 : Expression retrieved from cache: 16*10
MyApp.exe Information: 0 : Expression added to cache: 18.855520754*45.5445916666667/100
MyApp.exe Information: 0 : Expression added to cache: 18.855520754*45.5445916666667/100
MyApp.exe Information: 0 : Expression added to cache: 45.5445916666667/6
MyApp.exe Information: 0 : Expression added to cache: 45.5445916666667/6

Where do I define the output verbosity for NCalc? Thanks

Here is what my App.config looks like (I removed appSettings section. Also, The logging section you see here is for Quartz.NET):

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
  </configSections>
  <common>
    <logging>
      <!--Used by Quartz-->
      <factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
        <arg key="level" value="Warn" />
        <!--All / Debug / Info / Warn / Error / Fatal / Off-->
        <arg key="showLogName" value="true" />
        <arg key="showDataTime" value="true" />
        <arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff" />
      </factoryAdapter>
    </logging>
  </common>



  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Cors" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="StackExchange.Redis.StrongName" publicKeyToken="c219ff1ca8c2ce46" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.6.0" newVersion="1.2.6.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

  <system.web>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>


<system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add description=".Net Framework Data Provider for MySQL" invariant="MySql.Data.MySqlClient" name="MySQL Data Provider" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.10.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data></configuration>
1

There are 1 best solutions below

0
On

In case anyone else stumbles across this. The statements are coming from the Expression.cs file within NCalc. It has several calls that use Trace:

Trace.TraceInformation("Expression retrieved from cache: " + expression)
...
Trace.TraceInformation("Expression added to cache: " + expression);
...
Trace.TraceInformation("Cache entry released: " + key);

System.Diagnostics.Trace is sealed and the TraceListenerCollection is static. I couldn't find a simple way of disabling "just" NCalc's traces. All trace listeners registered in your app in that collection will receive these messages. This includes the "Default" listener -- which is what was relaying the messages in my case.

As of right now, I've just got "Default" turned off entirely in my web.config, which suppresses the console output, and critically, vastly improves debugging performance in NCalc heavy sections:

<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

The only way to remove them (assuming you want to leave TRACE enabled as you're using it elsewhere) seems to be to register a custom TraceListener / inherit from DefaultTraceListener. Then you can implement new Write / WriteLine methods which filter out NCalc's traces. Either by matching the string syntax or by inspecting the stack-trace and suppressing any traces that originated from the NCalc assembly.

The former seems clunky, and the latter excessive & wastes undo CPU cycles. So if anyone has a better approach, I'd be keen to hear it, lol.