লগাররা প্রতি ক্লাসে লগার ব্যবহারের পরামর্শ দেয় কেন?


88

এনএলগের ডকুমেন্টেশন অনুসারে:

বেশিরভাগ অ্যাপ্লিকেশনগুলি ক্লাস প্রতি এক লগার ব্যবহার করবে, যেখানে লগারের নাম বর্গের নামের সাথে একই।

লগ 4 নেট একইভাবে কাজ করে। কেন এটি একটি ভাল অনুশীলন?


4
হুঁ। মনে হচ্ছে এখানে দুটি সমস্যা রয়েছে - একটিতে প্রতি ক্লাসে আসল লগ অবজেক্ট রয়েছে, এবং একটিতে লগের নামটি ক্লাসের মতো হতে পারে।
পিটার পুনরুদ্ধার করুন

উত্তর:


59

লগ 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

দ্বিতীয় উদাহরণটি ব্যবহার করে, লগার কে স্ট্যাক করছে তা দেখতে আপনার স্ট্যাক ট্রেস তৈরি করতে হবে বা আপনার কোডটি সর্বদা কলকারীকে পাস করতে হবে। লগার-প্রতি-শ্রেণীর শৈলীর সাহায্যে, আপনি এখনও এটি করতে পারেন তবে আপনি একবার প্রতি কলের পরিবর্তে ক্লাসে একবার এটি করতে পারেন এবং গুরুতর পারফরম্যান্স সমস্যাটি দূর করতে পারেন।


ধন্যবাদ, এটি বিষয়গুলি পরিষ্কার করতে সহায়তা করে। আমরা স্রেফ বার্তাটিতে ক্লাসের নাম এবং পদ্ধতিটি ম্যানুয়ালি রেখেছিলাম (অর্থাত "" ImageCretor.CreateThumbnail () ") বলা হয়, তবে লগার এটি পরিচালনা করতে পারলে আরও ভাল।
ড্যানিয়েল টি।

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

7
@ উইল, আপনি কি আরও কিছু ব্যাখ্যা করতে পারেন? প্রতি ক্লাসে কোনও লগার ব্যবহার করে লগইন করার সময় আমি সর্বদা থ্রেড আইডি লগ করি যাতে লগার বর্তমান থ্রেডের তথ্য পেতে পারে। অন্য যে কোনও থ্রেড তথ্য লগারের জন্যও উপলব্ধ।
জেরেমি ওয়েইব

@ জেরেমি উইবে: এটাই কি একমাত্র কারণ? কার্যত কোনও সমস্যা নেই যদি আমি পুরো অ্যাপের জন্য টাইপ লগারের একক গ্লোবাল ভেরিয়েবল ব্যবহার করি?
gmoniava

4
@ জিয়েরগি না, আমি এটি মনে করি না। - তুমি CallerInformation বৈশিষ্ট্যাবলী যা বর্গ প্রতি এক এটির একটু কম প্রাসঙ্গিক তোলে সঙ্গে এই দিন এই তথ্য দর্শন পেতে পারেন msdn.microsoft.com/en-us/library/hh534540.aspx
জেরেমি Wiebe

16

এনএলএগ-এ "ফাইলের প্রতি লগার" ব্যবহারের সুবিধা: আপনার কাছে নেমস্পেস এবং শ্রেণীর নাম দ্বারা লগগুলি পরিচালনা / ফিল্টার করার সম্ভাবনা রয়েছে। উদাহরণ:

<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}বিন্যাসে ব্যবহার করে ।


5

আমি এই পছন্দটির কয়েকটি কারণ দেখতে পারি।

  • আপনি লগের আউটপুট ফর্ম্যাটে যদি লগারের নাম অন্তর্ভুক্ত করেন তবে আপনি সর্বদা জানতে পারবেন যে কোনও নির্দিষ্ট লগ স্টেটমেন্টটি এসেছে।
  • নির্দিষ্ট লগার চালু বা বন্ধ করে বা তাদের স্তর নির্ধারণ করে আপনি সূক্ষ্ম দানাদার স্তরে কোন লগ স্টেটমেন্টগুলি দেখতে পান তা নিয়ন্ত্রণ করতে পারেন।

4

এনএলগের ক্ষেত্রে পারফরম্যান্স সুবিধাও রয়েছে। বেশিরভাগ ব্যবহারকারীরা ব্যবহার করবেন

Logger logger = LogManager.GetCurrentClassLogger()

স্ট্যাক ট্রেস থেকে বর্তমান শ্রেণীর সন্ধান করা কিছু (তবে খুব বেশি নয়) পারফরম্যান্স নিন।


3

বেশিরভাগ ক্ষেত্রে ক্লাসের নাম লগারের জন্য একটি ভাল নাম সরবরাহ করে। লগ ফাইলগুলি স্ক্যান করার সময় আপনি লগ বার্তাটি দেখতে এবং কোডের একটি লাইনের সাথে সরাসরি যুক্ত করতে পারেন।

একটি ভাল উদাহরণ যেখানে এটি সর্বোত্তম পদ্ধতির নয়, এটি হবারনেটের এসকিউএল লগ। "হাইবারনেট.এসকিউএল" নামে একটি ভাগ করা লগার বা এর মতো কিছু রয়েছে, যেখানে বিভিন্ন শ্রেণীর একটি সংখ্যা একক লগার বিভাগে কাঁচা এসকিউএল লেখেন।


2

বিকাশের দিক থেকে, যদি আপনাকে প্রতিবার লগার অবজেক্ট তৈরি না করতে হয় তবে এটি সবচেয়ে সহজ। অন্যদিকে, আপনি যদি না করেন তবে পরিবর্তে আপনি প্রতিচ্ছবি ব্যবহার করে এটি গতিশীলভাবে তৈরি করেন, এটি কার্য সম্পাদনকে কমিয়ে দেবে। এটি সমাধানের জন্য, আপনি নিম্নলিখিত কোডটি ব্যবহার করতে পারেন যা লগারকে অবিচ্ছিন্নভাবে তৈরি করে:

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

        }
    }
}

1

দুটি কারণ অবিলম্বে মনে মনে বসন্ত:

  1. প্রতিটি শ্রেণীর জন্য পৃথক লগ থাকার ফলে প্রদত্ত শ্রেণীর সাথে সম্পর্কিত সমস্ত লগ বার্তা / ত্রুটিগুলি একসাথে গ্রুপ করা সহজ হয়।
  2. শ্রেণীর মধ্যে লগ থাকা আপনাকে অভ্যন্তরীণ বিশদ লগ করতে দেয় যা শ্রেণীর বাইরে অ্যাক্সেসযোগ্য নাও হতে পারে (যেমন, ব্যক্তিগত রাষ্ট্র, শ্রেণীর প্রয়োগের সাথে সম্পর্কিত তথ্য ইত্যাদি)।

4
ক্লাস পর্যায়ে বা বিশ্বব্যাপী এটি সংজ্ঞায়িত না করেই আপনার ক্লাসে একটি লগার রয়েছে। গ্লোবাল লগারগুলি দৃশ্যমানতার দৃষ্টিকোণ থেকে শ্রেণীর "বাইরে" থাকে না। আপনি এখনও থেকে বিশ্বব্যাপী এটির উল্লেখ করছি মধ্যে প্রশ্নে বর্গ যাতে আপনি পূর্ণ দৃশ্যমানতা আছে।
রবার্ট

0

সম্ভবত যেহেতু আপনি এমন পদ্ধতিগুলি লগ করতে সক্ষম হতে চান যা কেবল ক্লাসে কেবল এনক্যাপসুলেশন না ভেঙে দৃশ্যমান, লগিং কার্যকারিতা ভঙ্গ না করে ক্লাসটি অন্য অ্যাপ্লিকেশনটিতে ব্যবহার করা সহজ করে তোলে।


4
ক্লাসটি অন্য অ্যাপ্লিকেশনটিতে ব্যবহার করা শক্ত করে তোলে। আপনি লগিং লাইব্রেরিটি পছন্দ করতে চান না তা উল্লেখ করতে হবে।
পাইওত্রে পেরাক

0

নাম স্থান বা শ্রেণি দ্বারা অ্যাপেন্ডারগুলিকে কনফিগার করা সহজ করে তোলে।


0

আপনি যদি এনএলওজি ব্যবহার করছেন তবে আপনি কনফিগারেশনে কলসিট নির্দিষ্ট করতে পারবেন, এটি লগিংয়ের বিবৃতিটি যেখানে অবস্থিত সেখানে শ্রেণীর নাম এবং পদ্ধতি রেকর্ড করবে।

<property name="CallSite" value="${callsite}" />

তারপরে আপনি আপনার লগার নাম বা সমাবেশের নামের জন্য একটি ধ্রুবক ব্যবহার করতে পারেন।

দাবি অস্বীকার: এনএলওজি কীভাবে এই তথ্য সংগ্রহ করে তা আমি জানি না, আমার অনুমান প্রতিফলন হবে যাতে আপনার পারফরম্যান্সটি বিবেচনা করা প্রয়োজন। আপনি এনএলজি ভি 4.4 বা তার পরে ব্যবহার না করে থাকলে অ্যাসিঙ্ক পদ্ধতিতে কয়েকটি সমস্যা রয়েছে।

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