এনএলগের ডকুমেন্টেশন অনুসারে:
বেশিরভাগ অ্যাপ্লিকেশনগুলি ক্লাস প্রতি এক লগার ব্যবহার করবে, যেখানে লগারের নাম বর্গের নামের সাথে একই।
লগ 4 নেট একইভাবে কাজ করে। কেন এটি একটি ভাল অনুশীলন?
এনএলগের ডকুমেন্টেশন অনুসারে:
বেশিরভাগ অ্যাপ্লিকেশনগুলি ক্লাস প্রতি এক লগার ব্যবহার করবে, যেখানে লগারের নাম বর্গের নামের সাথে একই।
লগ 4 নেট একইভাবে কাজ করে। কেন এটি একটি ভাল অনুশীলন?
উত্তর:
লগ 4 নেট দিয়ে, প্রতি ক্লাসে একটি লগার ব্যবহার করে লগ বার্তার উত্স ক্যাপচার করা সহজ করে (যেমন লগতে ক্লাস রাইটিং)। ক্লাসে আপনার কাছে যদি একটি লগার না থাকে তবে তার পরিবর্তে পুরো অ্যাপ্লিকেশনের জন্য একটি লগার থাকে তবে লগ বার্তাটি কোথা থেকে আসছে তা জানতে আপনাকে আরও প্রতিবিম্বের কৌশল অবলম্বন করতে হবে।
নিম্নলিখিত তুলনা করুন:
using System.Reflection;
private static readonly ILog _logger =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public void SomeMethod()
{
_logger.DebugFormat("File not found: {0}", _filename);
}
Logger.DebugFormat("File not found: {0}", _filename); // Logger determines caller
-- or --
Logger.DebugFormat(this, "File not found: {0}", _filename); // Pass in the caller
দ্বিতীয় উদাহরণটি ব্যবহার করে, লগার কে স্ট্যাক করছে তা দেখতে আপনার স্ট্যাক ট্রেস তৈরি করতে হবে বা আপনার কোডটি সর্বদা কলকারীকে পাস করতে হবে। লগার-প্রতি-শ্রেণীর শৈলীর সাহায্যে, আপনি এখনও এটি করতে পারেন তবে আপনি একবার প্রতি কলের পরিবর্তে ক্লাসে একবার এটি করতে পারেন এবং গুরুতর পারফরম্যান্স সমস্যাটি দূর করতে পারেন।
এনএলএগ-এ "ফাইলের প্রতি লগার" ব্যবহারের সুবিধা: আপনার কাছে নেমস্পেস এবং শ্রেণীর নাম দ্বারা লগগুলি পরিচালনা / ফিল্টার করার সম্ভাবনা রয়েছে। উদাহরণ:
<logger name="A.NameSpace.MyClass" minlevel="Debug" writeTo="ImportantLogs" />
<logger name="A.NameSpace.MyOtherClass" minlevel="Trace" writeTo="ImportantLogs" />
<logger name="StupidLibrary.*" minlevel="Error" writeTo="StupidLibraryLogs" />
<!-- Hide other messages from StupidLibrary -->
<logger name="StupidLibrary.*" final="true" />
<!-- Log all but hidden messages -->
<logger name="*" writeTo="AllLogs" />
এটি করার জন্য এনএলগ্রারের একটি খুব দরকারী কোড স্নিপেট রয়েছে। nlogger
স্নিপেট নিম্নলিখিত কোড তৈরি হবে:
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
সুতরাং প্রতি ক্লাসে কেবল কয়েকটি কীস্ট্রোক এবং আপনার কাছে লগার রয়েছে। এটি লগারের নাম হিসাবে নেমস্পেস এবং শ্রেণীর নাম ব্যবহার করবে। আপনার শ্রেণি লগারে আলাদা নাম সেট করতে, আপনি এটি ব্যবহার করতে পারেন:
private static NLog.Logger logger = NLog.LogManager.GetLogger("MyLib.MyName");
এবং @ জেরেমি ওয়েইব যেমন বলেছিলেন, আপনাকে যে ক্লাসটি বার্তা লগ করার চেষ্টা করছে তার নাম পেতে কৌশলগুলি ব্যবহার করতে হবে না: লগারের নাম (যা সাধারণত শ্রেণীর নাম) ফাইলের জন্য সহজে লগইন করা যায় (বা অন্যান্য লক্ষ্য) ${logger}
বিন্যাসে ব্যবহার করে ।
আমি এই পছন্দটির কয়েকটি কারণ দেখতে পারি।
বেশিরভাগ ক্ষেত্রে ক্লাসের নাম লগারের জন্য একটি ভাল নাম সরবরাহ করে। লগ ফাইলগুলি স্ক্যান করার সময় আপনি লগ বার্তাটি দেখতে এবং কোডের একটি লাইনের সাথে সরাসরি যুক্ত করতে পারেন।
একটি ভাল উদাহরণ যেখানে এটি সর্বোত্তম পদ্ধতির নয়, এটি হবারনেটের এসকিউএল লগ। "হাইবারনেট.এসকিউএল" নামে একটি ভাগ করা লগার বা এর মতো কিছু রয়েছে, যেখানে বিভিন্ন শ্রেণীর একটি সংখ্যা একক লগার বিভাগে কাঁচা এসকিউএল লেখেন।
বিকাশের দিক থেকে, যদি আপনাকে প্রতিবার লগার অবজেক্ট তৈরি না করতে হয় তবে এটি সবচেয়ে সহজ। অন্যদিকে, আপনি যদি না করেন তবে পরিবর্তে আপনি প্রতিচ্ছবি ব্যবহার করে এটি গতিশীলভাবে তৈরি করেন, এটি কার্য সম্পাদনকে কমিয়ে দেবে। এটি সমাধানের জন্য, আপনি নিম্নলিখিত কোডটি ব্যবহার করতে পারেন যা লগারকে অবিচ্ছিন্নভাবে তৈরি করে:
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinForms
{
class log
{
public static async void Log(int severity, string message)
{
await Task.Run(() => LogIt(severity, message));
}
private static void LogIt(int severity, string message)
{
StackTrace st = new StackTrace();
StackFrame x = st.GetFrame(2); //the third one goes back to the original caller
Type t = x.GetMethod().DeclaringType;
Logger theLogger = LogManager.GetLogger(t.FullName);
//https://github.com/NLog/NLog/wiki/Log-levels
string[] levels = { "Off", "Trace", "Debug", "Info", "Warn", "Error", "Fatal" };
int level = Math.Min(levels.Length, severity);
theLogger.Log(LogLevel.FromOrdinal(level), message);
}
}
}
দুটি কারণ অবিলম্বে মনে মনে বসন্ত:
সম্ভবত যেহেতু আপনি এমন পদ্ধতিগুলি লগ করতে সক্ষম হতে চান যা কেবল ক্লাসে কেবল এনক্যাপসুলেশন না ভেঙে দৃশ্যমান, লগিং কার্যকারিতা ভঙ্গ না করে ক্লাসটি অন্য অ্যাপ্লিকেশনটিতে ব্যবহার করা সহজ করে তোলে।
আপনি যদি এনএলওজি ব্যবহার করছেন তবে আপনি কনফিগারেশনে কলসিট নির্দিষ্ট করতে পারবেন, এটি লগিংয়ের বিবৃতিটি যেখানে অবস্থিত সেখানে শ্রেণীর নাম এবং পদ্ধতি রেকর্ড করবে।
<property name="CallSite" value="${callsite}" />
তারপরে আপনি আপনার লগার নাম বা সমাবেশের নামের জন্য একটি ধ্রুবক ব্যবহার করতে পারেন।
দাবি অস্বীকার: এনএলওজি কীভাবে এই তথ্য সংগ্রহ করে তা আমি জানি না, আমার অনুমান প্রতিফলন হবে যাতে আপনার পারফরম্যান্সটি বিবেচনা করা প্রয়োজন। আপনি এনএলজি ভি 4.4 বা তার পরে ব্যবহার না করে থাকলে অ্যাসিঙ্ক পদ্ধতিতে কয়েকটি সমস্যা রয়েছে।