使用Azure SQL的ASP.Net Core 2.1 Serilog SQL Server Sink在本地运行,但不能从Azure应用服务运行 [英] ASP.Net Core 2.1 Serilog SQL Server Sink using Azure SQL is working locally but not from Azure app service

查看:219
本文介绍了使用Azure SQL的ASP.Net Core 2.1 Serilog SQL Server Sink在本地运行,但不能从Azure应用服务运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.Net Core 2.1网站,该网站使用Azure SQL数据库作为Microsoft Identity组件.

I have an ASP.Net Core 2.1 Website that uses Azure SQL Database for the Microsoft Identity component.

我将Logs表添加到该数据库,并使用SQL Server Sink将Serilog添加到我的网站.

I added a Logs table to that database and added Serilog to my website with the SQL Server Sink.

当我在本地运行网站但仍连接到Azure SQL数据库时,可以在 Logs 表中看到我的日志条目.但是,当我将网站部署到Azure应用服务时,我不再在数据库的 Logs 表中获得任何日志条目.

When I run the website locally, while still connected to the Azure SQL database, I can see my log entries in the Logs table just fine. However, when I deploy the website to my Azure App Service, I no longer get any log entries in the Logs table of the database.

请记住,在已部署的版本中,我可以正常连接并使用Azure SQL数据库存储我的MS Identity,并且可以很好地创建新用户和编辑现有用户.因此,我知道我的App Service应用程序设置中的连接字符串是正确的.

Mind you, in the deployed version, I am connecting to and using the Azure SQL database for my MS Identity stuff just fine and I can create new users and edit existing users just fine. So I know the Connection String in my App Service Application Settings is correct.

我已经查看了 Serilog MSSQL Github ,以将其配置建议与我自己的配置建议进行比较并且找不到任何突出的东西.

I have reviewed the Serilog MSSQL Github to compare their configuration recommendations to my own and could not find anything that stood out.

我让此安装程序在我部署到另一个Azure App Service的ASP.Net Core API上正常工作.该服务使用不同的数据库,但是它在相同的SQL Server资源上.

I have this setup working correctly on an ASP.Net Core API that I deploy to another Azure App Service. That service uses a different database but it is on the same SQL Server resource.

当我开始这个问题时,我很幸运地查看了推荐的SO职位列表.

I have reviewed the list of SO posts recommended when I started this question with no luck.

当我第一次设置用户帐户时,我在数据库上运行了以下SQL;

I ran the following SQL on the database when I first set up the user account;

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表中更新并添加用户数据.因此,这似乎不是用户帐户问题.

And, as I stated, the user account can update and add user data in the AspNetUsers table just fine. So, it doesn't seem like a user account issue.

我已验证Azure应用程序服务DEV部署插槽(我正在测试的一个),应用程序设置,连接字符串中的连接字符串与本地DEV UserSecrets中的字符串完全相同.另外,再次部署到Azure时,我可以读取/写入同一数据库中的AspNet *表.

I have verified that the connection string in my Azure app service DEV deployment slot (the one I am testing), Application Settings, Connection Strings is the exact same as what I have in my local DEV UserSecrets. Plus, again, I can read/write to the AspNet* tables in that same database when deployed to Azure.

这是我设置Serilog的Program.cs类;

Here is my Program.cs class where I set up Serilog;

    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中,我拥有

The only difference between the API that I have deployed in Azure that is writing logs to Azure SQL and this website is that in the API, which is older, I have

public static IWebHost BuildWebHost(string[] args)

在program.cs中,而较新的网站具有

in program.cs whereas the newer website has

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

所以...任何想法都将不胜感激.

So... any ideas would be greatly appreciated.

[UPDATE 1/23/19]

我将连接字符串直接添加到

I added the connection string directly to the

var connectionString 

在Program.cs中,而不是从中获取

in Program.cs rather than getting it from

Configuration.GetConnectionString("MyConnectionString") 

,它开始记录到数据库.

and it started logging to the database.

所以看来,问题出在Program.cs能够从Azure App Service部署插槽的应用程序设置",连接字符串"部分读取连接字符串.

So it seems the issue is with Program.cs being able to read the connection string from Azure App Service deployment slot, Application Settings, Connection Strings section.

此连接字符串已从Startup.cs中正确读取,并且自从我首次创建网站以来一直有效.

This connection string is being correctly read from Startup.cs and has worked since I first created the website.

那么,Azure无法从Program.cs的部署插槽应用程序设置"/连接字符串"中读取值是否存在一些已知问题?

So, is there some known issue with Azure not being able to read values from deployment slot Application Settings / Connection Strings from Program.cs?

推荐答案

由于Azure似乎存在问题,因此在调用CreateWebHostBuilder之前,它不会向Web应用程序提供应用程序设置,这是一个简单的解决方法(假设在源代码中对连接字符串进行硬编码是不可行的选择)是将Serilog配置为在Startup.cs中使用SqlServer而不是Program.cs.
如果记录在应用程序启动期间发生的初始事件很重要,则可以在Program.cs中将Serilog临时配置为写入文件.

Since there seems to be an issue with Azure, that it doesn't provide the application settings to the web app until CreateWebHostBuilder is invoked, a straightforward workaround (assuming that hardcoding the connection string in the source code isn't a viable option) would be to configure Serilog to use SqlServer in Startup.cs instead of Program.cs.
If it's important to log the initial events that occur during the app's starting up, Serilog can temporarily be configured in Program.cs to write to a file.

Program.cs:

Program.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();
}

Startup.cs:

Startup.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 SQL的ASP.Net Core 2.1 Serilog SQL Server Sink在本地运行,但不能从Azure应用服务运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆