আমি কীভাবে স্টার্টআপ। সি এর মধ্যে থেকে লগগুলি লিখব?


120

শুরুতে ব্যর্থ হওয়া .NET কোর অ্যাপটি ডিবাগ করার জন্য, আমি startup.cs ফাইলের মধ্যে থেকে লগগুলি লিখতে চাই। আমার কাছে ফাইলটির মধ্যে লগিং সেটআপ রয়েছে যা স্টার্টআপ.এস ফাইলের বাইরে থাকা অন্যান্য অ্যাপ্লিকেশনটিতে ব্যবহার করা যেতে পারে, তবে কীভাবে স্টার্টআপ.সিএস ফাইলের মধ্যে থেকে লগগুলি লিখবেন তা নিশ্চিত নই।

উত্তর:


188

। নেট কোর 3.1

দুর্ভাগ্যক্রমে, এএসপি.নেট কোর 3.0 এর জন্য পরিস্থিতি আবার কিছুটা আলাদা। ডিফল্ট টেমপ্লেটগুলি HostBuilder(এর পরিবর্তে WebHostBuilder) ব্যবহার করে যা একটি নতুন জেনেরিক হোস্ট সেট করে যা ওয়েব অ্যাপ্লিকেশনগুলিতে সীমাবদ্ধ নয়, বেশ কয়েকটি বিভিন্ন অ্যাপ্লিকেশন হোস্ট করতে পারে। এই নতুন হোস্টের অংশটি হ'ল দ্বিতীয় হোস্টের জন্য বিদ্যমান দ্বিতীয় নির্ভরতা ইঞ্জেকশন ধারকটিকে অপসারণ করা। এই পরিণামে মানে হল আপনি ছাড়া অন্য কোন নির্ভরতা উদ্বুদ্ধ করতে সক্ষম হবেন না IConfigurationবা Startupবর্গ। সুতরাং আপনি ConfigureServicesপদ্ধতির সময় লগ করতে সক্ষম হবেন না । তবে আপনি Configureপদ্ধতিটিতে লগার ইনজেক্ট করতে এবং সেখানে লগ ইন করতে পারেন:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
{
    logger.LogInformation("Configure called");

    // …
}

যদি আপনার মধ্যে অবশ্যই লগ ইন করার প্রয়োজন হয় ConfigureServicesতবে আপনি ব্যবহার করতে চালিয়ে যেতে পারেন WebHostBuilderযা উত্তরাধিকার তৈরি করবে যা ক্লাসে WebHostলগার ইনজেক্ট করতে পারে Startup। মনে রাখবেন যে সম্ভবত ভবিষ্যতে ওয়েব হোস্টটি অপসারণ করা হবে। সুতরাং আপনার মধ্যে এমন কোনও সমাধানের সন্ধান করার চেষ্টা করা উচিত যা লগইন না করেই আপনার পক্ষে কার্যকর হয় ConfigureServices


.NET কোর 2.x

এটিএসপি.এনইটি কোর ২.০ প্রকাশের সাথে এটি উল্লেখযোগ্যভাবে পরিবর্তিত হয়েছে। এএসপি.এনইটি কোর 2.x এ, হোস্ট বিল্ডারে লগিং তৈরি করা হয়। এর অর্থ হ'ল লগিং ডিআইএর মাধ্যমে ডিফল্টরূপে পাওয়া যায় এবং Startupশ্রেণিতে ইনজেকশনের ব্যবস্থা করা যেতে পারে :

public class Startup
{
    private readonly ILogger<Startup> _logger;

    public IConfiguration Configuration { get; }

    public Startup(ILogger<Startup> logger, IConfiguration configuration)
    {
        _logger = logger;
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        _logger.LogInformation("ConfigureServices called");

        // …
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        _logger.LogInformation("Configure called");

        // …
    }
}

4
ধন্যবাদ. সাধারণ প্রশ্নের উত্তর খুঁজতে আপনি কতটা সময় জ্বলতে পারেন তা আশ্চর্যজনক। @ পোকে আমার বিকল্পগুলি কী তা আমাকে জানানোর জন্য আপনাকে (আবার) ধন্যবাদ জানায়। আপনি কোথায় এই তথ্য পেয়েছেন? আমি নিশ্চিত করেছি যে আমি কনফিগারে স্টাফ লগ করতে পারি, যা একটি ধারালো কাঠি দিয়ে চোখে একটি পোকার (পাং উদ্দেশ্যযুক্ত) ভাল তবে সম্ভবত কনফিগার সার্ভিসগুলির সময় সক্ষম হওয়ার মতো দুর্দান্ত নয়। আমার ক্ষেত্রে আমি এনভির সেটিংস পেয়েছি বা না পেয়ে লগ করতে চাইছি, এমনকি তাদের লগে লগইন করুন। কোন পাশা? দীর্ঘশ্বাস ফেলুন ... কেন এটি এত শক্ত হওয়া উচিত তা নিশ্চিত নয়। তবে কমপক্ষে, এই পোস্টের জন্য ধন্যবাদ, আমি জানি যে আমি কী করতে পারি এবং কী করতে পারি না।
ওয়েলস্প্রিং

4
@ ওয়েলস্প্রিং ৩.০-তে, এটি "শক্ত" কারণ ConfigureServicesরান হওয়ার সময় অনুসারে লগারটি এখনও বিদ্যমান নেই। সুতরাং আপনি এখনও পয়েন্ট নেই যে লগ ইন করতে পারবেন না কারণ এখনও কোন লগার নেই। প্লাস সাইডে, এটি এখনও আপনাকে ConfigureServicesএকইভাবে ডিআই কনটেইনারের (যা আসলে একটি ভাল জিনিস) মধ্যে লগারটি কনফিগার করার ক্ষমতা দেয় । - আপনার যদি সামগ্রীতে লগ করার প্রয়োজন হয়, আপনি উদাহরণস্বরূপ পৃথকভাবে তথ্য সংগ্রহ করতে পারেন (উদাহরণস্বরূপ একটি তালিকায়) এবং তারপরে লগারটি পাওয়া মাত্রই লগ আউট করতে পারেন।
অকর্মা

আপনার মধ্যে .NET 3.1বর্তমানে পিছনে না পড়ে ConfigureServicesপদ্ধতিতে লগইন করতে পারেন । : নীচের ব্যবহারের উত্তর stackoverflow.com/a/61488490/2877982WebHostBuilder
Aage

4
@ অ্যাজেজ এর বেশ কয়েকটি অসুবিধা হবে যদিও: আপনাকে আপনার সম্পূর্ণ লগিং কনফিগারেশনটি পুনরাবৃত্তি করতে হবে, লগিং কনফিগারেশনটি আপনার অ্যাপ্লিকেশন কনফিগারেশনকেও প্রতিফলিত করবে না (উদাহরণস্বরূপ অ্যাপসেটিংগুলিতে কনফিগার করা লগ স্তরগুলি) এবং আপনি সাধারণত দ্বিতীয় লগিং অবকাঠামো স্থাপন করছেন। আমি আপনাকে এখনও কোনও সমাধানের সন্ধানের পরামর্শ দেব যাতে আপনি ডিআই সেটআপের সময় কীভাবে লগইন এড়াতে পারেন।
অকর্মা

4
। নেট 5 : " Startupহোস্টের সাথে আরম্ভ করা অতিরিক্ত প্যারামিটারগুলি পাস করুন " builder.UseStartup(context => new Startup(logger));- ডকস.মাইক্রোসফটকম
প্যাং

37

বিকল্প 1: সরাসরি প্রারম্ভে লগ (যেমন সেরিলোগ) ব্যবহার করুন-

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        Log.Logger = new LoggerConfiguration()
           .MinimumLevel.Debug()
           .WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "Serilog-{Date}.txt"))
           .CreateLogger();

        Log.Information("Inside Startup ctor");
        ....
    }

    public void ConfigureServices(IServiceCollection services)
    {
        Log.Information("ConfigureServices");
        ....
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        Log.Information("Configure");
        ....
    }

আউটপুট:

সেরিলোগ

এসপ নেট-কোর অ্যাপ্লিকেশনটিতে সেরিলোগ সেটআপ করতে, গিটহাবের সেরিলগ.এএসপনেটকোর প্যাকেজটি দেখুন


অপশন 2: প্রোগ্রামে লগিং কনফিগার করুন

var host = new WebHostBuilder()
            .UseKestrel()
            .ConfigureServices(s => {
                s.AddSingleton<IFormatter, LowercaseFormatter>();
            })
            .ConfigureLogging(f => f.AddConsole(LogLevel.Debug))
            .UseStartup<Startup>()
            .Build();

host.Run();

ব্যবহারকারী লগারফ্যাক্টরির শুরুতে এটির মতো-

public class Startup
{
    ILogger _logger;
    IFormatter _formatter;
    public Startup(ILoggerFactory loggerFactory, IFormatter formatter)
    {
        _logger = loggerFactory.CreateLogger<Startup>();
        _formatter = formatter;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        _logger.LogDebug($"Total Services Initially: {services.Count}");

        // register services
        //services.AddSingleton<IFoo, Foo>();
    }

    public void Configure(IApplicationBuilder app, IFormatter formatter)
    {
        // note: can request IFormatter here as well as via constructor
        _logger.LogDebug("Configure() started...");
        app.Run(async (context) => await context.Response.WriteAsync(_formatter.Format("Hi!")));
        _logger.LogDebug("Configure() complete.");
    }
}

এই লিঙ্কে সম্পূর্ণ বিবরণ উপলব্ধ


7

ইন .NET কোর 3.1 , আপনি সরাসরি LogFactory ব্যবহার করে একটি এটির তৈরি করতে পারেন।

var loggerFactory = LoggerFactory.Create(builder =>
{
     builder.AddConsole();                
});

ILogger logger = loggerFactory.CreateLogger<Startup>();
logger.LogInformation("Example log message");

লগ 4নেটের জন্য এটি নীচে সিদ্ধ হয় ILogger logger = LoggerFactory.Create(builder => builder.AddLog4Net()).CreateLogger<Startup>();। তবে, আপনি যদি কেবল ব্যতিক্রমগুলি লগ করেন তবে এটি উইন্ডোজ ইভেন্টলগের (আইআইএস ব্যবহার করার সময়) ইতিমধ্যে যা প্রদর্শিত হবে তার চেয়ে বেশি কিছু প্রকাশিত হবে না।
লুই সোমারস

6

.NET কোর 3.0 এর জন্য অফিসিয়াল ডক্সের এই কথাটি আছে: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.0#create-logs-in-startup

Startup.ConfigureServicesপদ্ধতিতে ডিআই কনটেইনার সেটআপ শেষ হওয়ার আগে লগগুলি লেখার জন্য সমর্থন করা যায় না:

  • Startupকনস্ট্রাক্টারে লগার ইনজেকশন সমর্থিত নয়।
  • Startup.ConfigureServicesপদ্ধতি স্বাক্ষরে লগার ইনজেকশন সমর্থিত নয়

তবে তারা ডক্সে যেমন বলেছে আপনি কোনও পরিষেবা কনফিগার করতে পারেন যা ILogger এর উপর নির্ভর করে, আপনি যদি একটি ক্লাস স্টার্টআপলগার লিখে থাকেন:

public class StartupLogger
{
    private readonly ILogger _logger;

    public StartupLogger(ILogger<StartupLogger> logger)
    {
        _logger = logger;
    }

    public void Log(string message)
    {
        _logger.LogInformation(message);
    }
}

তারপরে শুরুতে।

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(provider =>
    {
        var service = provider.GetRequiredService<ILogger<StartupLogger>>();
        return new StartupLogger(service);
    });
    var logger = services.BuildServiceProvider().GetRequiredService<StartupLogger>();
    logger.Log("Startup.ConfigureServices called");
}

সম্পাদনা: এটি একটি সংকলক সতর্কতা তৈরি করে, আপনার স্টার্টআপ ক্লাসটি ডিবাগ করার জন্য এটি ঠিক হওয়া উচিত তবে উত্পাদনের জন্য নয়:

স্টার্টআপ.সি (39, 32): [এএসপি 10000] অ্যাপ্লিকেশন কোড থেকে 'বিল্ডস সার্ভিস প্রোভাইডার' কল করার ফলে সিঙ্গলটন পরিষেবাদিগুলির একটি অতিরিক্ত অনুলিপি তৈরি হচ্ছে। 'কনফিগার' করার প্যারামিটার হিসাবে নির্ভরতা ইনজেকশন পরিষেবাগুলির বিকল্প বিবেচনা করুন।


5

সরকারী সমাধানটি বর্তমানে একটি স্থানীয় লগার ফ্যাক্টরি সেটআপ করার জন্য রয়েছে:

    using var loggerFactory = LoggerFactory.Create(builder =>
    {
        builder.SetMinimumLevel(LogLevel.Information);
        builder.AddConsole();
        builder.AddEventSourceLogger();
    });
    var logger = loggerFactory.CreateLogger("Startup");
    logger.LogInformation("Hello World");

আরও দেখুন: https://github.com/dotnet/aspnetcore/issues/9337#issuecomment-539859667


4

আমি ILogger ইন্টারফেসের সাথে "লগার বাফার" প্রয়োগকারী তৃতীয় পক্ষের লগারগুলি এড়িয়ে একটি সমাধান ব্যবহার করি ।

public class LoggerBuffered : ILogger
{
    class Entry
    {
        public LogLevel _logLevel;
        public EventId  _eventId;
        public string   _message;
    }
    LogLevel            _minLogLevel;
    List<Entry>         _buffer;
    public LoggerBuffered(LogLevel minLogLevel)
    {
        _minLogLevel = minLogLevel;
        _buffer = new List<Entry>();
    }
    public IDisposable BeginScope<TState>(TState state)
    {
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel >= _minLogLevel;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        if (IsEnabled(logLevel)) {
            var str = formatter(state, exception);
            _buffer.Add(new Entry { _logLevel = logLevel, _eventId = eventId, _message = str });
        }
    }
    public void CopyToLogger (ILogger logger)
    {
        foreach (var entry in _buffer)
        {
            logger.Log(entry._logLevel, entry._eventId, entry._message);
        }
        _buffer.Clear();
    }
}

স্টার্টআপ.সগুলিতে ব্যবহার সহজ, কনফিগার করার পরে অবশ্যই লগ আউটপুট পান। তবে কিছুই চেয়ে ভাল। :

public class Startup
{
ILogger         _logger;

public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
    _logger = new LoggerBuffered(LogLevel.Debug);
    _logger.LogInformation($"Create Startup {env.ApplicationName} - {env.EnvironmentName}");

}

public void ConfigureServices(IServiceCollection services)
{
    _logger.LogInformation("ConfigureServices");
    services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
    (_logger as LoggerBuffered).CopyToLogger(logger);
    _logger = logger;   // Replace buffered by "real" logger
    _logger.LogInformation("Configure");

    if (env.IsDevelopment())

1

প্রধান কোড:

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}

ক্রিয়েটএফল্টবিল্ডার একটি ডিফল্ট কনসোল লগার সেট করে।

... কনসোল এবং ডিবাগ আউটপুটটিতে লগ করতে আইলগারফ্যাক্টিকে কনফিগার করে

স্টার্টআপ কোড:

using Microsoft.Extensions.Logging;
...
public class Startup
{
    private readonly ILogger _logger;

    public Startup(IConfiguration configuration, ILoggerFactory logFactory)
    {
        _logger = logFactory.CreateLogger<Startup>();
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        _logger.LogInformation("hello stackoverflow");
    }

ILogger এর ইনজেকশনটি কাজ করতে পারিনি, তবে সম্ভবত এটি কারণ এটি কোনও নিয়ামক নয়। আরও তথ্য স্বাগতম!

রেফার্স:


0

উপরের উত্তরগুলির মধ্যে আমার পক্ষে কাজ হয়নি worked আমি এনএলজি ব্যবহার করছি, এমনকি একটি নতুন সার্ভিস সংগ্রহ সংগ্রহ করছি, কোনও সার্ভিস সংগ্রহের জন্য .CreateBuilder () কল করে একটি লগিং পরিষেবা তৈরি করছি ... এর মধ্যে কোনওটি কনফিগার সার্ভিসগুলির সময় কোনও লগ ফাইলে লিখবে না।

সমস্যাটি হ'ল সার্ভিস কালেকশনটি তৈরি হওয়ার পরে লগিং আসলে কোনও জিনিস নয় এবং এটি কনফিগার সার্ভিসগুলির সময় নির্মিত হয় না।

মূলত আমি একটি কনফিগারেশন এক্সটেনশন পদ্ধতিতে প্রারম্ভকালে যা চলছে তা লগইন করতে (প্রয়োজন) চাই, কারণ কেবলমাত্র টিয়ারে আমার সমস্যা হচ্ছে পিআরডি, যেখানে আমি কোনও ডিবাগার সংযুক্ত করতে পারি না।

আমার জন্য যে সমাধানটি কাজ করেছিল তা পুরানো .NET ফ্রেমওয়ার্ক এনএলওগ পদ্ধতিটি ব্যবহার করেছিল: private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); এক্সটেনশন পদ্ধতি শ্রেণিতে এই অধিকারটি যুক্ত করা হয়েছিল এবং আমি কনফিগার সার্ভিসগুলির সময় এবং তার পরে একটি লগ ("লগ") লিখতে সক্ষম হয়েছি।

প্রকৃতপক্ষে প্রোডাকশন কোডে ছেড়ে দেওয়া যদি ভাল ধারণা হয় তবে আমার কোনও ধারণা নেই (আমি জানি না। নেট নিয়ন্ত্রিত ILogger এবং এই NLog.ILogger যে কোনও মুহুর্তে দ্বন্দ্ব করবে) তবে আমার কেবল এটি কী দরকার তা দেখার দরকার ছিল চালু.


-1

আমি স্ট্যাটিকভাবে ফাইলটিতে নলগের সাথে একটি লগার তৈরি করে এটি পরিচালনা করেছিলাম, তারপরে এটি প্রারম্ভিক পদ্ধতিতে ব্যবহার করুন।

private readonly NLog.Logger _logger = new NLog.LogFactory().GetCurrentClassLogger();

4
এটি কাজ করার সময়, আমি লগিংয়ের জন্য অভ্যন্তরীণ বা তৃতীয় পক্ষ - - এএসপি.নেট কোর এবং নির্ভরতা ইনজেকশন (ডিআই) এর সাথে আসা স্ট্যান্ডার্ড ইন্টারফেসগুলি ব্যবহার করার পরামর্শ দেব ইন্টারফেস ব্যবহার করে আপনি ক) প্রয়োজনে প্রদত্ত লগিং প্রতিস্থাপন করতে পারেন এবং খ) আপনি ক্লাস পরীক্ষা করার সময় তাদের উপহাস করা সহজ (যেমন নিয়ন্ত্রক) যেখানে আপনি ILogger <Tontroller> সার্ভিস হিসাবে ইনজেক্ট করেন।
মনফ্রেড

ঠিক একই জিনিসটির নিজস্ব উত্তর পোস্ট করার পরে আমি প্রথমবার এটি দেখেছি। @ ম্যানফ্রেডে আর কোনও উপায় নেই যা কাজ করে। আমি System.IO.File.Write()পদ্ধতি ছাড়া অন্য অনুমান ।
এমেরি.নোয়েল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.