প্রোগ্রাম 4 লগ 4j2 এ লগ স্তর পরিবর্তন করুন


108

আমি প্রোগ্রাম 4 লগ 4 জ 2 এ লগ স্তর পরিবর্তন করতে আগ্রহী। আমি তাদের কনফিগারেশনের ডকুমেন্টেশনগুলি দেখার চেষ্টা করেছি তবে তাতে কিছু নেই বলে মনে হচ্ছে। আমি প্যাকেজটিও দেখার চেষ্টা করেছি: org.apache.logging.log4j.core.configতবে সেখানে কিছুই কার্যকর দেখা যায় নি।


2
আপনি যদি এখানে কোনও উত্তর না পান তবে মেল তালিকাটি চেষ্টা করে দেখুন, এটি সাধারণত প্রধান লেখকরা 2 দিনের মধ্যে একবার দেখে। তারপরে ফিরে আসুন এবং আপনার নিজের প্রশ্নের উত্তর দিন :-)
tgkprog

উত্তর:


138

লগ 4j2 সংস্করণ 2.4 এফএকিউ অনুসারে সম্পাদিত

আপনি Log4j কোর থেকে ক্লাস কনফিগারারের সাথে লগারের স্তর নির্ধারণ করতে পারেন। কিন্তু জেনে রাখুন যে কনফিগারেশন ব্যবস্থা বর্গ পাবলিক API- এর অংশ নয় হও।

// org.apache.logging.log4j.core.config.Configurator;
Configurator.setLevel("com.example.Foo", Level.DEBUG);

// You can also set the root logger:
Configurator.setRootLevel(Level.DEBUG);

উৎস

লগ 4 জ 2 সংস্করণ 2.0.2 এ প্রবর্তিত এপিআইতে পরিবর্তনগুলি প্রতিফলিত করতে সম্পাদিত

আপনি যদি রুট লগার স্তরটি পরিবর্তন করতে চান তবে এই জাতীয় কিছু করুন:

LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); 
loggerConfig.setLevel(level);
ctx.updateLoggers();  // This causes all Loggers to refetch information from their LoggerConfig.

লগারগারফিগের জাভাদোক এখানে


3
ডান এবং আপনি যদি কোনও নির্দিষ্ট লগারের জন্য পরিবর্তন করতে চান (একটি শ্রেণি / প্যাকেজের) সেই লগার, সেটলভেল এবং আপডেটলগারগুলির প্রসঙ্গটি পান।
tgkprog

34
লগিংয়ের মাত্রা নির্ধারণের জন্য এই জাতীয় সংশ্লেষিত উপায়। আমি নিশ্চিত যে লগ 4j এর পূর্ববর্তী সংস্করণগুলিতে মূল এক লাইন পরিবর্তে পাঁচ লাইন কোডের সাথে এটি করার কারণ রয়েছে তবে আমি এটি দেখতে পাচ্ছি না। যাই হোক না কেন, এর জন্য ধন্যবাদ, @ স্লাডভাক!
ঝড়

1
.updateLoggers () প্রয়োজনীয় বলে মনে হয় না। দেখে মনে হচ্ছে .setLevel () দিয়ে সম্পন্ন পরিবর্তনগুলি তাত্ক্ষণিকভাবে প্রয়োগ করা হয়েছে।
zbyszek

1
আপনি নতুন লগারকনফিগ যুক্ত করলেও আপডেটলগারদের কলটি সর্বদা প্রয়োজন। আপডেটলগারগুলি সমস্ত লগারকে লগার কনফিগগুলির সাথে নিজেকে যুক্ত করে এবং তাদের লগ স্তরকে তাদের সম্পর্কিত লগার কনফিগের পরিবর্তিত করে causes যদি আপনি একটি নতুন লগার কনফিগ যুক্ত করেন তবে নতুন লগার কনফিগ প্যাটার্নের সাথে মেলে এমন কোনও লগার এতে পুনঃনির্দেশিত হবে। "সংশ্লেষিত" উপায়টি প্রয়োজনীয় কারণ লোগার এবং তাদের কনফিগারেশনটি লগ 4 জ 2 এ পৃথক করা হয়েছে।
rgoers

1
এখানে একটি উত্তর যে একটি আপডেট প্রদান করে, 1- বা Log4J এর নতুন সংস্করণে জন্য 2-লাইন সমাধান stackoverflow.com/a/44678752/1339923
Lambart

37

@ স্লাডভাকের গৃহীত উত্তর আমার জন্য লগ 4 জে ২.৮.২ এর জন্য কাজ করে না । নিম্নলিখিতগুলি করেছে।

Level সর্বজনীনভাবে লগটি পরিবর্তন করতে:

Configurator.setAllLevels(LogManager.getRootLogger().getName(), level);

Levelশুধুমাত্র বর্তমান শ্রেণীর জন্য লগ পরিবর্তন করতে , ব্যবহার করুন:

Configurator.setLevel(LogManager.getLogger(CallingClass.class).getName(), level);

1
আমার ভোট পেয়েছে কারণ আপনি নামটিকে স্ট্রিং হিসাবে হার্ড কোডিংয়ের পরিবর্তে লগারদের থেকে নিজের নাম টেনেছেন।
DWoldrich

18

আপনি যদি কোনও একক নির্দিষ্ট লগার স্তর পরিবর্তন করতে চান (কনফিগারেশন ফাইলে কনফিগার করা রুট লগার বা লগার নয়) আপনি এটি করতে পারেন:

public static void setLevel(Logger logger, Level level) {
    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();

    LoggerConfig loggerConfig = config.getLoggerConfig(logger.getName());
    LoggerConfig specificConfig = loggerConfig;

    // We need a specific configuration for this logger,
    // otherwise we would change the level of all other loggers
    // having the original configuration as parent as well

    if (!loggerConfig.getName().equals(logger.getName())) {
        specificConfig = new LoggerConfig(logger.getName(), level, true);
        specificConfig.setParent(loggerConfig);
        config.addLogger(logger.getName(), specificConfig);
    }
    specificConfig.setLevel(level);
    ctx.updateLoggers();
}

3
এটি আমার লগার মোটেও প্রভাব ফেলেনি। আমি ব্যবহার করেছি setLevel(logger, Level.ERROR);এবং লগার.ডিগব্যাগের বিবৃতি এখনও মুদ্রিত। আমার লগ 4j2.xML ফাইলটি পেস্টবিন.
নুমেনন

আমি কোড আপডেট করেছি। এটিতে কোনও সমস্যা আছে কিনা তা আমাকে জানান।
জার্গ ফ্রেডরিচ

4
লোগোজেজে ২. 2.-তে লগগারকন্টেক্সটে একটি getConfigration () পদ্ধতি নেই, দেখুন logging.apache.org/log4j/2.x/log4j-api/apidocs/index.html?org/…
ম্যাক্সেক্সিম

log4j-core-2.7.jar এর চূড়ান্ত LoggerContext ctx = (LoggerContext) LogManager.getContext (মিথ্যা) হিসাবে ব্যবহার করা যেতে পারে; চূড়ান্ত কনফিগারেশন কনফিগারেশন = ctx.getConfigration ();
অলৌকিক

3
এটি দেখার পরে আমি ভাবছি .. "সম্ভবত তারা কি চান না যে আমরা রানটাইমে স্তর পরিবর্তন করবো?"
Koray Tugay

13

আমি এখানে একটি ভাল উত্তর পেয়েছি: https://garygregory.wordpress.com/2016/01/11/changing-log-levels-in-log4j2/

নির্দিষ্ট লগারের জন্য স্তর নির্ধারণ করতে আপনি org.apache.logging.log4j.core.config.Configurator ব্যবহার করতে পারেন।

Logger logger = LogManager.getLogger(Test.class);
Configurator.setLevel(logger.getName(), Level.DEBUG);

2
এই উত্তরটি একই সমাধানটি দেখায়, পাশাপাশি এটি রুট লগারের জন্য কীভাবে সেট করা যায় - যা কখনও কখনও দরকারী: stackoverflow.com/a/44678752/1339923
লাম্বার্ট

4

প্রোগ্রামেটিক পদ্ধতির পরিবর্তে অনুপ্রবেশকারী। সম্ভবত আপনার লগ 4 জ 2 দ্বারা প্রদত্ত জেএমএক্স সমর্থন পরীক্ষা করা উচিত:

  1. আপনার অ্যাপ্লিকেশনটিতে জেএমএক্স পোর্ট সক্ষম করুন:

    -Dcom.sun.management.jmxremote.port = [port_num]

  2. আপনার অ্যাপ্লিকেশনটি সম্পাদন করার সময় উপলব্ধ যে কোনও জেএমএক্স ক্লায়েন্ট ব্যবহার করুন (JVM JAVA_HOME / bin / jconsole.exe তে একটি সরবরাহ করে)।

  3. জে কনসোলে "org.apache.logging.log4j2.Loggers" বিনের সন্ধান করুন

  4. অবশেষে আপনার লগারের স্তর পরিবর্তন করুন

আমি এর বেশিরভাগ জিনিসটি পছন্দ করি তা হ'ল এটি পরিচালনা করার জন্য আপনাকে আপনার কোড বা কনফিগারেশনটি পরিবর্তন করতে হবে না। এটি সমস্ত বাহ্যিক এবং স্বচ্ছ।

আরও তথ্য: http://logging.apache.org/log4j/2.x/manual/jmx.html


খুব সহায়ক, ধন্যবাদ!
ড্যারেন পার্কার

3

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

    public class LogConfigManager {

    public void setLogLevel(String loggerName, String level) {
        Level newLevel = Level.valueOf(level);
        LoggerContext logContext = (LoggerContext) LogManager.getContext(false);
        Configuration configuration = logContext.getConfiguration();
        LoggerConfig loggerConfig = configuration.getLoggerConfig(loggerName);
        // getLoggerConfig("a.b.c") could return logger for "a.b" if there is no logger for "a.b.c"
        if (loggerConfig.getName().equalsIgnoreCase(loggerName)) {
            loggerConfig.setLevel(newLevel);
            log.info("Changed logger level for {} to {} ", loggerName, newLevel);
        } else {
            // create a new config.
            loggerConfig = new LoggerConfig(loggerName, newLevel, false);
            log.info("Adding config for: {} with level: {}", loggerConfig, newLevel);
            configuration.addLogger(loggerName, loggerConfig);


            LoggerConfig parentConfig = loggerConfig.getParent();
            do {
                for (Map.Entry<String, Appender> entry : parentConfig.getAppenders().entrySet()) {
                    loggerConfig.addAppender(entry.getValue(), null, null);
                }
                parentConfig = parentConfig.getParent();
            } while (null != parentConfig && parentConfig.isAdditive());
        }
        logContext.updateLoggers();
    }
}

একই জন্য একটি পরীক্ষা কেস

public class LogConfigManagerTest {
    @Test
    public void testLogChange() throws IOException {
        LogConfigManager logConfigManager = new LogConfigManager();
        File file = new File("logs/server.log");
        Files.write(file.toPath(), new byte[0], StandardOpenOption.TRUNCATE_EXISTING);
        Logger logger = LoggerFactory.getLogger("a.b.c");
        logger.debug("Marvel-1");
        logConfigManager.setLogLevel("a.b.c", "debug");
        logger.debug("DC-1");
        // Parent logger level should remain same
        LoggerFactory.getLogger("a.b").debug("Marvel-2");
        logConfigManager.setLogLevel("a.b.c", "info");
        logger.debug("Marvel-3");
        // Flush everything
        LogManager.shutdown();

        String content = Files.readAllLines(file.toPath()).stream().reduce((s1, s2) -> s1 + "\t" + s2).orElse(null);
        Assert.assertEquals(content, "DC-1");
    }
}

নিম্নলিখিত log4j2.xml ধরে নেওয়া ক্লাসপথে রয়েছে

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

    <Appenders>
        <File name="FILE" fileName="logs/server.log" append="true">
            <PatternLayout pattern="%m%n"/>
        </File>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%m%n"/>
        </Console>
    </Appenders>

    <Loggers>
        <AsyncLogger name="a.b" level="info">
            <AppenderRef ref="STDOUT"/>
            <AppenderRef ref="FILE"/>
        </AsyncLogger>

        <AsyncRoot level="info">
            <AppenderRef ref="STDOUT"/>
        </AsyncRoot>
    </Loggers>

</Configuration>

2

একটি অ-স্বাভাবিক উপায় আমি খুঁজে পেয়েছি হ'ল ভিন্ন লগিং স্তরের সাথে দুটি পৃথক ফাইল তৈরি করা।
উদাহরণ স্বরূপ. log4j2.xML এবং log4j-debug.xml এখন এই ফাইলগুলি থেকে কনফিগারেশন পরিবর্তন করুন।
কোডের উদাহরণ:

ConfigurationFactory configFactory = XmlConfigurationFactory.getInstance();
            ConfigurationFactory.setConfigurationFactory(configFactory);
            LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            ClassLoader classloader = Thread.currentThread().getContextClassLoader();
            InputStream inputStream = classloader.getResourceAsStream(logFileName);
            ConfigurationSource configurationSource = new ConfigurationSource(inputStream);

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