Nlog can't send logs to Oracle Database

431 Views Asked by At

We are trying to send logs to an Oracle Database but can't run the Nlogs because we receive an error message:

2021-11-18 13:00:25.5506 Error DatabaseTarget(Name=oracle): Failed to create ConnectionType from DBProvider=Oracle.ManagedDataAccess.Client.OracleConnection, Oracle.ManagedDataAccess Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Oracle.ManagedDataAccess, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'Oracle.ManagedDataAccess, Culture=neutral, PublicKeyToken=null'
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMarkHandle stackMark, ObjectHandleOnStack assemblyLoadContext, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext)
   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
   at NLog.Targets.DatabaseTarget.SetConnectionType()
   at NLog.Targets.DatabaseTarget.InitializeTarget()
2021-11-18 13:00:25.5726 Error Database Target[oracle]: Error initializing target Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Oracle.ManagedDataAccess, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'Oracle.ManagedDataAccess, Culture=neutral, PublicKeyToken=null'
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMarkHandle stackMark, ObjectHandleOnStack assemblyLoadContext, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext)
   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
   at NLog.Targets.DatabaseTarget.SetConnectionType()
   at NLog.Targets.DatabaseTarget.InitializeTarget()
   at NLog.Targets.Target.Initialize(LoggingConfiguration configuration)
2021-11-18 13:00:25.5726 Trace Initializing BufferingWrapper Target[OracleDatabase_wrapped](Database Target[oracle])

We have the Oracle.ManagedDataAccess.dll in the path folder where we run the process and our nlog config file is:

      <target xsi:type="BufferingWrapper" name="OracleDatabase" bufferSize="100" flushTimeout="5000" slidingTimeout="false">
      <target xsi:type="Database" name="oracle" dbProvider="Oracle.ManagedDataAccess.Client.OracleConnection, Oracle.ManagedDataAccess" connectionString="${ui-connection-strings:item=oracle}" keepConnection="true">
            <commandText>
                insert into ....
            </commandText>
            <parameter name="...." />

        </target>
      </target>

NLog: 4.7.7

Do we need to assembly the dll? Which could be the reason of this error?

1

There are 1 best solutions below

1
Mahesh Patil On

NLog with .Net Core And Oracle Database.

I tried the below code and it's worked fine.

below Nugets you must include in project

  • NLog
  • NLog.Database
  • NLog.Extenstion.Logging
  • NLog.Web.AspNetCore
  • Oracle.ManagedDataAccess.Core

Add connectionstring information in appsetings.json

nlog.config file must as below (edit connection string and log file path information as per you)

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Warn"
      internalLogFile="C:\temp\Logs\internal-nlog4txt">
    <extensions>
        <add assembly="NLog.Database"/>
        <add assembly="NLog.Web.AspNetCore"/>
    </extensions>

    <targets>
        <target name="database"
                xsi:type="Database"
                connectionString="${configsetting:item:=ConnectionStrings.your_connectionstring_namefrom_appsettings_json_file}"
                dbProvider="Oracle.ManagedDataAccess.Client.OracleConnection,Oracle.ManagedDataAccess"
                commandText="INSERT INTO APPLICATIONLOG (ACTIONTIME,DETAILS) VALUES (sysdate,:details)"
                commandType="Text">
            <parameter name="details" layout="${message}" />
        </target>
    </targets>
    
    <rules>
        <logger name="*" minlevel="Trace" writeTo="database" />
    </rules>
</nlog>

Program.cs

     public class Program
    {
        public static void Main(string[] args)
        {
            var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
            try
            {
                //logger.Debug("init main function");
                CreateWebHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error in init");
                throw;
            }
            finally
            {
                NLog.LogManager.Shutdown();
            }
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.SetMinimumLevel(LogLevel.Information);
                })
                .UseNLog();
    }

No configuration needed in Startup.cs class

Inject and use Logger in your controller like below

public class ValuesController : ControllerBase
{
    private readonly ILogger<ValuesController> _logger;

    public ValuesController(ILogger<ValuesController> logger)
    {
        _logger = logger;
    }

    [HttpGet("{id}")]
    public ActionResult<IEnumerable<string>> Get(int id)
    {
        _logger.LogInformation("Start : Getting item details for {ID} ", id);

        List<string> list = new List<string>();

        list.Add("A");
        list.Add("B");

        _logger.LogInformation($"Completed : Item details for  {string.Join(", ", list)}");

        return list;
    }
}

Thank you