জাভাতে ডিবাগ আউটপুট পরিচালনা করার সঠিক উপায় কী?


32

আমার বর্তমান জাভা প্রকল্পগুলি বড় এবং বড় হওয়ার সাথে সাথে আমার কোডের বেশ কয়েকটি পয়েন্টে ডিবাগ আউটপুট inোকানোর অনুরূপ বর্ধমান বোধ অনুভব করছি।

এই বৈশিষ্ট্যটি যথাযথভাবে সক্ষম বা অক্ষম করতে, পরীক্ষার সেশনগুলি খোলার বা বন্ধ হওয়ার উপর নির্ভর করে, আমি সাধারণত private static final boolean DEBUG = falseআমার পরীক্ষাগুলি পরিদর্শন করা ক্লাসগুলির শুরুতে রেখেছি এবং তুচ্ছভাবে এটি এইভাবে ব্যবহার করি (উদাহরণস্বরূপ):

public MyClass {
  private static final boolean DEBUG = false;

  ... some code ...

  public void myMethod(String s) {
    if (DEBUG) {
      System.out.println(s);
    }
  }
}

এবং পছন্দ.

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

বিপরীতে, আমি (যেমন - আমি মনে করি - আরও অনেক) পুরো অ্যাপ্লিকেশনটিকে ডিবাগ মোডে রাখতে পছন্দ করেন না, কারণ পাঠ্যটির আউটপুট হওয়ার পরিমাণ অপ্রতিরোধ্য হতে পারে।

সুতরাং, স্থিতিশীলভাবে এই জাতীয় পরিস্থিতি পরিচালনা করার কোনও সঠিক উপায় বা সবচেয়ে সঠিক উপায় হ'ল ডিইইবিইউজি শ্রেণীর সদস্যকে ব্যবহার করা?


14
জাভাতে, সঠিক উপায়টি লগিংয়ের জন্য হোমব্রব কোড ব্যবহার না করা to একটি প্রতিষ্ঠিত কাঠামো চয়ন করুন, চাকা reinvent না
মশা

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

1
আমি সম্ভব হলে কোনও ডিবাগারের উপর আরও নির্ভর করে এবং আপনার কোডটি ডিবাগের বিবৃতি দিয়ে ফাঁক না করার সুপারিশ করব would
অ্যান্ড্রু টি ফিনেল

1
আপনি ইউনিট পরীক্ষা দিয়ে টেস্ট ড্রাইভেন ডেভলপমেন্ট (টিডিডি) অনুশীলন করেন? একবার আমি এটি করা শুরু করলে, আমি 'ডিবাগ কোড'-এ ব্যাপক হ্রাস লক্ষ্য করেছি।
JW01

উত্তর:


52

আপনি একটি লগিং ফ্রেমওয়ার্ক এবং সম্ভবত একটি লগিং সম্মুখের ফ্রেমওয়ার্কটি দেখতে চান।

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

ফ্রেমওয়ার্ক

কিছু লগিং ফ্রেমওয়ার্ক

কিছু লগিং মুখোমুখি

ব্যবহার

বেসিক উদাহরণ

এই ফ্রেমওয়ার্কগুলির বেশিরভাগই আপনাকে ফর্মটির কিছু লেখার অনুমতি দেয় (এখানে ব্যবহার করে slf4j-apiএবং logback-core):

package chapters.introduction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// copied from: http://www.slf4j.org/manual.html
public class HelloWorld {

  public static void main(String[] args) {
    final Logger logger = LoggerFactory.getLogger(HelloWorld.class);

    logger.debug("Hello world, I'm a DEBUG level message");
    logger.info("Hello world, I'm an INFO level message");
    logger.warn("Hello world, I'm a WARNING level message");
    logger.error("Hello world, I'm an ERROR level message");
  }
}

ডেডিকেটেড লগার তৈরি করতে একটি বর্তমান বর্গের ব্যবহারটি নোট করুন, যা এসএলএফ 4 জ / লগব্যাককে আউটপুট ফর্ম্যাট করতে দেয় এবং লগিং বার্তাটি কোথা থেকে এসেছে তা নির্দেশ করে।

এসএলএফ 4 জে ম্যানুয়ালটিতে উল্লিখিত হিসাবে , ক্লাসে একটি সাধারণ ব্যবহারের ধরণটি সাধারণত:

import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  

public class MyClass {

    final Logger logger = LoggerFactory.getLogger(MyCLASS.class);

    public void doSomething() {
        // some code here
        logger.debug("this is useful");

        if (isSomeConditionTrue()) {
            logger.info("I entered by conditional block!");
        }
    }
}

তবে প্রকৃতপক্ষে, ফর্মটি দিয়ে লগারটি ঘোষণা করা আরও সাধারণ:

private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);

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

লগার ইনস্ট্যান্ট করার অন্যান্য উপায় রয়েছে, উদাহরণস্বরূপ একটি নামযুক্ত লগার তৈরি করার জন্য স্ট্রিং প্যারামিটার ব্যবহার করে:

Logger logger = LoggerFactory.getLogger("MyModuleName");

ডিবাগ স্তর

ডিবাগের স্তরগুলি এক কাঠামো থেকে অন্য কাঠামোর পরিবর্তিত হয়, তবে সাধারণগুলি হ'ল সমালোচনার ভিত্তিতে, সৌম্য থেকে ব্যাট-শিট খারাপ, এবং সম্ভবত খুব সাধারণ থেকে আশাবাদী খুব বিরল):

  • TRACE খুব বিস্তারিত তথ্য। শুধুমাত্র লগ লিখতে হবে। শুধুমাত্র চেকপয়েন্টগুলিতে প্রোগ্রামের প্রবাহটি ট্র্যাক করতে ব্যবহৃত হয়।

  • DEBUG বিস্তারিত তথ্য. শুধুমাত্র লগ লিখতে হবে।

  • INFO উল্লেখযোগ্য রানটাইম ইভেন্ট। কনসোলে তাত্ক্ষণিকভাবে দৃশ্যমান হওয়া উচিত, তাই অল্প পরিমাণে ব্যবহার করুন।

  • WARNING রানটাইম বিজোড় এবং পুনরুদ্ধারযোগ্য ত্রুটি।

  • ERROR অন্যান্য রানটাইম ত্রুটি বা অপ্রত্যাশিত শর্ত।

  • FATAL গুরুতর ত্রুটিগুলি অকাল সমাপ্তির কারণ হয়।

ব্লক এবং গার্ডস

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

এই ধরণের সমস্যা এড়াতে আপনার প্রায়শই ফর্মটির কিছু লিখতে চান:

if (LOGGER.isDebugEnabled()) {
   // lots of debug logging here, or even code that
   // is only used in a debugging context.
   LOGGER.debug(" result: " + heavyComputation());
}

আপনার ডিবাগ স্টেটমেন্টগুলি ব্লক করার আগে আপনি যদি এই প্রহরীটি ব্যবহার না করেন, যদিও বার্তাগুলি আউটপুট নাও হতে পারে (উদাহরণস্বরূপ, আপনার লগার বর্তমানে কেবলমাত্র INFOস্তরের উপরে জিনিসগুলি মুদ্রণের জন্য কনফিগার করা হয়েছে ), heavyComputation()পদ্ধতিটি এখনও কার্যকর করা হত ।

কনফিগারেশন

কনফিগারেশনটি আপনার লগিং ফ্রেমওয়ার্কের উপর নির্ভর করে তবে তারা বেশিরভাগ ক্ষেত্রে একই কৌশলগুলি সরবরাহ করে:

  • প্রোগ্রামেটিক কনফিগারেশন (রানটাইম এ, একটি এপিআই এর মাধ্যমে) - রানটাইম পরিবর্তনের জন্য অনুমতি দেয় ),
  • স্থির ঘোষিত কনফিগারেশন (শুরু সময়ে, সাধারণত একটি এক্সএমএল বা বৈশিষ্ট্য ফাইলের মাধ্যমে - সম্ভবত আপনার প্রথমে যা প্রয়োজন তা সম্ভবত )।

তারা বেশিরভাগ একই ক্ষমতা প্রদান করে:

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

একটি logback.xmlফাইল ব্যবহার করে এখানে ঘোষিত কনফিগারেশনের একটি সাধারণ উদাহরণ ।

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

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

আরও কনফিগারেশন উদাহরণের জন্য, দয়া করে (অন্যদের মধ্যে) উল্লেখ করুন:

কিছু Funতিহাসিক মজা

দয়া করে নোট করুন যে লগ 4 জে এই মুহুর্তে একটি বড় আপডেট দেখছে, সংস্করণ 1.x থেকে 2.x এ রূপান্তর করছে । আপনি আরও historical তিহাসিক মজা বা বিভ্রান্তির জন্য উভয় দিকে নজর রাখতে চাইতে পারেন এবং আপনি যদি লগ 4 জে পছন্দ করেন তবে সম্ভবত 2.x সংস্করণটি নিয়ে যেতে পছন্দ করেন।

এটি লক্ষণীয়, মাইক পার্টরিজ যেমন মন্তব্যে উল্লেখ করেছেন যে লগব্যাকটি প্রাক্তন লগ 4 জে টিমের সদস্য দ্বারা তৈরি হয়েছিল। যা জাভা লগিং ফ্রেমওয়ার্কের ঘাটতিগুলি সমাধান করার জন্য তৈরি করা হয়েছিল। এবং আসন্ন বড় লগ 4 জে 2.x সংস্করণটি এখন লগব্যাক থেকে নেওয়া কয়েকটি বৈশিষ্ট্য একীভূত করছে।

সুপারিশ

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

তবুও, যদি আমাকে আজ একটি সংমিশ্রণ বেছে নিতে হয়, আমি লগব্যাক + এসএলএফ 4 জে সাথে যাব। তবে আপনি যদি কয়েক বছর পরে আমাকে জিজ্ঞাসা করেছিলেন তবে আমি অ্যাপাচি কমন্স লগিংয়ের সাথে লগ 4 জে সুপারিশ করেছিলাম, তাই আপনার নির্ভরতাগুলির দিকে নজর রাখুন এবং তাদের সাথে বিকশিত হন।


1
এসএলএফ 4 জে এবং লগব্যাকটি মূলত লোগ 4 জ লিখেছেন এমন লোক দ্বারা লেখা হয়েছিল।
মাইক পার্টরিজ

4
লগিংয়ের পারফরম্যান্স প্রভাব সম্পর্কে যারা চিন্তিত হতে পারেন তাদের জন্য: slf4j.org/faq.html#logging_performance
মাইক

2
এটা তোলে মূল্য উল্লেখ করে এটা এত সুস্পষ্ট কিনা আপনি আপনার কাঠুরে করা উচিত নয় এর static, যেহেতু এটি মেমরি অল্প পরিমাণ সংরক্ষণ করে, কিন্তু নির্দিষ্ট স্থানেই সমস্যার কারণ: slf4j.org/faq.html#declared_static
পুনর্বহাল মনিকা

1
@ মাইকপার্টরিজ: আমি লিঙ্কটির বিষয়বস্তু সম্পর্কে সচেতন, তবে এটি এখনও উদাহরণস্বরূপ প্যারামিটারের মূল্যায়ণকে আটকাবে না। বাইট প্যারামিটারাইজড লগিং আরও পারফরম্যান্ট কারণ লগ বার্তা প্রসেসিং ঘটবে না (স্ট্রিং উল্লেখযোগ্যভাবে সংক্ষিপ্তকরণ)। তবে যে কোনও মেথড কল প্যারামিটার হিসাবে পাস হলে তা কার্যকর করা হবে। সুতরাং, আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে ব্লকগুলি কার্যকর হতে পারে। এবং পোস্টে উল্লিখিত হিসাবে, ডিইবিইউজি স্তরটি সক্ষম করা থাকলে অন্যান্য ডিবাগ সম্পর্কিত ক্রিয়াকলাপগুলি (কেবলমাত্র লগিং নয়) গোষ্ঠীভুক্ত করার জন্য এগুলি আপনার পক্ষে কার্যকর হতে পারে।
হাইলেমে

1
@ হাইলেম - এটা সত্য, আমার ভুল
মাইক পার্টরিজ

2

একটি লগিং ফ্রেমওয়ার্ক ব্যবহার করুন

বেশিরভাগ সময় একটি স্থির কারখানার পদ্ধতি থাকে

private static final Logger logger = Logger.create("classname");

তারপরে আপনি বিভিন্ন স্তর সহ আপনার লগিং কোড আউটপুট করতে পারেন:

logger.warning("error message");
logger.info("informational message");
logger.trace("detailed message");

তারপরে একটি একক ফাইল থাকবে যেখানে আপনি নির্ধারণ করতে পারবেন প্রতিটি ক্লাসের জন্য কোন বার্তা লগ আউটপুটে লিখতে হবে (ফাইল বা স্টডার)


1

লগিং ফ্রেমওয়ার্কগুলি লোগোজেজে বা নতুন এসএলএফ 4 জনের মতো ঠিক এটির জন্য। তারা আপনাকে দুর্দান্ত বিশদে লগিং নিয়ন্ত্রণ করতে এবং অ্যাপ্লিকেশন চলাকালীন এটি কনফিগার করার অনুমতি দেয়।


0

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


আপনি যদি লগিং ফ্রেমওয়ার্ক ব্যবহার করেন এবং ডিবাগ লগিং উপলব্ধ থাকে - এমন একটি সময় আসবে যখন এটি আপনাকে সত্যিকারের খারাপ দিন থেকে বাঁচাবে।
ফোরটিয়ার্নার

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