• .NET跨平台之旅:在Linux上将ASP.NET 5运行日志写入文件团队


    在前一篇博文(增加文件日志功能遇到的挫折)中,我们遇到了这样一个问题:虽然有一些.NET日志组件(比如Serilog, NLog)已经开始支持.NET Core,但目前只支持控制台输出日志,不支持将日志写入文件;这就意味着我们在Linux上运行的示例ASP.NET 5站点无法将日志写入文件,给排查问题造成很大的麻烦,比如现在示例站点经常挂掉的问题。

    面对这个问题我们没有善罢甘休,不想因为这个问题影响.NET跨平台之旅的步伐,我们要解决它,而且希望先用简单的方法解决,不想从头实现一个日志组件。

    在上一篇博文发布后,一位同事给出了这样一个提示:既然Serilog记录日志时是直接将日志信息写入控制台的输出流( .WriteTo.TextWriter(Console.Out) ),那么应该也可以用它写入文件的写入流,都是Stream嘛。

    好主意!可行!但有一个前提是corefx中的文件操作类库要支持Linux,也就是System.IO.FileSystem实现了跨平台。

    那.NET Core中的文件操作类库是否已经跨平台了呢?我们的文件日志问题是否可以通过它解决呢?码一下,就会知道。

    于是将Startup.cs中的 .WriteTo.TextWriter(Console.Out) 改为下面的代码:

    .WriteTo.TextWriter(new StreamWriter(logFilePath))

    运行 dnx kestrel 命令却出现下面的错误:

    DNXCore,Version=v5.0 error CS1503: Argument 1: cannot convert from 'string' to 'System.IO.Stream'

    出现这个错误是因为corefx中实现的StreamWriter的构造函数不支持文件路径作为参数,.NET Framework中是支持的。所以需要修改一下代码,将FileStream类型的参数传递给StreamWriter的构造函数,代码如下:

    .WriteTo.TextWriter(new StreamWriter(new FileStream(logFilePath, FileMode.OpenOrCreate)))

    这样改了之后,站点成功启动。

    Logging to /data/git/AboutUs/logs/log.txt
    Hosting environment: Production
    Now listening on: http://*:8001
    Application started. Press Ctrl+C to shut down.

    然后用浏览器访问一下站点,并用tail命令看一下日志是否成功写入到了日志文件中?

    # tail log.txt
    11/22/2015 14:08:58 +08:00 [Debug] The view '"Intro"' was found.
    11/22/2015 14:08:58 +08:00 [Information] Executing ViewResult, running view at path "/Views/About/Intro.cshtml".
    11/22/2015 14:08:58 +08:00 [Information] User profile is available. Using '"/root/.aspnet/DataProtection-Keys"' as key repository; keys will not be encrypted at rest.
    11/22/2015 14:09:01 +08:00 [Debug] Data Source=xxx
    11/22/2015 14:09:03 +08:00 [Information] Microsoft.Data.Entity.Storage.DbCommandLogData
    11/22/2015 14:09:03 +08:00 [Debug] Data Source=xxx
    11/22/2015 14:09:03 +08:00 [Information] Executed action "CNBlogs.AboutUs.Web.AboutController.Intro" in 0.6192ms
    11/22/2015 14:09:03 +08:00 [Information] Request finished in 0.6196ms 200 text/html; charset=utf-8
    11/22/2015 14:09:16 +08:00 [Error] Connection id "4" disconnected.
    11/22/2015 14:09:16 +08:00 [Error] Connection id "3" disconnected.

    成功!在Linux上记录ASP.NET 5站点的运行日志到文件的问题就这么临时解决了。

    顺便分享一下目前Startup.cs中的最新代码:

    using System;
    using System.IO;
    using System.Linq;
    using Microsoft.AspNet.Builder;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Data.Entity;
    using CNBlogs.AboutUs.Data;
    using Microsoft.Dnx.Runtime;
    using Microsoft.Extensions.PlatformAbstractions;
    using Microsoft.Extensions.Configuration;
    using System.Data.SqlClient;
    using Microsoft.Extensions.Logging;
    using Serilog;
    
    namespace CNBlogs.AboutUs.Web
    {
        public class Startup
        {
            public Startup(IApplicationEnvironment appEnv)
            {
                IConfigurationBuilder builder = new ConfigurationBuilder()
                    .SetBasePath(appEnv.ApplicationBasePath)
                    .AddJsonFile("config.json", false);
                Configuration = builder.Build();
    
                var logFilePath = Path.Combine(appEnv.ApplicationBasePath,"logs/log.txt");
                Console.WriteLine("Logging to "+ logFilePath);
                Log.Logger = new LoggerConfiguration()
                        .MinimumLevel.Debug()
                        .WriteTo.TextWriter(new StreamWriter(
                            new FileStream(logFilePath, FileMode.OpenOrCreate)))
                        .CreateLogger();    
            }
    
            public IConfiguration Configuration { get; set; }
    
            public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
            {
                loggerFactory
                    .AddSerilog()
                    .AddConsole();
    
                app.UseDeveloperExceptionPage();
                app.UseMvcWithDefaultRoute();            
                app.UseStaticFiles();            
                app.UseRuntimeInfoPage();
            }
    
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc();
                services.AddEntityFramework()
                    .AddSqlServer()
                    .AddDbContext<EfDbContext>(options =>
                    {
                        options.UseSqlServer(Configuration["data:ConnectionString"]);
                    });
                services.AddTransient<ITabNavRepository, TabNavRepository>();
            }
        }
    }
  • 相关阅读:
    20道JS原理题助你面试一臂之力!
    10实用的JS实用技巧
    10实用的JS实用技巧
    比尔盖茨的30条经典语录
    比尔盖茨的30条经典语录
    成为优秀程序员应该具备的8个特质
    成为优秀程序员应该具备的8个特质
    不懂开发的人员,请不要随意说这功能很容易实现
    不懂开发的人员,请不要随意说这功能很容易实现
    15句乔布斯经典语录(中英文)
  • 原文地址:https://www.cnblogs.com/cmt/p/4985777.html
Copyright © 2020-2023  润新知