ডিজাইনের দৃষ্টিকোণ থেকে, লগিংয়ের জন্য সেরা অনুশীলনগুলি কী কী? [বন্ধ]


11

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

তবে কোনও অবজেক্ট-ওরিয়েন্টেড ভাষায় ডিজাইনের দৃষ্টিকোণ থেকে, লগিংয়ের জন্য ওওপি এবং নিদর্শনগুলি অনুসরণ করার জন্য সর্বোত্তম অনুশীলনগুলি কী কী?

দ্রষ্টব্য: আমি বর্তমানে সি # তে এটি করছি, সুতরাং সি # তে উদাহরণগুলি অবশ্যই স্বাগত। আমি জাভা এবং রুবিতে উদাহরণগুলি দেখতে চাই।


সম্পাদনা: আমি লগ 4 নেট ব্যবহার করছি। এটিকে প্লাগ ইন করার সর্বোত্তম উপায়টি আমি জানি না।

উত্তর:


6

সবচেয়ে ভাল অনুশীলন যা আমি সুপারিশ করব তা হল নিজের নিজের ঘূর্ণায়মানের পরিবর্তে লগ 4 জে ব্যবহার করা । (যা জাভা থেকে সি # এবং রুবি উভয় ক্ষেত্রেই পোর্ট করা হয়েছে, সুতরাং আপনার আগ্রহী সমস্ত 3 টি ভাষার ক্ষেত্রে এটি প্রযোজ্য))

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


5

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


ইভেন্ট / পর্যবেক্ষক নিদর্শন ব্যবহারের জন্য +1: পর্যবেক্ষক পরিবর্তন করুন, আপনি লগিং পরিবর্তন করেছেন
ম্যাথিউ এম।

2

যেহেতু আপনি সি # তে এটি করছেন, তাই আমি আপনাকে এনএলগ এবং এলএমএএচ দেখার পরামর্শ দিচ্ছি। এগুলি NUGET ব্যবহার করে খুব সহজেই ইনস্টল করা যেতে পারে। নীচেরগুলিতে কিছু লিঙ্ক রেখেছি যাতে আপনি আরও তথ্য পেতে পারেন।


2

ব্যক্তিগতভাবে, আমি পছন্দের লগিং কাঠামোটি গ্রহণ করি (আমার ক্ষেত্রে, এনটলিব কারণ আমি .NET নিয়ে কাজ করি) এবং লগিংয়ের জন্য একটি এওপি দিক লিখি।

তারপরে আপনি যে কোনও পদ্ধতি / বৈশিষ্ট্য / শ্রেণি / নেমস্পেসগুলি বিশিষ্ট করতে পারেন এবং উত্সকে বিশৃঙ্খলা না করে সেগুলিতে লগিং যুক্ত করতে পারেন।


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

@ মার্জান ভেনেমা: পোস্টটি তীক্ষ্ণ ডকুমেন্টেশনের এমন একটি দিকের উদাহরণ রয়েছে যা কোনও পদ্ধতিতে প্রবেশ / প্রস্থান করে লগ করে। doc.sharpcrafters.com/postsharp/2.0/## পোস্টশার্প.সিএম / এইচটিএমএল পোস্ট পোস্টের ক্ষেত্রে, এটি নির্ধারিত সময়ে উত্সটিতে বৈশিষ্ট্যটি থেকে কোডটি বুনে, তাই এটি অন্যদের মতো কার্য সম্পাদনকে প্রভাবিত করে না।
স্টিভেন এভার্স

1

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

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

আমি অগত্যা বলব না যে এটি সর্বোত্তম অনুশীলনের হাতছাড়া হয়েছে, কারণ আমি কীভাবে এবং কীভাবে প্রায়শই লগ করতে হবে সে সম্পর্কে আমার মন পরিবর্তন করতে দেখা যায় - এবং প্রতিবারই কোনও সমস্যা নির্ণয় করার জন্য আমাকে লগ ব্যবহার করা দরকার আমি অবশ্যম্ভাবীভাবে উন্নতি করার উপায়গুলি খুঁজে পাই আমি রেকর্ড তথ্য।

আমি বলব, প্রাসঙ্গিক তথ্যের রেকর্ডিং (বিশেষত একটি সিটিআরএল-এফ / সন্ধানযোগ্য উপায়ে অনুসন্ধান করা) সবচেয়ে গুরুত্বপূর্ণ অংশ।

দ্বিতীয় সর্বাধিক গুরুত্বপূর্ণ অংশটি লগিং কোডটি আপনার মূল যুক্তি থেকে দূরে সরিয়ে নিয়েছে - এটি কোনও পদ্ধতিটিকে কুৎসিত এবং দীর্ঘ এবং জটিলভাবে খুব দ্রুত তৈরি করতে পারে।

public class MctLogger :
    IEventHandler<StoryImported>,
    IEventHandler<StoryScanned>,
    IEventHandler<SourceDirectoryMissing>,
    IEventHandler<SourceDirectoryAccessError>,
    IEventHandler<CannotCreateScannedStoryDirectory>,
    IEventHandler<CannotReadStoryDocument>,
    IEventHandler<StorySkippedPastCutoff>,
    IEventHandler<StorySkippedDuplicateUniqueId>,
    IEventHandler<StorySkippedByFilter>
{

    public void Observe(StoryImported e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryImported");
        log.Info("Story Unique ID: {Story.UniqueId}, Content ID: {ContentId}, Title: {Story.Headline}".SmartFormat(e));
    }

    public void Observe(StoryScanned e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryScanned");
        log.Info("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
    }

    public void Observe(SourceDirectoryMissing e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryMissing");
        log.Error("Directory: " + e.Directory);
    }

    public void Observe(SourceDirectoryAccessError e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryAccessError");
        log.Error(e.Exception, "Exception: " + e.Exception.Message);
    }

    public void Observe(CannotCreateScannedStoryDirectory e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotCreateScannedStoryDirectory");
        log.Error(e.Exception, "Directory: {Directory}, Exception: {Exception.Message}".SmartFormat(e));
    }

    public void Observe(CannotReadStoryDocument e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotReadStoryDocument");
        if (e.Exception == null) {
            log.Warn("File: {FilePath}".SmartFormat(e));
        }
        else {
            log.Warn(e.Exception, "File: {FilePath}, Exception: {Exception.Message}".SmartFormat(e));
        }
    }

    public void Observe(StorySkippedPastCutoff e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedPastCutoff");
        log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
    }

    public void Observe(StorySkippedDuplicateUniqueId e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedDuplicateUniqueId");
        log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
    }

    public void Observe(StorySkippedByFilter e)
    {
        var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedByFilter");
        log.Warn("Story Unique ID: {Story.UniqueId}, Reason: {Reason}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
    }
}

1

অন্যরা যেমন বলেছে, ব্যবহার করুন log4jবা log4netঅন্য কোনও সুনির্দিষ্ট লগিং ফ্রেমওয়ার্ক।

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

[Log(LogLevel.Info, "Counting characters.")]
int CountCharacters(string arg) 
{
    return arg.Length;
}

বা সমাবেশের প্রতিটি পদ্ধতি এর মতো:

[assembly: Log(AttributeTargetTypes = "*", 
 EntryLevel = LogLevel.Debug, ExitLevel = LogLevel.Debug, 
 ExceptionLevel = LogLevel.Error)]

0

কোনও কাঠামো এটি করে কিনা তা সম্পর্কে আমি নিশ্চিত নই, তবে ডিজাইনের দৃষ্টিকোণ থেকে আমি তথ্যটি মডেল করব মূলত তিনটি বিভাগে লগ ইন করার জন্য:

  1. পদ্ধতি স্তর ট্রেসিং
  2. ব্যতিক্রম লগিং
  3. অতিরিক্ত রান-টাইম তথ্য বিকাশকারীরা বিশ্বাস করেন যে রান-টাইম ব্যর্থতার ক্ষেত্রে তদন্তের জন্য গুরুত্বপূর্ণ (বা কেবল রান-টাইম পরিস্থিতি সম্পর্কিত কোনও আচরণ)।

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

Trace YourNamespace.* [public methods|constructors]
{  # options
   ignore trivial methods,
   format: "{time stamp}: {method name}({parameter list})",
   condition: "{Context.Instance.UserID in (12432,23432)}",
}

Exception YourNamespace.Program.Main [unhandled exceptions]
{
  format: "{time stamp}: {Context.Instance.UserId} {exception}",
  action: die,  # options are throw, swallow,
}

তৃতীয় বিভাগের জন্য, প্রোগ্রামাররা কেবলমাত্র এক বা একাধিক নিবেদিত "লগিং" পদ্ধতি তৈরি করতে পারে এবং প্রথম বিভাগের জন্য ট্রেসিংটি উত্তোলন করতে পারে। লগিং পদ্ধতিগুলি স্ট্যাব পয়েন্টটি সরবরাহ করা ছাড়া আর কিছুই করে না যেখানে ট্রেসিংয়ের নিয়ম প্রয়োগ করা যেতে পারে।

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