ASP.Net Core 2.1 Serilog Приемник SQL Server с использованием Azure SQL работает локально, но не из службы приложений Azure - PullRequest
0 голосов
/ 23 января 2019

У меня есть веб-сайт ASP.Net Core 2.1, использующий базу данных Azure SQL для компонента Microsoft Identity.

Я добавил таблицу Logs в эту базу данных и добавил Serilog на свой веб-сайт с приемником SQL Server.

Когда я запускаю веб-сайт локально, хотя он все еще подключен к базе данных SQL Azure, я прекрасно вижу свои записи в таблице Logs.Однако при развертывании веб-сайта в моей службе приложений Azure я больше не получаю никаких записей журнала в таблице Logs базы данных.

Имейте в виду, что в развернутой версии я подключаюсь и использую базу данных SQL Azure для своих приложений MS Identity, и я могу создавать новых пользователей и редактировать существующих просто.Таким образом, я знаю, что строка подключения в настройках приложения службы приложения верна.

Я просмотрел Serilog MSSQL Github , чтобы сравнить их рекомендации по конфигурации с моими, и не смог найти ничего выдающегося,

У меня правильно работает эта настройка API-интерфейса ASP.Net Core, который я развертываю в другой службе приложений Azure.Эта служба использует другую базу данных, но находится на том же ресурсе 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.стол просто отлично.Таким образом, это не похоже на проблему с учетной записью пользователя.

Я проверил, что строка подключения в моем слоте развертывания DEV службы приложений Azure (который я тестирую), Параметры приложения, Строки подключения, точно такая же, как и в моих локальных секретных пользователях DEV.Кроме того, я могу читать и записывать таблицы AspNet * в той же базе данных при развертывании в Azure.

Вот мой класс Program.cs, в котором я настроил 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();

    }
}

Единственное отличие между API, который я развернул в Azure, который записывает журналы в Azure SQL и на этот веб-сайт.это то, что в API, который старше, у меня есть

public static IWebHost BuildWebHost(string[] args)

в program.cs, тогда как на более новом веб-сайте есть

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

Так что ... любые идеи будут с благодарностью.

[ОБНОВЛЕНИЕ 1/23/19]

Я добавил строку подключения непосредственно к

var connectionString 

в Program.cs вместо полученияэто из

Configuration.GetConnectionString("MyConnectionString") 

, и он начал входить в базу данных.

Похоже, проблема в том, что Program.cs может прочитать строку подключения из слота развертывания службы приложений Azure, раздел «Параметры приложения», «Строки подключения».

Эта строка подключения правильно читаетсяиз Startup.cs и работает с тех пор, как я впервые создал сайт.

Итак, существует ли известная проблема с тем, что Azure не может прочитать значения из слота развертывания Параметры приложения / Строки подключения из Program.cs?

1 Ответ

0 голосов
/ 26 марта 2019

Поскольку в Azure, похоже, существует проблема, заключающаяся в том, что он не предоставляет параметры приложения веб-приложению до вызова CreateWebHostBuilder, это простой обходной путь (при условии, что жесткое кодирование строки подключения в исходном коде не является жизнеспособнымопцией) будет настроить Serilog для использования SqlServer в Startup.cs вместо Program.cs.
Если важно регистрировать начальные события, которые происходят во время запуска приложения, Serilog может быть временно настроен в 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:

    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();

        //...
    }
}
...