এসএলএফ 4 জে রানটাইমে বার্তার লগ স্তরের সেট করা


102

লগ 4 জ ব্যবহার করার সময়, Logger.log(Priority p, Object message)পদ্ধতিটি উপলব্ধ থাকে এবং রানটাইম নির্ধারিত লগ স্তরে কোনও বার্তা লগ করতে ব্যবহার করা যেতে পারে। আমরা স্ট্যান্ডারকে একটি নির্দিষ্ট লগ স্তরে লগারে পুনর্নির্দেশ করতে এই সত্য এবং এই টিপটি ব্যবহার করছি ।

slf4j এর একটি জেনেরিক log()পদ্ধতি নেই যা আমি খুঁজে পেতে পারি। তার মানে কি উপরোক্ত প্রয়োগের কোনও উপায় নেই?


4
দেখে মনে হচ্ছে এটি ডেভ মেইলিং লিস্টে slf4j
এডওয়ার্ড ডেল

4
মার্কার একবার দেখুন, এটি কাস্টম ডেটা যা আপনি লগ চেইনে যেতে পারেন।
tuxSlayer

4
@ টাক্সলেয়ার আপনি কীভাবে এই ক্ষেত্রে মার্কার ব্যবহার করবেন তা দয়া করে বিস্তারিত বলতে পারেন?
দুর্বল পরিবর্তনশীল

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

4
এই বৈশিষ্ট্যটির অংশ হওয়ার কথা slf4j 2.0jira.qos.ch/browse/SLF4J-124 বিস্তারিত এবং একটি সম্ভাব্য slf4j 1.xকাজের জন্য আমার উত্তর দেখুন ।
স্লারতিদান

উত্তর:


47

এটি করার কোনও উপায় নেই slf4j

আমি কল্পনা যে কারণে যে এই কার্যকারিতা হারিয়েছে যে এটা অসম্ভব পরবর্তী একটি গঠন করা হয় Levelটাইপ জন্য slf4jযে দক্ষতার ম্যাপ করা যেতে পারে Level(অথবা সমতুল্য) ছদ্মরূপ পিছনে সম্ভব লগিং বাস্তবায়নের সব ব্যবহৃত প্রকার। বিকল্পভাবে, ডিজাইনাররা সিদ্ধান্ত নিয়েছেন যে আপনার ব্যবহারের ক্ষেত্রে এটি সমর্থন করার ওভারহেডগুলি ন্যায়সঙ্গত করার পক্ষে খুব অস্বাভাবিক

বিষয়ে @ ripper234 এর ব্যবহার-কেস (একক পরীক্ষামূলক), আমি মনে করি বাস্তবমুখী সমাধান কি লগিং সিস্টেম slf4j ছদ্মরূপ পিছনে ... যখন ইউনিট পরীক্ষা চলমান হার্ড টেলিগ্রাম জ্ঞান ইউনিট পরীক্ষা (গুলি) সংশোধন করা হয়।


10
সত্যিই কোনও ম্যাপিংয়ের দরকার নেই। এর মধ্যে পাঁচটি স্তর ইতিমধ্যে নিখুঁতভাবে পদ্ধতি দ্বারা সংজ্ঞায়িত করা হয়েছে org.slf4j.Logger: ডিবাগ, ত্রুটি, তথ্য, ট্রেস, সতর্কতা।
এডওয়ার্ড ডেল

4
এবং সমস্যাগুলি অবৈধ হিসাবে বন্ধ হয়ে গেছে। যতদূর আমি এটি বুঝতে পারি এটি ইচ্ছাকৃতভাবে নকশা পছন্দ।
রিপার 234

9
@ রিপার 234 - আমি মনে করি না যে আপনার বাগটি স্কম্পট ডট কমের মূল প্রশ্ন হিসাবে একই সমস্যার সমাধান করেছে। আপনি SLF4J API এর মাধ্যমে অন্তর্নিহিত লগিং সিস্টেমের স্তরটি কনফিগার করার বিষয়ে জিজ্ঞাসা করেছেন about স্কোমপট.কমের পরে এসএলএফ 4 জে এপিআই-তে একটি জেনেরিক 'লগ' পদ্ধতি ছিল যা বার্তাটির প্যারামিটার হিসাবে লগিং স্তরকে নিয়ে যায়
রিচার্ড ফেরন 21

4
+1 @ রিচার্ডফার্ন এবং কেউ 60 সেকেন্ডের পরে মন্তব্যটি আপোড করতে পারবেন না, মেহ । : বৈশিষ্ট্য অনুরোধ এদিকে বিদ্যমান হয় bugzilla.slf4j.org/show_bug.cgi?id=133
জানুয়ারী

4
আরএফই লিঙ্কগুলি আর কোনও সমাধান করে না। সম্পর্কিত লিঙ্কগুলি এখন: jira.qos.ch/browse/SLF4J-124 এবং jira.qos.ch/browse/SLF4J-197 ... এবং উভয়ই বন্ধ হয়ে গেছে। যুক্তি জন্য মন্তব্য পড়ুন।
স্টিফেন সি

28

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

import org.slf4j.Logger;

public class LogLevel {

    /**
     * Allowed levels, as an enum. Import using "import [package].LogLevel.Level"
     * Every logging implementation has something like this except SLF4J.
     */

    public static enum Level {
        TRACE, DEBUG, INFO, WARN, ERROR
    }

    /**
     * This class cannot be instantiated, why would you want to?
     */

    private LogLevel() {
        // Unreachable
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "txt" is null,
     * behaviour depends on the SLF4J implementation.
     */

    public static void log(Logger logger, Level level, String txt) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt);
                break;
            case DEBUG:
                logger.debug(txt);
                break;
            case INFO:
                logger.info(txt);
                break;
            case WARN:
                logger.warn(txt);
                break;
            case ERROR:
                logger.error(txt);
                break;
            }
        }
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "format" or the "argArray"
     * are null, behaviour depends on the SLF4J-backing implementation.
     */

    public static void log(Logger logger, Level level, String format, Object[] argArray) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(format, argArray);
                break;
            case DEBUG:
                logger.debug(format, argArray);
                break;
            case INFO:
                logger.info(format, argArray);
                break;
            case WARN:
                logger.warn(format, argArray);
                break;
            case ERROR:
                logger.error(format, argArray);
                break;
            }
        }
    }

    /**
     * Log at the specified level, with a Throwable on top. If the "logger" is null,
     * nothing is logged. If the "level" is null, nothing is logged. If the "format" or
     * the "argArray" or the "throwable" are null, behaviour depends on the SLF4J-backing
     * implementation.
     */

    public static void log(Logger logger, Level level, String txt, Throwable throwable) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt, throwable);
                break;
            case DEBUG:
                logger.debug(txt, throwable);
                break;
            case INFO:
                logger.info(txt, throwable);
                break;
            case WARN:
                logger.warn(txt, throwable);
                break;
            case ERROR:
                logger.error(txt, throwable);
                break;
            }
        }
    }

    /**
     * Check whether a SLF4J logger is enabled for a certain loglevel. 
     * If the "logger" or the "level" is null, false is returned.
     */

    public static boolean isEnabledFor(Logger logger, Level level) {
        boolean res = false;
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                res = logger.isTraceEnabled();
                break;
            case DEBUG:
                res = logger.isDebugEnabled();
                break;
            case INFO:
                res = logger.isInfoEnabled();
                break;
            case WARN:
                res = logger.isWarnEnabled();
                break;
            case ERROR:
                res = logger.isErrorEnabled();
                break;
            }
        }
        return res;
    }
}

বৈকল্পিক (অবজেক্ট ...) আরগস প্যারামিটার দিয়ে এটি ব্যবহার করা সহজ হবে।
অজ্ঞাতনামা

"org.slf4j.Logger" এর বেশ কয়েকটি লগিং পদ্ধতির স্বাক্ষর রয়েছে যা উপরের শ্রেণিতে পরিচালনা করা হয় না, তাই সম্ভবত একটি এক্সটেনশানটি নিশ্চিত করা হয়েছে: slf4j.org/api/org/slf4j/Logger.html
ডেভিড টোনহোফার

4
আমি মনে করি যে এই বাস্তবায়নটি একটি অনাকাঙ্ক্ষিত পরিবর্তন যুক্ত করবে। আপনি যখন কল logger.info (...) কলটি ব্যবহার করেন তখন লগারের কলার শ্রেণি এবং পদ্ধতিতে অ্যাক্সেস থাকে এবং এটি স্বয়ংক্রিয়ভাবে লগ এন্ট্রিতে যুক্ত হতে পারে। এখন, এই প্রয়োগের মাধ্যমে, কল লগ (লগার, স্তর, txt) একটি লগ এন্ট্রি তৈরি করবে যা সর্বদা একই কলার থাকবে: লগলেভেল.লগ। আমি কি সঠিক?
ডোমিন

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

@ ডেভিড, হ্যাঁ, আপনি ঠিক বলেছেন :-)। আমি নিশ্চিত নই যে এটি অ্যাপেন্ডারের পক্ষে কাজ, কারণ সেই ক্ষেত্রে আপনি অ্যাপেন্ডার এবং লগারের মধ্যে একটি কঠিন নির্ভরতা নির্ধারণ করছেন ... তবে ... এটি একটি সমাধান is ধন্যবাদ ডেভিড
ডোমিন

12

আপনি জাভা 8 ল্যাম্বডাস ব্যবহার করে এটি বাস্তবায়ন করতে পারেন।

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;

public class LevelLogger {
    private static final Logger LOGGER = LoggerFactory.getLogger(LevelLogger.class);
    private static final Map<Level, LoggingFunction> map;

    static {
        map = new HashMap<>();
        map.put(Level.TRACE, (o) -> LOGGER.trace(o));
        map.put(Level.DEBUG, (o) -> LOGGER.debug(o));
        map.put(Level.INFO, (o) -> LOGGER.info(o));
        map.put(Level.WARN, (o) -> LOGGER.warn(o));
        map.put(Level.ERROR, (o) -> LOGGER.error(o));
    }

    public static void log(Level level, String s) {
        map.get(level).log(s);
    }

    @FunctionalInterface
    private interface LoggingFunction {
        public void log(String arg);
    }
}

হ্যাঁ হ্যাঁ ... তবে এখন এই কোডটি এসএফ 4 জ এর পরিবর্তে বা আপনার পরিবর্তে আপনার কোডবেসটি পরিবর্তন করতে হবে। আপনি যদি এসএলফ 4 জ 1 এর পরিবর্তে এটি ব্যবহার করেন তবে এটি সম্ভবত আরও সমৃদ্ধ হওয়া দরকার, 2) প্রচুর পরিমাণে (কমপক্ষে) আমদানি পরিবর্তন করা দরকার এবং 3) এসএফ 4 জজের সামনে এই নতুন স্তরটি অতিরিক্ত লগিং ওভারহেড যুক্ত করে।
স্টিফেন সি

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

12

লগব্যাক এবং স্যুইচ করার চেষ্টা করুন

ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.toLevel("info"));

আমি বিশ্বাস করি এটি কেবলমাত্র লগব্যাকের কল হবে এবং আপনার বাকী কোডটি অপরিবর্তিত থাকবে। লগব্যাক এসএলএফ 4 জে ব্যবহার করে এবং মাইগ্রেশন ব্যথাহীন হবে, কেবল এক্সএমএল কনফিগারেশন ফাইলগুলি পরিবর্তন করতে হবে।

আপনার কাজ শেষ করার পরে লগ স্তরটি সেট করতে মনে রাখবেন।


আমি ইতিমধ্যে লগব্যাক-ব্যাকড এসএলএফ 4 জ ব্যবহার করছিলাম এবং এটি আমাকে তত্ক্ষণাত্ আমার ইউনিট পরীক্ষাগুলি পরিষ্কার করার অনুমতি দেয়। ধন্যবাদ!
ল্যাম্বার্ট

4
ধন্যবাদ এটি আমার প্রথম -1, ধন্যবাদ। আমি বিশ্বাস করি আপনি ভুল বলেছেন। লগব্যাক এসএলএফ 4 জে ব্যবহার করে, সুতরাং উত্তরটি প্রাসঙ্গিক।
18

4
@ অ্যালেক্সান্দ্রোস জেলবেসিস আপনার প্রশ্নটি পুনরায় পড়া উচিত। এটি এমন একটি পদ্ধতির জন্য জিজ্ঞাসা করা হয়েছিল যা কোনও স্তরে প্রোগ্রামগতভাবে একটি লগ বার্তা লগ করতে পারে। আপনি কেবলমাত্র একটির জন্য নয়, সমস্ত বার্তাগুলির জন্য রুট লগারের স্তর পরিবর্তন করছেন।
জানু

7

এটি একটি enumএবং একটি সহায়ক পদ্ধতির সাহায্যে করা যেতে পারে :

enum LogLevel {
    TRACE,
    DEBUG,
    INFO,
    WARN,
    ERROR,
}

public static void log(Logger logger, LogLevel level, String format, Object[] argArray) {
    switch (level) {
        case TRACE:
            logger.trace(format, argArray);
            break;
        case DEBUG:
            logger.debug(format, argArray);
            break;
        case INFO:
            logger.info(format, argArray);
            break;
        case WARN:
            logger.warn(format, argArray);
            break;
        case ERROR:
            logger.error(format, argArray);
            break;
    }
}

// example usage:
private static final Logger logger = ...
final LogLevel level = ...
log(logger, level, "Something bad happened", ...);

আপনি এর অন্যান্য রূপগুলি যুক্ত করতে পারেন log, যদি আপনি এসএলএফ 4 জ এর 1-পরামিতি বা 2-পরামিতি warn/ error/ ইত্যাদির জেনেরিক সমতুল্য চান তবে বলুন । পদ্ধতি।


4
সত্য, তবে slf4j উদ্দেশ্যটি লগের মোড়ক লেখার জন্য নয়।
djjeck

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

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

5

যে কেউ এই সমস্যার পুরোপুরি এসএলএফ 4 জে সামঞ্জস্যপূর্ণ সমাধান চাইছেন তিনি লিডালিয়া এসএলএফ 4 জ এক্সটেনশনগুলি চেক করে দেখতে চাইতে পারেন - এটি ম্যাভেন সেন্ট্রালে রয়েছে।


3

আমার সবেমাত্র এরকম কিছু দরকার ছিল এবং নিয়ে এসেছি:

@RequiredArgsConstructor //lombok annotation
public enum LogLevel{

    TRACE(l -> l::trace),
    INFO (l -> l::info),
    WARN (l -> l::warn),
    ERROR(l -> l::error);

    private final Function<Logger, Consumer<String>> function;

    public void log(Logger logger, String message) {
        function.apply(logger).accept(message);
    }
}

ব্যবহার:

    LogLevel level = LogLevel.TRACE;
    level.log(logger, "message");

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


এই দুর্দান্ত পদ্ধতির জন্য আপনাকে অনেক ধন্যবাদ - আমি আপনার ধারণার ভিত্তিতে একটি অনুরূপ উত্তর পোস্ট করেছি posted
স্লার্তিদান

DEBUGধ্রুবক হিসাবে অনুপস্থিত।
স্লার্তিদান

এই সমাধানটি সর্বদা LogLevelশ্রেণি হিসাবে এবং logপদ্ধতি হিসাবে লগ করবে , যা লগগুলিকে কম অর্থবহ করে তোলে।
স্লার্তিদান

3

এটা না sjf4j মধ্যে একটি লগ স্তর উল্লেখ করা সম্ভব 1.xবাক্সের বাইরে। তবে সমস্যাটি2.0 সমাধানের জন্য slf4j এর আশা রয়েছে । 2.0 এ এটির মতো দেখতে পাওয়া যাবে:

// POTENTIAL 2.0 SOLUTION
import org.slf4j.helpers.Util;
import static org.slf4j.spi.LocationAwareLogger.*;

// does not work with slf4j 1.x
Util.log(logger, DEBUG_INT, "hello world!");

এরই মধ্যে, slf4j 1.x এর জন্য, আপনি এই কাজেরটি ব্যবহার করতে পারেন:

এই ক্লাসটি আপনার ক্লাসপথে অনুলিপি করুন:

import org.slf4j.Logger;
import java.util.function.Function;

public enum LogLevel {

    TRACE(l -> l::trace, Logger::isTraceEnabled),
    DEBUG(l -> l::debug, Logger::isDebugEnabled),
    INFO(l -> l::info, Logger::isInfoEnabled),
    WARN(l -> l::warn, Logger::isWarnEnabled),
    ERROR(l -> l::error, Logger::isErrorEnabled);

    interface LogMethod {
        void log(String format, Object... arguments);
    }

    private final Function<Logger, LogMethod> logMethod;
    private final Function<Logger, Boolean> isEnabledMethod;

    LogLevel(Function<Logger, LogMethod> logMethod, Function<Logger, Boolean> isEnabledMethod) {
        this.logMethod = logMethod;
        this.isEnabledMethod = isEnabledMethod;
    }

    public LogMethod prepare(Logger logger) {
        return logMethod.apply(logger);
    }

    public boolean isEnabled(Logger logger) {
        return isEnabledMethod.apply(logger);
    }
}

তারপরে আপনি এটি ব্যবহার করতে পারেন:

Logger logger = LoggerFactory.getLogger(Application.class);

LogLevel level = LogLevel.ERROR;
level.prepare(logger).log("It works!"); // just message, without parameter
level.prepare(logger).log("Hello {}!", "world"); // with slf4j's parameter replacing

try {
    throw new RuntimeException("Oops");
} catch (Throwable t) {
    level.prepare(logger).log("Exception", t);
}

if (level.isEnabled(logger)) {
    level.prepare(logger).log("logging is enabled");
}

এটি এর মতো একটি লগ আউটপুট দেবে:

[main] ERROR Application - It works!
[main] ERROR Application - Hello world!
[main] ERROR Application - Exception
java.lang.RuntimeException: Oops
    at Application.main(Application.java:14)
[main] ERROR Application - logging is enabled

এটা কি মূল্য?

  • Proএটি উত্স কোডের অবস্থানটি রাখে (শ্রেণীর নাম, পদ্ধতির নাম, লাইন নম্বরগুলি আপনার কোডকে নির্দেশ করবে )
  • Proআপনি সহজেই ভেরিয়েবল , প্যারামিটার এবং রিটার্নের ধরণগুলি সংজ্ঞায়িত করতে পারেনLogLevel
  • Proআপনার ব্যবসায়ের কোডটি ছোট এবং পড়তে সহজ এবং কোন অতিরিক্ত নির্ভরতার প্রয়োজন নেই required

সর্বনিম্ন উদাহরণ হিসাবে উত্স কোডটি গিটহাবটিতে হোস্ট করা হয়েছে


দ্রষ্টব্য: LogMethodইন্টারফেসটি এর প্যাকেজের বাইরে ক্লাসগুলির সাথে কাজ করার জন্য সর্বজনীন হওয়া দরকার। ব্যতীত, এটি উদ্দেশ্য হিসাবে কাজ করে। ধন্যবাদ!
andrebrait

1

আমি যে পদ্ধতিটি ব্যবহার করি তা হ'ল ch.qos.logback মডিউলগুলি আমদানি করা এবং তারপরে একটি ch.qos.logback.classic.Logger এ slf4j লগার উদাহরণ টাইপ করুন। এই উদাহরণে একটি সেটলিভেল () পদ্ধতি অন্তর্ভুক্ত রয়েছে।

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

Logger levelSet = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);

// Now you can set the desired logging-level
levelSet.setLevel( Level.OFF );

সম্ভব লগিং-মাত্রা জানতে, আপনার জন্য সব সম্ভাব্য মান দেখতে ch.qos.logback বর্গ বিস্ফোরিত করা করতে পারেন শ্রেনী :

prompt$ javap -cp logback-classic-1.2.3.jar ch.qos.logback.classic.Level

ফলাফলগুলি নিম্নলিখিত:

{
   // ...skipping
   public static final ch.qos.logback.classic.Level OFF;
   public static final ch.qos.logback.classic.Level ERROR;
   public static final ch.qos.logback.classic.Level WARN;
   public static final ch.qos.logback.classic.Level INFO;
   public static final ch.qos.logback.classic.Level DEBUG;
   public static final ch.qos.logback.classic.Level TRACE;
   public static final ch.qos.logback.classic.Level ALL;
}

1

গতিবেগে লগ স্তর পরিবর্তন করা slf4j এপিআই দিয়ে সম্ভব নয় তবে আপনি নিজেরাই লগব্যাক কনফিগার করতে পারেন (যদি আপনি এটি ব্যবহার করেন)। সেক্ষেত্রে আপনার লগারের জন্য ফ্যাক্টরি ক্লাস তৈরি করুন এবং আপনার প্রয়োজনীয় কনফিগারেশন সহ রুট লগার প্রয়োগ করুন।

LoggerContext loggerContext = new LoggerContext();
ch.qos.logback.classic.Logger root = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

// Configure appender
final TTLLLayout layout = new TTLLLayout();
layout.start(); // default layout of logging messages (the form that message displays 
// e.g. 10:26:49.113 [main] INFO com.yourpackage.YourClazz - log message

final LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<>();
encoder.setCharset(StandardCharsets.UTF_8);
encoder.setLayout(layout);

final ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();
appender.setContext(loggerContext);
appender.setEncoder(encoder);
appender.setName("console");
appender.start();

root.addAppender(appender);

রুট লগারটি কনফিগার করার পরে (কেবলমাত্র একবারে যথেষ্ট) আপনি নতুন লগারের মাধ্যমে প্রতিনিধিত্ব করতে পারেন

final ch.qos.logback.classic.Logger logger = loggerContext.getLogger(clazz);

একই ব্যবহার করতে ভুলবেন না loggerContext

দেওয়া লগের সাথে দেওয়া লগ স্তর পরিবর্তন করা সহজ loggerContext

root.setLevel(Level.DEBUG);

1

উত্তরটি নিশ্চিত করুন ওন্দ্রেজ স্কোপেক

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;

var rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.TRACE);

আপনি ফলাফল পাবেন:

2020-05-14 14: 01: 16,644 ট্র্যাক [] [ওকসিএমমেট্রিক্স] পরীক্ষক কর্মী নিবন্ধিত মেট্রিক নামক মেট্রিকনাম [নাম = বাফারপুল-ওয়েট-টাইম-মোট, গ্রুপ = প্রযোজক-মেট্রিকস, বিবরণ = মোট কোনও সময় স্থান বরাদ্দের জন্য অপেক্ষা করেন ।, ট্যাগগুলি = {ক্লায়েন্ট-আইডি = প্রযোজক -২}]


0

আমি সবেমাত্র একটি অনুরূপ প্রয়োজনের মুখোমুখি হয়েছি। আমার ক্ষেত্রে, slf4j জাভা লগিং অ্যাডাপ্টারের (jdk14 এক) দিয়ে কনফিগার করা হয়েছে। নিম্নলিখিত কোড স্নিপেট ব্যবহার করে আমি রানটাইমে ডিবাগ স্তর পরিবর্তন করতে পরিচালিত করেছি:

Logger logger = LoggerFactory.getLogger("testing");
java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("testing");
julLogger.setLevel(java.util.logging.Level.FINE);
logger.debug("hello world");

4
অন্যান্য উত্তরের মতো এটিও মূল প্রশ্নটির দিকে লক্ষ্য করে না, এটি একটি ভিন্ন সমস্যা।
ই-রিজ

0

ম্যাসিমো ভার্জিলিওর উত্তরের উপর ভিত্তি করে, আমি অন্তর্দৃষ্টি ব্যবহার করে slf4j-log4j দিয়ে এটি পরিচালনা করতেও সক্ষম হয়েছি। এইচটিএইচ।

Logger LOG = LoggerFactory.getLogger(MyOwnClass.class);

org.apache.logging.slf4j.Log4jLogger LOGGER = (org.apache.logging.slf4j.Log4jLogger) LOG;

try {
    Class loggerIntrospected = LOGGER.getClass();
    Field fields[] = loggerIntrospected.getDeclaredFields();
    for (int i = 0; i < fields.length; i++) {
        String fieldName = fields[i].getName();
        if (fieldName.equals("logger")) {
            fields[i].setAccessible(true);
            org.apache.logging.log4j.core.Logger loggerImpl = (org.apache.logging.log4j.core.Logger) fields[i].get(LOGGER);
            loggerImpl.setLevel(Level.DEBUG);
        }
    }
} catch (Exception e) {
    System.out.println("ERROR :" + e.getMessage());
}

0

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

package test.lambda;
import java.util.function.*;
import org.slf4j.*;

public class LoggerLambda {
    private static final Logger LOG = LoggerFactory.getLogger(LoggerLambda.class);

    private LoggerLambda() {}

    public static void log(BiConsumer<? super String, ? super Object[]> logFunc, Supplier<Boolean> logEnabledPredicate, 
            String format, Object... args) {
        if (logEnabledPredicate.get()) {
            logFunc.accept(format, args);
        }
    }

    public static void main(String[] args) {
        int a = 1, b = 2, c = 3;
        Throwable e = new Exception("something went wrong", new IllegalArgumentException());
        log(LOG::info, LOG::isInfoEnabled, "a = {}, b = {}, c = {}", a, b, c);

        // warn(String, Object...) instead of warn(String, Throwable), but prints stacktrace nevertheless
        log(LOG::warn, LOG::isWarnEnabled, "error doing something: {}", e, e);
    }
}

যেহেতু slf4j একটি ভারসাম্য (যার স্ট্যাক ট্রেস লগ করা উচিত) ভারারাগস পরমের অভ্যন্তরে অনুমতি দেয় , তাই আমি মনে করি এর logচেয়ে অন্য গ্রাহকদের জন্য সহায়ক পদ্ধতি ওভারলোড করার দরকার নেই (String, Object[])


0

আমি প্রথমে এসএলএফ 4 জে লগার দৃষ্টান্তটি অনুরোধ করে এবং তারপরে বাঁধার উপর স্তর নির্ধারণ করে জেডকে 14 জনের জন্য এটি করতে পেরেছিলাম - আপনি লগ 4 জাই বাইন্ডিংয়ের জন্য এটি চেষ্টা করতে পারেন।

private void setLevel(Class loggerClass, java.util.logging.Level level) {
  org.slf4j.LoggerFactory.getLogger(loggerClass);
  java.util.logging.Logger.getLogger(loggerClass.getName()).setLevel(level);
}

-2

জাভা আত্মনির্মাণ ব্যবহার করে আপনি এটি করতে পারেন, উদাহরণস্বরূপ:

private void changeRootLoggerLevel(int level) {

    if (logger instanceof org.slf4j.impl.Log4jLoggerAdapter) {
        try {
            Class loggerIntrospected = logger.getClass();
            Field fields[] = loggerIntrospected.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                String fieldName = fields[i].getName();
                if (fieldName.equals("logger")) {
                    fields[i].setAccessible(true);
                    org.apache.log4j.Logger loggerImpl = (org.apache.log4j.Logger) fields[i]
                            .get(logger);

                    if (level == DIAGNOSTIC_LEVEL) {
                        loggerImpl.setLevel(Level.DEBUG);
                    } else {
                        loggerImpl.setLevel(org.apache.log4j.Logger.getRootLogger().getLevel());
                    }

                    // fields[i].setAccessible(false);
                }
            }
        } catch (Exception e) {
            org.apache.log4j.Logger.getLogger(LoggerSLF4JImpl.class).error("An error was thrown while changing the Logger level", e);
        }
    }

}

4
এটি স্পষ্টভাবে লগ 4 জকে বোঝায় এবং slf4j সাধারণভাবে নয়
থরবজর্ন রাভন অ্যান্ডারসেন

-6

না, এর বেশ কয়েকটি পদ্ধতি, তথ্য (), ডিবাগ (), সতর্কতা () ইত্যাদি রয়েছে (এটি অগ্রাধিকার ক্ষেত্রটি প্রতিস্থাপন করে)

সম্পূর্ণ লগার এপিআইয়ের জন্য http://www.slf4j.org/api/org/slf4j/Logger.html দেখুন ।


দুঃখিত, আমি এখন আপনি কি জিজ্ঞাসা করছি দেখুন। না, রানটাইমের সময় লগ স্তর পরিবর্তন করার কোনও জেনেরিক উপায় নেই তবে আপনি খুব সহজেই একটি স্যুইচ স্ট্যাচমেন্ট সহ কোনও সহায়ক পদ্ধতি প্রয়োগ করতে পারেন।
খ্রিস্ট

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