为什么 NLog 无法将日志存储在 Azure Blob 存储中?

问题描述 投票:0回答:1

我正在开发一个 ASP.NET Core 6 MVC 应用程序“AzureLogging”,该应用程序测试使用 NLog 将日志写入 Azure Blob 存储。我遇到了无法在 Azure Blob 存储中存储日志文件的问题,即使 NLog 完美运行本地机器。

这是我的设置和测试步骤:

  1. Blob 存储已在 Azure 门户中设置,并成功测试了所有文件操作:读取、上传、下载和删除。

  2. 在MVC应用程序中,加载以下包(参见下面的代码段#1)

  3. 设置 NLog.config 文件,包括 Azure 中的日志记录目标(请参阅下面的代码段 #2)

  4. 在program.cs文件中,指定使用NLog作为日志记录提供程序(请参阅下面的代码段#3)

  5. 为了确保 Blob 连接字符串和存储访问正常工作,我添加了在 MVC 应用程序中执行文件操作的操作:列出文件、上传和删除。他们工作得很好。 (参见下面的代码段#4)

问题描述

  • Nlog 使用与 MVC 应用程序中执行文件操作的操作相同的 Blob 存储连接字符串、帐户名和访问密钥。当日志记录目标更改为“azure”时,没有日志文件写入 Blob 存储。

  • 我还将Nlog内部日志记录级别设置为“Trace”,并检查了内部日志文件。没有发现明显错误

  • 到目前为止,我还无法确定根本原因是什么。我将不胜感激任何建议或故障排除建议。

代码#1:加载的包

<PackageReference Include="Azure.Storage.Blobs" Version="12.18.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="NLog.Extensions.AzureBlobStorage" Version="4.3.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.5" />

代码#2 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"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="c:\temp\internal-nlog-AspNetCore.txt">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <add assembly="NLog.Extensions.AzureStorage"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
    <target xsi:type="Console" name="consoleTarget" layout="${MicrosoftConsoleLayout}" />

    <!-- File target for output app logs on local machine-->
    <target xsi:type="File" name="webLogTarget" fileName="c:\temp\logs\AzureLogging\AzureLogging_${shortdate}.log"
            layout="${longdate} ${level:uppercase=true} ${callsite} ${message}"/>

    <!-- Azure blob storage target for output app logs to Azure storage -->
    <target xsi:type="AzureBlobStorage"  
        name="azure"
        connectionString="DefaultEndpointsProtocol=https; AccountName=mdxstorage1; AccountKey=a/g/KptWTDUpY76/dZQYBkqmVB+CgjlgRw4LM7kb1pxMIlZkvg32x/ifbMtFh9uY9wRUoX6DxQSu+AStK//VEg==; EndpointSuffix=core.windows.net"        
        containerName="mdxweblogs"
        blobName="AzureLogging_${shortdate}.log"
        layout="${longdate} ${uppercase:${level}} ${message}" />

  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->

    <logger name="Microsoft.AspNetCore.*" level="Warn" writeTo="consoleTarget" final="true" />
    
    <logger name="AzureLogging.*" minlevel ="Trace" writeTo="azure" />

  </rules>
</nlog>

代码#3:program.cs文件

using NLog;
using NLog.Web;

// Early init of NLog to allow startup and exception logging, before host is built
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Host.UseNLog();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

代码#4:StorageController.cs

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using AzureLogging.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using NLog;

namespace AzureLogging.Controllers
{
    public class StorageController : Controller
    {
        private readonly ILogger<StorageController> _logger;
        private readonly string _stgConnString;
        private readonly string _stgContainer;

        public StorageController(ILogger<StorageController> logger)
        {
            _logger = logger;
            _stgConnString = "DefaultEndpointsProtocol=https;AccountName=mdxstorage1;AccountKey=a/g/KptWTDUpY76/dZQYBkqmVB+CgjlgRw4LM7kb1pxMIlZkvg32x/ifbMtFh9uY9wRUoX6DxQSu+AStK//VEg==;EndpointSuffix=core.windows.net";

            _stgContainer = "mdxweblogs";
        }

        public IActionResult Index()
        {
            return View("ListFiles");
        }

        public IActionResult ListFiles()
        {
            BlobStgViewModel viewModel = new();
            try
            {
                _logger.LogInformation("List files in Azure Blob Storage");

                viewModel.Container = _stgContainer;    

                BlobContainerClient cntClient = new BlobContainerClient(_stgConnString, _stgContainer);

                foreach(BlobItem blob in cntClient.GetBlobs())
                {
                    viewModel.BlobList.Add(blob.Name);
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Error occurred when listing files in Azure Blob Storage");
            }
            return View(viewModel);
        }

        public IActionResult UploadFile()
        { 
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile mediaFile)
        {
            try
            {
                _logger.LogInformation($"Upload file {mediaFile.Name} to Azure Blob storage");

                if (mediaFile is not null && (!string.IsNullOrEmpty(mediaFile.Name)))
                {
                    BlobContainerClient cntClient = new BlobContainerClient(_stgConnString, _stgContainer);

                    // Initialize BlobClient with the uploaded file name
                    var blobClient = cntClient.GetBlobClient(mediaFile.FileName);

                    // Get stream from uploaded file
                    using (var stream = mediaFile.OpenReadStream())
                    {
                        // Upload the stream to Azure Blob storage asynchronously
                        await blobClient.UploadAsync(stream);
                    }
                    return RedirectToAction("ListFiles");
                }
                else
                {
                    return View();
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Error occurred when listing files in Azure Blob Storage");
            }
        }

        public IActionResult DeleteFile()
        {
            BlobStgViewModel viewModel = new();

            try
            {
                BlobContainerClient cntClient = new BlobContainerClient(_stgConnString, _stgContainer);

                foreach (var blobItem in cntClient.GetBlobs())
                {
                    viewModel.SelectionList.Add(new SelectListItem(blobItem.Name, blobItem.Name ));
                }
            }
            catch(Exception ex)
            {
                throw new ApplicationException("Error occurred when retrieving files from storage");
            }
            return View(viewModel);
        }

        [HttpPost]
        public IActionResult DeleteFile(string selectedItem)
        {
            try
            {
                _logger.LogInformation($"Delete file {selectedItem} from Azure Blob Storage");

                BlobContainerClient cntClient = new BlobContainerClient(_stgConnString, _stgContainer);
                BlobClient blobClient = cntClient.GetBlobClient(selectedItem);
                blobClient.Delete();
                return RedirectToAction("ListFiles");
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Error occurred when delete file from storage");
            }
            return View();
        }
    }
}
asp.net-core logging azure-blob-storage nlog
1个回答
0
投票

通过将 Nlog.extensions.AzureStorage 包替换为 NLog.extensions.AzureBlobStorage 解决了该问题。 NLog.Config 使用 Blob 存储连接字符串和容器名称来指定 Blob 存储作为日志记录

© www.soinside.com 2019 - 2024. All rights reserved.