markmcdowell / NLog.Targets.ElasticSearch

NLog target for Elasticsearch
MIT License
176 stars 89 forks source link

ArgumentException: Target cannot be found: 'ElasticSearch' #104

Closed bluetianx closed 5 years ago

bluetianx commented 5 years ago

I have a problem when i use ElasticSearch in asp.net core;

Error Parsing configuration from E:\codeLib\WebApplication1\WebApplication1\bin\Debug\netcoreapp2.2\nlog.config failed. Exception: NLog.NLogConfigurationException: Exception when parsing E:\codeLib\WebApplication1\WebApplication1\bin\Debug\netcoreapp2.2\nlog.config.  ---> System.ArgumentException: Target cannot be found: 'ElasticSearch'
   at NLog.Config.Factory`2.CreateInstance(String itemName)
   at NLog.Config.LoggingConfigurationParser.ParseTargetWrapper(Dictionary`2 typeNameToDefaultTargetParameters, String name, ILoggingConfigurationElement childElement, WrapperTargetBase wrapper)
   at NLog.Config.LoggingConfigurationParser.ParseTargetElement(Target target, ILoggingConfigurationElement targetElement, Dictionary`2 typeNameToDefaultTargetParameters)
   at NLog.Config.LoggingConfigurationParser.ParseTargetsElement(ILoggingConfigurationElement targetsElement)
   at NLog.Config.LoggingConfigurationParser.ParseNLogSection(ILoggingConfigurationElement configSection)
   at NLog.Config.LoggingConfigurationParser.LoadConfig(ILoggingConfigurationElement nlogConfig, String basePath)
   at NLog.Config.XmlLoggingConfiguration.ParseNLogElement(ILoggingConfigurationElement nlogElement, String filePath, Boolean autoReloadDefault)
   at NLog.Config.XmlLoggingConfiguration.Initialize(XmlReader reader, String fileName, Boolean ignoreErrors)
   --- End of inner exception stack trace ---

my code as

public class Program
    {
        public static void Main(string[] args)
        {
            LogManager.ThrowExceptions = true;
            var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)

                .UseStartup<Startup>()
            .ConfigureLogging(logging =>
            {
                //logging.ClearProviders();
                logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
            })
        .UseNLog();
    }

my nlog xml as :

<?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="info"
      internalLogFile="logs/internal-nlog.txt">

  <!-- the targets to write to -->
  <targets>
    <target name="ESErrorLog" xsi:type="RetryingWrapper" retryDelayMilliseconds="2000" retryCount="3">
      <target xsi:type="ElasticSearch"
              uri="http://localhost:9200"
              index="NlogTest"
              includeAllProperties="true"
              disableAutomaticProxyDetection="false"

           >

        <!-- repeated, optional -->
      </target>
    </target>
    <target name="ESGeneralLog" xsi:type="BufferingWrapper" flushTimeout="5000">
      <target xsi:type="ElasticSearch"

              uri="http://localhost:9200"
              index="NlogTest"
              includeAllProperties="true"
              disableAutomaticProxyDetection="false"
           >

        <!-- repeated, optional -->
      </target>
    </target>
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->

    <!--Skip Microsoft logs and so log only own logs-->

    <logger name="*"  minlevel="Warn" writeTo="ESErrorLog" />
    <logger name="*"  minlevel="Trace" writeTo="ESGeneralLog" />

  </rules>
</nlog>

my csproj as

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <Content Remove="Nlog.config" />
  </ItemGroup>

  <ItemGroup>
    <None Include="Nlog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="NLog" Version="4.6.6" />
    <PackageReference Include="NLog.Extensions.Logging" Version="1.5.2" />
    <PackageReference Include="NLog.Targets.ElasticSearch" Version="6.1.0" />
    <PackageReference Include="NLog.Web.AspNetCore" Version="4.8.4" />
    <PackageReference Include="Winton.Extensions.Configuration.Consul" Version="2.3.0" />
  </ItemGroup>

</Project>
snakefoot commented 5 years ago

The frontpage https://github.com/markmcdowell/NLog.Targets.ElasticSearch suggests that you add the following to the top of the nlog.config:

  <extensions>
    <add assembly="NLog.Targets.ElasticSearch"/>
  </extensions>
bluetianx commented 5 years ago

OK ,thanks, It has worked

bluetianx commented 5 years ago

one more thing,i have got a exception that Error initializing target Exception: System.ArgumentException: Argument can not be an empty collection when I want set ESUrl by appsetting,

exception info as

2019-07-26 08:55:06.4425 Error ElasticSearch Target[ElasticSearch]: Error initializing target Exception: System.ArgumentException: Argument can not be an empty collection
Parameter name: nodes
   at Elasticsearch.Net.Extensions.ThrowIfEmpty[T](IEnumerable`1 object, String parameterName)
   at Elasticsearch.Net.StaticConnectionPool..ctor(IEnumerable`1 nodes, Func`2 nodeScorer, IDateTimeProvider dateTimeProvider)
   at Elasticsearch.Net.StaticConnectionPool..ctor(IEnumerable`1 uris, Boolean randomize, IDateTimeProvider dateTimeProvider)
   at NLog.Targets.ElasticSearch.ElasticSearchTarget.InitializeTarget()
   at NLog.Targets.Target.Initialize(LoggingConfiguration configuration)

my appsetting as

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ESUrl": "http://IP:9200"
}

my nlog xml as

<?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="info"
      internalLogFile="logs/internal-nlog.txt">

<extensions>
    <add assembly="NLog.Targets.ElasticSearch"/>
  </extensions>
  <!-- the targets to write to -->
  <targets>
    <target name="ESErrorLog" xsi:type="RetryingWrapper" retryDelayMilliseconds="2000" retryCount="3">
      <target xsi:type="ElasticSearch"
              uri="${configsetting:name=ESUrl}"
              index="NlogTest"
              includeAllProperties="true"
              disableAutomaticProxyDetection="false"

           >

        <!-- repeated, optional -->
      </target>
    </target>
    <target name="ESGeneralLog" xsi:type="BufferingWrapper" flushTimeout="5000">
      <target xsi:type="ElasticSearch"

              uri="${configsetting:name=ESUrl}"
              index="NlogTest"
              includeAllProperties="true"
              disableAutomaticProxyDetection="false"
           >

        <!-- repeated, optional -->
      </target>
    </target>
  </targets>

  <rules>

    <logger name="*"  minlevel="Warn" writeTo="ESErrorLog" />
    <logger name="*"  minlevel="Trace" writeTo="ESGeneralLog" />

  </rules>
</nlog>
snakefoot commented 5 years ago

Maybe the NLog.config is being loaded before having fully initialized the ConfigSetting (so it returns empty value).

See also: https://github.com/NLog/NLog.Extensions.Logging/issues/265

And see also: https://github.com/NLog/NLog/wiki/Reinitialize-NLog-configuration

bluetianx commented 5 years ago

ok . thanks

snakefoot commented 4 years ago

NLog.Web.AspNetCore ver 4.9.3 has been released, and now you can do this:

var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();

That replaces the old style:

var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();