লগার মোড়ক সেরা অনুশীলন


91

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

কী কী সেগুলি লিখতে বিদ্যমান উদাহরণগুলির জন্য কোনও প্রস্তাবনা জানেন? অথবা আমাকে এই অঞ্চলে কয়েকটি সেরা অনুশীলনের লিঙ্ক দিন।




উত্তর:


207

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

আমার অ্যাপ্লিকেশনগুলিতে বিমূর্ততাটি প্রায়শই দেখতে লাগে:

public interface ILogger
{
    void Log(LogEntry entry);
}

public enum LoggingEventType { Debug, Information, Warning, Error, Fatal };

// Immutable DTO that contains the log information.
public class LogEntry 
{
    public readonly LoggingEventType Severity;
    public readonly string Message;
    public readonly Exception Exception;

    public LogEntry(LoggingEventType severity, string message, Exception exception = null)
    {
        if (message == null) throw new ArgumentNullException("message");
        if (message == string.Empty) throw new ArgumentException("empty", "message");

        this.Severity = severity;
        this.Message = message;
        this.Exception = exception;
    }
}

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

public static class LoggerExtensions
{
    public static void Log(this ILogger logger, string message) {
        logger.Log(new LogEntry(LoggingEventType.Information, message));
    }

    public static void Log(this ILogger logger, Exception exception) {
        logger.Log(new LogEntry(LoggingEventType.Error, exception.Message, exception));
    }

    // More methods here.
}

যেহেতু ইন্টারফেস কেবলমাত্র একটি পদ্ধতি রয়েছে, আপনি সহজেই একটি তৈরি করতে পারেন ILoggerবাস্তবায়ন যে log4net করতে প্রক্সি , Serilog করতে , Microsoft.Extensions.Logging , NLog বা অন্য কোন লগিং গ্রন্থাগার এবং আপনার দ্বি ধারক কনফিগার শ্রেণীর একটি আছে এটা উদ্বুদ্ধ করতে ILoggerতাদের নির্মাতা

মনে রাখবেন যে একক পদ্ধতির সাথে ইন্টারফেসের উপরে স্থিতিশীল এক্সটেনশন পদ্ধতি থাকা অনেক সদস্যের সাথে ইন্টারফেস থাকা থেকে একেবারে আলাদা। এক্সটেনশন পদ্ধতিগুলি হ'ল সহায়ক পদ্ধতি যা কোনও LogEntryবার্তা তৈরি করে এবং এটিকে ILoggerইন্টারফেসের একমাত্র পদ্ধতিতে পাস করে । এক্সটেনশন পদ্ধতিগুলি গ্রাহকের কোডের অংশ হয়ে যায়; বিমূর্তির অংশ নয়। এটি কেবল বিমূর্ততা, এক্সটেনশন পদ্ধতি এবং এগুলি পরিবর্তন না করেই এক্সটেনশন পদ্ধতিগুলি বিকশিত হতে দেয়LogEntryলগার বিমূর্ততা ব্যবহার করা হয় এমন সময়েও কনস্ট্রাক্টর সর্বদা মৃত্যুদন্ড কার্যকর করা হয়, এমনকি সেই লগারটি স্ট্যাবড / বিদ্রূপ করা হলেও। এটি পরীক্ষার স্যুটটিতে চলাকালীন লগারে কলগুলির যথার্থতা সম্পর্কে আরও নিশ্চিততা দেয়। ওয়ান-মেম্বার ইন্টারফেস পরীক্ষার পাশাপাশি আরও সহজ করে তোলে; অনেক সদস্যের সাথে বিমূর্ততা প্রয়োগ বাস্তবায়ন (যেমন মক, অ্যাডাপ্টার এবং সজ্জকার) তৈরি করা শক্ত করে তোলে।

আপনি যখন এটি করেন, লগিং ফেসিয়াস (বা অন্য কোনও লাইব্রেরি) অফার করতে পারে এমন কোনও স্থির বিমূর্ততার জন্য খুব কমই প্রয়োজন হয়।


4
@ গ্যাব্রিয়েল এসপিনোজা: এটি সম্পূর্ণরূপে নির্ভর করে আপনি নামের স্থানটির উপরে এক্সটেনশন পদ্ধতি রাখুন y আপনি যদি এটি ইন্টারফেসের মতো একই নামস্থানে বা আপনার প্রকল্পের মূল নামের জায়গায় রেখে দেন তবে সমস্যাটি থাকবে না।
স্টিভেন

4
@ ব্যবহারকারী 1829319 এটি কেবল একটি উদাহরণ। আমি নিশ্চিত যে আপনি এই উত্তরটির উপর ভিত্তি করে একটি বাস্তবায়ন নিয়ে আসতে পারেন যা আপনার বিশেষ প্রয়োজনগুলির জন্য উপযুক্ত।
স্টিভেন

4
আমি এখনও এটি পাচ্ছি না ... আইলোগারের সম্প্রসারণ হিসাবে 5 লগার পদ্ধতি থাকার এবং আইলোগারের সদস্য না হওয়ার সুবিধা কোথায়?
এলিজাবেথ

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

4
কেন এটি দুর্দান্ত তা আমাকে আবার জোর দেওয়ার দরকার। আপনার কোডটি ডটনেট ফ্রেমওয়ার্ক থেকে ডটনেটকরে রূপান্তর করছে। যে প্রকল্পগুলি আমি এটি করেছি সেখানে আমার কেবল একটি নতুন কংক্রিট লিখতে হয়েছিল। আমি যেখানে যাইনি .... গআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআ! আমি খুশী আমি এই "ফেরার উপায়" পেয়েছি।
গ্রানাডা কোডার

10

আমি + থেকে অ্যাডাপ্টারের মোড়কের ছোট ইন্টারফেস ব্যবহার করা https://github.com/uhaciogullari/NLog.Interface হয় যে NuGet মাধ্যমে উপলব্ধ :

PM> Install-Package NLog.Interface 

10
V4.0 দ্বারা NLog লাইব্রেরিতে একটি ILogger ইন্টারফেস রয়েছে। আপনার আর এই লাইব্রেরির দরকার নেই
Jowen

8

এখন পর্যন্ত, সেরা বাজি হ'ল মাইক্রোসফ্ট.এক্সটেনশনগুলি.লগিং প্যাকেজটি ( জুলিয়ান দেখিয়েছেন ) ব্যবহার করা। বেশিরভাগ লগিং কাঠামো এটির সাহায্যে ব্যবহার করা যেতে পারে।

আপনার নিজস্ব ইন্টারফেসের সংজ্ঞা দেওয়া, যেমন স্টিভেনের উত্তরে ব্যাখ্যা করা হয়েছে সাধারণ ক্ষেত্রে এটি ঠিক আছে তবে আমি কয়েকটি বিষয় মিস করি যা আমি গুরুত্বপূর্ণ বিবেচনা করি:

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

আপনি সম্ভবত নিজের বিমূর্ততায় এগুলি সমস্ত বাস্তবায়ন করতে পারেন, তবে সেই মুহুর্তে আপনি চাকাটি পুনর্বহাল করবেন।


4

সাধারণত আমি একটি ইন্টারফেস তৈরি পছন্দ

public interface ILogger
{
 void LogInformation(string msg);
 void LogError(string error);
}

এবং রানটাইমে আমি একটি কংক্রিট শ্রেণি ইনজেক্ট করি যা এই ইন্টারফেস থেকে প্রয়োগ করা হয়।


11
LogWarningএবং LogCriticalপদ্ধতি এবং পদ্ধতি এবং তাদের সমস্ত ওভারলোডগুলি ভুলে যাবেন না । এটি করার সময় আপনি ইন্টারফেস বিভাজন নীতি লঙ্ঘন করবেন । ILoggerএকটি একক Logপদ্ধতিতে ইন্টারফেস সংজ্ঞায়িত করতে পছন্দ করুন ।
স্টিভেন

4
আমি সত্যিই দুঃখিত, এটা আমার উদ্দেশ্য ছিল না। লজ্জার দরকার নেই। আমি এই নকশাটি সত্যই প্রায়ই দেখি কারণ অনেক বিকাশকারী জনপ্রিয় লগ 4 নেট (যা এই সঠিক নকশা ব্যবহার করে) উদাহরণ হিসাবে ব্যবহার করে। দুর্ভাগ্যক্রমে যে নকশা সত্যিই ভাল না।
স্টিভেন

4
আমি এটি @ স্টিভেনের উত্তরের চেয়ে পছন্দ করি। তিনি একটি নির্ভরতা LogEntryএবং এভাবে নির্ভরতার পরিচয় দেয় LoggingEventTypeILoggerবাস্তবায়ন এই সঙ্গে মোকাবিলা করতে হবে LoggingEventTypes, সম্ভবত যদিও case/switch, যা একটি হল কোড গন্ধLoggingEventTypesনির্ভরতা কেন আড়াল করবেন ? বাস্তবায়ন লগিং মাত্রা হ্যান্ডেল আবশ্যক যাহাই হউক না কেন , তাই এটি ভাল হবে স্পষ্ট কি একটি বাস্তবায়ন করা উচিত, বরং একটি সাধারণ যুক্তি সঙ্গে একটি একক পদ্ধতি পিছনে এটা গোপন চেয়েও।
ধর্মতুর্তিল

4
চরম উদাহরণ হিসাবে, কল্পনা করুন ICommandযার একটি রয়েছে Handleযা একটি গ্রহণ করে objectcase/switchইন্টারফেসের চুক্তিটি সম্পাদনের জন্য সম্ভাব্য প্রকারের উপর প্রয়োগ অবশ্যই প্রয়োজন must এটি আদর্শ নয়। কোনও বিমূর্ততা নেই যা নির্ভরতা লুকিয়ে রাখে যা অবশ্যই হ্যান্ডল করা উচিত। পরিবর্তে একটি ইন্টারফেস রয়েছে যা প্রত্যাশিতভাবে পরিষ্কারভাবে বলে: "আমি আশা করি সমস্ত লগার সতর্কতা, ত্রুটি, ফ্যাটালস ইত্যাদি পরিচালনা করবে"। এটি "আমি আশা করি যে সমস্ত লগারের বার্তাগুলি পরিচালনা করতে হবে যার মধ্যে সতর্কতা, ত্রুটি, ফ্যাটালস ইত্যাদি রয়েছে" "
ধর্মতুর্তল

আমি @ স্টেভেন এবং @ ধর্মটর্ল্ট উভয়ের সাথেই একমত। এছাড়া LoggingEventTypeবলা উচিত LoggingEventLevelযেমন ধরনের ক্লাস এবং গলি মধ্যে যেমন কোডেড করা উচিত। আমার জন্য কোনও ইন্টারফেস পদ্ধতি ব্যবহার করে বনাম সংশ্লিষ্ট enumমানটি ব্যবহার না করার মধ্যে কোনও পার্থক্য নেই । পরিবর্তে ব্যবহার করুন ErrorLoggger : ILogger, InformationLogger : ILoggerযেখানে প্রতিটি লগার তার নিজস্ব স্তরটি নির্ধারণ করে। তারপরে ডিআই-র প্রয়োজনীয় লগারগুলি সম্ভবত একটি কী (এনাম) এর মাধ্যমে ইনজেক্ট করতে হবে তবে এই কীটি আর ইন্টারফেসের অংশ নয়। (আপনি এখন সলড)
ওয়াটার

4

এই সমস্যার একটি দুর্দান্ত সমাধান LibLog প্রকল্প আকারে উদ্ভূত হয়েছে ।

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

সুতরাং, লাইব্রেরি প্রকল্পগুলির মধ্যে লগইন করার জন্য লিবলগ একটি দুর্দান্ত সমাধান। আপনার মূল অ্যাপ্লিকেশন বা পরিষেবায় একটি কংক্রিট লগার (জয়ের জন্য সেরিলোগ) কেবলমাত্র রেফারেন্স এবং কনফিগার করুন এবং আপনার লাইব্রেরিতে LibLog যুক্ত করুন!


আমি লগ 4 নেট ব্রেকিং চেঞ্জ ইস্যু (ইয়াক) পাস করার জন্য এটি ব্যবহার করেছি ( উইক্টোরিজাইলা ডটকম / ২২/৩ / ২০১pat ) আপনার কোডটিতে প্রম্পম্পাইলড ডলসের উল্লেখ উল্লেখ করার পরিবর্তে। .Cs ফাইলটি আপনার প্রকল্পের নামগতির। সুতরাং আপনার যদি পৃথক স্তর থাকে (সিএসপোজ), আপনার হয় হয় একাধিক সংস্করণ, বা আপনার একটি ভাগ করা সিএসপ্রোজকে একত্রীকরণ করতে হবে। আপনি যখন এটি ব্যবহার করার চেষ্টা করবেন তখন আপনি এটি আবিষ্কার করতে পারবেন। তবে আমি যেমন বলেছিলাম, এটি লগ 4 নেট ব্রেকিং চেঞ্জ ইস্যু সহ একটি লাইফসেভার ছিল।
গ্রানাডা কোডার


2

2015 সাল থেকে আপনি । নেট কোর অ্যাপ্লিকেশন তৈরি করতে পারলে। নেট কোর লগিং ব্যবহার করতে পারেন।

NLog হুক করার জন্য প্যাকেজটি হ'ল:

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