我有一个 ASP.Net Core 2.1 网站,该网站使用 Azure SQL 数据库作为 Microsoft Identity 组件。
我向该数据库添加了一个日志表,并使用 SQL Server Sink 将 Serilog 添加到我的网站。
当我在本地运行网站时,同时仍连接到 Azure SQL 数据库,我可以在 Logs
表中正常看到我的日志条目。但是,当我将网站部署到 Azure 应用服务时,我不再在数据库的 Logs
表中获取任何日志条目。
请注意,在部署版本中,我可以很好地连接到并使用 Azure SQL 数据库来存储我的 MS Identity 内容,并且可以很好地创建新用户和编辑现有用户。所以我知道我的应用服务应用程序设置中的连接字符串是正确的。
我已经查看了Serilog MSSQL Github将他们的配置建议与我自己的配置建议进行比较,但找不到任何突出的内容。
我的此设置在部署到另一个 Azure 应用服务的 ASP.Net Core API 上正常工作。该服务使用不同的数据库,但位于同一 SQL Server 资源上。
当我开始这个问题时,我已经查看了推荐的 SO 帖子列表,但运气不佳。
当我第一次设置用户帐户时,我在数据库上运行了以下 SQL;
EXEC sp_addrolemember N'db_datareader', N'myuser'
EXEC sp_addrolemember N'db_datawriter', N'myuser'
EXEC sp_addrolemember N'db_ddladmin', N'myuser'
而且,正如我所说,用户帐户可以在 AspNetUsers 表中更新和添加用户数据。因此,这似乎不是用户帐户问题。
我已验证我的 Azure 应用服务 DEV 部署槽(我正在测试的槽)、应用程序设置、连接字符串中的连接字符串与本地 DEV UserSecrets 中的连接字符串完全相同。另外,当部署到 Azure 时,我可以读取/写入同一数据库中的 AspNet* 表。
这是我设置 Serilog 的 Program.cs 类;
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddUserSecrets<Startup>()
.AddEnvironmentVariables()
.Build();
public static void Main(string[] args)
{
var connectionString = Configuration.GetConnectionString("MyConnectionString");
const string tableName = "Logs";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithThreadId()
.WriteTo.MSSqlServer(connectionString, tableName)
.CreateLogger();
// TODO Enable to debug any startup Serilog issues. Make sure to comment out for PROD
//Serilog.Debugging.SelfLog.Enable(msg =>
//{
// Debug.Print(msg);
// Debugger.Break();
//});
try
{
Log.Information("Starting Application");
CreateWebHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog();
}
}
我在 Azure 中部署的将日志写入 Azure SQL 的 API 与此网站之间的唯一区别是,在较旧的 API 中,我有
public static IWebHost BuildWebHost(string[] args)
在program.cs中,而新网站有
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
所以...任何想法将不胜感激。
[更新 2019 年 1 月 23 日]
我直接将连接字符串添加到
var connectionString
在 Program.cs 中而不是从中获取
Configuration.GetConnectionString("MyConnectionString")
它开始记录到数据库。
看来问题在于 Program.cs 能够从 Azure 应用服务部署槽、应用程序设置、连接字符串部分读取连接字符串。
此连接字符串已从 Startup.cs 中正确读取,并且 self 第一次创建网站以来一直有效。
那么,Azure 是否存在无法从 Program.cs 的部署槽应用程序设置/连接字符串读取值的已知问题?
最佳答案
由于 Azure 似乎存在问题,在调用 CreateWebHostBuilder 之前它不会向 Web 应用程序提供应用程序设置,这是一个简单的解决方法(假设在源代码中硬编码连接字符串不可行)选项)将配置 Serilog 在 Startup.cs 中使用 SqlServer 而不是 Program.cs。
如果记录应用程序启动期间发生的初始事件很重要,可以在 Program.cs 中临时配置 Serilog 以写入文件。
程序.cs:
public class Program
{
public static void Main(string[] args)
{
var AzureLogFilePath = @"D:\home\LogFiles\Application\log.txt";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.File(path: AzureLogFilePath, fileSizeLimitBytes: 1_000_000, rollOnFileSizeLimit: true, shared: true);
.CreateLogger();
try
{
Log.Information("Starting Application");
CreateWebHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog();
}
启动.cs:
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName ?? "Production"}.json", optional: true)
.AddEnvironmentVariables();
if (env.IsDevelopment()) builder.AddUserSecrets<Startup>(); // according to the docs, AddUserSecrets should be used only in development
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("MyConnectionString");
const string tableName = "Logs";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithThreadId()
.WriteTo.MSSqlServer(connectionString, tableName)
.CreateLogger();
//...
}
}
关于azure - 使用 Azure SQL 的 ASP.Net Core 2.1 Serilog SQL Server 接收器在本地运行,但不能从 Azure 应用服务运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54317910/
相关文章:
proxy - JProfiler - 有防火墙时如何配置远程应用程序?
python - 如何在 Python 的特定范围内替换数据框中的数字?
forms - 如何使用 cakephp 和 twitter bootstrap 在 poSTLin
visual-studio-code - 如何在 visual studio 代码中显示完整的长行(
macos - undefined symbol : "boost::system::generic
macos - 检查签名工具失败并显示消息 : resource envelope is obsol