লগার.জেটলগার (মাইক্লাস.class) লগ 4 জে লগারগুলি শুরু করার সেরা উপায়?


13

এই ম্যাকিয়ং টিউটোরিয়ালটি লগারদের অন্তর্নিহিত করার পরামর্শ দেয়:

@Controller
public class WelcomeController {

    private static final Logger logger = Logger.getLogger(WelcomeController.class);

   // etc

}

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

আমার প্রশ্ন হ'ল এটি কি এটি সবচেয়ে ভাল উপায়? মনে হচ্ছে ... পুনরাবৃত্তি।


2
আপনি (জাভার বাক্য গঠনটি আলাদা করে রেখে) এ সম্পর্কে ভারবজ কী পান? লগার ধরে রাখার জন্য আপনাকে একটি ভেরিয়েবল তৈরি করতে হবে এবং আপনাকে getLogger()লগারের নামটি জানাতে হবে।
কেডগ্রিগরি

2
@ কেডিগ্রিগরি এই সত্য যে আমি প্রতিটি ক্লাসে একই জিনিস করছি।
দ্বিজোহনস্টন


3
স্থানান্তরিত করতে খুব পুরানো, তবে এই প্রশ্নটি এখানে অফ-টপিক এবং স্ট্যাকওভারফ্লোয়ের জন্য আরও উপযুক্ত।
আন্দ্রেস এফ।

1
@AndresF। আমি মনে করি যে আমি এটি এখানে রেখেছি কারণ এটি কোনও প্রযুক্তিগত সমস্যার চেয়ে কোড শৈলী / ডিজাইনের ধরণ সম্পর্কে আরও প্রশ্ন।
দ্বিজোহনস্টন

উত্তর:


16

আপনার মন্তব্য বলে যে "ভার্বোজ" প্রতিটি শ্রেণিতে কোডের এই লাইনটি পুনরাবৃত্তি করার প্রয়োজনকে বোঝায়। আমার প্রথম প্রতিক্রিয়াটি হ'ল, বড় ছবিতে প্রতিটি শ্রেণিতে দুটি লাইনের কোড (ভেরিয়েবল সংজ্ঞা এবং আমদানি বিবৃতি) যুক্ত করা কোনও বড় চুক্তি নয়। বিশেষত যেহেতু আপনার কেবল তাদের ক্লাসগুলিতে যুক্ত করা দরকার যা আচরণ করে এবং তাই লগিং করা প্রয়োজন। এটি বলেছিল, আপনি যে নির্দিষ্ট কোডের কোডটি ব্যবহার করছেন তা অনুলিপি করে কপি-পেস্ট করার ত্রুটিযুক্ত (আরও পরে এটি)।

তবে, যেহেতু আপনি বিকল্পগুলি চান, এখানে কয়েকটি কারণ রয়েছে যেগুলি আপনি সেগুলি ব্যবহার করতে বা নাও চাইতে পারেন।

পুরো অ্যাপ্লিকেশনটির জন্য একটি একক লগার ব্যবহার করুন

কোন ক্লাসটি কী প্রতিবেদন করছে সে সম্পর্কে যদি আপনি চিন্তা না করেন বা কোনও সাধারণ সিঙ্গলটন লগারের কাজটি করার চেয়ে বার্তাটিতে সমস্ত প্রয়োজনীয় প্রসঙ্গটি রাখতে ইচ্ছুক থাকেন:

LoggerSingleton.getInstance().debug("MyController is running")

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

এছাড়াও, এটি ব্যবহারের স্থানে ভার্বোসটি বাড়ে, যা আরও বেশি কীস্ট্রোকে শেষ হবে।

ব্যবহারের স্থানে আপনার লগার তৈরি করুন

আমি এটিকে বাইরে ফেলে দিচ্ছি কারণ এটি ভেরিয়েবলটি সরিয়ে দেয়। আমি এটি সম্পর্কে মন্তব্য করার প্রয়োজন মনে করি না। যদিও এটি লগারের উদাহরণ পাওয়ার জন্য আমার পছন্দসই কৌশলটি দেখায়।

Logger.getLogger(getClass()).debug("blah blah blah");

লগার ইনজেকশন করতে শিম পোস্ট প্রসেসর ব্যবহার করুন

আপনার উদাহরণটি স্প্রিং ব্যবহার করে এবং স্প্রিং আপনাকে মটরশুটি সূচনা কোডটিতে প্রবেশ করতে দেয়। আপনি একটি পোস্ট প্রসেসর তৈরি করতে পারেন যা কোনও loggerসদস্য ভেরিয়েবলের জন্য শিমটি পরিদর্শন করে এবং Loggerযখন এটি খুঁজে পায় তখন একটি উদাহরণ তৈরি করে ।

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

একটি মিশ্রণ ব্যবহার করুন

স্কালা এবং গ্রোভি বৈশিষ্ট্য সরবরাহ করে , যা আপনাকে আচরণকে সজ্জিত করতে দেয়। একটি সাধারণ স্কালাল প্যাটার্ন হ'ল একটি Loggingবৈশিষ্ট্য তৈরি করা , তারপরে এটিকে ক্লাসে যুক্ত করুন যার জন্য লগিং দরকার:

class MyController with Logging

দুর্ভাগ্যক্রমে, এর অর্থ হ'ল আপনাকে ভাষা পরিবর্তন করতে হবে। আপনি যদি জাভা 8 ব্যবহার না করেন তবে আপনি Logging"ডিফল্ট পদ্ধতি" দিয়ে একটি ইন্টারফেস তৈরি করতে পারবেন :

public interface Logging {
    default Logger getLogger() {
        return Logger.getLogger(getClass());
    } 
}

এখন, আপনার শ্রেণি কোডের মধ্যে, আপনি কেবল ব্যবহার করতে পারেন

getLogger().debug("blah blah blah");

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

সবচেয়ে বড় সমস্যাটি হ'ল প্রতিটি কলটিতে এটি আসল লগার উদাহরণ সন্ধান করতে হবে। যা দ্রুত তবে অপ্রয়োজনীয়।

এবং আপনার এখনও একটি আমদানি বিবৃতি প্রয়োজন।

লগার একটি সুপারক্লাসে সরান

আমি পুনরাবৃত্তি করব: আমি বারবার লগারের সংজ্ঞাগুলি ভার্বোসটি পাই না, তবে আপনি যদি মনে করেন এটি এগুলি অপসারণের জন্য এটি সর্বোত্তম পন্থা।

public abstract class AbstractController {
    protected Logger logger = Logger.getLogger(getClass());
}

এখন আপনার নিয়ামক শ্রেণিগুলি উত্তরাধিকার সূত্রে পেয়েছে AbstractControllerএবং তাদের loggerভেরিয়েবলের অ্যাক্সেস রয়েছে । মনে রাখবেন যে আপনাকে @Controllerকংক্রিটের ক্লাসে টিকা দিতে হবে।

কিছু লোক এটিকে উত্তরাধিকার হিসাবে বিকৃত মনে করবে। আমি ক্লাসটির AbstractControllerপরিবর্তে নামকরণ করে তাদের গলিত করার চেষ্টা করেছি AbstractProjectClassএকটি সম্পর্ক আছে কিনা তা আপনি নিজেরাই স্থির করতে পারেন ।

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


আমার মনে হয় আপনি getClass () উত্তরাধিকার ক্লাসে, MethodHandles.lookup () সম্পর্কে সতর্কতা অবলম্বন করা উচিত lookupClass () পরে ভাল JDK 7।
yuxh

@ ফ্ল্যাক্স - এর জন্য আপনার কী ব্যাখ্যা আছে?
kdgregory

: এখানে চেক stackoverflow.com/a/6653577/4652536
yuxh

@ ইউক্স - প্রশ্নটিতে মেথডহ্যান্ডলসের একমাত্র উল্লেখ (যা আপনি উত্তর দিয়েছিলেন তার উত্তর নয়) স্পষ্টতা চেয়ে জিজ্ঞাসা করা একটি মন্তব্যে অনুরূপ অসমর্থিত প্রতিপত্তি। এর চেয়ে ভাল যে দাবি রয়েছে তার পক্ষে কি আপনার অনুমোদনমূলক সমর্থন MethodHandles.lookup().lookupClass()রয়েছে Object.getClass()?
কেডগ্রিগরি

MethodHandles.lookup().lookupClass()স্ট্যাটিক ভেরিয়েবল ব্যবহার করা যেতে পারে, না ত্রুটি কপি-পেস্ট করতে প্রবণ এবং দ্রুত: stackoverflow.com/a/47112323/898747 আমি বেশ স্ট্যাটিক bein আমার কাঠুরে মত তাই এটা এটা একটা অতিরিক্ত inport মানে, কিন্তু অন্তত মূল্য একটি এ উল্লেখ :)
ফেবলব্লেজ

0

@Kdgregory দ্বারা উপলব্ধ উত্তর প্রসারিত করার জন্য, খাঁজকাটা প্রদান করে @Slf4j( groovy.util.logging.Slf4jএকটি টীকা যে সঞ্চালিত বর্গ উপর একটি এবং AST রূপান্তর একটি এটির যা পরিবর্তনশীল নাম অনুমান সঙ্গে এটি কর্মপ্রণালী হিসেবে বাক্সের) আউট logডিফল্ট যদি বাম অনির্দিষ্ট দ্বারা।

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