লগারটি ব্যক্তিগত স্ট্যাটিক হওয়া উচিত


103

লগার কি স্থির ঘোষণা করা উচিত? সাধারণত আমি লগারের জন্য দুটি প্রকারের ঘোষণা দেখেছি:

    সুরক্ষিত লগ লগ = নতুন Log4JLogger (aClass.class);

অথবা

    ব্যক্তিগত স্ট্যাটিক লগ লগ = নতুন লগ 4 জে লোগার (aClass.class);

কোনটি ব্যবহার করা উচিত? উভয়ের প্রো এবং কনসের কী?


1
লগিং একটি ক্রস কাটিয়া উদ্বেগ। দিকগুলি ব্যবহার করুন এবং প্রশ্নটি মূল বিষয়।
ডেভ জার্ভিস

4
staticপ্রতি ক্লাসে একটি রেফারেন্স। অ-স্থিতিশীল প্রতি উদাহরণ (+ আরম্ভ) one সুতরাং কিছু ক্ষেত্রে, যদি আপনার কাছে প্রচুর উদাহরণ থাকে তবে উত্তরোত্তরটি একটি উল্লেখযোগ্য মেমরির প্রভাব নিয়ে আসে। ঘন ঘন অবজেক্টে অ-স্থির কখনও ব্যবহার করবেন না । আমি সবসময় স্থির সংস্করণ ব্যবহার করি। (যা বড় আকারের হওয়া উচিত LOG)
কিট আছে - অ্যানি-মৌসে

2
ইতিমধ্যে প্রস্তাবিত হিসাবে, এওপি এবং টীকাগুলি ব্যবহার করুন, উদাহরণস্বরূপ: jcabi.com/jcabi-aspects/annotation-loggable.html
yegor256

1
RobertHume স্ট্যাটিক সংস্করণ হয় একটি ধ্রুবক ব্যবহার করে। ঠিক এ কারণেই এটি বড়হাতে উচিত।
কিউইট আছে - অ্যানি-মুউসে

2
না এটি private static final Log logলোয়ারকেস হওয়া উচিত । লগার কোনও ধ্রুবক নয়, লগার একটি স্ট্যাটিক ফাইনাল অবজেক্ট (যা রূপান্তরিত হতে পারে)। ব্যক্তিগতভাবে আমি সর্বদা ব্যবহার করি logger
osundblad

উত্তর:


99

অ-স্থিতিশীল ফর্মের সুবিধাটি হ'ল আপনি এটিকে (বিমূর্ত) বেস ক্লাসে নীচের মতো ডান ক্লাসের নামটি ব্যবহার করা হবে তা উদ্বেগ না করে ঘোষণা করতে পারেন:

protected Log log = new Log4JLogger(getClass());

তবে এর অসুবিধা স্পষ্টতই ক্লাসের প্রতিটি ঘটনার জন্য একটি সম্পূর্ণ নতুন লগার উদাহরণ তৈরি করা হবে। এটি প্রতি সেফ ব্যয়বহুল নাও হতে পারে, তবে এটি একটি উল্লেখযোগ্য ওভারহেড যুক্ত করে। আপনি যদি এড়াতে চান তবে আপনি staticপরিবর্তে ফর্মটি ব্যবহার করতে চান । তবে এর অসুবিধাটি ঘুরে দেখা গেছে যে আপনাকে প্রতিটি স্বতন্ত্র শ্রেণিতে এটি ঘোষণা করতে হবে এবং প্রতিটি শ্রেণিতে যত্ন নিতে হবে যে লগার নির্মাণের সময় সঠিক শ্রেণিকামটি ব্যবহৃত হয়েছিল কারণ getClass()স্থির প্রসঙ্গে ব্যবহার করা যায় না। তবে, গড় আইডিইতে আপনি এর জন্য একটি স্বতঃপূরণ টেম্পলেট তৈরি করতে পারেন। যেমন logger+ ctrl+space

অন্যদিকে, আপনি যদি এমন কোনও কারখানার দ্বারা লগারটি পান যা ইতিমধ্যে ইনস্ট্যান্টিয়েটেড লগারগুলিকে ক্যাশে করতে পারে, তবে অ স্থির ফর্মটি ব্যবহার করে এত বেশি ওভারহেড যুক্ত হবে না। উদাহরণস্বরূপ Log4j এর একটি LogManagerউদ্দেশ্য রয়েছে।

protected Log log = LogManager.getLogger(getClass());

6
abstract Log getLogger();বিমূর্ত শ্রেণিতে ঘোষণা করুন । নির্দিষ্ট উদাহরণের জন্য স্ট্যাটিক লগার ফিরিয়ে এই পদ্ধতিটি প্রয়োগ করুন। যোগ private final static Log LOG = LogManager.getLogger(Clazz.class);আপনার আইডিই বর্গ টেমপ্লেটে।
কিট আছে - অ্যানি-মৌসে

2
protected Logger log = LoggerFactory.getLogger(getClass());
Slf4j এর

3
@ বালাসসি getClass () getLogger পদ্ধতিতে পাস করার সমস্যাটি হ'ল এটি বর্তমানের ক্লাসটি প্রদান করে। সাধারণত লগিংটি কোডটি যেখানে শ্রেণীর সাথে যুক্ত করা যায় তা আরও পছন্দসই। উদাহরণস্বরূপ, যদি লগিং কোডটি প্যারেন্ট ক্লাসে থাকে তবে আমরা চাই লগিংটি প্যারেন্টের সাথে যুক্ত করা হোক যদিও কার্যকরকারী উদাহরণ এবং ক্লাস চাইল্ডের উদাহরণ যা প্যারেন্টের সাব-ক্লাস। GetClass () এর সাথে এটি সন্তানের সাথে যুক্ত হবে, ভুলভাবে
inor

@ ইনার: "ভুলভাবে"? আপনি যদি ক্লাসটি বিমূর্ত করতে চান না, তবে আপনার উত্তরাধিকারসূত্রে প্রাপ্ত getClass () প্রথম স্থানে ব্যবহার করা উচিত নয়। এমন বিকাশকারী রয়েছে যা এটিকে সঠিক এবং দরকারী বলে মনে করে কারণ এটি উপাত্ত শ্রেণিতে ঠিক যুক্তি সম্পাদন করে।
BalusC

2
@ বালাসসি getLogger (getClass ()) এর ফলে সর্বদা সাব-ক্লাসের নামটি ভুলভাবে লগ করা যায়। ক্ল্যাগ ক্লজে কোড দ্বারা করা লগিং সংযুক্ত করতে লগিং ক্লাসগুলি সর্বদা getLogger (Clazz.class) করা উচিত। ডেভেলপাররা যা উপ-শ্রেণীর মধ্যে কোনটি চালাচ্ছে তা জানতে চায় (যেমন সাবক্লাজ ক্লজকে প্রসারিত করে) সাবক্লাজে করা উচিত: getLogger (সাবক্লাজ। ক্লাস) এবং এর মতো কিছু: লগইনফিনফো ("কলিং <আমার বেস ক্লাসে কিছু">);
inor

44

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

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


4
আমার সন্দেহ ছিল যে স্থির ক্ষেত্রটিতে মেমরি ফাঁস হওয়ার সমস্যাও থাকবে। অন্যরা যেমন বলেছে তেমন স্ট্যাটিকের পারফরম্যান্স সমস্যা থাকতে পারে। তাহলে আদর্শ উপায় কি?
লিয়াং

আপনি যে নিবন্ধটি উল্লেখ করেছেন তাতে @ পেপেরা হ'ল প্রধান সমস্যা হ'ল প্রতিটি অ্যাপ্লিকেশনে লগিং স্তর নিয়ন্ত্রণ করার ক্ষমতা যখন "ব্যক্তিগত স্ট্যাটিক লগ লগ =" ব্যবহার করে কোনও শ্রেণি ক্লাসলয়েডারের মাধ্যমে স্থাপন করা হয় যা একাধিকভাবে বংশধরদের পূর্বসূর্রে রয়েছে স্বতন্ত্র "অ্যাপ্লিকেশন" "। আমি সমস্যা হিসাবে দেখছি না কারণ এই বিশেষ পরিস্থিতিতে অ্যাপ্লিকেশনগুলির একটি "সাধারণ ভিত্তি" রয়েছে এবং সেই "সাধারণ ভিত্তিতে" শ্রেণীর জন্য লগিংয়ের স্তরটি সিদ্ধান্ত নেওয়া হয় এবং হ্যাঁ, এটি সমস্ত আবেদনকারীর জন্য রয়েছে ... তবে রাখুন মনে রাখবেন যে এই অ্যাপ্লিকেশনটির বাইরে এই শ্রেণিটি [বোঝাই] রয়েছে
in

17

সবচেয়ে গুরুত্বপূর্ণ পার্থক্যটি হল এটি কীভাবে আপনার লগ ফাইলগুলিকে প্রভাবিত করে: লগগুলি কোন বিভাগে যায়?

  • আপনার প্রথম পছন্দটিতে, একটি সাবক্লাসের লগগুলি সুপারক্লাসের বিভাগে শেষ হয়। এটি আমার কাছে খুব স্ব-স্বজ্ঞাত বলে মনে হচ্ছে।
  • আপনার প্রথম কেসের একটি বৈকল্পিক রয়েছে:

    সুরক্ষিত লগ লগ = নতুন লগ 4 জে লোগার (getClass ());

    সেক্ষেত্রে আপনার লগ ক্যাটাগরিটি বলছে যে লগড কোডটি কী কাজ করছে তা কাজ করে।

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

আমি দৃ last়ভাবে এই শেষ বিকল্পটি সুপারিশ করব। অন্যান্য সমাধানগুলির তুলনায় এর এই সুবিধা রয়েছে:

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

এর অসুবিধাগুলিও রয়েছে:

  • আপনি বার্তাগুলি লগইন করেন এমন প্রতিটি শ্রেণিতে এটি ঘোষণা করা দরকার (সুপারক্লাস লগারের কোনও পুনরায় ব্যবহার নয়)।
  • লগার শুরু করার সময় আপনার সঠিক ক্লাসের নামটি রাখার যত্ন নেওয়া দরকার। (তবে ভাল আইডিই এটির যত্ন নেবে)।

4

নিয়ন্ত্রণের বিপরীতমুখী ব্যবহার করুন এবং লগারটি কনস্ট্রাক্টরে পাস করুন। আপনি যদি শ্রেণীর ভিতরে লগার তৈরি করেন তবে আপনি আপনার ইউনিট পরীক্ষার সাথে একটি সময়ের শয়তান পেতে চলেছেন। আপনি ইউনিট পরীক্ষা লিখছেন আপনি না?


5
ইউনিট পরীক্ষাগুলি যা লগিং পরীক্ষা করে আপনি উভয়ই বেহুদা এবং অবিশ্বাস্যরকম ভঙ্গুর শব্দ তৈরি করছেন।
মাইকেল

1
পরীক্ষার অধীনে সিস্টেমের উপর নির্ভরশীলতা। কখনও কখনও লগিং আপনার অ্যাক্সেস থাকে।
ওয়েইন অ্যালেন

@ ওয়াইন অ্যালেন যখন আপনি ইউনিট পরীক্ষা করছেন, সংজ্ঞা অনুসারে, আপনার পরীক্ষার ফলাফলও রয়েছে। আপনি কি এমন পরিস্থিতির জন্য পরামর্শ দিচ্ছেন যার মধ্যে ইউনিট পরীক্ষা হয় তবে পরীক্ষার ফলাফল হয় না? শুধুমাত্র লগ আছে?
inor

শ্রেণীর ভিতরে লগার তৈরি করা সমস্যা তৈরি করে না। শ্রেণীর নিজস্ব লগার তৈরি করার কারণে আপনি খুব সাধারণ উদাহরণটি প্রদর্শন করতে পারেন যা ইউটি এর পক্ষে শক্ত?
inor

1
অবশ্যই। ইমেল পাঠায় এমন লগার সম্পর্কে কীভাবে How প্রতিবার আপনার পরীক্ষা চালানোর সময় তা করতে চাইবেন না। এছাড়াও আপনি কীভাবে পার্শ্ব প্রতিক্রিয়াটিকে দৃ ?়তাযুক্ত করেন?
ওয়েইন অ্যালেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.