简体   繁体   中英

AWS Lambda writes extra line in cloudwatch (.NET Core 3.1)

I am programming a lambda function in .NET Core 3.1(C#) and I want to leave log of the actions being performed in my logic, when I deploy my lambda in the AWS Lambda service in cloudwatch it adds an extra line that is only displayed in the output (also affects my local but not my plain text file) what could I be misconfiguring?

To create the project use the template "AWS Lambda Project (.NET Core - C#)" from the AWS Toolkit For Visual Studio 2019.

Dependencies:

NLog.Web.AspNetCore (4.14.0)
NLog (4.7.13)
Microsoft.Extensions.Configuration.Abstractions (6.0.0)
Amazon.Lambda.Serialization.SystemTextJson (2.2.0)
Amazon.Lambda.Core (2.1.0)

Repository: https://github.com/Weyne/AWS-NET_CORE-NLOG/

NLog.config

<?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"
        >

    <targets>
        <target name="aws"
                xsi:type="AWSTarget"
                logGroup="aws/lambda/WeyneLoggingWithNLog"
                region="us-east-1"
                layout="
               -------------- ${level} (${longdate}) --------------${newline}
                ${newline}
                Call Site: ${callsite}${newline}
                Exception Type: ${exception:format=Type}${newline}
                Exception Message: ${exception:format=Message}${newline}
                Stack Trace: ${exception:format=StackTrace}${newline}
                Additional Info: ${message}${newline}" />
        <target xsi:type="File" name="fileTarget" filename="C:\Log\${machinename}-${local-ip}-mylambda-${date:format=yyyy-MM-dd}.txt" layout="${longdate}|${level:uppercase=true}|${local-ip}|${callsite}|${message}|${exception:format=tostring}"></target>

        <target name="aws" type="AWSTarget" />
    </targets>
    <rules>
        <!--Skip Microsoft logs and so log only own logs-->
        <logger name="Microsoft.*" maxlevel="Info" final="true" />
        <logger name="*" minlevel="Trace" writeTo="fileTarget" />
        <logger minlevel="Error" name="*" writeTo="aws"/>
    </rules>

</nlog>

Function.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;
    
    using Amazon.Lambda.Core;
    using Microsoft.AspNetCore.Mvc.Infrastructure;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection.Extensions;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using NLog;
    using NLog.Web;
    using WeyneLoggingWithNLog.Interfaces;
    using WeyneLoggingWithNLog.Services;
    
    // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
    [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
    
    namespace WeyneLoggingWithNLog
    {
        public class Function
        {
    
            /// <summary>
            /// A simple function that takes a string and does a ToUpper
            /// </summary>
            /// <param name="input"></param>
            /// <param name="context"></param>
            /// <returns></returns>
            public string FunctionHandler(string input, ILambdaContext context)
            {
                var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
                try
                {
    
                    var builder = new ConfigurationBuilder();
                    BuildConfig(builder);
    
                    var host = Host.CreateDefaultBuilder()
                        .ConfigureLogging((hostingContext, logging) =>
                        {
                            logging.ClearProviders(); //esta línea hace la diferencia
                            logging.AddConsole();//mal
                            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //esta línea hace la diferencia
                            logging.AddNLogWeb();
                        })
                        .ConfigureServices((context, services) =>
                        {
                            services.AddHttpContextAccessor();
                            services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
                            services.AddScoped<IProcessService, ProcessService>();
                            services.BuildServiceProvider();
                            services.AddLogging();
                        })
                        .UseNLog()
                        .Build();
    
                    var service = ActivatorUtilities.CreateInstance<ProcessService>(host.Services);
    
                    return service.Invoke(input).Result.ToUpper();
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Stopped program because of exception");
                    throw ex;
                }
                finally
                {
                    NLog.LogManager.Shutdown();
                }
            }
    
            static void BuildConfig(IConfigurationBuilder builder)
            {
                builder.SetBasePath(Directory.GetCurrentDirectory())
                    //.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                    .AddEnvironmentVariables();
            }
        }    
    }

ProcessService.cs

    using System.Threading.Tasks;
    using WeyneLoggingWithNLog.Interfaces;
    using Microsoft.Extensions.Logging;
    
    
    namespace WeyneLoggingWithNLog.Services
    {
        public class ProcessService : IProcessService
        {
            private readonly ILogger<ProcessService> _logger;
    
            public ProcessService(ILogger<ProcessService> logger)
            {
                _logger = logger;
            }
    
            public async Task<string> Invoke(string input)
            {
                _logger.LogInformation("Hola mundo: {0}", input);
                _logger.LogError("Error: {0}", input);
                _logger.LogTrace("Trace: {0}", input);
                return input;
            }
        }
    }

The log printing on my local本地注册

I have noticed that if I remove the "logging.AddConsole();" line from Function.cs, the extra line (marked in yellow) is no longer displayed but the Log ouput stops working (in my local and in aws) and only prints the physical log.

本地日志输出

cloudwatch: 在此处输入图像描述

aws lambda: 在此处输入图像描述

I achieved this result:

Local: 在此处输入图像描述

AWS Lambda: 在此处输入图像描述

Cloudwatch: 在此处输入图像描述

the modifications I made, were as follows:

Repository: https://github.com/Weyne/AWS-NET_CORE-NLOG/

remove the reference of

NLog

modify the NLog.config:

<?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"
        >

    <targets>
        <target xsi:type="File" name="fileTarget" filename="C:\Log\${machinename}-${local-ip}-mylambda-${date:format=yyyy-MM-dd}.txt" layout="${longdate}|${level:uppercase=true}|${local-ip}|${callsite}|${message}"></target>
        <target name="console" xsi:type="Console" layout="${level:uppercase=true}|${callsite}|${message}" />

        <target name="aws" type="AWSTarget" />
    </targets>
    <rules>
        <logger name="*" minlevel="Info" writeTo="console" />
        <logger name="*" minlevel="Trace" writeTo="fileTarget" />
    </rules>

</nlog>

remove the line "logging.AddConsole();" from Function.cs.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

using Amazon.Lambda.Core;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Web;
using WeyneLoggingWithNLog.Interfaces;
using WeyneLoggingWithNLog.Services;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace WeyneLoggingWithNLog
{
    public class Function
    {

        /// <summary>
        /// A simple function that takes a string and does a ToUpper
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public string FunctionHandler(string input, ILambdaContext context)
        {
            var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
            try
            {

                var builder = new ConfigurationBuilder();
                BuildConfig(builder);

                var host = Host.CreateDefaultBuilder()
                    .ConfigureLogging((hostingContext, logging) =>
                    {
                        logging.ClearProviders(); //esta línea hace la diferencia
                        logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //esta línea hace la diferencia
                        logging.AddNLogWeb();
                    })
                    .ConfigureServices((context, services) =>
                    {
                        services.AddHttpContextAccessor();
                        services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
                        services.AddScoped<IProcessService, ProcessService>();
                        services.BuildServiceProvider();
                        services.AddLogging();
                    })
                    .UseNLog()
                    .Build();

                var service = ActivatorUtilities.CreateInstance<ProcessService>(host.Services);

                return service.Invoke(input).Result.ToUpper();
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Stopped program because of exception");
                throw ex;
            }
            finally
            {
                NLog.LogManager.Shutdown();
            }
        }

        static void BuildConfig(IConfigurationBuilder builder)
        {
            builder.SetBasePath(Directory.GetCurrentDirectory())
                //.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
        }
    }    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM