স্তর কেন? ফিন লগিং বার্তা প্রদর্শিত হচ্ছে না?


110

জন্য JavaDocsjava.util.logging.Level রাজ্য:


অবতরণ ক্রমের স্তরগুলি হ'ল:

  • SEVERE (সর্বোচ্চ মান)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST (সর্বনিম্ন মান)

উৎস

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        logger.setLevel(Level.FINER);
        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

আউটপুট

Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .

সমস্যা বিবৃতি

আমার উদাহরণ স্থাপন Levelকরতে FINER, তাই আমি প্রতিটি লুপ জন্য 2 বার্তা দেখতে আশা করা হয়। পরিবর্তে আমি প্রতিটি লুপের জন্য একটি বার্তা দেখি ( Level.FINEবার্তাটি অনুপস্থিত)।

প্রশ্ন

FINE(, FINERবা FINEST) আউটপুটটি দেখতে কী পরিবর্তন করতে হবে ?

আপডেট (সমাধান)

ভিনিত রেনল্ডসের জবাবের জন্য ধন্যবাদ , এই সংস্করণটি আমার প্রত্যাশা অনুযায়ী কাজ করে। এটি 3 এক্স INFOবার্তা এবং 3 এক্স FINEবার্তা প্রদর্শন করে।

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        // LOG this level to the log
        logger.setLevel(Level.FINER);

        ConsoleHandler handler = new ConsoleHandler();
        // PUBLISH this level
        handler.setLevel(Level.FINER);
        logger.addHandler(handler);

        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

10
আমার কাছে মনে হচ্ছে আপনার কাছে INFO এবং তারপরে কনসোলে দুটি বার্তা মুদ্রিত হবে: প্রথমে বেনামে লগারের মাধ্যমে, তারপরে তার পিতামাতার দ্বারা, কনসোলহ্যান্ডলারটিতে ডিফল্টরূপে INFO এ সেট করা কনসোলহ্যান্ডলারও রয়েছে। গ্লোবাল লগারটি নিষ্ক্রিয় করতে আপনাকে এই কোডের লাইনটি যুক্ত করতে হবে: logger.setUseParentHandlers (মিথ্যা);
মিনিট

আমি কেবল ডাবলস সম্পর্কে মিনিটের মন্তব্য নিশ্চিত করতে চাই। আপনি .setUseParentHandlers (মিথ্যা) ব্যবহার না করা হলে আপনি দুটি আউটপুট পাবেন;
xpagesbeast

উত্তর:


124

লগাররা কেবল বার্তাটি লগ করে, অর্থাত তারা লগ রেকর্ড তৈরি করে (বা লগিংয়ের অনুরোধগুলি)। তারা গন্তব্যগুলিতে বার্তাগুলি প্রকাশ করে না, যা হ্যান্ডলারদের দ্বারা যত্ন নেওয়া হয়। লগারের স্তর নির্ধারণ করা কেবলমাত্র সেই স্তরটি বা তারও বেশি উচ্চতার সাথে মিল রেখে লগ রেকর্ড তৈরি করে

আপনি একটি ব্যবহার ConsoleHandlerকরতে পারেন (আপনার আউটপুট সিস্টেম.আর বা ফাইল যেখানে আছে তা আমি অনুমান করতে পারিনি, তবে আমি ধরে নেব যে এটি পূর্ববর্তী), যা স্তরের লগ রেকর্ড প্রকাশের ক্ষেত্রে ডিফল্ট Level.INFOLevel.FINERকাঙ্ক্ষিত ফলাফলের জন্য আপনাকে এই হ্যান্ডলারটি কনফিগার করতে হবে, স্তর এবং উচ্চতর লগ রেকর্ডগুলি প্রকাশ করতে হবে ।

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

হ্যান্ডলার স্তর সম্পাদনা করা হচ্ছে

1. কনফিগারেশন ফাইল ব্যবহার করে

কনসোলহ্যান্ডলারের ডিফল্ট স্তরটি পরিবর্তন করতে java.util.logging বৈশিষ্ট্য ফাইল (ডিফল্টরূপে, এটি logging.propertiesফাইলটি মধ্যে রয়েছে JRE_HOME/lib) পরিবর্তন করা যেতে পারে:

java.util.logging.ConsoleHandler.level = FINER

২. রানটাইমে হ্যান্ডলার তৈরি করা

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

Handler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINER);
Logger.getAnonymousLogger().addHandler(consoleHandler);

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

3
আপনাকে স্বাগতম. এবং হ্যাঁ, ডিজাইনটি আপনাকে পেয়েছে, যদি কেউ এমন লগার লিখতে থাকে যা কেবল একটি ফাইল, কনসোল ইত্যাদিতে স্ট্রিং ফেলে দেয়
ভিনেট রেনল্ডস

7
এবং গ্লোবাল জেআরই লাইব্রেরিতে লগিং.প্রেটিটি পরিবর্তন করা কি পরিচালনাযোগ্য?
জেমস অ্যান্ডারসন

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

আমি অনুমান করি এটি একটি ওয়ান-লাইনার হিসাবে সমস্যার সমাধান করবে, এমনকি আপনি যখন কোনও ডিফল্ট পরিবেশে বেনামী এবং নামযুক্ত লগার ব্যবহার করেন:Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
মার্ক জেরোনিমাস

27

কেন

java.util.logging এর একটি রুট লগার থাকে যা ডিফল্ট হয় Level.INFOএবং এর সাথে একটি কনসোলহ্যান্ডলার সংযুক্ত থাকে যা ডিফল্টও হয় Level.INFOFINEএর চেয়ে কম INFO, সুতরাং সূক্ষ্ম বার্তা ডিফল্টরূপে প্রদর্শিত হয় না are


সমাধান 1

আপনার পুরো অ্যাপ্লিকেশনটির জন্য একটি লগার তৈরি করুন, যেমন আপনার প্যাকেজের নাম বা ব্যবহার থেকে Logger.getGlobal(), এবং এটিতে আপনার নিজস্ব কনসোল লগারকে আটকান। তারপরে হয় রুট লগারটি চুপ করতে বলুন (উচ্চ স্তরের বার্তাগুলির সদৃশ আউটপুট এড়াতে) অথবা আপনার লগারকে লগগুলি রুটে ফরোয়ার্ড না করতে বলুন ।

public static final Logger applog = Logger.getGlobal();
...

// Create and set handler
Handler systemOut = new ConsoleHandler();
systemOut.setLevel( Level.ALL );
applog.addHandler( systemOut );
applog.setLevel( Level.ALL );

// Prevent logs from processed by default Console handler.
applog.setUseParentHandlers( false ); // Solution 1
Logger.getLogger("").setLevel( Level.OFF ); // Solution 2

সমাধান 2

বিকল্পভাবে, আপনি রুট লগারের বারটি কমিয়ে দিতে পারেন।

আপনি কোড দ্বারা সেগুলি সেট করতে পারেন:

Logger rootLog = Logger.getLogger("");
rootLog.setLevel( Level.FINE );
rootLog.getHandlers()[0].setLevel( Level.FINE ); // Default console handler

অথবা লগিং কনফিগারেশন ফাইল সহ, আপনি যদি এটি ব্যবহার করছেন :

.level = FINE
java.util.logging.ConsoleHandler.level = FINE

গ্লোবাল স্তর হ্রাস করে, আপনি মূল লাইব্রেরি থেকে বার্তা দেখতে শুরু করতে পারেন যেমন কিছু সুইং বা জাভাএফএক্স উপাদান থেকে from এই ক্ষেত্রে আপনি আপনার প্রোগ্রাম থেকে প্রাপ্ত বার্তাগুলি ফিল্টার করতে রুট লগারে একটি ফিল্টার সেট করতে পারেন ।


applog.setUseParentHandlers (মিথ্যা) এই কোডগুলি আমাকে সহায়তা করে, অনেক ধন্যবাদ।
aolphn

4

আমার জাভা লগিং কেন কাজ করছে না?

এমন একটি জার ফাইল সরবরাহ করে যা আপনার লগ ইন প্রত্যাশার মতো কাজ না করায় আপনাকে কাজ করতে সহায়তা করবে। এটি আপনাকে কোন লগার এবং হ্যান্ডলারগুলি ইনস্টল করা হয়েছে এবং কোন স্তরগুলি সেট করা হয়েছে এবং লগিংয়ের স্তরক্রমটিতে কোন স্তরে একটি সম্পূর্ণ ডাম্প দেয়।


এটি একটি মন্তব্য নয়, কোনও উত্তর নয়।
hfontanez

4

কেন

@ শিপি দ্বারা উল্লিখিত হিসাবে, এটি কাজ না করার কারণটি হ'ল java.util.logging.Loggerএকটি রুট লগার থাকে যা ডিফল্ট হয় Level.INFOএবং সেই ConsoleHandlerরুট লগারের সাথে সংযুক্ত এছাড়াও ডিফল্ট হয় Level.INFO। অতএব, অর্ডার দেখার জন্য FINE( FINERবা FINEST) আউটপুট, আপনি মূল এটির ডিফল্ট মান সেট করতে হবে এবং তার ConsoleHandlerজন্য Level.FINEনিম্নরূপ:

Logger.getLogger("").setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);


আপনার আপডেটের সমস্যা (সমাধান)

@ মিনস দ্বারা উল্লিখিত হিসাবে, আপনার বার্তাগুলির জন্য INFOএবং তারপরে কনসোলে দু'বার মুদ্রণ হবে : প্রথমে বেনামে লগারের দ্বারা, তারপরে তার পিতামাতার দ্বারা, ডিফল্টরূপে ConsoleHandlerসেটও রয়েছে রুট লগার INFO। রুট লগারটি নিষ্ক্রিয় করতে আপনাকে কোডের এই লাইনটি যুক্ত করতে হবে:logger.setUseParentHandlers(false);

@ শিপি দ্বারা উল্লিখিত রুট লগারটির ডিফল্ট কনসোল হ্যান্ডলার দ্বারা লগগুলি প্রক্রিয়াজাতকরণ থেকে রোধ করার অন্যান্য উপায় রয়েছে, যেমন:

Logger.getLogger("").getHandlers()[0].setLevel( Level.OFF );

তবে Logger.getLogger("").setLevel( Level.OFF );কাজ করবে না কারণ এটি কেবলমাত্র রুট লগারে সরাসরি পাঠানো বার্তাটিকে অবরুদ্ধ করে, বাচ্চা লগার থেকে বার্তা আসে না। কীভাবে Logger Hierarchyকাজ করে তা বর্ণনা করার জন্য , আমি নিম্নলিখিত চিত্রটি আঁকছি:

এখানে চিত্র বর্ণনা লিখুন

public void setLevel(Level newLevel)এই লগার দ্বারা কোন বার্তা স্তরগুলি লগ করা হবে তা উল্লেখ করে লগ স্তর সেট করুন। এই মানের চেয়ে কম বার্তার স্তর বাদ দেওয়া হবে। স্তর মান.এফএফ লগিং বন্ধ করতে ব্যবহার করা যেতে পারে। যদি নতুন স্তরটি নাল হয় তবে এর অর্থ হ'ল এই নোডটি নির্দিষ্ট (নন-নাল) স্তরের মানের সাথে তার নিকটতম পূর্বপুরুষের থেকে তার স্তরটি উত্তরাধিকার সূত্রে প্রাপ্ত হওয়া উচিত।


0

আমি আমার আসল সমস্যাটি খুঁজে পেয়েছি এবং এটির কোনও উত্তরে উল্লেখ করা হয়নি: আমার কিছু ইউনিট-পরীক্ষাগুলি লগিং ইনিশিয়াল কোডটি একই পরীক্ষার স্যুটের মধ্যে একাধিকবার চালানো হতে পারে, পরবর্তী পরীক্ষাগুলিতে লগিংকে বিশৃঙ্খলাবদ্ধ করে তোলে।


0

অন্যান্য রূপগুলির চেষ্টা করা হয়েছে, এটি যথাযথ হতে পারে

    Logger logger = Logger.getLogger(MyClass.class.getName());        
    Level level = Level.ALL;
    for(Handler h : java.util.logging.Logger.getLogger("").getHandlers())    
        h.setLevel(level);
    logger.setLevel(level);
// this must be shown
    logger.fine("fine");
    logger.info("info");

0

পরিবর্তনের জন্য রক্ষণাবেক্ষণযোগ্যতা এবং নকশা সম্পর্কে এই সমাধানটি আমার কাছে আরও ভাল প্রদর্শিত হয়েছে:

  1. জার ফাইলটিতে অন্তর্ভুক্ত করার জন্য লসিং সম্পত্তি ফাইলটিকে রিসোর্স প্রকল্প ফোল্ডারে এম্বেড করে তৈরি করুন:

    # Logging
    handlers = java.util.logging.ConsoleHandler
    .level = ALL
    
    # Console Logging
    java.util.logging.ConsoleHandler.level = ALL
  2. কোড থেকে সম্পত্তি ফাইলটি লোড করুন:

    public static java.net.URL retrieveURLOfJarResource(String resourceName) {
       return Thread.currentThread().getContextClassLoader().getResource(resourceName);
    }
    
    public synchronized void initializeLogger() {
       try (InputStream is = retrieveURLOfJarResource("logging.properties").openStream()) {
          LogManager.getLogManager().readConfiguration(is);
       } catch (IOException e) {
          // ...
       }
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.