AWS Lambda 在 cloudwatch (.NET Core 3.1) 中写入额外的行
AWS Lambda writes extra line in cloudwatch (.NET Core 3.1)
我正在 .NET Core 3.1(C#) 中编写一个 lambda 函数,我想在我的逻辑中保留正在执行的操作的日志,当我在 cloudwatch 的 AWS Lambda 服务中部署我的 lambda 时,它会额外添加一个仅显示在输出中的行(也影响我的本地但不影响我的纯文本文件)我可能配置错误吗?
要创建项目,请使用 AWS Toolkit For Visual Studio 2019 中的模板“AWS Lambda Project (.NET Core - C#)”。
依赖关系:
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)
存储库: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;
}
}
}
本地打印日志
我注意到如果我删除“logging.AddConsole();”来自 Function.cs 的行,不再显示额外的行(标记为黄色),但日志输出停止工作(在我的本地和 aws 中)并且只打印物理日志。
云观察:
AWS 拉姆达:
我取得了这个成绩:
本地:
AWS 拉姆达:
云观察:
我做的修改如下:
存储库:https://github.com/Weyne/AWS-NET_CORE-NLOG/
删除对
的引用
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 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>
删除行“logging.AddConsole();”来自 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();
}
}
}
我正在 .NET Core 3.1(C#) 中编写一个 lambda 函数,我想在我的逻辑中保留正在执行的操作的日志,当我在 cloudwatch 的 AWS Lambda 服务中部署我的 lambda 时,它会额外添加一个仅显示在输出中的行(也影响我的本地但不影响我的纯文本文件)我可能配置错误吗?
要创建项目,请使用 AWS Toolkit For Visual Studio 2019 中的模板“AWS Lambda Project (.NET Core - C#)”。
依赖关系:
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)
存储库: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;
}
}
}
本地打印日志
我注意到如果我删除“logging.AddConsole();”来自 Function.cs 的行,不再显示额外的行(标记为黄色),但日志输出停止工作(在我的本地和 aws 中)并且只打印物理日志。
云观察:
AWS 拉姆达:
我取得了这个成绩:
本地:
AWS 拉姆达:
云观察:
我做的修改如下:
存储库:https://github.com/Weyne/AWS-NET_CORE-NLOG/
删除对
的引用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 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>
删除行“logging.AddConsole();”来自 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();
}
}
}